diff --git a/.azure-pipeline-task.yml b/.azure-pipeline-task.yml deleted file mode 100644 index d83d70d..0000000 --- a/.azure-pipeline-task.yml +++ /dev/null @@ -1,14 +0,0 @@ -parameters: - vstsTasks: [] - -steps: -- ${{ each vstsTask in parameters.vstsTasks }}: - - script: | - npm install --production - workingDirectory: ${{ vstsTask }}/v2 - displayName: ${{ vstsTask }} - npm install - - - script: | - npm run build - workingDirectory: ${{ vstsTask }}/v2 - displayName: ${{ vstsTask }} - npm run build \ No newline at end of file diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml deleted file mode 100644 index 9894ed7..0000000 --- a/.azure-pipelines.yml +++ /dev/null @@ -1,54 +0,0 @@ -variables: - extensionversion: "0.0.0" - -pool: - vmImage: "windows-2019" - -steps: - - task: NodeTool@0 - displayName: "Install Node.js" - inputs: - versionSpec: "10.x" - - - template: .azure-pipeline-task.yml - parameters: - vstsTasks: - - delete-adf-items - - deploy-adf-json - - toggle-adf-trigger - - trigger-adf-pipeline - - - script: | - npm install tfx-cli -g --silent - displayName: "install tfx-cli" - - - script: | - tfx extension create --manifest-globs ./vss-extension.json - displayName: "create extension" - - - script: | - node -e "const v = require('./vss-extension.json').version;console.log('##vso[task.setvariable variable=extensionversion]' + v);" - displayName: "extract version name" - - - task: GitHubRelease@0 - displayName: "release to github" - inputs: - gitHubConnection: GitHub - repositoryName: liprec/vsts-publish-adf - action: edit - target: $(Build.SourceVersion) - tagSource: manual - tag: $(extensionversion) - title: Version $(extensionversion) - isDraft: true - addChangeLog: true - assets: liprec.vsts-publish-adf-$(extensionversion).vsix - assetUploadMode: "delete" - releaseNotesSource: input - releaseNotes: | - # Azure Data Factory - This extension adds release tasks related to Azure Data Factory to Visual Studio Team Service. - - ## Availability - This version is available at the Visual Studio Marketplace: http://marketplace.visualstudio.com/items?itemName=liprec.vsts-publish-adf - condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d04bf37 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,75 @@ +name: Build and test + +on: + push: + branches: [develop, main] + +jobs: + build: + name: Build, test and pack tasks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup NodeJS + uses: actions/setup-node@v1 + with: + node-version: 12 + - name: install modclean + run: | + npm install modclean + env: + CI: true + - name: build tasks + run: | + tasks=./**/v2 + for task in $tasks + do + echo Build and test $task + cd $task + npm install + npm run test + echo Prepare 'node_modules' of $task + rm -Rf node_modules + npm install --production + $GITHUB_WORKSPACE/node_modules/.bin/modclean -r -n default:safe,default:caution + cd $GITHUB_WORKSPACE + done + - name: install tfx-cli + run: | + npm install tfx-cli + env: + CI: true + # Production package + - name: run tfx-cli - production version + if: ${{ endsWith(github.ref, 'main') }} + run: | + $GITHUB_WORKSPACE/node_modules/.bin/tfx extension create --manifest-globs $GITHUB_WORKSPACE/vss-extension.json + - name: extract version name - production version + if: ${{ endsWith(github.ref, 'main') }} + id: extract_version + run: | + node -e "const v = require('./vss-extension.json').version;console.log('::set-output name=version::' + v);" + - name: store extension - production version + if: ${{ endsWith(github.ref, 'main') }} + uses: actions/upload-artifact@v2 + with: + name: liprec.vsts-publish-adf-${{ steps.extract_version.outputs.version }} + path: | + liprec.vsts-publish-adf-${{ steps.extract_version.outputs.version }}.vsix + # Preview package + - name: run tfx-cli - preview version + if: ${{ endsWith(github.ref, 'develop') }} + run: | + $GITHUB_WORKSPACE/node_modules/.bin/tfx extension create --manifest-globs $GITHUB_WORKSPACE/vss-extension-preview.json + - name: extract version name - preview version + if: ${{ endsWith(github.ref, 'develop') }} + id: extract_version_preview + run: | + node -e "const v = require('./vss-extension-preview.json').version;console.log('::set-output name=version::' + v);" + - name: store extension - preview version + if: ${{ endsWith(github.ref, 'develop') }} + uses: actions/upload-artifact@v2 + with: + name: liprec.vsts-publish-adf-preview-${{ steps.extract_version_preview.outputs.version }} + path: | + liprec.vsts-publish-adf-preview-${{ steps.extract_version_preview.outputs.version }}.vsix diff --git a/.vscode/settings.json b/.vscode/settings.json index 517baa7..288d474 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,12 @@ { + "editor.tabSize": 4, + "editor.insertSpaces": true, "editor.formatOnSave": true, + "[yaml]": { + "editor.tabSize": 2, + "editor.defaultFormatter": "redhat.vscode-yaml" + }, + "files.eol": "\n", "cSpell.words": [ "datafactory", "dataset", diff --git a/README.md b/README.md index 83aee88..bf7e6c0 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,53 @@ -[![Build Status](https://dev.azure.com/datascenarios/GitHub%20Projects/_apis/build/status/vsts-publish-adf?branchName=master)](https://dev.azure.com/datascenarios/GitHub%20Projects/_build/latest?definitionId=23&branchName=master) - # Azure Data Factory This extension adds release tasks related to Azure Data Factory (V1 and V2) to release pipelines of Azure DevOps. -## Azure Data Factory Deployment - -Azure DevOps release task that will deploy JSON files with definition of Linked Services, Datasets, Pipelines and/or Triggers (V2) to an existing Azure Data Factory. -![](images/screenshot-2.png) - -[More information](deploy-adf-json/README.md) - -## Azure Data Factory Trigger - -Azure DevOps release task to either Start or Stop Azure Data Factory triggers. -![](images/screenshot-4.png) - -[More information](toggle-adf-trigger/README.md) - -## Azure Data Factory Delete Items - -Azure DevOps release task to delete Azure Data Factory items, like triggers, pipelines, datasets and linked services. -![](images/screenshot-5.png) - -[More information](delete-adf-items/README.md) +## Build status -## Azure Data Factory Trigger Pipelines +| Branch | status | +| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Main | [![Build and test](https://github.com/liprec/vsts-publish-adf/workflows/Build%20and%20test/badge.svg?branch=main)](https://github.com/liprec/vsts-publish-adf/actions?query=branch%3Amain+workflow%3A%22Build+and+test%22) | +| Develop | [![Build and test](https://github.com/liprec/vsts-publish-adf/workflows/Build%20and%20test/badge.svg?branch=develop)](https://github.com/liprec/vsts-publish-adf/actions?query=branch%3Adevelop+workflow%3A%22Build+and+test%22) | -Azure DevOps release task to trigger an Azure Data Factory pipeline to start. -![](images/screenshot-6.png) +## Azure Data Factory Azure DevOps tasks -[More information](trigger-adf-pipeline/README.md) +See https://azurebi-docs.jppp.org/vsts-extensions/azure-data-factory.html for the complete documentation. -## Azure Data Factory Pipelines Management (Deprecated) - -Azure DevOps release task to either suspend or resume all pipelines of an Azure Data Factory. -![](images/screenshot-3.png) +## Release notes -[More information](suspend-adf-pipeline/README.md) +**2.3** -## Release notes +- Added support for dependencies between pipelines and linked services +- Added release gate (serverless task) for active runs +- Changed filters (trigger/delete task) to RegEx filters **2.2** -- Added support for deploy Data flows definition files -- Added paging support for data factories with more than 50 objects -- Adding support for trigger parameter files +- Added support for deploy Data flows definition files +- Added paging support for data factories with more than 50 objects +- Adding support for trigger parameter files **2.0.0** -- Added new task: Delete Items -- Added new task: Toggle Pipeline -- Rewrite to platform independent version by using NodeJS and REST APIs -- This version only support Azure Data Factory v2 -- Readme updated to version 2 functionality + +- Added new task: Delete Items +- Added new task: Toggle Pipeline +- Rewrite to platform independent version by using NodeJS and REST APIs +- This version only support Azure Data Factory v2 +- Readme updated to version 2 functionality **1.5.7** -- Added support for V2 deployments -- Added trigger start/stop task (V2) + +- Added support for V2 deployments +- Added trigger start/stop task (V2) **1.0.7** -- Add extra error logging + +- Add extra error logging **1.0.5** -- [Bug] Fixed suspend/resume logic + +- [Bug] Fixed suspend/resume logic **1.0.0** -- Initial public release \ No newline at end of file + +- Initial public release diff --git a/delete-adf-items/v2/.mocharc.json b/delete-adf-items/v2/.mocharc.json new file mode 100644 index 0000000..4552636 --- /dev/null +++ b/delete-adf-items/v2/.mocharc.json @@ -0,0 +1,6 @@ +{ + "extension": ["ts"], + "spec": "**/*.spec.ts", + "require": "ts-node/register", + "reporter": ["list"] +} diff --git a/delete-adf-items/v2/deleteadfitem.spec.ts b/delete-adf-items/v2/deleteadfitem.spec.ts new file mode 100644 index 0000000..1e866bd --- /dev/null +++ b/delete-adf-items/v2/deleteadfitem.spec.ts @@ -0,0 +1,35 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +describe("delete-adf-items tests", function () {}); diff --git a/delete-adf-items/v2/deleteadfitems.ts b/delete-adf-items/v2/deleteadfitems.ts index aab4e66..40b963b 100644 --- a/delete-adf-items/v2/deleteadfitems.ts +++ b/delete-adf-items/v2/deleteadfitems.ts @@ -26,51 +26,36 @@ * THE SOFTWARE. */ -import * as Q from "q"; import throat from "throat"; -import * as task from "azure-pipelines-task-lib/task"; -import * as path from "path"; -import * as msRestAzure from "ms-rest-azure"; -import { TaskParameters, SortingDirection } from "./models/taskParameters"; -import { AzureModels } from "./models/azureModels"; - -import AzureServiceClient = msRestAzure.AzureServiceClient; -import { UrlBasedRequestPrepareOptions } from "./node_modules/ms-rest"; - -task.setResourcePath(path.join(__dirname, "../task.json")); - -enum DatafactoryTypes { - Pipeline = "pipeline", - Dataflow = "dataflow", - Dataset = "dataset", - Trigger = "trigger", - LinkedService = "linked service", -} +import { + error, + warning, + loc, + setResourcePath, + debug, + getVariable, + TaskResult, + setResult, +} from "azure-pipelines-task-lib/task"; +import { join } from "path"; +import { AzureServiceClient, loginWithServicePrincipalSecret } from "ms-rest-azure"; +import { UrlBasedRequestPrepareOptions, Mapper } from "ms-rest"; -interface DatafactoryOptions { - azureClient?: AzureServiceClient; - subscriptionId: string; - resourceGroup: string; - dataFactoryName: string; -} - -interface DatafactoryTaskOptions { - continue: boolean; - throttle: number; - sorting: SortingDirection; -} +import { TaskParameters } from "./models/taskParameters"; +import { AzureModels } from "./models/azureModels"; +import { addSummary, findDependency, splitBuckets } from "./lib/helpers"; +import { DatafactoryOptions, DatafactoryTaskOptions, DatafactoryTaskObject } from "./lib/interfaces"; +import { DatafactoryTypes, SortingDirection } from "./lib/enums"; +import { wildcardFilter } from "./lib/helpers"; -interface DatafactoryObject { - name: string; - type: DatafactoryTypes; -} +setResourcePath(join(__dirname, "../task.json")); function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - msRestAzure.loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { + loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { if (err) { - task.error(task.loc("Generic_LoginAzure", err.message)); - reject(task.loc("Generic_LoginAzure", err.message)); + error(loc("Generic_LoginAzure", err.message)); + reject(loc("Generic_LoginAzure", err.message)); } resolve(new AzureServiceClient(credentials, {})); }); @@ -79,24 +64,24 @@ function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err) { - task.error(task.loc("Generic_CheckDataFactory", err)); - reject(task.loc("Generic_CheckDataFactory", err)); + error(loc("Generic_CheckDataFactory", err)); + reject(loc("Generic_CheckDataFactory", err)); } - if (response.statusCode !== 200) { - task.error(task.loc("Generic_CheckDataFactory2", dataFactoryName)); - reject(task.loc("Generic_CheckDataFactory2", dataFactoryName)); + if (response && response.statusCode !== 200) { + error(loc("Generic_CheckDataFactory2", dataFactoryName)); + reject(loc("Generic_CheckDataFactory2", dataFactoryName)); } else { resolve(true); } @@ -109,9 +94,9 @@ function getObjects( taskOptions: DatafactoryTaskOptions, datafactoryType: DatafactoryTypes, filter: string -): Promise { - return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, +): Promise { + return new Promise((resolve, reject) => { + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; @@ -133,40 +118,65 @@ function getObjects( objectType = "linkedservices"; break; } - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/${objectType}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, async (err, result, request, response) => { + const request = azureClient.sendRequest(options, async (err, result, request, response) => { if (err) { - task.error(task.loc("DeleteAdfItems_GetObjects", datafactoryType, err.message)); - reject(task.loc("DeleteAdfItems_GetObjects", datafactoryType, err.message)); - } else if (response.statusCode !== 200) { - task.debug(task.loc("DeleteAdfItems_GetObjects2", datafactoryType)); - reject(task.loc("DeleteAdfItems_GetObjects2", datafactoryType)); + error(loc("DeleteAdfItems_GetObjects", datafactoryType, err.message)); + reject(loc("DeleteAdfItems_GetObjects", datafactoryType, err.message)); + } else if (response && response.statusCode !== 200) { + debug(loc("DeleteAdfItems_GetObjects2", datafactoryType)); + reject(loc("DeleteAdfItems_GetObjects2", datafactoryType)); } else { let objects = JSON.parse(JSON.stringify(result)); let items = objects.value; let nextLink = objects.nextLink; while (nextLink !== undefined) { - let result = await processNextLink(datafactoryOption, nextLink); + const result = await processNextLink(datafactoryOption, nextLink); objects = JSON.parse(JSON.stringify(result)); items = items.concat(objects.value); nextLink = objects.nextLink; } if (filter) - items = items.filter((item) => { + items = items.filter((item: any) => { return wildcardFilter(item.name, filter); }); taskOptions.sorting === SortingDirection.Ascending - ? items.sort((item1, item2) => (item1.name > item2.name) - (item1.name < item2.name)) - : items.sort((item1, item2) => (item2.name > item1.name) - (item2.name < item1.name)); + ? items.sort( + (item1: any, item2: any) => (item1.name > item2.name) - (item1.name < item2.name) + ) + : items.sort( + (item1: any, item2: any) => (item2.name > item1.name) - (item2.name < item1.name) + ); console.log(`Found ${items.length} ${datafactoryType}(s).`); resolve( - items.map((value) => { - return { name: value.name, type: datafactoryType }; + items.map((item: any) => { + let dependency: string[]; + switch (datafactoryType) { + case DatafactoryTypes.LinkedService: + dependency = taskOptions.detectDependency + ? findDependency(item, "LinkedServiceReference") + : []; + break; + case DatafactoryTypes.Pipeline: + dependency = taskOptions.detectDependency + ? findDependency(item, "PipelineReference") + : []; + break; + default: + dependency = []; + break; + } + return { + name: item.name, + type: datafactoryType, + dependency, + bucket: dependency.length === 0 ? 0 : -1, + }; }) ); } @@ -175,14 +185,14 @@ function getObjects( } function processNextLink(datafactoryOption: DatafactoryOptions, nextLink: string): Promise { - const azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, options: UrlBasedRequestPrepareOptions = { method: "GET", url: nextLink, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - task.debug(`Following next link`); + debug(`Following next link`); return new Promise((resolve, reject) => { azureClient.sendRequest(options, (err, result, request, response) => { resolve(result); @@ -193,14 +203,14 @@ function processNextLink(datafactoryOption: DatafactoryOptions, nextLink: string function deleteItem( datafactoryOption: DatafactoryOptions, taskOptions: DatafactoryTaskOptions, - item: DatafactoryObject + item: DatafactoryTaskObject ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let objectName = item.name; + const objectName = item.name; let objectType; switch (item.type) { case DatafactoryTypes.Dataset: @@ -219,28 +229,29 @@ function deleteItem( objectType = "linkedservices"; break; } - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "DELETE", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/${objectType}/${objectName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err && !taskOptions.continue) { - task.error(task.loc("DeleteAdfItems_DeleteItem", item.type, err.message)); - reject(task.loc("DeleteAdfItems_DeleteItem", item.type, err.message)); - } else if (response.statusCode === 400) { + error(loc("DeleteAdfItems_DeleteItem", item.type, err.message)); + reject(loc("DeleteAdfItems_DeleteItem", item.type, err.message)); + } else if (response && (response.statusCode === 400 || response.statusCode === 429)) { if (taskOptions.continue) { - task.warning(task.loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); + warning(loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); resolve(false); } else { - task.error(task.loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); - reject(task.loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); + error(loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); + reject(loc("DeleteAdfItems_DeleteItem2", item.name, item.type, JSON.stringify(result))); } - } else if (response.statusCode === 204) { - task.debug(`'${item.name}' not found.`); + } else if (response && response.statusCode === 204) { + debug(`'${item.name}' not found.`); resolve(true); - } else if (response.statusCode === 200) { + } else if (response && response.statusCode === 200) { + console.log(`Deleted ${item.type} '${item.name}' in chunk: ${item.bucket}.`); resolve(true); } else { resolve(false); @@ -255,23 +266,44 @@ function deleteItems( filter: string, datafactoryType: DatafactoryTypes ): Promise { - if (hasError) { - return; - } // Some error occurred, so returning + // Some error occurred, so returning + if (hasError) return Promise.reject(true); return new Promise((resolve, reject) => { getObjects(datafactoryOption, taskOptions, datafactoryType, filter) - .then((items: DatafactoryObject[]) => { - processItems(datafactoryOption, taskOptions, datafactoryType, items) + .then((items: DatafactoryTaskObject[]) => { + const numberOfBuckets = splitBuckets(taskOptions.detectDependency, items); + if (numberOfBuckets === -1) { + debug(loc("DeleteAdfJson_Depencency2", datafactoryType)); + reject(loc("DeleteAdfJson_Depencency2", datafactoryType)); + } + const invalidItems = items.filter((item: DatafactoryTaskObject) => item.bucket === -1); + if (invalidItems.length !== 0) { + debug( + loc( + "DeleteAdfJson_Depencency", + datafactoryType, + invalidItems.map((item: DatafactoryTaskObject) => item.name).join(", ") + ) + ); + reject( + loc( + "DeleteAdfJson_Depencency", + datafactoryType, + invalidItems.map((item: DatafactoryTaskObject) => item.name).join(", ") + ) + ); + } + processItems(datafactoryOption, taskOptions, datafactoryType, items, numberOfBuckets) .catch((err) => { reject(err); }) - .then((result: boolean) => { - resolve(result); + .then((result: boolean | void) => { + resolve(result); }); }) .catch((err) => { - task.error(task.loc("DeleteAdfItems_DeleteItems", datafactoryType, err.message)); - reject(task.loc("DeleteAdfItems_DeleteItems", datafactoryType, err.message)); + error(loc("DeleteAdfItems_DeleteItems", datafactoryType, err.message)); + reject(loc("DeleteAdfItems_DeleteItems", datafactoryType, err.message)); }); }); } @@ -280,32 +312,45 @@ function processItems( datafactoryOption: DatafactoryOptions, taskOptions: DatafactoryTaskOptions, datafactoryType: DatafactoryTypes, - items: DatafactoryObject[] + items: DatafactoryTaskObject[], + numberOfBuckets: number ): Promise { - let firstError; + let firstError: boolean; return new Promise((resolve, reject) => { - let totalItems = items.length; + if (items.length === 0) return Promise.resolve(true); + let totalItems = 0; + let issues = 0; + const start: number = Date.now(); + const runs: DatafactoryTaskObject[][] = Array.from({ length: numberOfBuckets }, (_, index: number) => + items.filter((item: DatafactoryTaskObject) => item.bucket === index) + ).reverse(); + console.log( + `Start deleting ${items.length} ${datafactoryType}(s) in ${numberOfBuckets} chunk(s) with ${taskOptions.throttle} thread(s).` + ); - let process = Q.all( - items.map( - throat(taskOptions.throttle, (item) => { - console.log(`Delete ${datafactoryType} '${item.name}'.`); - return deleteItem(datafactoryOption, taskOptions, item); - }) - ) - ) + runs.reduce((promiseChain: Promise, currentTask: DatafactoryTaskObject[]) => { + return promiseChain.then((chainResults) => + Promise.all( + currentTask.map( + throat(taskOptions.throttle, (item) => { + totalItems++; + return deleteItem(datafactoryOption, taskOptions, item); + }) + ) + ).then((currentResult) => [...chainResults, currentResult]) + ); + }, Promise.resolve([])) .catch((err) => { + issues++; hasError = true; firstError = firstError || err; }) - .done((results: any) => { - console.log(`${totalItems} ${datafactoryType}(s) deleted.`); + .then((arrayOfResults: any) => { + const duration = Date.now() - start; + addSummary(totalItems, issues, datafactoryType, "deleted", undefined, duration); if (hasError) { reject(firstError); } else { - let issues = results.filter((result) => { - return !result; - }).length; if (issues > 0) { resolve(false); } else { @@ -317,69 +362,70 @@ function processItems( } async function main(): Promise { - let promise = new Promise(async (resolve, reject) => { + const promise = new Promise(async (resolve, reject) => { let taskParameters: TaskParameters; let azureModels: AzureModels; + let firstError: boolean; try { - let debugMode: string = task.getVariable("System.Debug"); - let isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; + const debugMode: string = getVariable("System.Debug"); + const isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; - task.debug("Task execution started ..."); + debug("Task execution started ..."); taskParameters = new TaskParameters(); - let connectedServiceName = taskParameters.ConnectedServiceName; - let resourceGroup = taskParameters.ResourceGroupName; - let dataFactoryName = taskParameters.DatafactoryName; + const connectedServiceName = taskParameters.ConnectedServiceName; + const resourceGroup = taskParameters.ResourceGroupName; + const dataFactoryName = taskParameters.DatafactoryName; - let serviceFilter = taskParameters.ServiceFilter; - let pipelineFilter = taskParameters.PipelineFilter; - let dataflowFilter = taskParameters.DataflowFilter; - let datasetFilter = taskParameters.DatasetFilter; - let triggerFilter = taskParameters.TriggerFilter; + const serviceFilter = taskParameters.ServiceFilter; + const pipelineFilter = taskParameters.PipelineFilter; + const dataflowFilter = taskParameters.DataflowFilter; + const datasetFilter = taskParameters.DatasetFilter; + const triggerFilter = taskParameters.TriggerFilter; - let taskOptions = { + const taskOptions = { continue: taskParameters.Continue, throttle: taskParameters.Throttle, sorting: taskParameters.Sorting, + detectDependency: taskParameters.DetectDependency, }; azureModels = new AzureModels(connectedServiceName); - let clientId = azureModels.getServicePrincipalClientId(); - let key = azureModels.getServicePrincipalKey(); - let tenantID = azureModels.getTenantId(); - let datafactoryOption: DatafactoryOptions = { + const clientId = azureModels.getServicePrincipalClientId(); + const key = azureModels.getServicePrincipalKey(); + const tenantID = azureModels.getTenantId(); + const datafactoryOption: DatafactoryOptions = { subscriptionId: azureModels.getSubscriptionId(), resourceGroup: resourceGroup, dataFactoryName: dataFactoryName, }; - let firstError; - task.debug("Parsed task inputs"); + debug("Parsed task inputs"); loginAzure(clientId, key, tenantID) .then((azureClient: AzureServiceClient) => { datafactoryOption.azureClient = azureClient; - task.debug("Azure client retrieved."); + debug("Azure client retrieved."); return checkDataFactory(datafactoryOption); }) .then((result) => { - task.debug(`Datafactory '${dataFactoryName}' exist`); - let deleteTasks = []; - if (triggerFilter !== null) { + debug(`Datafactory '${dataFactoryName}' exist`); + const deleteTasks = []; + if (triggerFilter) { deleteTasks.push({ filter: triggerFilter, type: DatafactoryTypes.Trigger }); } - if (pipelineFilter !== null) { + if (pipelineFilter) { deleteTasks.push({ filter: pipelineFilter, type: DatafactoryTypes.Pipeline }); } - if (dataflowFilter !== null) { + if (dataflowFilter) { deleteTasks.push({ filter: dataflowFilter, type: DatafactoryTypes.Dataflow }); } - if (datasetFilter !== null) { + if (datasetFilter) { deleteTasks.push({ filter: datasetFilter, type: DatafactoryTypes.Dataset }); } - if (serviceFilter !== null) { + if (serviceFilter) { deleteTasks.push({ filter: serviceFilter, type: DatafactoryTypes.LinkedService }); } - Q.all( + Promise.all( deleteTasks.map( throat(1, (task) => { return deleteItems(datafactoryOption, taskOptions, task.filter, task.type); @@ -390,11 +436,11 @@ async function main(): Promise { hasError = true; firstError = firstError || err; }) - .done((results: any) => { + .then((results: boolean[] | void) => { if (hasError) { reject(firstError); } else { - let issues = results.filter((result) => { + const issues = (results).filter((result: boolean) => { return !result; }).length; if (issues > 0) { @@ -415,17 +461,13 @@ async function main(): Promise { return promise; } -function wildcardFilter(value: string, rule: string) { - return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); -} - // Set generic error flag let hasError = false; main() .then((result) => { - task.setResult(result ? task.TaskResult.Succeeded : task.TaskResult.SucceededWithIssues, ""); + setResult(result ? TaskResult.Succeeded : TaskResult.SucceededWithIssues, ""); }) .catch((err) => { - task.setResult(task.TaskResult.Failed, err); + setResult(TaskResult.Failed, err); }); diff --git a/delete-adf-items/v2/icon.svg b/delete-adf-items/v2/icon.svg new file mode 100644 index 0000000..32f1f65 --- /dev/null +++ b/delete-adf-items/v2/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/delete-adf-items/v2/lib/enums.ts b/delete-adf-items/v2/lib/enums.ts new file mode 100644 index 0000000..64bd436 --- /dev/null +++ b/delete-adf-items/v2/lib/enums.ts @@ -0,0 +1,42 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export enum SortingDirection { + Ascending, + Descending, +} + +export enum DatafactoryTypes { + Pipeline = "pipeline", + Dataflow = "dataflow", + Dataset = "dataset", + Trigger = "trigger", + LinkedService = "linked service", +} diff --git a/delete-adf-items/v2/lib/helpers.spec.ts b/delete-adf-items/v2/lib/helpers.spec.ts new file mode 100644 index 0000000..01528cc --- /dev/null +++ b/delete-adf-items/v2/lib/helpers.spec.ts @@ -0,0 +1,96 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import { wildcardFilter } from "./helpers"; +import { getReadableFileSize, getReadableInterval } from "./helpers"; + +describe("Helpers", () => { + describe("getReadableInterval()", () => { + it("59000 => '59.000 second(s)'", () => { + assert.strictEqual(getReadableInterval(59000), "59.000 second(s)"); + }); + + it("59001 => '59.001 second(s)'", () => { + assert.strictEqual(getReadableInterval(59001), "59.001 second(s)"); + }); + + it("60001 => '1 minute(s) 0.001 seconds'", () => { + assert.strictEqual(getReadableInterval(60001), "1 minute(s) 0.001 second(s)"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1000 => 1000 byte", () => { + assert.strictEqual(getReadableFileSize(1000), "1000.0 bytes"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1024 => 1024.0 bytes", () => { + assert.strictEqual(getReadableFileSize(1024), "1024.0 bytes"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1025 => 1.0 kB", () => { + assert.strictEqual(getReadableFileSize(1025), "1.0 kB"); + }); + }); +}); + +describe("helpers.ts", function () { + describe("wildcardFilter()", () => { + describe("old wildcard functionality", () => { + it("validate 'trigger' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("trigger", "trigge*r"), true); + }); + + it("validate 'triggetr' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge*r"), true); + }); + }); + + describe("new RegExp functionality", () => { + it("validate 'triggetr' with rule 'trigge.r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge.r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.*r' => true", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.*r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.r' => false", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.r"), false); + }); + }); + }); +}); diff --git a/delete-adf-items/v2/lib/helpers.ts b/delete-adf-items/v2/lib/helpers.ts new file mode 100644 index 0000000..88e7fb1 --- /dev/null +++ b/delete-adf-items/v2/lib/helpers.ts @@ -0,0 +1,116 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { DatafactoryTypes } from "./enums"; +import { DatafactoryTaskObject } from "./interfaces"; + +export function addSummary( + totalItems: number, + issues: number, + datafactoryType: DatafactoryTypes, + action: string, + size: number | undefined, + duration: number +) { + console.log(``); + if (issues > 0) console.log(`${issues} ${datafactoryType}(s) failed`); + console.log(`${totalItems - issues} ${datafactoryType}(s) ${action}.\n\nStats:`); + console.log(`======`); + if (size) console.log(`Total size:\t${getReadableFileSize(size)}.`); + console.log(`Duration:\t${getReadableInterval(duration)}.`); + if (size) console.log(`Performance:\t${getReadableFileSize(size / (duration / 1000))}/sec.`); + console.log(`\t\t${(totalItems / (duration / 1000)).toFixed(1)} items/sec.`); +} + +export function getReadableFileSize(fileSizeInBytes: number): string { + var i = 0; + var byteUnits = [" bytes", " kB", " MB", " GB", " TB", "PB", "EB", "ZB", "YB"]; + while (fileSizeInBytes > 1024) { + fileSizeInBytes = fileSizeInBytes / 1024; + i++; + } + + return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]; +} + +export function getReadableInterval(interval: number): string { + let x = interval / 1000; + const seconds = (x % 60).toFixed(3); + x /= 60; + const minutes = Math.floor(x % 60); + x /= 60; + const hours = Math.floor(x % 24); + let r = ""; + if (hours !== 0) r += hours + " hour(s) "; + if (minutes !== 0) r += (minutes < 10 && hours > 0 ? "0" : "") + minutes + " minute(s) "; + return r + seconds + " second(s)"; +} + +export function splitBuckets(detectDependency: boolean, items: DatafactoryTaskObject[]): number { + let loop = detectDependency; + let change = true; + let numberOfBuckets = 1; + while (loop || change) { + loop = false; + change = false; + const loopItems = items.filter((item: DatafactoryTaskObject) => item.bucket === -1); + loopItems.forEach((item: DatafactoryTaskObject) => { + const pBucket = item.bucket; + const buckets = item.dependency.map((i) => { + const findItem = items.find((item) => item.name === i); + if (!findItem) return -1; + return findItem.bucket; + }); + if (Math.min(...buckets) !== -1) { + numberOfBuckets++; + change = true; + item.bucket = Math.max(...buckets) + 1; + } + loop = pBucket !== item.bucket; + }); + } + return numberOfBuckets; +} + +export function findDependency(json: any, type: string): string[] { + let refs: string[] = []; + if (json.referenceName && json.type === type) { + return [json.referenceName]; + } + for (const key in json) { + if (typeof json[key] === typeof [Object]) refs = refs.concat(findDependency(json[key], type)); + } + return refs.filter((current: string, index: number, array: string[]) => array.indexOf(current) === index); +} + +export function wildcardFilter(value: string, rule: string) { + if (RegExp(/\w\*.*/g).test(rule)) return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); + else return new RegExp(rule).test(value); +} diff --git a/delete-adf-items/v2/lib/interfaces.ts b/delete-adf-items/v2/lib/interfaces.ts new file mode 100644 index 0000000..3d81fc3 --- /dev/null +++ b/delete-adf-items/v2/lib/interfaces.ts @@ -0,0 +1,58 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import * as msRestAzure from "ms-rest-azure"; + +import AzureServiceClient = msRestAzure.AzureServiceClient; + +import { SortingDirection, DatafactoryTypes } from "./enums"; + +export interface DatafactoryOptions { + azureClient?: AzureServiceClient; + subscriptionId: string; + resourceGroup: string; + dataFactoryName: string; +} + +export interface DatafactoryTaskOptions { + continue: boolean; + throttle: number; + sorting: SortingDirection; + detectDependency: boolean; +} + +export interface DatafactoryTaskObject { + name: string; + json: string; + size: number; + type: DatafactoryTypes; + dependency: string[]; + bucket: number; +} diff --git a/delete-adf-items/v2/models/azureModels.ts b/delete-adf-items/v2/models/azureModels.ts index cf00a96..95ab781 100644 --- a/delete-adf-items/v2/models/azureModels.ts +++ b/delete-adf-items/v2/models/azureModels.ts @@ -43,13 +43,13 @@ export class AzureModels { this.connectedServiceName = connectedServiceName; if (this.connectedServiceName === "local") { // local debug - this.subscriptionId = task.getInput("subscriptionid", true); - this.subscriptionName = task.getInput("subscriptionname", true); - this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); - this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); - this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); - this.tenantId = task.getInput("tenantid", true); - this.url = task.getInput("connectedServiceNameUrl", true); + this.subscriptionId = task.getInput("subscriptionid", true); + this.subscriptionName = task.getInput("subscriptionname", true); + this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); + this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); + this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); + this.tenantId = task.getInput("tenantid", true); + this.url = task.getInput("connectedServiceNameUrl", true); } else { this.subscriptionId = task.getEndpointDataParameter(this.connectedServiceName, "subscriptionid", true); this.subscriptionName = task.getEndpointDataParameter( @@ -57,22 +57,20 @@ export class AzureModels { "subscriptionname", true ); - this.servicePrincipalClientId = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalid", - true + this.servicePrincipalClientId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalid", true) ); - this.servicePrincipalKey = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalkey", - true + this.servicePrincipalKey = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalkey", true) ); this.environmentAuthorityUrl = task.getEndpointDataParameter( this.connectedServiceName, "environmentAuthorityUrl", true ); - this.tenantId = task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false); + this.tenantId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false) + ); this.url = task.getEndpointUrl(this.connectedServiceName, true); } } catch (err) { diff --git a/delete-adf-items/v2/models/taskParameters.ts b/delete-adf-items/v2/models/taskParameters.ts index cbd65d9..2315900 100644 --- a/delete-adf-items/v2/models/taskParameters.ts +++ b/delete-adf-items/v2/models/taskParameters.ts @@ -27,32 +27,31 @@ */ import * as task from "azure-pipelines-task-lib/task"; +import { exit } from "process"; -export enum SortingDirection { - Ascending, - Descending, -} +import { SortingDirection } from "../lib/enums"; export class TaskParameters { private connectedServiceName: string; private resourceGroupName: string; private datafactoryName: string; - private serviceFilter: string; - private pipelineFilter: string; - private dataflowFilter: string; - private datasetFilter: string; - private triggerFilter: string; + private serviceFilter: string | undefined; + private pipelineFilter: string | undefined; + private dataflowFilter: string | undefined; + private datasetFilter: string | undefined; + private triggerFilter: string | undefined; private continue: boolean; private throttle: number; - private sorting: SortingDirection; + private sorting: SortingDirection = SortingDirection.Ascending; + private detectDependency: boolean; constructor() { try { - this.connectedServiceName = task.getInput("ConnectedServiceName", true); - this.resourceGroupName = task.getInput("ResourceGroupName", true); - this.datafactoryName = task.getInput("DatafactoryName", true); + this.connectedServiceName = task.getInput("ConnectedServiceName", true); + this.resourceGroupName = task.getInput("ResourceGroupName", true); + this.datafactoryName = task.getInput("DatafactoryName", true); this.serviceFilter = task.getInput("ServiceFilter", false); this.pipelineFilter = task.getInput("PipelineFilter", false); @@ -60,17 +59,17 @@ export class TaskParameters { this.datasetFilter = task.getInput("DatasetFilter", false); this.triggerFilter = task.getInput("TriggerFilter", false); - this.serviceFilter = this.serviceFilter === "" ? null : this.serviceFilter; - this.pipelineFilter = this.pipelineFilter === "" ? null : this.pipelineFilter; - this.dataflowFilter = this.dataflowFilter === "" ? null : this.dataflowFilter; - this.datasetFilter = this.datasetFilter === "" ? null : this.datasetFilter; - this.triggerFilter = this.triggerFilter === "" ? null : this.triggerFilter; + this.serviceFilter = this.serviceFilter === "" ? undefined : this.serviceFilter; + this.pipelineFilter = this.pipelineFilter === "" ? undefined : this.pipelineFilter; + this.dataflowFilter = this.dataflowFilter === "" ? undefined : this.dataflowFilter; + this.datasetFilter = this.datasetFilter === "" ? undefined : this.datasetFilter; + this.triggerFilter = this.triggerFilter === "" ? undefined : this.triggerFilter; this.continue = task.getBoolInput("Continue", false); - this.throttle = Number.parseInt(task.getInput("Throttle", false)); + this.throttle = Number.parseInt(task.getInput("Throttle", false)); this.throttle = this.throttle === NaN ? 5 : this.throttle; - - let sorting = task.getInput("Sorting", true); + this.detectDependency = task.getBoolInput("detectDependency", false); + let sorting = task.getInput("Sorting", true); switch (sorting.toLowerCase()) { case "ascending": this.sorting = SortingDirection.Ascending; @@ -96,23 +95,23 @@ export class TaskParameters { return this.datafactoryName; } - public get ServiceFilter(): string { + public get ServiceFilter(): string | undefined { return this.serviceFilter; } - public get PipelineFilter(): string { + public get PipelineFilter(): string | undefined { return this.pipelineFilter; } - public get DataflowFilter(): string { + public get DataflowFilter(): string | undefined { return this.dataflowFilter; } - public get DatasetFilter(): string { + public get DatasetFilter(): string | undefined { return this.datasetFilter; } - public get TriggerFilter(): string { + public get TriggerFilter(): string | undefined { return this.triggerFilter; } @@ -127,4 +126,8 @@ export class TaskParameters { public get Sorting(): SortingDirection { return this.sorting; } + + public get DetectDependency(): boolean { + return this.detectDependency; + } } diff --git a/delete-adf-items/v2/package-lock.json b/delete-adf-items/v2/package-lock.json index 2ebe8a6..e3d87f0 100644 --- a/delete-adf-items/v2/package-lock.json +++ b/delete-adf-items/v2/package-lock.json @@ -1,18 +1,55 @@ { "name": "delete-adf-items", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "dev": true + }, "@types/node": { - "version": "8.10.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz", - "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==" + "version": "12.19.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.0.tgz", + "integrity": "sha512-4BVAE9yp5DU3ISqBInsaRp9J474HWNaNVs8eZ1Far3dI1MwS3Wk0EvBRMM4xBh3Oz+c05hUgJmcbtAVmG8bv7w==", + "dev": true }, "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "adal-node": { @@ -20,7 +57,6 @@ "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", @@ -42,6 +78,58 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -79,9 +167,9 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "azure-pipelines-task-lib": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.9.3.tgz", - "integrity": "sha512-SPWKSfgmjyBDVIMzXnnPH0Gv7YXZ+AQ3SyIhNNALAmQpOltqJhgslvzrOClR5rKuoOyJlG0AWZILbZIXCkztAA==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.11.3.tgz", + "integrity": "sha512-gXops6Npkloh7AKPIvptx0KY1kdf1yd+BFdp/ksnbyW7CS3uXzBQXU1Dermr7A895TrOd02PI6hmsL8cBlePNA==", "requires": { "minimatch": "3.0.4", "mockery": "^1.7.0", @@ -104,6 +192,12 @@ "tweetnacl": "^0.14.3" } }, + "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 + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -113,16 +207,123 @@ "concat-map": "0.0.1" } }, + "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" + } + }, + "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 + }, "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 + }, + "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=" }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "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 + }, + "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" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -136,6 +337,18 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "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" + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -154,11 +367,32 @@ "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "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=" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -181,6 +415,24 @@ "safe-buffer": "^5.0.1" } }, + "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 + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -201,6 +453,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "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" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -216,6 +493,31 @@ "mime-types": "^2.1.12" } }, + "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": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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 + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -224,6 +526,35 @@ "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-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" + } + }, + "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", @@ -238,6 +569,47 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.42.tgz", + "integrity": "sha512-HElxYF7C/MSkuvlaHB2c+82zhXiuO49Cq056Dol8AQuTph7oJtduo2n6J8rFa+YhJyNgQ/Lm20ZaxqD0vxU0+Q==", + "dev": true + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -248,11 +620,69 @@ "sshpk": "^1.7.0" } }, + "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==", + "dev": true + }, + "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-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "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-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": "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 + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -263,11 +693,33 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "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 + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "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", @@ -318,10 +770,34 @@ "safe-buffer": "^5.0.1" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "mime-db": { "version": "1.40.0", @@ -344,6 +820,39 @@ "brace-expansion": "^1.1.7" } }, + "mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.0.tgz", + "integrity": "sha512-lEWEMq2LMfNJMKeuEwb5UELi+OgFDollXaytR5ggQcHpzG3NP/R7rvixAvF+9/lLsTWhWG+4yD2M70GsM06nxw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, "mockery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", @@ -354,6 +863,12 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "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 + }, "ms-rest": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", @@ -382,16 +897,100 @@ "uuid": "^3.2.1" } }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "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==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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 + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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 + }, "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 + }, + "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": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, "psl": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", @@ -412,6 +1011,47 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "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" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~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": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -446,6 +1086,18 @@ } } }, + "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 + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -457,15 +1109,52 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "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 }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, + "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-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -482,6 +1171,104 @@ "tweetnacl": "~0.14.0" } }, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "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" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.65", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.65.tgz", + "integrity": "sha512-xdcqtQl1g3p/49kmcj7ZixPWOcNHA1tYNz+uN0PJEcgtN6zywK74aacTnd3eFGPuBpD7kK8vowmMRkUt6jHU/Q==", + "dev": true + } + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -492,6 +1279,15 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "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" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -508,6 +1304,19 @@ } } }, + "ts-node": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", + "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "tunnel": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", @@ -526,6 +1335,18 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", + "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", + "dev": true + }, "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", @@ -539,6 +1360,12 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", @@ -554,6 +1381,105 @@ "extsprintf": "^1.2.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "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" + } + }, + "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 + }, + "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", @@ -563,6 +1489,143 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + }, + "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 + }, + "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": { + "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 + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.1.0.tgz", + "integrity": "sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/delete-adf-items/v2/package.json b/delete-adf-items/v2/package.json index b880401..1c11d1e 100644 --- a/delete-adf-items/v2/package.json +++ b/delete-adf-items/v2/package.json @@ -1,22 +1,27 @@ { - "name": "delete-adf-items", - "version": "2.2.0", - "description": "Deletes ADFv2 items", - "main": "tasks.js", - "scripts": { - "build": "tsc", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Jan Pieter Posthuma", - "license": "MIT", - "repository": {}, - "dependencies": { - "azure-pipelines-task-lib": "^2.9.3", - "ms-rest-azure": "^3.0.0", - "q": "1.5.1", - "throat": "^5.0.0" - }, - "devDependencies": { - "@types/q": "^1.5.2" - } + "name": "delete-adf-items", + "version": "2.2.0", + "description": "Deletes ADFv2 items", + "main": "tasks.js", + "scripts": { + "build": "tsc", + "test": "npm run build && mocha" + }, + "author": "Jan Pieter Posthuma", + "license": "MIT", + "repository": {}, + "dependencies": { + "azure-pipelines-task-lib": "^2.11.3", + "ms-rest-azure": "^3.0.0", + "throat": "^5.0.0" + }, + "devDependencies": { + "@types/mocha": "^8.0.3", + "@types/node": "^12.12.70", + "@types/q": "^1.5.4", + "mocha": "^8.2.0", + "sync-request": "^6.1.0", + "ts-node": "^9.0.0", + "typescript": "^4.0.3" + } } diff --git a/delete-adf-items/v2/task.json b/delete-adf-items/v2/task.json index 8824815..a93b718 100644 --- a/delete-adf-items/v2/task.json +++ b/delete-adf-items/v2/task.json @@ -12,7 +12,7 @@ "demands": [], "version": { "Major": "2", - "Minor": "2", + "Minor": "3", "Patch": "2" }, "minimumAgentVersion": "1.100.0", @@ -67,28 +67,28 @@ "name": "ServiceFilter", "type": "string", "label": "Linked Service Filter", - "helpMarkDown": "Filter to determine which linked service to delete.\n-Empty string: *none* linked services will be deleted.\n-`*`: *all* linked services will be deleted.", + "helpMarkDown": "Regex filter to determine which linked service to delete.\n-Empty string: *none* linked services will be deleted.\n-`*`: *all* linked services will be deleted.", "groupname": "adf" }, { "name": "PipelineFilter", "type": "string", "label": "Pipeline Filter", - "helpMarkDown": "Filter to determine which pipeline to delete.\n-Empty string: *none* pipelines will be deleted.\n-`*`: *all* pipelines will be deleted.", + "helpMarkDown": "Regex filter to determine which pipeline to delete.\n-Empty string: *none* pipelines will be deleted.\n-`*`: *all* pipelines will be deleted.", "groupname": "adf" }, { "name": "DataflowFilter", "type": "string", "label": "Data flow Filter", - "helpMarkDown": "Filter to determine which data flow to delete.\n-Empty string: *none* data flows will be deleted.\n-`*`: *all* data flows will be deleted.", + "helpMarkDown": "Regex filter to determine which data flow to delete.\n-Empty string: *none* data flows will be deleted.\n-`*`: *all* data flows will be deleted.", "groupname": "adf" }, { "name": "DatasetFilter", "type": "string", "label": "Dataset Filter", - "helpMarkDown": "Filter to determine which datasets to delete.\n-Empty string: *none* datasets will be deleted.\n-`*`: *all* datasets will be deleted.", + "helpMarkDown": "Regex filter to determine which datasets to delete.\n-Empty string: *none* datasets will be deleted.\n-`*`: *all* datasets will be deleted.", "groupname": "adf" }, { @@ -127,6 +127,15 @@ "ascending": "Ascending", "descending": "Descending" } + }, + { + "name": "detectDependancy", + "type": "boolean", + "label": "Detect object dependancy", + "defaultValue": "false", + "required": false, + "helpMarkDown": "Option to scan deployment files to detect dependancy between the same objects types. This dependancy is used to sort the deploy order.", + "groupName": "advanced" } ], "dataSourceBindings": [ @@ -149,6 +158,8 @@ "Generic_LoginAzure": "Error login in to Azure. Please check the Service Configuration. Error: %s.", "Generic_CheckDataFactory": "Error calling DataFactory API. Error: %s.", "Generic_CheckDataFactory2": "Datafactory not found: %s.", + "DeleteAdfJson_Depencency": "Error detecting dependencies: circular reference in %s(s): %s.", + "DeleteAdfJson_Depencency2": "Found missing reference in %s(s).", "DeleteAdfItems_GetObjects": "Error calling DataFactory/%s API. Error: %s.", "DeleteAdfItems_GetObjects2": "No %s found.", "DeleteAdfItems_DeleteItem": "Error calling DELETE DataFactory/%s API. Error: %s.", diff --git a/delete-adf-items/v2/tsconfig.json b/delete-adf-items/v2/tsconfig.json index b441b4a..c1a2180 100644 --- a/delete-adf-items/v2/tsconfig.json +++ b/delete-adf-items/v2/tsconfig.json @@ -1,14 +1,20 @@ { "compilerOptions": { + "alwaysStrict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, "module": "commonjs", - "target": "es6", - "noImplicitAny": false, + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitThis": true, "outDir": "dist", + "removeComments": true, "rootDir": ".", + "skipLibCheck": true, "sourceMap": false, - "moduleResolution": "node" + "strict": true, + "target": "es6" }, - "exclude": [ - "node_modules" - ] + "files": ["deleteadfitems.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/deploy-adf-json/1.1.11/deploy-adf-json.ps1 b/deploy-adf-json/1.1.11/deploy-adf-json.ps1 index 55a2a58..87f78b5 100644 --- a/deploy-adf-json/1.1.11/deploy-adf-json.ps1 +++ b/deploy-adf-json/1.1.11/deploy-adf-json.ps1 @@ -35,19 +35,22 @@ $parallel = Get-VstsInput -Name "parallel" # This is a hack since the agent passes this as a string. if ($overwrite -eq "true") { $overwrite = $true -} else { +} +else { $overwrite = $false } if ($continue -eq "true") { $continue = $true -} else { +} +else { $continue = $false } if ($clear -eq "true") { $clear = $true -} else { +} +else { $clear = $false } @@ -83,4 +86,6 @@ $result = deploy -DataFactory $adf -Version $adfversion -DeployType $deployType $deployType = 3 #trigger $result = deploy -DataFactory $adf -Version $adfversion -DeployType $deployType -Path $pathToTriggers -Overwrite $overwrite -Continue $continue -Parallel $parallel -Write-Host "Deploy JSON files to $adfname complete" \ No newline at end of file +Write-Host "Deploy JSON files to $adfname complete" + +Write-Host "##vso[task.LogIssue type=warning;]Please be adviced that this task version (v1) is deprecated and will be removed in a future release. Please update your pipeline to use the V2 version of this task." \ No newline at end of file diff --git a/deploy-adf-json/v2/.mocharc.json b/deploy-adf-json/v2/.mocharc.json new file mode 100644 index 0000000..4552636 --- /dev/null +++ b/deploy-adf-json/v2/.mocharc.json @@ -0,0 +1,6 @@ +{ + "extension": ["ts"], + "spec": "**/*.spec.ts", + "require": "ts-node/register", + "reporter": ["list"] +} diff --git a/deploy-adf-json/v2/deployadfjson.spec.ts b/deploy-adf-json/v2/deployadfjson.spec.ts new file mode 100644 index 0000000..93a39fb --- /dev/null +++ b/deploy-adf-json/v2/deployadfjson.spec.ts @@ -0,0 +1,35 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +describe("deploy-adf-json tests", function () {}); diff --git a/deploy-adf-json/v2/deployadfjson.ts b/deploy-adf-json/v2/deployadfjson.ts index 202b628..e4c4ac7 100644 --- a/deploy-adf-json/v2/deployadfjson.ts +++ b/deploy-adf-json/v2/deployadfjson.ts @@ -26,53 +26,40 @@ * THE SOFTWARE. */ -import * as Q from "q"; -import throat from "throat"; -import * as task from "azure-pipelines-task-lib/task"; -import * as path from "path"; -import * as fs from "fs"; -import * as msRestAzure from "ms-rest-azure"; -import { TaskParameters, SortingDirection } from "./models/taskParameters"; -import { AzureModels } from "./models/azureModels"; - -import AzureServiceClient = msRestAzure.AzureServiceClient; -import { UrlBasedRequestPrepareOptions } from "ms-rest"; - -task.setResourcePath(path.join(__dirname, "../task.json")); - -enum DatafactoryTypes { - Pipeline = "pipeline", - Dataflow = "dataflow", - Dataset = "dataset", - Trigger = "trigger", - LinkedService = "linked service", -} +"use sctrict"; -interface DatafactoryOptions { - azureClient?: AzureServiceClient; - subscriptionId: string; - resourceGroup: string; - dataFactoryName: string; -} +import throat from "throat"; +import { + error, + warning, + loc, + setResourcePath, + debug, + getVariable, + TaskResult, + setResult, + find, + stats, +} from "azure-pipelines-task-lib/task"; +import { basename, join, normalize, parse } from "path"; +import { readFileSync } from "fs"; +import { AzureServiceClient, loginWithServicePrincipalSecret } from "ms-rest-azure"; +import { UrlBasedRequestPrepareOptions, Mapper } from "ms-rest"; -interface DatafactoryTaskOptions { - continue: boolean; - throttle: number; - sorting: SortingDirection; -} +import { TaskParameters } from "./models/taskParameters"; +import { AzureModels } from "./models/azureModels"; +import { DatafactoryTypes, SortingDirection } from "./lib/enums"; +import { addSummary, findDependency, splitBuckets } from "./lib/helpers"; +import { DatafactoryTaskObject, DatafactoryOptions, DatafactoryTaskOptions } from "./lib/interfaces"; -interface DatafactoryDeployObject { - name: string; - json: string; - type: DatafactoryTypes; -} +setResourcePath(join(__dirname, "../task.json")); function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - msRestAzure.loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { + loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { if (err) { - task.error(task.loc("Generic_LoginAzure", err.message)); - reject(task.loc("Generic_LoginAzure", err.message)); + error(loc("Generic_LoginAzure", err.message)); + reject(loc("Generic_LoginAzure", err.message)); } resolve(new AzureServiceClient(credentials, {})); }); @@ -81,24 +68,24 @@ function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err) { - task.error(task.loc("Generic_CheckDataFactory", err)); - reject(task.loc("Generic_CheckDataFactory", err)); + error(loc("Generic_CheckDataFactory", err)); + reject(loc("Generic_CheckDataFactory", err)); } - if (response.statusCode !== 200) { - task.error(task.loc("Generic_CheckDataFactory2", dataFactoryName)); - reject(task.loc("Generic_CheckDataFactory2", dataFactoryName)); + if (response && response.statusCode !== 200) { + error(loc("Generic_CheckDataFactory2", dataFactoryName)); + reject(loc("Generic_CheckDataFactory2", dataFactoryName)); } else { resolve(true); } @@ -110,33 +97,50 @@ function getObjects( datafactoryType: DatafactoryTypes, taskOptions: DatafactoryTaskOptions, folder: string -): Promise { - return new Promise((resolve, reject) => { - let sourceFolder = path.normalize(folder); - let allPaths: string[] = task.find(sourceFolder); // default find options (follow sym links) - let matchedFiles: string[] = allPaths.filter((itemPath: string) => !task.stats(itemPath).isDirectory()); // filter-out directories +): Promise { + return new Promise((resolve, reject) => { + const sourceFolder = normalize(folder); + const allPaths: string[] = find(sourceFolder); // default find options (follow sym links) + const matchedFiles: string[] = allPaths.filter((itemPath: string) => !stats(itemPath).isDirectory()); // filter-out directories if (matchedFiles.length > 0) { taskOptions.sorting === SortingDirection.Ascending ? matchedFiles.sort( (item1, item2) => - (path.basename(item1) > path.basename(item2)) - - (path.basename(item1) < path.basename(item2)) + (basename(item1) > basename(item2)) - (basename(item1) < basename(item2)) ) : matchedFiles.sort( (item1, item2) => - (path.basename(item2) > path.basename(item1)) - - (path.basename(item2) < path.basename(item1)) + (basename(item2) > basename(item1)) - (basename(item2) < basename(item1)) ); console.log(`Found ${matchedFiles.length} ${datafactoryType}(s) definitions.`); resolve( matchedFiles.map((file: string) => { - let data = fs.readFileSync(file, "utf8"); - let json = JSON.parse(data); - let name = json.name || path.parse(file).name.replace(" ", "_"); + const data = readFileSync(file, "utf8"); + const json = JSON.parse(data); + const name = json.name || parse(file).name.replace(" ", "_"); + const size = data.length; + let dependency: string[]; + switch (datafactoryType) { + case DatafactoryTypes.LinkedService: + dependency = taskOptions.detectDependency + ? findDependency(json, "LinkedServiceReference") + : []; + break; + case DatafactoryTypes.Pipeline: + dependency = taskOptions.detectDependency ? findDependency(json, "PipelineReference") : []; + break; + default: + dependency = []; + break; + } + return { - name: name, + name, json: JSON.stringify(json), type: datafactoryType, + size, + dependency, + bucket: dependency.length === 0 ? 0 : -1, }; }) ); @@ -147,14 +151,14 @@ function getObjects( function deployItem( datafactoryOption: DatafactoryOptions, taskOptions: DatafactoryTaskOptions, - item: DatafactoryDeployObject + item: DatafactoryTaskObject ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let objectName = item.name; + const objectName = item.name; let objectType; switch (item.type) { case DatafactoryTypes.Dataflow: @@ -173,29 +177,31 @@ function deployItem( objectType = "linkedservices"; break; } - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "PUT", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/${objectType}/${objectName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), headers: { "Content-Type": "application/json", }, body: item.json, disableJsonStringifyOnBody: true, }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err && !taskOptions.continue) { - task.error(task.loc("DeployAdfJson_DeployItems2", item.name, item.type, err.message)); - reject(task.loc("DeployAdfJson_DeployItems2", item.name, item.type, err.message)); - } else if (response.statusCode !== 200) { + error(loc("DeployAdfJson_DeployItems2", item.name, item.type, err.message)); + reject(loc("DeployAdfJson_DeployItems2", item.name, item.type, err.message)); + } else if (response && response.statusCode !== 200) { if (taskOptions.continue) { - task.warning(task.loc("DeployAdfJson_DeployItems2", item.name, item.type, JSON.stringify(result))); + warning(loc("DeployAdfJson_DeployItems2", item.name, item.type, JSON.stringify(result))); resolve(false); } else { - reject(task.loc("DeployAdfJson_DeployItems2", item.name, item.type, JSON.stringify(result))); + error(loc("DeployAdfJson_DeployItems2", item.name, item.type, JSON.stringify(result))); + reject(loc("DeployAdfJson_DeployItems2", item.name, item.type, JSON.stringify(result))); } } else { + console.log(`Deployed ${item.type} '${item.name}' in chunk: ${item.bucket}.`); resolve(true); } }); @@ -208,23 +214,44 @@ function deployItems( folder: string, datafactoryType: DatafactoryTypes ): Promise { - if (hasError) { - return; - } // Some error occurred, so returning + // Some error occurred, so returning + if (hasError) return Promise.reject(true); return new Promise((resolve, reject) => { getObjects(datafactoryType, taskOptions, folder) - .then((items: DatafactoryDeployObject[]) => { - processItems(datafactoryOption, taskOptions, datafactoryType, items) + .then((items: DatafactoryTaskObject[]) => { + const numberOfBuckets = splitBuckets(taskOptions.detectDependency, items); + if (numberOfBuckets === -1) { + debug(loc("DeployAdfJson_Depencency2", datafactoryType)); + reject(loc("DeployAdfJson_Depencency2", datafactoryType)); + } + const invalidItems = items.filter((item: DatafactoryTaskObject) => item.bucket === -1); + if (invalidItems.length !== 0) { + debug( + loc( + "DeployAdfJson_Depencency", + datafactoryType, + invalidItems.map((item: DatafactoryTaskObject) => item.name).join(", ") + ) + ); + reject( + loc( + "DeployAdfJson_Depencency", + datafactoryType, + invalidItems.map((item: DatafactoryTaskObject) => item.name).join(", ") + ) + ); + } + processItems(datafactoryOption, taskOptions, datafactoryType, items, numberOfBuckets) .catch((err) => { reject(err); }) - .then((result: boolean) => { - resolve(result); + .then((result: boolean | void) => { + resolve(result); }); }) .catch((err) => { - task.debug(task.loc("DeployAdfJson_DeployItems", folder, err.message)); - reject(task.loc("DeployAdfJson_DeployItems", folder, err.message)); + debug(loc("DeployAdfJson_DeployItems", folder, err.message)); + reject(loc("DeployAdfJson_DeployItems", folder, err.message)); }); }); } @@ -233,32 +260,46 @@ function processItems( datafactoryOption: DatafactoryOptions, taskOptions: DatafactoryTaskOptions, datafactoryType: DatafactoryTypes, - items: DatafactoryDeployObject[] + items: DatafactoryTaskObject[], + numberOfBuckets: number ): Promise { - let firstError; + let firstError: boolean; return new Promise((resolve, reject) => { - let totalItems = items.length; - - let process = Q.all( - items.map( - throat(taskOptions.throttle, (item) => { - console.log(`Deploy ${datafactoryType} '${item.name}'.`); - return deployItem(datafactoryOption, taskOptions, item); - }) - ) - ) + if (items.length === 0) return Promise.resolve(true); + let totalItems = 0; + let issues = 0; + let size = 0; + const start: number = Date.now(); + const runs: DatafactoryTaskObject[][] = Array.from({ length: numberOfBuckets }, (_, index: number) => + items.filter((item: DatafactoryTaskObject) => item.bucket === index) + ); + console.log( + `Start deploying ${items.length} ${datafactoryType}(s) in ${numberOfBuckets} chunk(s) with ${taskOptions.throttle} thread(s).` + ); + runs.reduce((promiseChain: Promise, currentTask: DatafactoryTaskObject[]) => { + return promiseChain.then((chainResults) => + Promise.all( + currentTask.map( + throat(taskOptions.throttle, (item) => { + size += item.size; + totalItems++; + return deployItem(datafactoryOption, taskOptions, item); + }) + ) + ).then((currentResult) => [...chainResults, currentResult]) + ); + }, Promise.resolve([])) .catch((err) => { + issues++; hasError = true; firstError = firstError || err; }) - .done((results: any) => { - task.debug(`${totalItems} ${datafactoryType}(s) deployed.`); + .then((arrayOfResults: any) => { + const duration = Date.now() - start; + addSummary(totalItems, issues, datafactoryType, "deployed", size, duration); if (hasError) { reject(firstError); } else { - let issues = results.filter((result) => { - return !result; - }).length; if (issues > 0) { resolve(false); } else { @@ -270,71 +311,72 @@ function processItems( } async function main(): Promise { - let promise = new Promise(async (resolve, reject) => { + const promise = new Promise(async (resolve, reject) => { let taskParameters: TaskParameters; let azureModels: AzureModels; + let firstError: boolean; try { - let debugMode: string = task.getVariable("System.Debug"); - let isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; + const debugMode: string = getVariable("System.Debug"); + const isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; - task.debug("Task execution started ..."); + debug("Task execution started ..."); taskParameters = new TaskParameters(); - let connectedServiceName = taskParameters.ConnectedServiceName; - let resourceGroup = taskParameters.ResourceGroupName; - let dataFactoryName = taskParameters.DatafactoryName; + const connectedServiceName = taskParameters.ConnectedServiceName; + const resourceGroup = taskParameters.ResourceGroupName; + const dataFactoryName = taskParameters.DatafactoryName; - let servicePath = taskParameters.ServicePath; - let pipelinePath = taskParameters.PipelinePath; - let datasetPath = taskParameters.DatasetPath; - let dataflowPath = taskParameters.DataflowPath; - let triggerPath = taskParameters.TriggerPath; + const servicePath = taskParameters.ServicePath; + const pipelinePath = taskParameters.PipelinePath; + const datasetPath = taskParameters.DatasetPath; + const dataflowPath = taskParameters.DataflowPath; + const triggerPath = taskParameters.TriggerPath; - let taskOptions = { + const taskOptions = { continue: taskParameters.Continue, throttle: taskParameters.Throttle, sorting: taskParameters.Sorting, + detectDependency: taskParameters.DetectDependency, }; azureModels = new AzureModels(connectedServiceName); - let clientId = azureModels.getServicePrincipalClientId(); - let key = azureModels.getServicePrincipalKey(); - let tenantID = azureModels.getTenantId(); - let datafactoryOption: DatafactoryOptions = { + const clientId = azureModels.getServicePrincipalClientId(); + const key = azureModels.getServicePrincipalKey(); + const tenantID = azureModels.getTenantId(); + const datafactoryOption: DatafactoryOptions = { subscriptionId: azureModels.getSubscriptionId(), resourceGroup: resourceGroup, dataFactoryName: dataFactoryName, }; - let firstError; - task.debug("Parsed task inputs"); + debug("Parsed task inputs"); loginAzure(clientId, key, tenantID) .then((azureClient: AzureServiceClient) => { datafactoryOption.azureClient = azureClient; - task.debug("Azure client retrieved."); + debug("Azure client retrieved."); return checkDataFactory(datafactoryOption); }) .then(() => { - task.debug(`Datafactory '${dataFactoryName}' exist`); - let deployTasks = []; - if (servicePath !== null) { + debug(`Datafactory '${dataFactoryName}' exist`); + const deployTasks: any[] = []; + if (servicePath) { deployTasks.push({ path: servicePath, type: DatafactoryTypes.LinkedService }); } - if (datasetPath !== null) { + if (datasetPath) { deployTasks.push({ path: datasetPath, type: DatafactoryTypes.Dataset }); } - if (dataflowPath !== null) { + if (dataflowPath) { deployTasks.push({ path: dataflowPath, type: DatafactoryTypes.Dataflow }); } - if (pipelinePath !== null) { + if (pipelinePath) { deployTasks.push({ path: pipelinePath, type: DatafactoryTypes.Pipeline }); } - if (triggerPath !== null) { + if (triggerPath) { deployTasks.push({ path: triggerPath, type: DatafactoryTypes.Trigger }); } - Q.all( + Promise.all( deployTasks.map( - throat(1, (task) => { + throat(1, (task: any) => { return deployItems(datafactoryOption, taskOptions, task.path, task.type); }) ) @@ -343,11 +385,11 @@ async function main(): Promise { hasError = true; firstError = firstError || err; }) - .done((results: any) => { + .then((results: boolean[] | void) => { if (hasError) { reject(firstError); } else { - let issues = results.filter((result) => { + const issues = (results).filter((result: boolean) => { return !result; }).length; if (issues > 0) { @@ -373,8 +415,8 @@ let hasError = false; main() .then((result) => { - task.setResult(result ? task.TaskResult.Succeeded : task.TaskResult.SucceededWithIssues, ""); + setResult(result ? TaskResult.Succeeded : TaskResult.SucceededWithIssues, ""); }) .catch((err) => { - task.setResult(task.TaskResult.Failed, err); + setResult(TaskResult.Failed, err); }); diff --git a/deploy-adf-json/v2/icon.svg b/deploy-adf-json/v2/icon.svg new file mode 100644 index 0000000..b2ceec4 --- /dev/null +++ b/deploy-adf-json/v2/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/deploy-adf-json/v2/lib/enums.ts b/deploy-adf-json/v2/lib/enums.ts new file mode 100644 index 0000000..64bd436 --- /dev/null +++ b/deploy-adf-json/v2/lib/enums.ts @@ -0,0 +1,42 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export enum SortingDirection { + Ascending, + Descending, +} + +export enum DatafactoryTypes { + Pipeline = "pipeline", + Dataflow = "dataflow", + Dataset = "dataset", + Trigger = "trigger", + LinkedService = "linked service", +} diff --git a/deploy-adf-json/v2/lib/helpers.spec.ts b/deploy-adf-json/v2/lib/helpers.spec.ts new file mode 100644 index 0000000..bf19751 --- /dev/null +++ b/deploy-adf-json/v2/lib/helpers.spec.ts @@ -0,0 +1,67 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import { getReadableFileSize, getReadableInterval } from "./helpers"; + +describe("Helpers", () => { + describe("getReadableInterval()", () => { + it("59000 => '59.000 second(s)'", () => { + assert.strictEqual(getReadableInterval(59000), "59.000 second(s)"); + }); + + it("59001 => '59.001 second(s)'", () => { + assert.strictEqual(getReadableInterval(59001), "59.001 second(s)"); + }); + + it("60001 => '1 minute(s) 0.001 seconds'", () => { + assert.strictEqual(getReadableInterval(60001), "1 minute(s) 0.001 second(s)"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1000 => 1000 byte", () => { + assert.strictEqual(getReadableFileSize(1000), "1000.0 bytes"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1024 => 1024.0 bytes", () => { + assert.strictEqual(getReadableFileSize(1024), "1024.0 bytes"); + }); + }); + + describe("getReadableFileSize()", () => { + it("1025 => 1.0 kB", () => { + assert.strictEqual(getReadableFileSize(1025), "1.0 kB"); + }); + }); +}); diff --git a/deploy-adf-json/v2/lib/helpers.ts b/deploy-adf-json/v2/lib/helpers.ts new file mode 100644 index 0000000..56af67f --- /dev/null +++ b/deploy-adf-json/v2/lib/helpers.ts @@ -0,0 +1,111 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { DatafactoryTypes } from "./enums"; +import { DatafactoryTaskObject } from "./interfaces"; + +export function addSummary( + totalItems: number, + issues: number, + datafactoryType: DatafactoryTypes, + action: string, + size: number | undefined, + duration: number +) { + console.log(``); + if (issues > 0) console.log(`${issues} ${datafactoryType}(s) failed`); + console.log(`${totalItems - issues} ${datafactoryType}(s) ${action}.\n\nStats:`); + console.log(`======`); + if (size) console.log(`Total size:\t${getReadableFileSize(size)}.`); + console.log(`Duration:\t${getReadableInterval(duration)}.`); + if (size) console.log(`Performance:\t${getReadableFileSize(size / (duration / 1000))}/sec.`); + console.log(`\t\t${(totalItems / (duration / 1000)).toFixed(1)} items/sec.`); +} + +export function getReadableFileSize(fileSizeInBytes: number): string { + var i = 0; + var byteUnits = [" bytes", " kB", " MB", " GB", " TB", "PB", "EB", "ZB", "YB"]; + while (fileSizeInBytes > 1024) { + fileSizeInBytes = fileSizeInBytes / 1024; + i++; + } + + return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]; +} + +export function getReadableInterval(interval: number): string { + let x = interval / 1000; + const seconds = (x % 60).toFixed(3); + x /= 60; + const minutes = Math.floor(x % 60); + x /= 60; + const hours = Math.floor(x % 24); + let r = ""; + if (hours !== 0) r += hours + " hour(s) "; + if (minutes !== 0) r += (minutes < 10 && hours > 0 ? "0" : "") + minutes + " minute(s) "; + return r + seconds + " second(s)"; +} + +export function splitBuckets(detectDependency: boolean, items: DatafactoryTaskObject[]): number { + let loop = detectDependency; + let change = true; + let numberOfBuckets = 1; + while (loop || change) { + loop = false; + change = false; + const loopItems = items.filter((item: DatafactoryTaskObject) => item.bucket === -1); + loopItems.forEach((item: DatafactoryTaskObject) => { + const pBucket = item.bucket; + const buckets = item.dependency.map((i) => { + const findItem = items.find((item) => item.name === i); + if (!findItem) return -1; + return findItem.bucket; + }); + if (Math.min(...buckets) !== -1) { + numberOfBuckets++; + change = true; + item.bucket = Math.max(...buckets) + 1; + } + loop = pBucket !== item.bucket; + }); + } + return numberOfBuckets; +} + +export function findDependency(json: any, type: string): string[] { + let refs: string[] = []; + if (json.referenceName && json.type === type) { + return [json.referenceName]; + } + for (const key in json) { + if (typeof json[key] === typeof [Object]) refs = refs.concat(findDependency(json[key], type)); + } + return refs.filter((current: string, index: number, array: string[]) => array.indexOf(current) === index); +} diff --git a/deploy-adf-json/v2/lib/interfaces.ts b/deploy-adf-json/v2/lib/interfaces.ts new file mode 100644 index 0000000..3d81fc3 --- /dev/null +++ b/deploy-adf-json/v2/lib/interfaces.ts @@ -0,0 +1,58 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import * as msRestAzure from "ms-rest-azure"; + +import AzureServiceClient = msRestAzure.AzureServiceClient; + +import { SortingDirection, DatafactoryTypes } from "./enums"; + +export interface DatafactoryOptions { + azureClient?: AzureServiceClient; + subscriptionId: string; + resourceGroup: string; + dataFactoryName: string; +} + +export interface DatafactoryTaskOptions { + continue: boolean; + throttle: number; + sorting: SortingDirection; + detectDependency: boolean; +} + +export interface DatafactoryTaskObject { + name: string; + json: string; + size: number; + type: DatafactoryTypes; + dependency: string[]; + bucket: number; +} diff --git a/deploy-adf-json/v2/models/azureModels.ts b/deploy-adf-json/v2/models/azureModels.ts index a38b436..a67f36e 100644 --- a/deploy-adf-json/v2/models/azureModels.ts +++ b/deploy-adf-json/v2/models/azureModels.ts @@ -43,13 +43,13 @@ export class AzureModels { this.connectedServiceName = connectedServiceName; if (this.connectedServiceName === "local") { // local debug - this.subscriptionId = task.getInput("subscriptionid", true); - this.subscriptionName = task.getInput("subscriptionname", true); - this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); - this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); - this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); - this.tenantId = task.getInput("tenantid", true); - this.url = task.getInput("connectedServiceNameUrl", true); + this.subscriptionId = task.getInput("subscriptionid", true); + this.subscriptionName = task.getInput("subscriptionname", true); + this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); + this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); + this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); + this.tenantId = task.getInput("tenantid", true); + this.url = task.getInput("connectedServiceNameUrl", true); } else { this.subscriptionId = task.getEndpointDataParameter(this.connectedServiceName, "subscriptionid", true); this.subscriptionName = task.getEndpointDataParameter( @@ -57,22 +57,20 @@ export class AzureModels { "subscriptionname", true ); - this.servicePrincipalClientId = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalid", - true + this.servicePrincipalClientId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalid", true) ); - this.servicePrincipalKey = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalkey", - true + this.servicePrincipalKey = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalkey", true) ); this.environmentAuthorityUrl = task.getEndpointDataParameter( this.connectedServiceName, "environmentAuthorityUrl", true ); - this.tenantId = task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false); + this.tenantId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false) + ); this.url = task.getEndpointUrl(this.connectedServiceName, true); } } catch (err) { diff --git a/deploy-adf-json/v2/models/taskParameters.ts b/deploy-adf-json/v2/models/taskParameters.ts index 7a5c973..b0c1d1b 100644 --- a/deploy-adf-json/v2/models/taskParameters.ts +++ b/deploy-adf-json/v2/models/taskParameters.ts @@ -28,51 +28,55 @@ import * as task from "azure-pipelines-task-lib/task"; -export enum SortingDirection { - Ascending, - Descending, -} +import { SortingDirection } from "../lib/enums"; export class TaskParameters { private connectedServiceName: string; private resourceGroupName: string; private datafactoryName: string; - private servicePath: string; - private pipelinePath: string; - private datasetPath: string; - private dataflowPath: string; - private triggerPath: string; + private servicePath: string | undefined; + private pipelinePath: string | undefined; + private datasetPath: string | undefined; + private dataflowPath: string | undefined; + private triggerPath: string | undefined; private continue: boolean; private throttle: number; - private sorting: SortingDirection; + private sorting: SortingDirection = SortingDirection.Ascending; + private detectDependency: boolean; constructor() { try { let rootPath = task.getVariable("System.DefaultWorkingDirectory") || "C:\\"; - this.connectedServiceName = task.getInput("ConnectedServiceName", true); - this.resourceGroupName = task.getInput("ResourceGroupName", true); - this.datafactoryName = task.getInput("DatafactoryName", true); - - this.servicePath = task.getPathInput("ServicePath", false, true); - this.pipelinePath = task.getPathInput("PipelinePath", false, true); - this.datasetPath = task.getPathInput("DatasetPath", false, true); - this.dataflowPath = task.getPathInput("DataflowPath", false, true); - this.triggerPath = task.getPathInput("TriggerPath", false, true); - - // Replace "" with null - this.servicePath = this.servicePath.replace(rootPath, "") === "" ? null : this.servicePath; - this.pipelinePath = this.pipelinePath.replace(rootPath, "") === "" ? null : this.pipelinePath; - this.datasetPath = this.datasetPath.replace(rootPath, "") === "" ? null : this.datasetPath; - this.dataflowPath = this.dataflowPath.replace(rootPath, "") === "" ? null : this.dataflowPath; - this.triggerPath = this.triggerPath.replace(rootPath, "") === "" ? null : this.triggerPath; + this.connectedServiceName = task.getInput("ConnectedServiceName", true); + this.resourceGroupName = task.getInput("ResourceGroupName", true); + this.datafactoryName = task.getInput("DatafactoryName", true); + + this.servicePath = task.getPathInput("ServicePath", false, true); + this.pipelinePath = task.getPathInput("PipelinePath", false, true); + this.datasetPath = task.getPathInput("DatasetPath", false, true); + this.dataflowPath = task.getPathInput("DataflowPath", false, true); + this.triggerPath = task.getPathInput("TriggerPath", false, true); + + // Replace "" with undefined + this.servicePath = + (this.servicePath && this.servicePath.replace(rootPath, "")) === "" ? undefined : this.servicePath; + this.pipelinePath = + (this.pipelinePath && this.pipelinePath.replace(rootPath, "")) === "" ? undefined : this.pipelinePath; + this.datasetPath = + (this.datasetPath && this.datasetPath.replace(rootPath, "")) === "" ? undefined : this.datasetPath; + this.dataflowPath = + (this.dataflowPath && this.dataflowPath.replace(rootPath, "")) === "" ? undefined : this.dataflowPath; + this.triggerPath = + (this.triggerPath && this.triggerPath.replace(rootPath, "")) === "" ? undefined : this.triggerPath; this.continue = task.getBoolInput("Continue", false); - this.throttle = Number.parseInt(task.getInput("Throttle", false)); + this.throttle = Number.parseInt(task.getInput("Throttle", false)); this.throttle = this.throttle === NaN ? 5 : this.throttle; - let sorting = task.getInput("Sorting", true); + this.detectDependency = task.getBoolInput("detectDependency", false); + let sorting = task.getInput("Sorting", true); switch (sorting.toLowerCase()) { case "ascending": this.sorting = SortingDirection.Ascending; @@ -98,23 +102,23 @@ export class TaskParameters { return this.datafactoryName; } - public get ServicePath(): string { + public get ServicePath(): string | undefined { return this.servicePath; } - public get PipelinePath(): string { + public get PipelinePath(): string | undefined { return this.pipelinePath; } - public get DatasetPath(): string { + public get DatasetPath(): string | undefined { return this.datasetPath; } - public get DataflowPath(): string { + public get DataflowPath(): string | undefined { return this.dataflowPath; } - public get TriggerPath(): string { + public get TriggerPath(): string | undefined { return this.triggerPath; } @@ -129,4 +133,8 @@ export class TaskParameters { public get Sorting(): SortingDirection { return this.sorting; } + + public get DetectDependency(): boolean { + return this.detectDependency; + } } diff --git a/deploy-adf-json/v2/package-lock.json b/deploy-adf-json/v2/package-lock.json index 0476ba7..4a436c8 100644 --- a/deploy-adf-json/v2/package-lock.json +++ b/deploy-adf-json/v2/package-lock.json @@ -1,18 +1,55 @@ { "name": "deploy-adf-json", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "dev": true + }, "@types/node": { - "version": "8.10.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz", - "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==" + "version": "12.12.70", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.70.tgz", + "integrity": "sha512-i5y7HTbvhonZQE+GnUM2rz1Bi8QkzxdQmEv1LKOv4nWyaQk/gdeiTApuQR3PDJHX7WomAbpx2wlWSEpxXGZ/UQ==", + "dev": true }, "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "adal-node": { @@ -29,6 +66,13 @@ "uuid": "^3.1.0", "xmldom": ">= 0.1.x", "xpath.js": "~1.1.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.65", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.65.tgz", + "integrity": "sha512-xdcqtQl1g3p/49kmcj7ZixPWOcNHA1tYNz+uN0PJEcgtN6zywK74aacTnd3eFGPuBpD7kK8vowmMRkUt6jHU/Q==" + } } }, "ajv": { @@ -42,6 +86,57 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -79,16 +174,70 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "azure-pipelines-task-lib": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.9.3.tgz", - "integrity": "sha512-SPWKSfgmjyBDVIMzXnnPH0Gv7YXZ+AQ3SyIhNNALAmQpOltqJhgslvzrOClR5rKuoOyJlG0AWZILbZIXCkztAA==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.11.3.tgz", + "integrity": "sha512-gXops6Npkloh7AKPIvptx0KY1kdf1yd+BFdp/ksnbyW7CS3uXzBQXU1Dermr7A895TrOd02PI6hmsL8cBlePNA==", "requires": { "minimatch": "3.0.4", "mockery": "^1.7.0", "q": "^1.1.2", "semver": "^5.1.0", "shelljs": "^0.3.0", + "sync-request": "3.0.1", "uuid": "^3.0.1" + }, + "dependencies": { + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "http-basic": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-2.5.1.tgz", + "integrity": "sha1-jORHvbW2xXf4pj4/p4BW7Eu02/s=", + "requires": { + "caseless": "~0.11.0", + "concat-stream": "^1.4.6", + "http-response-object": "^1.0.0" + } + }, + "http-response-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-1.1.0.tgz", + "integrity": "sha1-p8TnWq6C87tJBOT0P2FWc7TVGMM=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "sync-request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-3.0.1.tgz", + "integrity": "sha1-yqEjWq+Im6UBB2oYNMQ2gwqC+3M=", + "requires": { + "concat-stream": "^1.4.7", + "http-response-object": "^1.0.1", + "then-request": "^2.0.1" + } + }, + "then-request": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-2.2.0.tgz", + "integrity": "sha1-ZnizL6DKIY/laZgbvYhxtZQGDYE=", + "requires": { + "caseless": "~0.11.0", + "concat-stream": "^1.4.7", + "http-basic": "^2.5.1", + "http-response-object": "^1.1.0", + "promise": "^7.1.1", + "qs": "^6.1.0" + } + } } }, "balanced-match": { @@ -104,6 +253,12 @@ "tweetnacl": "^0.14.3" } }, + "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 + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -113,16 +268,122 @@ "concat-map": "0.0.1" } }, + "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" + } + }, + "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 + }, "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==" + }, + "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=" }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "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 + }, + "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" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -136,6 +397,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -154,11 +426,32 @@ "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "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=" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -181,6 +474,24 @@ "safe-buffer": "^5.0.1" } }, + "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 + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -201,6 +512,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "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" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -216,6 +552,31 @@ "mime-types": "^2.1.12" } }, + "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": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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 + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -224,6 +585,35 @@ "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-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" + } + }, + "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", @@ -238,6 +628,47 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.40.tgz", + "integrity": "sha512-3hZT2z2/531A5pc8hYhn1gU5Qb1SIRSgMLQ6zuHA5xtt16lWAxUGprtr8lJuc9zNJMXEIIBWfSnzqBP/4mglpA==", + "dev": true + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -248,11 +679,68 @@ "sshpk": "^1.7.0" } }, + "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-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-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "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-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": "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 + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -263,11 +751,32 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "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", @@ -318,11 +827,35 @@ "safe-buffer": "^5.0.1" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", @@ -344,6 +877,39 @@ "brace-expansion": "^1.1.7" } }, + "mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.0.tgz", + "integrity": "sha512-lEWEMq2LMfNJMKeuEwb5UELi+OgFDollXaytR5ggQcHpzG3NP/R7rvixAvF+9/lLsTWhWG+4yD2M70GsM06nxw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, "mockery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", @@ -354,6 +920,12 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "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 + }, "ms-rest": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", @@ -382,16 +954,99 @@ "uuid": "^3.2.1" } }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "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==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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 + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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 + }, "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 + }, + "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==" + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, "psl": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", @@ -412,6 +1067,45 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "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" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~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": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -439,6 +1133,18 @@ "uuid": "^3.3.2" } }, + "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 + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -450,15 +1156,52 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "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 }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, + "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-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -475,6 +1218,102 @@ "tweetnacl": "~0.14.0" } }, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "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" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.65", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.65.tgz", + "integrity": "sha512-xdcqtQl1g3p/49kmcj7ZixPWOcNHA1tYNz+uN0PJEcgtN6zywK74aacTnd3eFGPuBpD7kK8vowmMRkUt6jHU/Q==", + "dev": true + } + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -485,6 +1324,15 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "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" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -501,6 +1349,19 @@ } } }, + "ts-node": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", + "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "tunnel": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", @@ -519,6 +1380,17 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typescript": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", + "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", + "dev": true + }, "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", @@ -532,6 +1404,11 @@ "punycode": "^2.1.0" } }, + "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", @@ -547,6 +1424,105 @@ "extsprintf": "^1.2.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "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" + } + }, + "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 + }, + "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", @@ -556,6 +1532,143 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + }, + "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 + }, + "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": { + "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 + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.1.0.tgz", + "integrity": "sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/deploy-adf-json/v2/package.json b/deploy-adf-json/v2/package.json index 583ff7f..313781d 100644 --- a/deploy-adf-json/v2/package.json +++ b/deploy-adf-json/v2/package.json @@ -1,22 +1,27 @@ { - "name": "deploy-adf-json", - "version": "2.2.0", - "description": "Deploy ADFv2 items", - "main": "tasks.js", - "scripts": { - "build": "tsc", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Jan Pieter Posthuma", - "license": "MIT", - "repository": {}, - "dependencies": { - "azure-pipelines-task-lib": "^2.9.3", - "ms-rest-azure": "^3.0.0", - "q": "1.5.1", - "throat": "^5.0.0" - }, - "devDependencies": { - "@types/q": "^1.5.2" - } + "name": "deploy-adf-json", + "version": "2.2.0", + "description": "Deploy ADFv2 items", + "main": "tasks.js", + "scripts": { + "build": "tsc", + "test": "npm run build && mocha" + }, + "author": "Jan Pieter Posthuma", + "license": "MIT", + "repository": {}, + "dependencies": { + "azure-pipelines-task-lib": "^2.11.3", + "ms-rest-azure": "^3.0.0", + "throat": "^5.0.0" + }, + "devDependencies": { + "@types/mocha": "^8.0.3", + "@types/node": "^12.12.70", + "@types/q": "^1.5.4", + "mocha": "^8.2.0", + "sync-request": "^6.1.0", + "ts-node": "^9.0.0", + "typescript": "^4.0.3" + } } diff --git a/deploy-adf-json/v2/task.json b/deploy-adf-json/v2/task.json index 017a2c2..aadf29e 100644 --- a/deploy-adf-json/v2/task.json +++ b/deploy-adf-json/v2/task.json @@ -7,18 +7,13 @@ "helpMarkDown": "[More Information](https://github.com/liprec/vsts-publish-adf)", "category": "Deploy", "preview": false, - "visibility": [ - "Build", - "Release" - ], - "runsOn": [ - "Agent" - ], + "visibility": ["Build", "Release"], + "runsOn": ["Agent"], "demands": [], "version": { "Major": "2", - "Minor": "2", - "Patch": "1" + "Minor": "3", + "Patch": "2" }, "minimumAgentVersion": "1.100.0", "groups": [ @@ -132,6 +127,15 @@ "ascending": "Ascending", "descending": "Descending" } + }, + { + "name": "detectDependancy", + "type": "boolean", + "label": "Detect object dependancy", + "defaultValue": "false", + "required": false, + "helpMarkDown": "Option to scan deployment files to detect dependancy between the same objects types. This dependancy is used to sort the deploy order.", + "groupName": "advanced" } ], "dataSourceBindings": [ @@ -154,9 +158,11 @@ "Generic_LoginAzure": "Error login in to Azure. Please check the Service Configuration. Error: %s.", "Generic_CheckDataFactory": "Error calling DataFactory API. Error: %s.", "Generic_CheckDataFactory2": "Datafactory not found: %s.", + "DeployAdfJson_Depencency": "Error detecting dependencies: circular reference in %s(s): %s.", + "DeployAdfJson_Depencency2": "Found missing reference in %s(s).", "DeployAdfJson_DeployItems": "Error processing folder %s: Error: %s.", "DeployAdfJson_DeployItems2": "Error deploying '%s' %s : %s", "DeployAdfJson_GetObjects": "Error reading %s definition file %s. Error: %s.", "DeployAdfJson_GetObjects2": "Error reading %s definition file %s." } -} \ No newline at end of file +} diff --git a/deploy-adf-json/v2/tsconfig.json b/deploy-adf-json/v2/tsconfig.json index b441b4a..fc8341e 100644 --- a/deploy-adf-json/v2/tsconfig.json +++ b/deploy-adf-json/v2/tsconfig.json @@ -1,14 +1,20 @@ { "compilerOptions": { + "alwaysStrict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, "module": "commonjs", - "target": "es6", - "noImplicitAny": false, + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitThis": true, "outDir": "dist", + "removeComments": true, "rootDir": ".", + "skipLibCheck": true, "sourceMap": false, - "moduleResolution": "node" + "strict": true, + "target": "es6" }, - "exclude": [ - "node_modules" - ] + "files": ["deployadfjson.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d1e7b52 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,20 @@ +{ + "name": "vsts-publish-adf", + "version": "2.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mocha": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "dev": true + }, + "@types/node": { + "version": "14.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.0.tgz", + "integrity": "sha512-BfbIHP9IapdupGhq/hc+jT5dyiBVZ2DdeC5WwJWQWDb0GijQlzUFAeIQn/2GtvZcd2HVUU7An8felIICFTC2qg==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..440d4af --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "vsts-publish-adf", + "version": "2.2.0", + "author": "Jan Pieter Posthuma", + "license": "MIT", + "repository": {}, + "dependencies": {}, + "devDependencies": { + "@types/mocha": "^8.0.3", + "@types/node": "^14.14.0" + } +} diff --git a/query-adf-run/icon.png b/query-adf-run/icon.png new file mode 100644 index 0000000..4cda89b Binary files /dev/null and b/query-adf-run/icon.png differ diff --git a/query-adf-run/icon.svg b/query-adf-run/icon.svg new file mode 100644 index 0000000..890c77a --- /dev/null +++ b/query-adf-run/icon.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/query-adf-run/task.json b/query-adf-run/task.json new file mode 100644 index 0000000..009ea01 --- /dev/null +++ b/query-adf-run/task.json @@ -0,0 +1,164 @@ +{ + "id": "1e050229-db74-48fd-afad-811c199bde29", + "name": "query-adf-run", + "friendlyName": "Query Azure Data Factory runs", + "description": "Observe the configured Azure Data Factory runs for active ones", + "author": "Jan Pieter Posthuma", + "helpUrl": "https://azurebi-docs.jppp.org/vsts-extensions/azure-data-factory-query.html", + "helpMarkDown": "[More Information](https://github.com/liprec/vsts-publish-adf)", + "category": "Utility", + "preview": false, + "releaseNotes": "What's new in Version 2:
 Added support for query Azure Data Factory runs.", + "visibility": ["Build", "Release"], + "runsOn": ["Server", "ServerGate"], + "demands": [], + "version": { + "Major": "2", + "Minor": "3", + "Patch": "2" + }, + "instanceNameFormat": "Query Azure Data Factory runs", + "groups": [ + { + "name": "advanced", + "displayName": "Advanced", + "isExpanded": false + } + ], + "inputs": [ + { + "name": "connectedServiceNameARM", + "aliases": ["azureSubscription"], + "type": "connectedService:AzureRM", + "label": "Azure Subscription", + "defaultValue": "", + "required": true, + "helpMarkDown": "This is needed to connect to your Azure account.
To configure new service connection, select the Azure subscription from the list and click 'Authorize'.
If your subscription is not listed or if you want to use an existing Service Principal, you can setup an Azure service connection using 'Add' or 'Manage' button." + }, + { + "name": "resourceGroupName", + "type": "pickList", + "label": "Resource group", + "required": true, + "helpMarkDown": "Provide the name of the resource group.", + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "datafactoryName", + "type": "string", + "label": "Azure Data Factory", + "defaultValue": "", + "required": "true", + "helpMarkDown": "Name of the Azure Data Factory." + }, + { + "name": "runType", + "type": "pickList", + "label": "Type of run", + "defaultValue": "pipeline", + "required": true, + "helpMarkDown": "Type of the Azure Data Factory run: Pipeline (default) or Trigger", + "options": { + "pipeline": "Pipeline", + "trigger": "Trigger" + } + }, + { + "name": "name", + "type": "string", + "label": "Name(s) of the pipeline(s) or trigger(s).", + "required": false, + "helpMarkDown": "Name(s) of the pipeline(s) or trigger(s). Multiple names seperated by commas (,). If not provided all pipelines / triggers are queried" + }, + { + "name": "statusPipeline", + "type": "pickList", + "label": "Pipeline filter for the run status", + "required": true, + "defaultValue": "Cancelled,Failed,InProgress,Queued", + "options": { + "Cancelled": "Cancelled", + "Failed": "Failed", + "InProgress": "InProgress", + "Queued": "Queued", + "Succeeded": "Succeeded" + }, + "properties": { + "MultiSelectFlatList": "True", + "EditableOptions": "True" + }, + "helpMarkDown": "Filter by pipeline status. Default value is all status except 'Succeeded'.", + "visibleRule": "runType = pipeline", + "groupName": "advanced" + }, + { + "name": "statusTrigger", + "type": "pickList", + "label": "Trigger filter for the run status", + "required": true, + "defaultValue": "Cancelled,Failed,Running,Waiting,WaitingOnDependency", + "options": { + "Cancelled": "Cancelled", + "Failed": "Failed", + "Running": "Running", + "Succeeded": "Succeeded", + "Waiting": "Waiting", + "WaitingOnDependency": "WaitingOnDependency" + }, + "properties": { + "MultiSelectFlatList": "True", + "EditableOptions": "True" + }, + "helpMarkDown": "Filter by trigger status. Default value is all status except 'Succeeded'.", + "visibleRule": "runType = trigger", + "groupName": "advanced" + }, + { + "name": "lastUpdatedAfter", + "type": "string", + "label": "Start time of the run event window", + "required": false, + "helpMarkDown": "The time at or after which the run event was updated in 'ISO 8601' format. Default value is Januari 1st, 2000.", + "groupName": "advanced" + }, + { + "name": "lastUpdatedBefore", + "type": "string", + "label": "End time of the run event window", + "required": false, + "helpMarkDown": "The time at or before which the run event was updated in 'ISO 8601' format. Default value is December 31st, 2199", + "groupName": "advanced" + }, + { + "name": "result", + "type": "boolean", + "label": "Expected results", + "defaultValue": "false", + "required": false, + "helpMarkDown": "Option to determine if the result should contain result (runs). Default value: 'false'", + "groupName": "advanced" + } + ], + "dataSourceBindings": [ + { + "target": "ResourceGroupName", + "endpointId": "$(connectedServiceNameARM)", + "dataSourceName": "AzureResourceGroups" + } + ], + "execution": { + "HttpRequest": { + "Execute": { + "EndpointId": "$(connectedServiceNameARM)", + "EndpointUrl": "$(endpoint.url)/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroupName}}/providers/Microsoft.DataFactory/factories/{{datafactoryName}}/{{#equals '$(runType)' 'pipeline' 1}}queryPipelineRuns{{/equals}}{{#equals '$(runType)' 'trigger' 1}}queryTriggerRuns{{/equals}}?api-version=2018-06-01", + "Method": "POST", + "Body": "{\"filters\": [{\"operand\": \"Status\",\"operator\": \"In\",\"values\": [\"{{#equals '$(runType)' 'pipeline' 1}}{{ #stringReplace ',' '\",\"' statusPipeline }}{{/equals}}{{#equals '$(runType)' 'trigger' 1}}{{ #stringReplace ',' '\",\"' statusTrigger }}{{/equals}}\"]},{{#name}}{{#equals '$(runType)' 'pipeline' 1}}{ \"operand\": \"PipelineName\", \"operator\": \"In\", \"values\": [\"{{ #stringReplace ',' '\",\"' name }}\"] }{{/equals}}{{#equals '$(runType)' 'trigger' 1}}{ \"operand\": \"TriggerName\", \"operator\": \"In\", \"values\": [\"{{ #stringReplace ',' '\",\"' name }}\"] }{{/equals}}{{/name}}{{^name}}{ \"operand\": \"LatestOnly\", \"operator\": \"Equals\", \"values\": [true] }{{/name}}],\"lastUpdatedAfter\": \"{{#lastUpdatedAfter}}{{ lastUpdatedAfter }}{{/lastUpdatedAfter}}{{^lastUpdatedAfter}}2000-01-01T00:00:00.000Z{{/lastUpdatedAfter}}\",\"lastUpdatedBefore\": \"{{#lastUpdatedBefore}}{{ lastUpdatedBefore }}{{/lastUpdatedBefore}}{{^lastUpdatedBefore}}2199-12-31T00:00:00.000Z{{/lastUpdatedBefore}}\"}", + "Headers": "{\"Content-Type\":\"application/json\"}", + "WaitForCompletion": "false", + "Expression": "or(and(eq(count(jsonpath('$.value[*]')), 0), eq($(result), false)), and(ne(count(jsonpath('$.value[*]')), 0), eq($(result), true)))" + } + } + } +} diff --git a/suspend-adf-pipeline/1.0.6/suspend-adf-pipeline.ps1 b/suspend-adf-pipeline/1.0.6/suspend-adf-pipeline.ps1 index 5cb8513..c2fb351 100644 --- a/suspend-adf-pipeline/1.0.6/suspend-adf-pipeline.ps1 +++ b/suspend-adf-pipeline/1.0.6/suspend-adf-pipeline.ps1 @@ -18,4 +18,6 @@ $adf = getAzureDataFactory -ResourceGroupName $resourceGroupName -DataFactoryNam $result = setPipelineStatus -DataFactory $adf -PipelineStatus $pipelineStatus -Parallel $p -Write-Host "Set pipelines to '$pipelineStatus' complete" \ No newline at end of file +Write-Host "Set pipelines to '$pipelineStatus' complete" + +Write-Host "##vso[task.LogIssue type=warning;]Please be adviced that this task version (v1) is deprecated and will be removed in a future release." \ No newline at end of file diff --git a/toggle-adf-trigger/1.0.4/toggle-adf-trigger.ps1 b/toggle-adf-trigger/1.0.4/toggle-adf-trigger.ps1 index 01afa09..808443d 100644 --- a/toggle-adf-trigger/1.0.4/toggle-adf-trigger.ps1 +++ b/toggle-adf-trigger/1.0.4/toggle-adf-trigger.ps1 @@ -21,10 +21,13 @@ $continue = Get-VstsInput -Name "continue" -Require if ($continue -eq "true") { $continue = $true -} else { +} +else { $continue = $false } $result = setTriggerStatus -ResourceGroupName $resourceGroupName -DataFactoryName $adfName -TriggerName $triggerName -TriggerStatus $triggerStatus -Continue $continue -Write-Host "'$result' trigger(s) in '$adfname' set to '$triggerStatus' complete" \ No newline at end of file +Write-Host "'$result' trigger(s) in '$adfname' set to '$triggerStatus' complete" + +Write-Host "##vso[task.LogIssue type=warning;]Please be adviced that this task version (v1) is deprecated and will be removed in a future release. Please update your pipeline to use the V2 version of this task." \ No newline at end of file diff --git a/toggle-adf-trigger/v2/.mocharc.json b/toggle-adf-trigger/v2/.mocharc.json new file mode 100644 index 0000000..4552636 --- /dev/null +++ b/toggle-adf-trigger/v2/.mocharc.json @@ -0,0 +1,6 @@ +{ + "extension": ["ts"], + "spec": "**/*.spec.ts", + "require": "ts-node/register", + "reporter": ["list"] +} diff --git a/toggle-adf-trigger/v2/icon.svg b/toggle-adf-trigger/v2/icon.svg new file mode 100644 index 0000000..4f1601a --- /dev/null +++ b/toggle-adf-trigger/v2/icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/toggle-adf-trigger/v2/lib/enums.ts b/toggle-adf-trigger/v2/lib/enums.ts new file mode 100644 index 0000000..9231b19 --- /dev/null +++ b/toggle-adf-trigger/v2/lib/enums.ts @@ -0,0 +1,34 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export enum DatafactoryToggle { + Start = "start", + Stop = "stop", +} diff --git a/toggle-adf-trigger/v2/lib/helpers.spec.ts b/toggle-adf-trigger/v2/lib/helpers.spec.ts new file mode 100644 index 0000000..9df4ef0 --- /dev/null +++ b/toggle-adf-trigger/v2/lib/helpers.spec.ts @@ -0,0 +1,61 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import { wildcardFilter } from "./helpers"; + +describe("helpers.ts", function () { + describe("wildcardFilter()", () => { + describe("old wildcard functionality", () => { + it("validate 'trigger' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("trigger", "trigge*r"), true); + }); + + it("validate 'triggetr' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge*r"), true); + }); + }); + + describe("new RegExp functionality", () => { + it("validate 'triggetr' with rule 'trigge.r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge.r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.*r' => true", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.*r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.r' => false", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.r"), false); + }); + }); + }); +}); diff --git a/toggle-adf-trigger/v2/lib/helpers.ts b/toggle-adf-trigger/v2/lib/helpers.ts new file mode 100644 index 0000000..1c280b4 --- /dev/null +++ b/toggle-adf-trigger/v2/lib/helpers.ts @@ -0,0 +1,34 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export function wildcardFilter(value: string, rule: string) { + if (RegExp(/\w\*.*/g).test(rule)) return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); + else return new RegExp(rule).test(value); +} diff --git a/toggle-adf-trigger/v2/lib/interfaces.ts b/toggle-adf-trigger/v2/lib/interfaces.ts new file mode 100644 index 0000000..66fb6db --- /dev/null +++ b/toggle-adf-trigger/v2/lib/interfaces.ts @@ -0,0 +1,52 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import * as msRestAzure from "ms-rest-azure"; + +import AzureServiceClient = msRestAzure.AzureServiceClient; + +import { DatafactoryToggle } from "./enums"; + +export interface DatafactoryOptions { + azureClient?: AzureServiceClient; + subscriptionId: string; + resourceGroup: string; + dataFactoryName: string; +} + +export interface DataFactoryDeployOptions { + continue: boolean; + throttle: number; +} + +export interface DatafactoryTriggerObject { + triggerName: string; + toggle: DatafactoryToggle; +} diff --git a/toggle-adf-trigger/v2/models/azureModels.ts b/toggle-adf-trigger/v2/models/azureModels.ts index 126bd39..5aa5bf3 100644 --- a/toggle-adf-trigger/v2/models/azureModels.ts +++ b/toggle-adf-trigger/v2/models/azureModels.ts @@ -43,13 +43,13 @@ export class AzureModels { this.connectedServiceName = connectedServiceName; if (this.connectedServiceName === "local") { // local debug - this.subscriptionId = task.getInput("subscriptionid", true); - this.subscriptionName = task.getInput("subscriptionname", true); - this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); - this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); - this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); - this.tenantId = task.getInput("tenantid", true); - this.url = task.getInput("connectedServiceNameUrl", true); + this.subscriptionId = task.getInput("subscriptionid", true); + this.subscriptionName = task.getInput("subscriptionname", true); + this.servicePrincipalClientId = task.getInput("serviceprincipalid", true); + this.servicePrincipalKey = task.getInput("serviceprincipalkey", true); + this.environmentAuthorityUrl = task.getInput("environmentAuthorityUrl", true); + this.tenantId = task.getInput("tenantid", true); + this.url = task.getInput("connectedServiceNameUrl", true); } else { this.subscriptionId = task.getEndpointDataParameter(this.connectedServiceName, "subscriptionid", true); this.subscriptionName = task.getEndpointDataParameter( @@ -57,22 +57,20 @@ export class AzureModels { "subscriptionname", true ); - this.servicePrincipalClientId = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalid", - true + this.servicePrincipalClientId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalid", true) ); - this.servicePrincipalKey = task.getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalkey", - true + this.servicePrincipalKey = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalkey", true) ); this.environmentAuthorityUrl = task.getEndpointDataParameter( this.connectedServiceName, "environmentAuthorityUrl", true ); - this.tenantId = task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false); + this.tenantId = ( + task.getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false) + ); this.url = task.getEndpointUrl(this.connectedServiceName, true); } } catch (err) { diff --git a/toggle-adf-trigger/v2/models/taskParameters.ts b/toggle-adf-trigger/v2/models/taskParameters.ts index ee8dc76..a1fc62e 100644 --- a/toggle-adf-trigger/v2/models/taskParameters.ts +++ b/toggle-adf-trigger/v2/models/taskParameters.ts @@ -28,10 +28,7 @@ import * as task from "azure-pipelines-task-lib/task"; -export enum DatafactoryToggle { - Start = "start", - Stop = "stop", -} +import { DatafactoryToggle } from "../lib/enums"; export class TaskParameters { private connectedServiceName: string; @@ -39,7 +36,7 @@ export class TaskParameters { private datafactoryName: string; private triggerFilter: string; - private triggerStatus: DatafactoryToggle; + private triggerStatus: DatafactoryToggle = DatafactoryToggle.Stop; private continue: boolean; private throttle: number; @@ -48,23 +45,24 @@ export class TaskParameters { try { let rootPath = task.getVariable("System.DefaultWorkingDirectory") || "C:\\"; - this.connectedServiceName = task.getInput("ConnectedServiceName", true); - this.resourceGroupName = task.getInput("ResourceGroupName", true); - this.datafactoryName = task.getInput("DatafactoryName", true); + this.connectedServiceName = task.getInput("ConnectedServiceName", true); + this.resourceGroupName = task.getInput("ResourceGroupName", true); + this.datafactoryName = task.getInput("DatafactoryName", true); + this.triggerFilter = task.getInput("TriggerFilter", false) || ""; - this.triggerFilter = task.getInput("TriggerFilter", true); - let status = task.getInput("TriggerStatus", true); + let status = task.getInput("TriggerStatus", true); switch (status.toLowerCase()) { case "start": this.triggerStatus = DatafactoryToggle.Start; break; case "stop": + default: this.triggerStatus = DatafactoryToggle.Stop; break; } this.continue = task.getBoolInput("Continue", false); - this.throttle = Number.parseInt(task.getInput("Throttle", false)); + this.throttle = Number.parseInt(task.getInput("Throttle", false)); this.throttle = this.throttle === NaN ? 5 : this.throttle; } catch (err) { throw new Error(task.loc("TaskParameters_ConstructorFailed", err.message)); diff --git a/toggle-adf-trigger/v2/package-lock.json b/toggle-adf-trigger/v2/package-lock.json index d070c7f..9c4e99d 100644 --- a/toggle-adf-trigger/v2/package-lock.json +++ b/toggle-adf-trigger/v2/package-lock.json @@ -1,18 +1,55 @@ { "name": "toggle-adf-trigger", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "dev": true + }, "@types/node": { - "version": "8.10.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz", - "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==" + "version": "12.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.3.tgz", + "integrity": "sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg==", + "dev": true }, "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "adal-node": { @@ -20,7 +57,6 @@ "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", @@ -42,6 +78,58 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -79,9 +167,9 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "azure-pipelines-task-lib": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.9.3.tgz", - "integrity": "sha512-SPWKSfgmjyBDVIMzXnnPH0Gv7YXZ+AQ3SyIhNNALAmQpOltqJhgslvzrOClR5rKuoOyJlG0AWZILbZIXCkztAA==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.11.3.tgz", + "integrity": "sha512-gXops6Npkloh7AKPIvptx0KY1kdf1yd+BFdp/ksnbyW7CS3uXzBQXU1Dermr7A895TrOd02PI6hmsL8cBlePNA==", "requires": { "minimatch": "3.0.4", "mockery": "^1.7.0", @@ -104,6 +192,12 @@ "tweetnacl": "^0.14.3" } }, + "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 + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -113,16 +207,123 @@ "concat-map": "0.0.1" } }, + "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" + } + }, + "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 + }, "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 + }, + "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=" }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "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 + }, + "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" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -136,6 +337,18 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "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" + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -154,11 +367,32 @@ "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "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=" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -181,6 +415,24 @@ "safe-buffer": "^5.0.1" } }, + "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 + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -201,6 +453,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "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" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -216,6 +493,31 @@ "mime-types": "^2.1.12" } }, + "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": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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 + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -224,6 +526,35 @@ "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-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" + } + }, + "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", @@ -238,6 +569,47 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.44", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.44.tgz", + "integrity": "sha512-vHPAyBX1ffLcy4fQHmDyIUMUb42gHZjPHU66nhvbMzAWJqHnySGZ6STwN3rwrnSd1FHB0DI/RWgGELgKSYRDmw==", + "dev": true + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -248,11 +620,69 @@ "sshpk": "^1.7.0" } }, + "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==", + "dev": true + }, + "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-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "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-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": "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 + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -263,11 +693,33 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "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 + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "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", @@ -318,10 +770,34 @@ "safe-buffer": "^5.0.1" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "mime-db": { "version": "1.40.0", @@ -344,6 +820,39 @@ "brace-expansion": "^1.1.7" } }, + "mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.0.tgz", + "integrity": "sha512-lEWEMq2LMfNJMKeuEwb5UELi+OgFDollXaytR5ggQcHpzG3NP/R7rvixAvF+9/lLsTWhWG+4yD2M70GsM06nxw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, "mockery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", @@ -354,6 +863,12 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "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 + }, "ms-rest": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", @@ -382,16 +897,100 @@ "uuid": "^3.2.1" } }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "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==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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 + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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 + }, "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 + }, + "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": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, "psl": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", @@ -412,6 +1011,47 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "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" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~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": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -439,6 +1079,18 @@ "uuid": "^3.3.2" } }, + "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 + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -450,15 +1102,52 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "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 }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, + "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-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -475,6 +1164,104 @@ "tweetnacl": "~0.14.0" } }, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "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" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + } + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -485,6 +1272,15 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "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" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -501,6 +1297,19 @@ } } }, + "ts-node": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", + "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "tunnel": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", @@ -519,6 +1328,18 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", + "dev": true + }, "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", @@ -532,6 +1353,12 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -547,6 +1374,105 @@ "extsprintf": "^1.2.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "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" + } + }, + "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 + }, + "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", @@ -556,6 +1482,143 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + }, + "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 + }, + "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": { + "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 + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/toggle-adf-trigger/v2/package.json b/toggle-adf-trigger/v2/package.json index 3482c6a..6e3feb9 100644 --- a/toggle-adf-trigger/v2/package.json +++ b/toggle-adf-trigger/v2/package.json @@ -1,22 +1,27 @@ { - "name": "toggle-adf-trigger", - "version": "2.2.0", - "description": "Toggle ADFv2 trigger", - "main": "tasks.js", - "scripts": { - "build": "tsc", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Jan Pieter Posthuma", - "license": "MIT", - "repository": {}, - "dependencies": { - "azure-pipelines-task-lib": "^2.9.3", - "ms-rest-azure": "^3.0.0", - "q": "1.5.1", - "throat": "^5.0.0" - }, - "devDependencies": { - "@types/q": "^1.5.2" - } + "name": "toggle-adf-trigger", + "version": "2.2.0", + "description": "Toggle ADFv2 trigger", + "main": "tasks.js", + "scripts": { + "build": "tsc", + "test": "npm run build && mocha" + }, + "author": "Jan Pieter Posthuma", + "license": "MIT", + "repository": {}, + "dependencies": { + "azure-pipelines-task-lib": "^2.11.3", + "ms-rest-azure": "^3.0.0", + "throat": "^5.0.0" + }, + "devDependencies": { + "@types/mocha": "^8.0.3", + "@types/node": "^12.12.70", + "@types/q": "^1.5.4", + "mocha": "^8.2.0", + "sync-request": "^6.1.0", + "ts-node": "^9.0.0", + "typescript": "^4.0.3" + } } diff --git a/toggle-adf-trigger/v2/task.json b/toggle-adf-trigger/v2/task.json index 9f1268f..a122929 100644 --- a/toggle-adf-trigger/v2/task.json +++ b/toggle-adf-trigger/v2/task.json @@ -7,18 +7,13 @@ "helpMarkDown": "[More Information](https://github.com/liprec/vsts-publish-adf)", "category": "Deploy", "preview": false, - "visibility": [ - "Build", - "Release" - ], - "runsOn": [ - "Agent" - ], + "visibility": ["Build", "Release"], + "runsOn": ["Agent"], "demands": [], "version": { "Major": "2", - "Minor": "2", - "Patch": "0" + "Minor": "3", + "Patch": "2" }, "minimumAgentVersion": "1.100.0", "groups": [ @@ -72,7 +67,7 @@ "name": "TriggerFilter", "type": "string", "label": "Trigger Filter", - "helpMarkDown": "Filter to determine which triggers to delete.\n-Empty string: *none* triggers will be deleted.\n-`*`: *all* triggers will be deleted.", + "helpMarkDown": "Regex filter to determine which triggers to toggle.\n-Empty string: *all* triggers will be toggled.", "groupname": "adf" }, { @@ -130,4 +125,4 @@ "ToggleAdfTrigger_ToggleTrigger": "Error toggle trigger(s) to state %s: Error: %s.", "ToggleAdfTrigger_ToggleTrigger2": "Error toggle trigger %s to state %s: Error: %s." } -} \ No newline at end of file +} diff --git a/toggle-adf-trigger/v2/toggleadftrigger.spec.ts b/toggle-adf-trigger/v2/toggleadftrigger.spec.ts new file mode 100644 index 0000000..610dfab --- /dev/null +++ b/toggle-adf-trigger/v2/toggleadftrigger.spec.ts @@ -0,0 +1,35 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +describe("toggle-adf-trigger tests", function () {}); diff --git a/toggle-adf-trigger/v2/toggleadftrigger.ts b/toggle-adf-trigger/v2/toggleadftrigger.ts index d9da8a3..958ece0 100644 --- a/toggle-adf-trigger/v2/toggleadftrigger.ts +++ b/toggle-adf-trigger/v2/toggleadftrigger.ts @@ -26,42 +26,35 @@ * THE SOFTWARE. */ -import * as Q from "q"; import throat from "throat"; -import * as task from "azure-pipelines-task-lib/task"; -import * as path from "path"; -import * as msRestAzure from "ms-rest-azure"; -import { TaskParameters, DatafactoryToggle } from "./models/taskParameters"; -import { AzureModels } from "./models/azureModels"; -import { UrlBasedRequestPrepareOptions } from "./node_modules/ms-rest"; - -import AzureServiceClient = msRestAzure.AzureServiceClient; - -task.setResourcePath(path.join(__dirname, "../task.json")); +import { + error, + warning, + loc, + setResourcePath, + debug, + getVariable, + TaskResult, + setResult, +} from "azure-pipelines-task-lib/task"; +import { join } from "path"; +import { AzureServiceClient, loginWithServicePrincipalSecret } from "ms-rest-azure"; +import { UrlBasedRequestPrepareOptions, Mapper } from "ms-rest"; -interface DatafactoryOptions { - azureClient?: AzureServiceClient; - subscriptionId: string; - resourceGroup: string; - dataFactoryName: string; -} - -interface DataFactoryDeployOptions { - continue: boolean; - throttle: number; -} +import { DatafactoryToggle } from "./lib/enums"; +import { DataFactoryDeployOptions, DatafactoryOptions, DatafactoryTriggerObject } from "./lib/interfaces"; +import { TaskParameters } from "./models/taskParameters"; +import { AzureModels } from "./models/azureModels"; +import { wildcardFilter } from "./lib/helpers"; -interface DatafactoryTriggerObject { - triggerName: string; - toggle: DatafactoryToggle; -} +setResourcePath(join(__dirname, "../task.json")); function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - msRestAzure.loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { + loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { if (err) { - task.error(task.loc("Generic_LoginAzure", err.message)); - reject(task.loc("Generic_LoginAzure", err.message)); + error(loc("Generic_LoginAzure", err.message)); + reject(loc("Generic_LoginAzure", err.message)); } resolve(new AzureServiceClient(credentials, {})); }); @@ -70,24 +63,24 @@ function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err) { - task.error(task.loc("Generic_CheckDataFactory", err)); - reject(task.loc("Generic_CheckDataFactory", err)); + error(loc("Generic_CheckDataFactory", err)); + reject(loc("Generic_CheckDataFactory", err)); } - if (response.statusCode !== 200) { - task.error(task.loc("Generic_CheckDataFactory2", dataFactoryName)); - reject(task.loc("Generic_CheckDataFactory2", dataFactoryName)); + if (response && response.statusCode !== 200) { + error(loc("Generic_CheckDataFactory2", dataFactoryName)); + reject(loc("Generic_CheckDataFactory2", dataFactoryName)); } else { resolve(true); } @@ -102,40 +95,40 @@ function getTriggers( toggle: DatafactoryToggle ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let options: UrlBasedRequestPrepareOptions = { + const options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/triggers?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - let request = azureClient.sendRequest(options, async (err, result, request, response) => { + const request = azureClient.sendRequest(options, async (err, result, request, response) => { if (err) { - task.error(task.loc("ToggleAdfTrigger_GetTriggers", err.message)); - reject(task.loc("ToggleAdfTrigger_GetTriggers", err.message)); - } else if (response.statusCode !== 200) { - task.debug(task.loc("ToggleAdfTrigger_GetTriggers2")); - reject(task.loc("ToggleAdfTrigger_GetTriggers2")); + error(loc("ToggleAdfTrigger_GetTriggers", err.message)); + reject(loc("ToggleAdfTrigger_GetTriggers", err.message)); + } else if (response && response.statusCode !== 200) { + debug(loc("ToggleAdfTrigger_GetTriggers2")); + reject(loc("ToggleAdfTrigger_GetTriggers2")); } else { let objects = JSON.parse(JSON.stringify(result)); let items = objects.value; let nextLink = objects.nextLink; while (nextLink !== undefined) { - let result = await processNextLink(datafactoryOption, nextLink); + const result = await processNextLink(datafactoryOption, nextLink); objects = JSON.parse(JSON.stringify(result)); items = items.concat(objects.value); nextLink = objects.nextLink; } - items = items.filter((item) => { + items = items.filter((item: any) => { return wildcardFilter(item.name, triggerFilter); }); console.log(`Found ${items.length} trigger(s).`); resolve( - items.map((value) => { - return { triggerName: value.name, toggle: toggle }; + items.map((item: any) => { + return { triggerName: item.name, toggle: toggle }; }) ); } @@ -144,14 +137,14 @@ function getTriggers( } function processNextLink(datafactoryOption: DatafactoryOptions, nextLink: string): Promise { - const azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, options: UrlBasedRequestPrepareOptions = { method: "GET", url: nextLink, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; - task.debug(`Following next link`); + debug(`Following next link`); return new Promise((resolve, reject) => { azureClient.sendRequest(options, (err, result, request, response) => { resolve(result); @@ -165,43 +158,33 @@ function toggleTrigger( trigger: DatafactoryTriggerObject ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; - let triggerName = trigger.triggerName; - let triggerAction = trigger.toggle; - let options: UrlBasedRequestPrepareOptions = { + const triggerName = trigger.triggerName; + const triggerAction = trigger.toggle; + const options: UrlBasedRequestPrepareOptions = { method: "POST", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/triggers/${triggerName}/${triggerAction}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), headers: { "Content-Type": "application/json", }, }; - let request = azureClient.sendRequest(options, (err, result, request, response) => { + const request = azureClient.sendRequest(options, (err, result, request, response) => { if (err && !deployOptions.continue) { - task.error( - task.loc( - "ToggleAdfTrigger_ToggleTrigger2", - trigger.triggerName, - trigger.toggle.toString(), - err.message - ) + error( + loc("ToggleAdfTrigger_ToggleTrigger2", trigger.triggerName, trigger.toggle.toString(), err.message) ); reject( - task.loc( - "ToggleAdfTrigger_ToggleTrigger2", - trigger.triggerName, - trigger.toggle.toString(), - err.message - ) + loc("ToggleAdfTrigger_ToggleTrigger2", trigger.triggerName, trigger.toggle.toString(), err.message) ); - } else if (response.statusCode !== 200) { + } else if (response && response.statusCode !== 200) { if (deployOptions.continue) { - task.warning( - task.loc( + warning( + loc( "ToggleAdfTrigger_ToggleTrigger2", trigger.triggerName, trigger.toggle.toString(), @@ -211,7 +194,7 @@ function toggleTrigger( resolve(false); } else { reject( - task.loc( + loc( "ToggleAdfTrigger_ToggleTrigger2", trigger.triggerName, trigger.toggle.toString(), @@ -239,13 +222,13 @@ function toggleTriggers( .catch((err) => { reject(err); }) - .then((result: boolean) => { - resolve(result); + .then((result: boolean | void) => { + resolve(result); }); }) .catch((err) => { - task.debug(task.loc("ToggleAdfTrigger_ToggleTrigger", toggle, err.message)); - reject(task.loc("ToggleAdfTrigger_ToggleTrigger", toggle, err.message)); + debug(loc("ToggleAdfTrigger_ToggleTrigger", toggle, err.message)); + reject(loc("ToggleAdfTrigger_ToggleTrigger", toggle, err.message)); }); }); } @@ -255,11 +238,11 @@ function processItems( deployOptions: DataFactoryDeployOptions, triggers: DatafactoryTriggerObject[] ) { - let firstError; + let firstError: boolean; return new Promise((resolve, reject) => { - let totalItems = triggers.length; + const totalItems = triggers.length; - let process = Q.all( + const process = Promise.all( triggers.map( throat(deployOptions.throttle, (trigger) => { console.log(`Toggle '${trigger.triggerName}' to '${trigger.toggle}'.`); @@ -271,12 +254,12 @@ function processItems( hasError = true; firstError = firstError || err; }) - .done((results: any) => { - task.debug(`${totalItems} trigger(s) toggled.`); + .then((results: boolean[] | void) => { + debug(`${totalItems} trigger(s) toggled.`); if (hasError) { reject(firstError); } else { - let issues = results.filter((result) => { + const issues = (results).filter((result: boolean) => { return !result; }).length; if (issues > 0) { @@ -290,63 +273,61 @@ function processItems( } async function main(): Promise { - let promise = new Promise(async (resolve, reject) => { + const promise = new Promise(async (resolve, reject) => { let taskParameters: TaskParameters; let azureModels: AzureModels; + let firstError: boolean; try { - let debugMode: string = task.getVariable("System.Debug"); - let isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; + const debugMode: string = getVariable("System.Debug"); + const isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; - task.debug("Task execution started ..."); + debug("Task execution started ..."); taskParameters = new TaskParameters(); - let connectedServiceName = taskParameters.getConnectedServiceName(); - let resourceGroup = taskParameters.getResourceGroupName(); - let dataFactoryName = taskParameters.getDatafactoryName(); + const connectedServiceName = taskParameters.getConnectedServiceName(); + const resourceGroup = taskParameters.getResourceGroupName(); + const dataFactoryName = taskParameters.getDatafactoryName(); - let triggerFilter = taskParameters.getTriggerFilter(); - let triggerStatus = taskParameters.getTriggerStatus(); + const triggerFilter = taskParameters.getTriggerFilter(); + const triggerStatus = taskParameters.getTriggerStatus(); - let deployOptions = { + const deployOptions = { continue: taskParameters.getContinue(), throttle: taskParameters.getThrottle(), }; azureModels = new AzureModels(connectedServiceName); - let clientId = azureModels.getServicePrincipalClientId(); - let key = azureModels.getServicePrincipalKey(); - let tenantID = azureModels.getTenantId(); - let datafactoryOption: DatafactoryOptions = { + const clientId = azureModels.getServicePrincipalClientId(); + const key = azureModels.getServicePrincipalKey(); + const tenantID = azureModels.getTenantId(); + const datafactoryOption: DatafactoryOptions = { subscriptionId: azureModels.getSubscriptionId(), resourceGroup: resourceGroup, dataFactoryName: dataFactoryName, }; - let firstError; - task.debug("Parsed task inputs"); + debug("Parsed task inputs"); loginAzure(clientId, key, tenantID) .then((azureClient: AzureServiceClient) => { datafactoryOption.azureClient = azureClient; - task.debug("Azure client retrieved."); + debug("Azure client retrieved."); return checkDataFactory(datafactoryOption); }) .then((result) => { - task.debug(`Datafactory '${dataFactoryName}' exist`); + debug(`Datafactory '${dataFactoryName}' exist`); // Toggle Trigger logic - if (triggerFilter !== null) { - toggleTriggers(datafactoryOption, deployOptions, triggerFilter, triggerStatus) - .then((result: boolean) => { - resolve(result); - }) - .catch((err) => { - if (!deployOptions.continue) { - task.debug("Cancelling toggle operation."); - reject(err); - } else { - resolve(); - } - }); - } + toggleTriggers(datafactoryOption, deployOptions, triggerFilter, triggerStatus) + .then((result: boolean) => { + resolve(result); + }) + .catch((err) => { + if (!deployOptions.continue) { + debug("Cancelling toggle operation."); + reject(err); + } else { + resolve(true); + } + }); }) .catch((err) => { reject(err.message); @@ -358,17 +339,13 @@ async function main(): Promise { return promise; } -function wildcardFilter(value: string, rule: string) { - return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); -} - // Set generic error flag let hasError = false; main() .then((result) => { - task.setResult(result ? task.TaskResult.Succeeded : task.TaskResult.SucceededWithIssues, ""); + setResult(result ? TaskResult.Succeeded : TaskResult.SucceededWithIssues, ""); }) .catch((err) => { - task.setResult(task.TaskResult.Failed, err); + setResult(TaskResult.Failed, err); }); diff --git a/toggle-adf-trigger/v2/tsconfig.json b/toggle-adf-trigger/v2/tsconfig.json index b441b4a..99a785e 100644 --- a/toggle-adf-trigger/v2/tsconfig.json +++ b/toggle-adf-trigger/v2/tsconfig.json @@ -1,14 +1,20 @@ { "compilerOptions": { + "alwaysStrict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, "module": "commonjs", - "target": "es6", - "noImplicitAny": false, + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitThis": true, "outDir": "dist", + "removeComments": true, "rootDir": ".", + "skipLibCheck": true, "sourceMap": false, - "moduleResolution": "node" + "strict": true, + "target": "es6" }, - "exclude": [ - "node_modules" - ] + "files": ["toggleadftrigger.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/trigger-adf-pipeline/v2/.mocharc.json b/trigger-adf-pipeline/v2/.mocharc.json new file mode 100644 index 0000000..4552636 --- /dev/null +++ b/trigger-adf-pipeline/v2/.mocharc.json @@ -0,0 +1,6 @@ +{ + "extension": ["ts"], + "spec": "**/*.spec.ts", + "require": "ts-node/register", + "reporter": ["list"] +} diff --git a/trigger-adf-pipeline/v2/icon.svg b/trigger-adf-pipeline/v2/icon.svg new file mode 100644 index 0000000..44820b6 --- /dev/null +++ b/trigger-adf-pipeline/v2/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/trigger-adf-pipeline/v2/lib/enums.ts b/trigger-adf-pipeline/v2/lib/enums.ts new file mode 100644 index 0000000..aab55f3 --- /dev/null +++ b/trigger-adf-pipeline/v2/lib/enums.ts @@ -0,0 +1,36 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export enum DatafactoryTypes { + Pipeline = "Pipeline", + Dataset = "Dataset", + Trigger = "Trigger", + LinkedService = "Linked Service", +} diff --git a/trigger-adf-pipeline/v2/lib/helpers.spec.ts b/trigger-adf-pipeline/v2/lib/helpers.spec.ts new file mode 100644 index 0000000..9df4ef0 --- /dev/null +++ b/trigger-adf-pipeline/v2/lib/helpers.spec.ts @@ -0,0 +1,61 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import { wildcardFilter } from "./helpers"; + +describe("helpers.ts", function () { + describe("wildcardFilter()", () => { + describe("old wildcard functionality", () => { + it("validate 'trigger' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("trigger", "trigge*r"), true); + }); + + it("validate 'triggetr' with rule 'trigge*r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge*r"), true); + }); + }); + + describe("new RegExp functionality", () => { + it("validate 'triggetr' with rule 'trigge.r' => true", () => { + assert.strictEqual(wildcardFilter("triggetr", "trigge.r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.*r' => true", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.*r"), true); + }); + + it("validate 'triggettr' with rule 'trigge.r' => false", () => { + assert.strictEqual(wildcardFilter("triggettr", "trigge.r"), false); + }); + }); + }); +}); diff --git a/trigger-adf-pipeline/v2/lib/helpers.ts b/trigger-adf-pipeline/v2/lib/helpers.ts new file mode 100644 index 0000000..1c280b4 --- /dev/null +++ b/trigger-adf-pipeline/v2/lib/helpers.ts @@ -0,0 +1,34 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +export function wildcardFilter(value: string, rule: string) { + if (RegExp(/\w\*.*/g).test(rule)) return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); + else return new RegExp(rule).test(value); +} diff --git a/trigger-adf-pipeline/v2/lib/interfaces.ts b/trigger-adf-pipeline/v2/lib/interfaces.ts new file mode 100644 index 0000000..3d5f919 --- /dev/null +++ b/trigger-adf-pipeline/v2/lib/interfaces.ts @@ -0,0 +1,58 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import * as msRestAzure from "ms-rest-azure"; + +import AzureServiceClient = msRestAzure.AzureServiceClient; + +export interface DatafactoryOptions { + azureClient?: AzureServiceClient; + subscriptionId: string; + resourceGroup: string; + dataFactoryName: string; +} + +export interface DataFactoryDeployOptions { + continue: boolean; + throttle: number; + deploymentOutputs: string; +} + +export interface DatafactoryPipelineObject { + pipelineName: string; + json?: string; +} + +interface DataFactoryRunResultInternal { + pipeline: string; + runId: string; +} + +export type DataFactoryRunResult = DataFactoryRunResultInternal | undefined; diff --git a/trigger-adf-pipeline/v2/models/azureModels.ts b/trigger-adf-pipeline/v2/models/azureModels.ts index 40e9551..94158b3 100644 --- a/trigger-adf-pipeline/v2/models/azureModels.ts +++ b/trigger-adf-pipeline/v2/models/azureModels.ts @@ -49,32 +49,28 @@ export class AzureModels { this.connectedServiceName = connectedServiceName; if (this.connectedServiceName === "local") { // local debug - this.subscriptionId = getInput("subscriptionid", true); - this.subscriptionName = getInput("subscriptionname", true); - this.servicePrincipalClientId = getInput("serviceprincipalid", true); - this.servicePrincipalKey = getInput("serviceprincipalkey", true); - this.environmentAuthorityUrl = getInput("environmentAuthorityUrl", true); - this.tenantId = getInput("tenantid", true); - this.url = getInput("connectedServiceNameUrl", true); + this.subscriptionId = getInput("subscriptionid", true); + this.subscriptionName = getInput("subscriptionname", true); + this.servicePrincipalClientId = getInput("serviceprincipalid", true); + this.servicePrincipalKey = getInput("serviceprincipalkey", true); + this.environmentAuthorityUrl = getInput("environmentAuthorityUrl", true); + this.tenantId = getInput("tenantid", true); + this.url = getInput("connectedServiceNameUrl", true); } else { this.subscriptionId = getEndpointDataParameter(this.connectedServiceName, "subscriptionid", true); this.subscriptionName = getEndpointDataParameter(this.connectedServiceName, "subscriptionname", true); - this.servicePrincipalClientId = getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalid", - true + this.servicePrincipalClientId = ( + getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalid", true) ); - this.servicePrincipalKey = getEndpointAuthorizationParameter( - this.connectedServiceName, - "serviceprincipalkey", - true + this.servicePrincipalKey = ( + getEndpointAuthorizationParameter(this.connectedServiceName, "serviceprincipalkey", true) ); this.environmentAuthorityUrl = getEndpointDataParameter( this.connectedServiceName, "environmentAuthorityUrl", true ); - this.tenantId = getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false); + this.tenantId = getEndpointAuthorizationParameter(this.connectedServiceName, "tenantid", false); this.url = getEndpointUrl(this.connectedServiceName, true); } } catch (err) { diff --git a/trigger-adf-pipeline/v2/models/taskParameters.ts b/trigger-adf-pipeline/v2/models/taskParameters.ts index 97e8dd2..f5c2414 100644 --- a/trigger-adf-pipeline/v2/models/taskParameters.ts +++ b/trigger-adf-pipeline/v2/models/taskParameters.ts @@ -41,7 +41,7 @@ export class TaskParameters { private pipelineFilter: string; private pipelineParameterType: PipelineParameterType; private pipelineParameter: string; - private pipelineParameterPath: string; + private pipelineParameterPath: string | undefined; private continue: boolean; private throttle: number; @@ -51,27 +51,14 @@ export class TaskParameters { try { const rootPath = getVariable("System.DefaultWorkingDirectory") || "C:\\"; - this.connectedServiceName = getInput("ConnectedServiceName", true); - this.resourceGroupName = getInput("ResourceGroupName", true); - this.datafactoryName = getInput("DatafactoryName", true); - - this.pipelineFilter = getInput("PipelineFilter", false); - const pipelineParameterType = getInput("PipelineParameterType", false); - this.pipelineParameter = getInput("PipelineParameter", false); - this.pipelineParameterPath = getPathInput( - "PipelineParameterPath", - false, - pipelineParameterType.toLowerCase() === "path" - ); - - this.continue = getBoolInput("Continue", false); - this.throttle = Number.parseInt(getInput("Throttle", false)); - this.deploymentOutputs = getInput("deploymentOutputs", false); - this.throttle = this.throttle === NaN ? 5 : this.throttle; + this.connectedServiceName = getInput("ConnectedServiceName", true); + this.resourceGroupName = getInput("ResourceGroupName", true); + this.datafactoryName = getInput("DatafactoryName", true); - this.pipelineParameterPath = - this.pipelineParameterPath.replace(rootPath, "") === "" ? null : this.pipelineParameterPath; - switch (pipelineParameterType.toLowerCase()) { + this.pipelineFilter = getInput("PipelineFilter", false) || ""; + this.pipelineParameter = getInput("PipelineParameter", false); + const pipelineParameterType = getInput("PipelineParameterType", false); + switch ((pipelineParameterType && pipelineParameterType).toLowerCase()) { case "path": this.pipelineParameterType = PipelineParameterType.Path; break; @@ -80,6 +67,19 @@ export class TaskParameters { this.pipelineParameterType = PipelineParameterType.Inline; break; } + this.pipelineParameterPath = ( + getPathInput("PipelineParameterPath", false, (pipelineParameterType).toLowerCase() === "path") + ); + + this.continue = getBoolInput("Continue", false); + this.throttle = Number.parseInt(getInput("Throttle", false)); + this.throttle = this.throttle === NaN ? 5 : this.throttle; + this.deploymentOutputs = getInput("deploymentOutputs", false); + + this.pipelineParameterPath = + (this.pipelineParameterPath && this.pipelineParameterPath).replace(rootPath, "") === "" + ? undefined + : this.pipelineParameterPath; } catch (err) { throw new Error(loc("TaskParameters_ConstructorFailed", err.message)); } @@ -109,7 +109,7 @@ export class TaskParameters { return this.pipelineParameter; } - public get PipelineParameterPath(): string { + public get PipelineParameterPath(): string | undefined { return this.pipelineParameterPath; } diff --git a/trigger-adf-pipeline/v2/package-lock.json b/trigger-adf-pipeline/v2/package-lock.json index 6b849fc..d26f540 100644 --- a/trigger-adf-pipeline/v2/package-lock.json +++ b/trigger-adf-pipeline/v2/package-lock.json @@ -1,18 +1,55 @@ { "name": "trigger-adf-piepline", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "dev": true + }, "@types/node": { - "version": "8.10.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz", - "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==" + "version": "12.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.3.tgz", + "integrity": "sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg==", + "dev": true }, "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "adal-node": { @@ -20,7 +57,6 @@ "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", @@ -42,6 +78,58 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -79,9 +167,9 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, "azure-pipelines-task-lib": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.9.3.tgz", - "integrity": "sha512-SPWKSfgmjyBDVIMzXnnPH0Gv7YXZ+AQ3SyIhNNALAmQpOltqJhgslvzrOClR5rKuoOyJlG0AWZILbZIXCkztAA==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-2.11.3.tgz", + "integrity": "sha512-gXops6Npkloh7AKPIvptx0KY1kdf1yd+BFdp/ksnbyW7CS3uXzBQXU1Dermr7A895TrOd02PI6hmsL8cBlePNA==", "requires": { "minimatch": "3.0.4", "mockery": "^1.7.0", @@ -104,6 +192,12 @@ "tweetnacl": "^0.14.3" } }, + "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 + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -113,16 +207,123 @@ "concat-map": "0.0.1" } }, + "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" + } + }, + "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 + }, "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 + }, + "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=" }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "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 + }, + "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" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -136,6 +337,18 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "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" + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -154,11 +367,32 @@ "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "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=" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -181,6 +415,24 @@ "safe-buffer": "^5.0.1" } }, + "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 + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -201,6 +453,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "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" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -216,6 +493,31 @@ "mime-types": "^2.1.12" } }, + "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": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "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 + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -224,6 +526,35 @@ "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-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" + } + }, + "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", @@ -238,6 +569,47 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.44", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.44.tgz", + "integrity": "sha512-vHPAyBX1ffLcy4fQHmDyIUMUb42gHZjPHU66nhvbMzAWJqHnySGZ6STwN3rwrnSd1FHB0DI/RWgGELgKSYRDmw==", + "dev": true + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -248,11 +620,69 @@ "sshpk": "^1.7.0" } }, + "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==", + "dev": true + }, + "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-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "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-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": "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 + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -263,11 +693,33 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "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 + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "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", @@ -318,10 +770,34 @@ "safe-buffer": "^5.0.1" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "mime-db": { "version": "1.40.0", @@ -344,6 +820,39 @@ "brace-expansion": "^1.1.7" } }, + "mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.0.tgz", + "integrity": "sha512-lEWEMq2LMfNJMKeuEwb5UELi+OgFDollXaytR5ggQcHpzG3NP/R7rvixAvF+9/lLsTWhWG+4yD2M70GsM06nxw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + } + }, "mockery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", @@ -354,6 +863,12 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "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 + }, "ms-rest": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", @@ -382,16 +897,100 @@ "uuid": "^3.2.1" } }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "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==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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 + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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 + }, "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 + }, + "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": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "requires": { + "asap": "~2.0.6" + } + }, "psl": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", @@ -412,6 +1011,47 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "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" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~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": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -446,6 +1086,18 @@ } } }, + "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 + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -457,15 +1109,52 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "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 }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, + "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-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -482,6 +1171,104 @@ "tweetnacl": "~0.14.0" } }, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "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" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + } + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -492,6 +1279,15 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "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" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -501,6 +1297,19 @@ "punycode": "^2.1.1" } }, + "ts-node": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", + "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "tunnel": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", @@ -519,6 +1328,18 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", + "dev": true + }, "underscore": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", @@ -532,6 +1353,12 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", @@ -547,6 +1374,105 @@ "extsprintf": "^1.2.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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" + } + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "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" + } + }, + "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 + }, + "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.2.1", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.2.1.tgz", @@ -556,6 +1482,143 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + }, + "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 + }, + "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": { + "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 + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/trigger-adf-pipeline/v2/package.json b/trigger-adf-pipeline/v2/package.json index 014bfb8..9422b36 100644 --- a/trigger-adf-pipeline/v2/package.json +++ b/trigger-adf-pipeline/v2/package.json @@ -1,22 +1,27 @@ { - "name": "trigger-adf-piepline", - "version": "2.2.0", - "description": "Trigger ADFv2 items", - "main": "tasks.js", - "scripts": { - "build": "tsc", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Jan Pieter Posthuma", - "license": "MIT", - "repository": {}, - "dependencies": { - "azure-pipelines-task-lib": "^2.9.3", - "ms-rest-azure": "^3.0.0", - "q": "1.5.1", - "throat": "^5.0.0" - }, - "devDependencies": { - "@types/q": "^1.5.2" - } + "name": "trigger-adf-piepline", + "version": "2.2.0", + "description": "Trigger ADFv2 items", + "main": "tasks.js", + "scripts": { + "build": "tsc", + "test": "npm run build && mocha" + }, + "author": "Jan Pieter Posthuma", + "license": "MIT", + "repository": {}, + "dependencies": { + "azure-pipelines-task-lib": "^2.11.3", + "ms-rest-azure": "^3.0.0", + "throat": "^5.0.0" + }, + "devDependencies": { + "@types/mocha": "^8.0.3", + "@types/node": "^12.12.70", + "@types/q": "^1.5.4", + "mocha": "^8.2.0", + "sync-request": "^6.1.0", + "ts-node": "^9.0.0", + "typescript": "^4.0.3" + } } diff --git a/trigger-adf-pipeline/v2/task.json b/trigger-adf-pipeline/v2/task.json index ee3bec7..a8d3682 100644 --- a/trigger-adf-pipeline/v2/task.json +++ b/trigger-adf-pipeline/v2/task.json @@ -7,18 +7,13 @@ "helpMarkDown": "[More Information](https://github.com/liprec/vsts-publish-adf)", "category": "Deploy", "preview": false, - "visibility": [ - "Build", - "Release" - ], - "runsOn": [ - "Agent" - ], + "visibility": ["Build", "Release"], + "runsOn": ["Agent"], "demands": [], "version": { "Major": "2", - "Minor": "2", - "Patch": "0" + "Minor": "3", + "Patch": "2" }, "minimumAgentVersion": "1.100.0", "groups": [ @@ -73,7 +68,7 @@ "type": "string", "label": "Pipeline Filter", "required": false, - "helpMarkDown": "Filter to determine which pipeline to trigger execution.\n`*`: *all* pipeline will be triggered.", + "helpMarkDown": "Regex filter to determine which triggers to toggle.\n-Empty string: *all* triggers will be toggled.", "groupname": "adf" }, { @@ -157,4 +152,4 @@ "TriggerAdfPipelines_TriggerPipelines": "Error retrieving pipelines: Error: ", "TriggerAdfPipelines_AddedOutputVariable": "Updated output variable '%s', which contains the RUN IDs of the package triggers in string format." } -} \ No newline at end of file +} diff --git a/trigger-adf-pipeline/v2/triggeradfpipeline.spec.ts b/trigger-adf-pipeline/v2/triggeradfpipeline.spec.ts new file mode 100644 index 0000000..4ea553d --- /dev/null +++ b/trigger-adf-pipeline/v2/triggeradfpipeline.spec.ts @@ -0,0 +1,35 @@ +/* + * Azure Pipelines Azure Datafactory Deploy Task + * + * Copyright (c) 2020 Jan Pieter Posthuma / DataScenarios + * + * All rights reserved. + * + * MIT License. + * + * 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. + */ + +"use strict"; + +import { strict as assert } from "assert"; + +import * as ttm from "azure-pipelines-task-lib/mock-test"; + +describe("trigger-adf-pipeline tests", function () {}); diff --git a/trigger-adf-pipeline/v2/triggeradfpipeline.ts b/trigger-adf-pipeline/v2/triggeradfpipeline.ts index 4341c60..4c0f83a 100644 --- a/trigger-adf-pipeline/v2/triggeradfpipeline.ts +++ b/trigger-adf-pipeline/v2/triggeradfpipeline.ts @@ -26,7 +26,8 @@ * THE SOFTWARE. */ -import { all } from "q"; +"use strict"; + import throat from "throat"; import { error, @@ -42,43 +43,20 @@ import { import { join } from "path"; import { readFileSync } from "fs"; import { AzureServiceClient, loginWithServicePrincipalSecret } from "ms-rest-azure"; -import { UrlBasedRequestPrepareOptions } from "ms-rest"; +import { UrlBasedRequestPrepareOptions, Mapper } from "ms-rest"; +import { + DataFactoryDeployOptions, + DatafactoryOptions, + DatafactoryPipelineObject, + DataFactoryRunResult, +} from "./lib/interfaces"; import { TaskParameters, PipelineParameterType } from "./models/taskParameters"; import { AzureModels } from "./models/azureModels"; +import { wildcardFilter } from "./lib/helpers"; setResourcePath(join(__dirname, "../task.json")); -enum DatafactoryTypes { - Pipeline = "Pipeline", - Dataset = "Dataset", - Trigger = "Trigger", - LinkedService = "Linked Service", -} - -interface DatafactoryOptions { - azureClient?: AzureServiceClient; - subscriptionId: string; - resourceGroup: string; - dataFactoryName: string; -} - -interface DataFactoryDeployOptions { - continue: boolean; - throttle: number; - deploymentOutputs: string; -} - -interface DatafactoryPipelineObject { - pipelineName: string; - json?: string; -} - -interface DataFactoryRunResult { - pipeline: string; - runId: string; -} - function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { loginWithServicePrincipalSecret(clientId, key, tenantID, (err, credentials) => { @@ -93,22 +71,22 @@ function loginAzure(clientId: string, key: string, tenantID: string): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + let azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; let options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; let request = azureClient.sendRequest(options, (err, result, request, response) => { if (err) { error(loc("Generic_CheckDataFactory", err)); reject(loc("Generic_CheckDataFactory", err)); } - if (response.statusCode !== 200) { + if (response && response.statusCode !== 200) { error(loc("Generic_CheckDataFactory2", dataFactoryName)); reject(loc("Generic_CheckDataFactory2", dataFactoryName)); } else { @@ -124,21 +102,21 @@ function getPipelines( parameter: string ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + let azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; let options: UrlBasedRequestPrepareOptions = { method: "GET", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/pipelines?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; let request = azureClient.sendRequest(options, async (err, result, request, response) => { if (err) { error(loc("TriggerAdfPipelines_GetPipelines", err.message)); reject(loc("TriggerAdfPipelines_GetPipelines", err.message)); - } else if (response.statusCode !== 200) { + } else if (response && response.statusCode !== 200) { debug(loc("TriggerAdfPipelines_GetPipelines2")); reject(loc("TriggerAdfPipelines_GetPipelines2")); } else { @@ -151,13 +129,13 @@ function getPipelines( items = items.concat(objects.value); nextLink = objects.nextLink; } - items = items.filter((item) => { + items = items.filter((item: any) => { return wildcardFilter(item.name, filter); }); console.log(`Found ${items.length} pipeline(s).`); resolve( - items.map((value) => { - return { pipelineName: value.name, json: parameter }; + items.map((item: any) => { + return { pipelineName: item.name, json: parameter }; }) ); } @@ -166,12 +144,12 @@ function getPipelines( } function processNextLink(datafactoryOption: DatafactoryOptions, nextLink: string): Promise { - const azureClient: AzureServiceClient = datafactoryOption.azureClient, + const azureClient: AzureServiceClient = datafactoryOption.azureClient, options: UrlBasedRequestPrepareOptions = { method: "GET", url: nextLink, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), }; debug(`Following next link`); return new Promise((resolve, reject) => { @@ -187,7 +165,7 @@ function triggerPipeline( pipeline: DatafactoryPipelineObject ): Promise { return new Promise((resolve, reject) => { - let azureClient: AzureServiceClient = datafactoryOption.azureClient, + let azureClient: AzureServiceClient = datafactoryOption.azureClient, subscriptionId: string = datafactoryOption.subscriptionId, resourceGroup: string = datafactoryOption.resourceGroup, dataFactoryName: string = datafactoryOption.dataFactoryName; @@ -195,34 +173,34 @@ function triggerPipeline( let options: UrlBasedRequestPrepareOptions = { method: "POST", url: `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DataFactory/factories/${dataFactoryName}/pipelines/${pipelineName}/createRun?api-version=2018-06-01`, - serializationMapper: null, - deserializationMapper: null, + serializationMapper: (undefined), + deserializationMapper: (undefined), headers: { "Content-Type": "application/json", }, body: pipeline.json, disableJsonStringifyOnBody: true, }; - let request = azureClient.sendRequest(options, (err, result: string, request, response) => { + let request = azureClient.sendRequest(options, (err, result, request, response) => { if (err) { if (deployOptions.continue) { warning(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, err.message)); - resolve(); + resolve(undefined); } else { error(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, err.message)); reject(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, err.message)); } - } else if (response.statusCode !== 200 && response.statusCode !== 204) { + } else if (response && response.statusCode !== 200 && response.statusCode !== 204) { if (deployOptions.continue) { warning(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, JSON.stringify(result))); - resolve(); + resolve(undefined); } else { error(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, JSON.stringify(result))); reject(loc("TriggerAdfPipelines_TriggerPipeline", pipelineName, JSON.stringify(result))); } - } else if (response.statusCode === 204) { + } else if (response && response.statusCode === 204) { warning(`'${pipelineName}' not found.`); - resolve(); + resolve(undefined); } else { const runId = (result as any).runId; console.log(`Pipeline '${pipelineName}' triggered with run id: '${runId}'.`); @@ -248,8 +226,8 @@ function triggerPipelines( .catch((err) => { reject(err); }) - .then((result: boolean) => { - resolve(result); + .then((result: boolean | void) => { + resolve(result); }); }) .catch((err) => { @@ -264,11 +242,11 @@ function processPipelines( deployOptions: DataFactoryDeployOptions, pipelines: DatafactoryPipelineObject[] ): Promise { - let firstError; + let firstError: boolean; return new Promise((resolve, reject) => { let totalItems = pipelines.length; - let process = all( + let process = Promise.all( pipelines.map( throat(deployOptions.throttle, (pipeline) => { // console.log(`Trigger pipeline '${pipeline.pipelineName}'.`); @@ -280,16 +258,19 @@ function processPipelines( hasError = true; firstError = firstError || err; }) - .done((results: any) => { + .then((results: any) => { debug(`${totalItems} pipeline(s) triggered.`); if (hasError) { reject(firstError); } else { if (isNonEmpty(deployOptions.deploymentOutputs)) { - setVariable(deployOptions.deploymentOutputs, JSON.stringify(results)); + setVariable( + deployOptions.deploymentOutputs, + JSON.stringify(results.filter((result: DataFactoryRunResult) => !result)) + ); console.log(loc("TriggerAdfPipelines_AddedOutputVariable", deployOptions.deploymentOutputs)); } - let issues = results.filter((result) => { + let issues = results.filter((result: any) => { return result === ""; }).length; if (issues > 0) { @@ -308,7 +289,7 @@ async function main(): Promise { let azureModels: AzureModels; try { - let debugMode: string = getVariable("System.Debug"); + let debugMode: string = getVariable("System.Debug"); let isVerbose: boolean = debugMode ? debugMode.toLowerCase() != "false" : false; debug("Task execution started ..."); @@ -326,7 +307,7 @@ async function main(): Promise { pipelineParameter = taskParameters.PipelineParameter; break; case PipelineParameterType.Path: - pipelineParameter = readFileSync(taskParameters.PipelineParameterPath, "utf8"); + pipelineParameter = readFileSync(taskParameters.PipelineParameterPath, "utf8"); console.log(pipelineParameter); break; } @@ -367,7 +348,7 @@ async function main(): Promise { debug("Cancelling trigger operation."); reject(err); } else { - resolve(); + resolve(true); } }); } @@ -382,10 +363,6 @@ async function main(): Promise { return promise; } -function wildcardFilter(value: string, rule: string) { - return new RegExp("^" + rule.split("*").join(".*") + "$").test(value); -} - function isNonEmpty(str: string): boolean { return !!str && !!str.trim(); } diff --git a/trigger-adf-pipeline/v2/tsconfig.json b/trigger-adf-pipeline/v2/tsconfig.json index b441b4a..b1a9b47 100644 --- a/trigger-adf-pipeline/v2/tsconfig.json +++ b/trigger-adf-pipeline/v2/tsconfig.json @@ -1,14 +1,20 @@ { "compilerOptions": { + "alwaysStrict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, "module": "commonjs", - "target": "es6", - "noImplicitAny": false, + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitThis": true, "outDir": "dist", + "removeComments": true, "rootDir": ".", + "skipLibCheck": true, "sourceMap": false, - "moduleResolution": "node" + "strict": true, + "target": "es6" }, - "exclude": [ - "node_modules" - ] + "files": ["triggeradfpipeline.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/vss-extension-preview.json b/vss-extension-preview.json index b2031f6..1f7ea3d 100644 --- a/vss-extension-preview.json +++ b/vss-extension-preview.json @@ -1,7 +1,7 @@ { "manifestVersion": 1, "id": "vsts-publish-adf-preview", - "version": "2.2.2", + "version": "2.3.3", "name": "Azure Data Factory (Preview)", "publisher": "liprec", "public": false, @@ -86,6 +86,14 @@ "properties": { "name": "trigger-adf-pipeline" } + }, + { + "id": "query-adf-run", + "type": "ms.vss-distributed-task.task", + "targets": ["ms.vss-distributed-task.tasks"], + "properties": { + "name": "query-adf-run" + } } ], "files": [ @@ -146,6 +154,12 @@ { "path": "trigger-adf-pipeline/v2/icon.png" }, + { + "path": "query-adf-run/task.json" + }, + { + "path": "query-adf-run/icon.png" + }, { "path": "images/logo.png", "addressable": true diff --git a/vss-extension.json b/vss-extension.json index b1a966a..f4fa42b 100644 --- a/vss-extension.json +++ b/vss-extension.json @@ -1,7 +1,7 @@ { "manifestVersion": 1, "id": "vsts-publish-adf", - "version": "2.2.2", + "version": "2.3.2", "name": "Azure Data Factory", "publisher": "liprec", "public": true, @@ -86,6 +86,14 @@ "properties": { "name": "trigger-adf-pipeline" } + }, + { + "id": "query-adf-run", + "type": "ms.vss-distributed-task.task", + "targets": ["ms.vss-distributed-task.tasks"], + "properties": { + "name": "query-adf-run" + } } ], "files": [ @@ -146,6 +154,12 @@ { "path": "trigger-adf-pipeline/v2/icon.png" }, + { + "path": "query-adf-run/task.json" + }, + { + "path": "query-adf-run/icon.png" + }, { "path": "images/logo.png", "addressable": true