From d3b8bbd206077bca9a7d8f064ad3971275a3517e Mon Sep 17 00:00:00 2001 From: Henry Been Date: Sat, 30 Mar 2019 14:05:05 +0100 Subject: [PATCH 1/3] Upgrade of azure-devops-node-api package --- app/exec/build/list.ts | 75 ++++++++++++----------- app/exec/build/queue.ts | 54 ++++++++-------- app/exec/build/show.ts | 17 ++--- app/exec/build/tasks/_resources/icon.png | Bin 2581 -> 2580 bytes app/exec/build/tasks/delete.ts | 33 +++++----- app/exec/build/tasks/list.ts | 32 +++++----- app/exec/build/tasks/upload.ts | 23 +++---- app/exec/extension/_lib/publish.ts | 21 +++---- app/exec/extension/default.ts | 4 +- app/exec/extension/install.ts | 10 +-- app/exec/extension/isvalid.ts | 4 +- app/exec/extension/publish.ts | 2 +- app/exec/extension/publisher/create.ts | 7 +-- app/exec/extension/publisher/delete.ts | 23 ++++--- app/exec/extension/share.ts | 48 ++++++++------- app/exec/extension/show.ts | 16 ++--- app/exec/extension/unshare.ts | 48 ++++++++------- app/exec/login.ts | 1 - app/exec/workitem/create.ts | 11 ++-- app/exec/workitem/default.ts | 4 +- app/exec/workitem/query.ts | 68 ++++++++++---------- app/exec/workitem/show.ts | 14 +++-- app/exec/workitem/update.ts | 11 ++-- app/lib/connection.ts | 6 +- app/lib/tfcommand.ts | 4 +- docs/basicAuthEnabled.png | Bin 70329 -> 70327 bytes docs/configureBasicAuthFeature.png | Bin 66532 -> 66531 bytes docs/help-screen.png | Bin 15528 -> 15527 bytes docs/tfsAuth.png | Bin 115775 -> 115774 bytes package.json | 2 +- 30 files changed, 280 insertions(+), 258 deletions(-) diff --git a/app/exec/build/list.ts b/app/exec/build/list.ts index c0fb612e..413c5b63 100644 --- a/app/exec/build/list.ts +++ b/app/exec/build/list.ts @@ -1,8 +1,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import buildBase = require("./default"); -import buildClient = require("vso-node-api/BuildApi"); -import buildContracts = require("vso-node-api/interfaces/BuildInterfaces"); +import buildClient = require("azure-devops-node-api/BuildApi"); +import buildContracts = require("azure-devops-node-api/interfaces/BuildInterfaces"); import trace = require("../../lib/trace"); @@ -20,40 +20,43 @@ export class BuildGetList extends buildBase.BuildBase { trace.debug("build-list.exec"); - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); - - return Promise.all([ - this.commandArgs.project.val(), - this.commandArgs.definitionId.val(), - this.commandArgs.definitionName.val(), - this.commandArgs.status.val(), - this.commandArgs.top.val(), - ]).then(values => { - const [project, definitionId, definitionName, status, top] = values; - var definitions: number[] = null; - if (definitionId) { - definitions = [definitionId as number]; - } else if (definitionName) { - trace.debug("No definition Id provided, checking for definitions with name " + definitionName); - return buildapi - .getDefinitions(project as string, definitionName as string) - .then((defs: buildContracts.DefinitionReference[]) => { - if (defs.length > 0) { - definitions = [defs[0].id]; - return this._getBuilds( - buildapi, - project as string, - definitions, - buildContracts.BuildStatus[status], - top as number, - ); - } else { - trace.debug("No definition found with name " + definitionName); - throw new Error("No definition found with name " + definitionName); - } - }); - } - return this._getBuilds(buildapi, project as string, definitions, buildContracts.BuildStatus[status], top as number); + + return this.webApi + .getBuildApi() + .then(buildApi => { + return Promise.all([ + this.commandArgs.project.val(), + this.commandArgs.definitionId.val(), + this.commandArgs.definitionName.val(), + this.commandArgs.status.val(), + this.commandArgs.top.val(), + ]).then(values => { + const [project, definitionId, definitionName, status, top] = values; + var definitions: number[] = null; + if (definitionId) { + definitions = [definitionId as number]; + } else if (definitionName) { + trace.debug("No definition Id provided, checking for definitions with name " + definitionName); + return buildApi + .getDefinitions(project as string, definitionName as string) + .then((defs: buildContracts.DefinitionReference[]) => { + if (defs.length > 0) { + definitions = [defs[0].id]; + return this._getBuilds( + buildApi, + project as string, + definitions, + buildContracts.BuildStatus[status], + top as number, + ); + } else { + trace.debug("No definition found with name " + definitionName); + throw new Error("No definition found with name " + definitionName); + } + }); + } + return this._getBuilds(buildApi, project as string, definitions, buildContracts.BuildStatus[status], top as number); + }); }); } diff --git a/app/exec/build/queue.ts b/app/exec/build/queue.ts index f70860bd..66c00ff5 100644 --- a/app/exec/build/queue.ts +++ b/app/exec/build/queue.ts @@ -1,8 +1,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import buildBase = require("./default"); -import buildClient = require("vso-node-api/BuildApi"); -import buildContracts = require("vso-node-api/interfaces/BuildInterfaces"); +import buildClient = require("azure-devops-node-api/BuildApi"); +import buildContracts = require("azure-devops-node-api/interfaces/BuildInterfaces"); import trace = require("../../lib/trace"); export function describe(): string { @@ -22,31 +22,33 @@ export class BuildQueue extends buildBase.BuildBase { - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); - - return this.commandArgs.project.val().then(project => { - return this.commandArgs.definitionId.val(true).then(definitionId => { - let definitionPromise: Promise; - if (definitionId) { - definitionPromise = buildapi.getDefinition(definitionId, project); - } else { - definitionPromise = this.commandArgs.definitionName.val().then(definitionName => { - trace.debug("No definition id provided, Searching for definitions with name: " + definitionName); - return buildapi - .getDefinitions(project, definitionName) - .then((definitions: buildContracts.DefinitionReference[]) => { - if (definitions.length > 0) { - var definition = definitions[0]; - return definition; - } else { - trace.debug("No definition found with name " + definitionName); - throw new Error("No definition found with name " + definitionName); - } - }); + return this.webApi + .getBuildApi() + .then(buildApi => { + return this.commandArgs.project.val().then(project => { + return this.commandArgs.definitionId.val(true).then(definitionId => { + let definitionPromise: Promise; + if (definitionId) { + definitionPromise = buildApi.getDefinition(definitionId, project); + } else { + definitionPromise = this.commandArgs.definitionName.val().then(definitionName => { + trace.debug("No definition id provided, Searching for definitions with name: " + definitionName); + return buildApi + .getDefinitions(project, definitionName) + .then((definitions: buildContracts.DefinitionReference[]) => { + if (definitions.length > 0) { + var definition = definitions[0]; + return definition; + } else { + trace.debug("No definition found with name " + definitionName); + throw new Error("No definition found with name " + definitionName); + } + }); + }); + } + return definitionPromise.then(definition => { + return this._queueBuild(buildApi, definition, project); }); - } - return definitionPromise.then(definition => { - return this._queueBuild(buildapi, definition, project); }); }); }); diff --git a/app/exec/build/show.ts b/app/exec/build/show.ts index c8c6967c..ba71a357 100644 --- a/app/exec/build/show.ts +++ b/app/exec/build/show.ts @@ -1,8 +1,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import buildBase = require("./default"); -import buildClient = require("vso-node-api/BuildApi"); -import buildContracts = require("vso-node-api/interfaces/BuildInterfaces"); +import buildClient = require("azure-devops-node-api/BuildApi"); +import buildContracts = require("azure-devops-node-api/interfaces/BuildInterfaces"); import trace = require("../../lib/trace"); export function getCommand(args: string[]): BuildShow { @@ -19,12 +19,15 @@ export class BuildShow extends buildBase.BuildBase { trace.debug("build-show.exec"); - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); - return this.commandArgs.project.val().then(project => { - return this.commandArgs.buildId.val().then(buildId => { - return buildapi.getBuild(buildId, project); + return this.webApi + .getBuildApi() + .then(buildApi => { + return this.commandArgs.project.val().then(project => { + return this.commandArgs.buildId.val().then(buildId => { + return buildApi.getBuild(buildId, project); + }); + }); }); - }); } public friendlyOutput(build: buildContracts.Build): void { diff --git a/app/exec/build/tasks/_resources/icon.png b/app/exec/build/tasks/_resources/icon.png index 2a4c1dde941b25f71be7d14f060b26dbaa185ba6..45fbc0d51ad92e6bc15561c91a128224b93fa839 100644 GIT binary patch delta 13 UcmbO#GDU=?Gr-S%BdY)x033n?lmGw# delta 14 VcmbOtGF61NGr-TCcO#1c7XTlO1EBx_ diff --git a/app/exec/build/tasks/delete.ts b/app/exec/build/tasks/delete.ts index 15bc6b69..cd59c498 100644 --- a/app/exec/build/tasks/delete.ts +++ b/app/exec/build/tasks/delete.ts @@ -1,5 +1,5 @@ import { TfCommand } from "../../../lib/tfcommand"; -import agentContracts = require("vso-node-api/interfaces/TaskAgentInterfaces"); +import agentContracts = require("azure-devops-node-api/interfaces/TaskAgentInterfaces"); import args = require("../../../lib/arguments"); import tasksBase = require("./default"); import trace = require("../../../lib/trace"); @@ -17,22 +17,25 @@ export class BuildTaskDelete extends tasksBase.BuildTaskBase { - let agentApi = this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); - return this.commandArgs.taskId.val().then(taskId => { - return agentApi.getTaskDefinitions(taskId).then(tasks => { - if (tasks && tasks.length > 0) { - trace.debug("Deleting task(s)..."); - return agentApi.deleteTaskDefinition(taskId).then(() => { - return { - id: taskId, - }; + return this.webApi + .getTaskAgentApi(this.connection.getCollectionUrl()) + .then(agentApi => { + return this.commandArgs.taskId.val().then(taskId => { + return agentApi.getTaskDefinitions(taskId).then(tasks => { + if (tasks && tasks.length > 0) { + trace.debug("Deleting task(s)..."); + return agentApi.deleteTaskDefinition(taskId).then(() => { + return { + id: taskId, + }; + }); + } else { + trace.debug("No such task."); + throw new Error("No task found with provided ID: " + taskId); + } }); - } else { - trace.debug("No such task."); - throw new Error("No task found with provided ID: " + taskId); - } + }); }); - }); } public friendlyOutput(data: agentContracts.TaskDefinition): void { diff --git a/app/exec/build/tasks/list.ts b/app/exec/build/tasks/list.ts index 2dc0d309..d62ebbbd 100644 --- a/app/exec/build/tasks/list.ts +++ b/app/exec/build/tasks/list.ts @@ -1,5 +1,5 @@ import { TfCommand } from "../../../lib/tfcommand"; -import agentContracts = require("vso-node-api/interfaces/TaskAgentInterfaces"); +import agentContracts = require("azure-devops-node-api/interfaces/TaskAgentInterfaces"); import args = require("../../../lib/arguments"); import tasksBase = require("./default"); import trace = require("../../../lib/trace"); @@ -17,21 +17,23 @@ export class BuildTaskList extends tasksBase.BuildTaskBase { - var agentapi = this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); - - trace.debug("Searching for build tasks..."); - return agentapi.getTaskDefinitions(null, ["build"], null).then(tasks => { - trace.debug("Retrieved " + tasks.length + " build tasks from server."); - return this.commandArgs.all.val().then(all => { - if (all) { - trace.debug("Listing all build tasks."); - return tasks; - } else { - trace.debug("Filtering build tasks to give only the latest versions."); - return this._getNewestTasks(tasks); - } + return this.webApi + .getTaskAgentApi(this.connection.getCollectionUrl()) + .then(agentApi => { + trace.debug("Searching for build tasks..."); + return agentApi.getTaskDefinitions(null, ["build"], null).then(tasks => { + trace.debug("Retrieved " + tasks.length + " build tasks from server."); + return this.commandArgs.all.val().then(all => { + if (all) { + trace.debug("Listing all build tasks."); + return tasks; + } else { + trace.debug("Filtering build tasks to give only the latest versions."); + return this._getNewestTasks(tasks); + } + }); + }); }); - }); } /* diff --git a/app/exec/build/tasks/upload.ts b/app/exec/build/tasks/upload.ts index a391d601..14a7d9ab 100644 --- a/app/exec/build/tasks/upload.ts +++ b/app/exec/build/tasks/upload.ts @@ -1,10 +1,9 @@ import { TfCommand } from "../../../lib/tfcommand"; -import agentContracts = require("vso-node-api/interfaces/TaskAgentInterfaces"); +import agentContracts = require("azure-devops-node-api/interfaces/TaskAgentInterfaces"); import archiver = require("archiver"); import args = require("../../../lib/arguments"); import fs = require("fs"); import path = require("path"); -import Q = require("q"); import tasksBase = require("./default"); import trace = require("../../../lib/trace"); import vm = require("../../../lib/jsonvalidate"); @@ -40,15 +39,17 @@ export class BuildTaskUpload extends tasksBase.BuildTaskBasearchive, taskJson.id, overwrite).then(() => { - trace.debug("Success"); - return { - sourceLocation: taskPath, - }; - }); + return this.webApi + .getTaskAgentApi(this.connection.getCollectionUrl()) + .then(agentApi => { + archive.finalize(); + return agentApi.uploadTaskDefinition(null, archive, taskJson.id, overwrite).then(() => { + trace.debug("Success"); + return { + sourceLocation: taskPath, + }; + }); + }); }); }); }); diff --git a/app/exec/extension/_lib/publish.ts b/app/exec/extension/_lib/publish.ts index b6ec10bb..c633d6e2 100644 --- a/app/exec/extension/_lib/publish.ts +++ b/app/exec/extension/_lib/publish.ts @@ -1,10 +1,10 @@ -import { IGalleryApi } from "vso-node-api/GalleryApi"; +import { IGalleryApi } from "azure-devops-node-api/GalleryApi"; import { PublishSettings } from "./interfaces"; import _ = require("lodash"); import colors = require("colors"); import errHandler = require("../../../lib/errorhandler"); import fs = require("fs"); -import GalleryInterfaces = require("vso-node-api/interfaces/GalleryInterfaces"); +import GalleryInterfaces = require("azure-devops-node-api/interfaces/GalleryInterfaces"); import trace = require("../../../lib/trace"); import xml2js = require("xml2js"); import zip = require("jszip"); @@ -120,6 +120,7 @@ export class GalleryBase { return this.getExtInfo().then(extInfo => { return this.galleryClient .getExtension( + null, extInfo.publisher, extInfo.id, extInfo.version, @@ -172,6 +173,7 @@ export class GalleryBase { return this.getExtInfo().then(extInfo => { return this.galleryClient .getExtension( + null, extInfo.publisher, extInfo.id, null, @@ -275,7 +277,7 @@ export class PackagePublisher extends GalleryBase { private checkVsixPublished(): Promise { return this.getExtInfo().then(extInfo => { return this.galleryClient - .getExtension(extInfo.publisher, extInfo.id) + .getExtension(null, extInfo.publisher, extInfo.id) .then(ext => { if (ext) { extInfo.published = true; @@ -293,9 +295,7 @@ export class PackagePublisher extends GalleryBase { * @return Q.Promise that is resolved when publish is complete */ public publish(): Promise { - const extPackage: GalleryInterfaces.ExtensionPackage = { - extensionManifest: fs.readFileSync(this.settings.vsixPath, "base64"), - }; + const extPackage = fs.createReadStream(this.settings.vsixPath); trace.debug("Publishing %s", this.settings.vsixPath); // Check if the app is already published. If so, call the update endpoint. Otherwise, create. @@ -356,22 +356,21 @@ export class PackagePublisher extends GalleryBase { }); } - private createOrUpdateExtension( - extPackage: GalleryInterfaces.ExtensionPackage, - ): Promise { + private createOrUpdateExtension(extPackage: NodeJS.ReadableStream): Promise { return this.checkVsixPublished().then(extInfo => { let publishPromise; if (extInfo && extInfo.published) { trace.info("It is, %s the extension", colors.cyan("update").toString()); publishPromise = this.galleryClient - .updateExtension(extPackage, extInfo.publisher, extInfo.id) + .updateExtension(null, extPackage, extInfo.publisher, extInfo.id) .catch(errHandler.httpErr); } else { trace.info("It isn't, %s a new extension.", colors.cyan("create").toString()); - publishPromise = this.galleryClient.createExtension(extPackage).catch(errHandler.httpErr); + publishPromise = this.galleryClient.createExtension(null, extPackage).catch(errHandler.httpErr); } return publishPromise.then(() => { return this.galleryClient.getExtension( + null, extInfo.publisher, extInfo.id, null, diff --git a/app/exec/extension/default.ts b/app/exec/extension/default.ts index cdc90d19..4ab8db63 100644 --- a/app/exec/extension/default.ts +++ b/app/exec/extension/default.ts @@ -1,7 +1,7 @@ import { TfCommand, CoreArguments } from "../../lib/tfcommand"; import { MergeSettings, PackageSettings, PublishSettings } from "./_lib/interfaces"; -import { WebApi, getBasicHandler } from "vso-node-api/WebApi"; -import { BasicCredentialHandler } from "vso-node-api/handlers/basiccreds"; +import { WebApi, getBasicHandler } from "azure-devops-node-api/WebApi"; +import { BasicCredentialHandler } from "azure-devops-node-api/handlers/basiccreds"; import { GalleryBase, CoreExtInfo, PublisherManager, PackagePublisher } from "./_lib/publish"; import * as path from "path"; import _ = require("lodash"); diff --git a/app/exec/extension/install.ts b/app/exec/extension/install.ts index c380d710..390b19d9 100644 --- a/app/exec/extension/install.ts +++ b/app/exec/extension/install.ts @@ -4,10 +4,10 @@ import colors = require("colors"); import extBase = require("./default"); import extInfo = require("./_lib/extensioninfo"); import trace = require("../../lib/trace"); -import GalleryInterfaces = require("vso-node-api/interfaces/GalleryInterfaces"); -import gallerym = require("vso-node-api/GalleryApi"); -import emsm = require("vso-node-api/ExtensionManagementApi"); -import EmsInterfaces = require("vso-node-api/interfaces/ExtensionManagementInterfaces"); +import GalleryInterfaces = require("azure-devops-node-api/interfaces/GalleryInterfaces"); +import gallerym = require("azure-devops-node-api/GalleryApi"); +import emsm = require("azure-devops-node-api/ExtensionManagementApi"); +import EmsInterfaces = require("azure-devops-node-api/interfaces/ExtensionManagementInterfaces"); import https = require("https"); import { realPromise } from "../../lib/promiseUtils"; @@ -99,7 +99,7 @@ export class ExtensionInstall extends extBase.ExtensionBase { - const galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + const galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); const extInfo = await this.identifyExtension(); const version = await this.commandArgs.version.val(); diff --git a/app/exec/extension/publish.ts b/app/exec/extension/publish.ts index ac8bf43b..a17c52f3 100644 --- a/app/exec/extension/publish.ts +++ b/app/exec/extension/publish.ts @@ -65,7 +65,7 @@ export class ExtensionPublish extends extBase.ExtensionBase { - const galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + const galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); let result = {}; const publishSettings = await this.getPublishSettings(); diff --git a/app/exec/extension/publisher/create.ts b/app/exec/extension/publisher/create.ts index 94316cc0..7349579a 100644 --- a/app/exec/extension/publisher/create.ts +++ b/app/exec/extension/publisher/create.ts @@ -3,7 +3,7 @@ import args = require("../../../lib/arguments"); import cm = require("../../../lib/common"); import extBase = require("../default"); import extPubBase = require("./default"); -import galleryInterfaces = require("vso-node-api/interfaces/GalleryInterfaces"); +import galleryInterfaces = require("azure-devops-node-api/interfaces/GalleryInterfaces"); import argm = require("../../../lib/arguments"); import trace = require("../../../lib/trace"); @@ -26,14 +26,13 @@ export class ExtensionPublisherCreate extends extPubBase.ExtensionPublisherBase< } public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); - return Promise.all([ this.commandArgs.publisher.val(), this.commandArgs.displayName.val(), this.commandArgs.description.val(), + this.webApi.getGalleryApi(this.webApi.serverUrl) ]).then(values => { - const [publisherName, displayName, description] = values; + const [publisherName, displayName, description, galleryApi] = values; return galleryApi.createPublisher({ publisherName: publisherName, displayName: displayName, diff --git a/app/exec/extension/publisher/delete.ts b/app/exec/extension/publisher/delete.ts index 0c3ed740..b7dc86c6 100644 --- a/app/exec/extension/publisher/delete.ts +++ b/app/exec/extension/publisher/delete.ts @@ -3,8 +3,8 @@ import args = require("../../../lib/arguments"); import cm = require("../../../lib/common"); import extBase = require("../default"); import extPubBase = require("./default"); -import gallerym = require("vso-node-api/GalleryApi"); -import galleryifm = require("vso-node-api/interfaces/GalleryInterfaces"); +import gallerym = require("azure-devops-node-api/GalleryApi"); +import galleryifm = require("azure-devops-node-api/interfaces/GalleryInterfaces"); import argm = require("../../../lib/arguments"); import trace = require("../../../lib/trace"); @@ -30,14 +30,17 @@ export class ExtensionPublisherDelete extends extPubBase.ExtensionPublisherBase< } public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); - return this.commandArgs.publisher.val().then(publisherName => { - return galleryApi.deletePublisher(publisherName).then(() => { - return { - publisher: { - publisherName: publisherName, - }, - }; + return this.webApi + .getGalleryApi(this.webApi.serverUrl) + .then(galleryApi => { + return this.commandArgs.publisher.val().then(publisherName => { + return galleryApi.deletePublisher(publisherName).then(() => { + return { + publisher: { + publisherName: publisherName, + }, + }; + }); }); }); } diff --git a/app/exec/extension/share.ts b/app/exec/extension/share.ts index f9667c0c..a944c99f 100644 --- a/app/exec/extension/share.ts +++ b/app/exec/extension/share.ts @@ -35,32 +35,34 @@ export class ExtensionShare extends extBase.ExtensionBase { } public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); - - return this.commandArgs.vsix.val(true).then(vsixPath => { - let extInfoPromise: Promise; - if (vsixPath !== null) { - extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); - } else { - extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< - extInfo.CoreExtInfo - >(values => { - const [publisher, extension] = values; - return extInfo.getExtInfo(null, extension, publisher); - }); - } - return extInfoPromise.then(extInfo => { - return this.commandArgs.shareWith.val().then(shareWith => { - let sharePromises: Promise[] = []; - shareWith.forEach(account => { - sharePromises.push(galleryApi.shareExtension(extInfo.publisher, extInfo.id, account)); - }); - return Promise.all(sharePromises).then(() => { - return shareWith; + return this.webApi + .getGalleryApi(this.webApi.serverUrl) + .then(galleryApi => { + return this.commandArgs.vsix.val(true).then(vsixPath => { + let extInfoPromise: Promise; + if (vsixPath !== null) { + extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); + } else { + extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< + extInfo.CoreExtInfo + >(values => { + const [publisher, extension] = values; + return extInfo.getExtInfo(null, extension, publisher); + }); + } + return extInfoPromise.then(extInfo => { + return this.commandArgs.shareWith.val().then(shareWith => { + let sharePromises: Promise[] = []; + shareWith.forEach(account => { + sharePromises.push(galleryApi.shareExtension(extInfo.publisher, extInfo.id, account)); + }); + return Promise.all(sharePromises).then(() => { + return shareWith; + }); + }); }); }); }); - }); } protected friendlyOutput(data: string[]): void { diff --git a/app/exec/extension/show.ts b/app/exec/extension/show.ts index c12369af..1ec58da7 100644 --- a/app/exec/extension/show.ts +++ b/app/exec/extension/show.ts @@ -1,6 +1,6 @@ import args = require("../../lib/arguments"); import extBase = require("./default"); -import galleryContracts = require("vso-node-api/interfaces/GalleryInterfaces"); +import galleryContracts = require("azure-devops-node-api/interfaces/GalleryInterfaces"); import publishUtils = require("./_lib/publish"); export function getCommand(args: string[]): extBase.ExtensionBase { @@ -27,11 +27,13 @@ export class ExtensionShow extends extBase.ExtensionBase { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); - - return this.identifyExtension().then(extInfo => { - let sharingMgr = new publishUtils.SharingManager({}, galleryApi, extInfo); - return sharingMgr.getExtensionInfo(); - }); + return this.webApi + .getGalleryApi(this.webApi.serverUrl) + .then(galleryApi => { + return this.identifyExtension().then(extInfo => { + let sharingMgr = new publishUtils.SharingManager({}, galleryApi, extInfo); + return sharingMgr.getExtensionInfo(); + }); + }); } } diff --git a/app/exec/extension/unshare.ts b/app/exec/extension/unshare.ts index d011dc91..8efed348 100644 --- a/app/exec/extension/unshare.ts +++ b/app/exec/extension/unshare.ts @@ -38,32 +38,34 @@ export class ExtensionShare extends extBase.ExtensionBase { } public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); - - return this.commandArgs.vsix.val(true).then(vsixPath => { - let extInfoPromise: Promise; - if (vsixPath !== null) { - extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); - } else { - extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< - extInfo.CoreExtInfo - >(values => { - const [publisher, extension] = values; - return extInfo.getExtInfo(null, extension, publisher); - }); - } - return extInfoPromise.then(extInfo => { - return this.commandArgs.unshareWith.val().then(unshareWith => { - let sharePromises: Promise[] = []; - unshareWith.forEach(account => { - sharePromises.push(galleryApi.unshareExtension(extInfo.publisher, extInfo.id, account)); - }); - return Promise.all(sharePromises).then(() => { - return unshareWith; + return this.webApi + .getGalleryApi(this.webApi.serverUrl) + .then(galleryApi => { + return this.commandArgs.vsix.val(true).then(vsixPath => { + let extInfoPromise: Promise; + if (vsixPath !== null) { + extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); + } else { + extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< + extInfo.CoreExtInfo + >(values => { + const [publisher, extension] = values; + return extInfo.getExtInfo(null, extension, publisher); + }); + } + return extInfoPromise.then(extInfo => { + return this.commandArgs.unshareWith.val().then(unshareWith => { + let sharePromises: Promise[] = []; + unshareWith.forEach(account => { + sharePromises.push(galleryApi.unshareExtension(extInfo.publisher, extInfo.id, account)); + }); + return Promise.all(sharePromises).then(() => { + return unshareWith; + }); + }); }); }); }); - }); } protected friendlyOutput(data: string[]): void { diff --git a/app/exec/login.ts b/app/exec/login.ts index d47a6227..ac2c472c 100644 --- a/app/exec/login.ts +++ b/app/exec/login.ts @@ -34,7 +34,6 @@ export class Login extends TfCommand { let agentApi = webApi.getTaskAgentApi(); return agentApi - .connect() .then(obj => { let tfxCredStore = getCredentialStore("tfx"); let tfxCache = new DiskCache("tfx"); diff --git a/app/exec/workitem/create.ts b/app/exec/workitem/create.ts index c66023c6..7461e6a0 100644 --- a/app/exec/workitem/create.ts +++ b/app/exec/workitem/create.ts @@ -3,8 +3,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import trace = require("../../lib/trace"); import witBase = require("./default"); -import witClient = require("vso-node-api/WorkItemTrackingApi"); -import witContracts = require("vso-node-api/interfaces/WorkItemTrackingInterfaces"); +import witClient = require("azure-devops-node-api/WorkItemTrackingApi"); +import witContracts = require("azure-devops-node-api/interfaces/WorkItemTrackingInterfaces"); export function getCommand(args: string[]): WorkItemCreate { return new WorkItemCreate(args); @@ -19,8 +19,6 @@ export class WorkItemCreate extends witBase.WorkItemBase } public exec(): Promise { - var witapi = this.webApi.getWorkItemTrackingApi(); - return Promise.all([ this.commandArgs.workItemType.val(), this.commandArgs.project.val(), @@ -28,14 +26,15 @@ export class WorkItemCreate extends witBase.WorkItemBase this.commandArgs.assignedTo.val(true), this.commandArgs.description.val(true), this.commandArgs.values.val(true), + this.webApi.getWorkItemTrackingApi() ]).then(promiseValues => { - const [wiType, project, title, assignedTo, description, values] = promiseValues; + const [wiType, project, title, assignedTo, description, values, witApi] = promiseValues; if (!title && !assignedTo && !description && (!values || Object.keys(values).length <= 0)) { throw new Error("At least one field value must be specified."); } var patchDoc = witBase.buildWorkItemPatchDoc(title, assignedTo, description, values); - return witapi.createWorkItem(null, patchDoc, project, wiType); + return witApi.createWorkItem(null, patchDoc, project, wiType); }); } diff --git a/app/exec/workitem/default.ts b/app/exec/workitem/default.ts index 91a342d9..0be55da4 100644 --- a/app/exec/workitem/default.ts +++ b/app/exec/workitem/default.ts @@ -1,7 +1,7 @@ import { TfCommand, CoreArguments } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); -import vssCoreContracts = require("vso-node-api/interfaces/common/VSSInterfaces"); -import witContracts = require("vso-node-api/interfaces/WorkItemTrackingInterfaces"); +import vssCoreContracts = require("azure-devops-node-api/interfaces/common/VSSInterfaces"); +import witContracts = require("azure-devops-node-api/interfaces/WorkItemTrackingInterfaces"); import trace = require("../../lib/trace"); import { EOL as eol } from "os"; import _ = require("lodash"); diff --git a/app/exec/workitem/query.ts b/app/exec/workitem/query.ts index 52145671..0e8a2205 100644 --- a/app/exec/workitem/query.ts +++ b/app/exec/workitem/query.ts @@ -2,11 +2,11 @@ import { EOL as eol } from "os"; import { TfCommand } from "../../lib/tfcommand"; import _ = require("lodash"); import args = require("../../lib/arguments"); -import coreContracts = require("vso-node-api/interfaces/CoreInterfaces"); +import coreContracts = require("azure-devops-node-api/interfaces/CoreInterfaces"); import trace = require("../../lib/trace"); import witBase = require("./default"); -import witClient = require("vso-node-api/WorkItemTrackingApi"); -import witContracts = require("vso-node-api/interfaces/WorkItemTrackingInterfaces"); +import witClient = require("azure-devops-node-api/WorkItemTrackingApi"); +import witContracts = require("azure-devops-node-api/interfaces/WorkItemTrackingInterfaces"); export function getCommand(args: string[]): WorkItemQuery { return new WorkItemQuery(args); @@ -21,38 +21,40 @@ export class WorkItemQuery extends witBase.WorkItemBase } public exec(): Promise { - var witApi: witClient.IWorkItemTrackingApi = this.webApi.getWorkItemTrackingApi(); - - return this.commandArgs.project.val(true).then(projectName => { - return this.commandArgs.query.val().then(query => { - let wiql: witContracts.Wiql = { query: query }; - return witApi.queryByWiql(wiql, { project: projectName }).then(result => { - let workItemIds: number[] = []; - - // Flat Query - if (result.queryType == witContracts.QueryType.Flat) { - workItemIds = result.workItems.map(val => val.id).slice(0, Math.min(200, result.workItems.length)); - } - - // Link Query - else { - let sourceIds = result.workItemRelations - .filter(relation => relation.source && relation.source.id) - .map(relation => relation.source.id); - let targetIds = result.workItemRelations - .filter(relation => relation.target && relation.target.id) - .map(relation => relation.target.id); - let allIds = sourceIds.concat(targetIds); - workItemIds = allIds.slice(0, Math.min(200, allIds.length)); - } - - let fieldRefs = result.columns.map(val => val.referenceName); - - fieldRefs = fieldRefs.slice(0, Math.min(20, result.columns.length)); - return workItemIds.length > 0 ? witApi.getWorkItems(workItemIds, fieldRefs) : []; + return this.webApi + .getWorkItemTrackingApi() + .then(witApi => { + return this.commandArgs.project.val(true).then(projectName => { + return this.commandArgs.query.val().then(query => { + let wiql: witContracts.Wiql = { query: query }; + return witApi.queryByWiql(wiql, { project: projectName }).then(result => { + let workItemIds: number[] = []; + + // Flat Query + if (result.queryType == witContracts.QueryType.Flat) { + workItemIds = result.workItems.map(val => val.id).slice(0, Math.min(200, result.workItems.length)); + } + + // Link Query + else { + let sourceIds = result.workItemRelations + .filter(relation => relation.source && relation.source.id) + .map(relation => relation.source.id); + let targetIds = result.workItemRelations + .filter(relation => relation.target && relation.target.id) + .map(relation => relation.target.id); + let allIds = sourceIds.concat(targetIds); + workItemIds = allIds.slice(0, Math.min(200, allIds.length)); + } + + let fieldRefs = result.columns.map(val => val.referenceName); + + fieldRefs = fieldRefs.slice(0, Math.min(20, result.columns.length)); + return workItemIds.length > 0 ? witApi.getWorkItems(workItemIds, fieldRefs) : []; + }); + }); }); }); - }); } public friendlyOutput(data: witContracts.WorkItem[]): void { diff --git a/app/exec/workitem/show.ts b/app/exec/workitem/show.ts index 990d3d01..68f7e06a 100644 --- a/app/exec/workitem/show.ts +++ b/app/exec/workitem/show.ts @@ -3,8 +3,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import trace = require("../../lib/trace"); import witBase = require("./default"); -import witClient = require("vso-node-api/WorkItemTrackingApi"); -import witContracts = require("vso-node-api/interfaces/WorkItemTrackingInterfaces"); +import witClient = require("azure-devops-node-api/WorkItemTrackingApi"); +import witContracts = require("azure-devops-node-api/interfaces/WorkItemTrackingInterfaces"); export function getCommand(args: string[]): WorkItemShow { return new WorkItemShow(args); @@ -19,10 +19,12 @@ export class WorkItemShow extends witBase.WorkItemBase { } public exec(): Promise { - var witapi: witClient.IWorkItemTrackingApi = this.webApi.getWorkItemTrackingApi(); - return this.commandArgs.workItemId.val().then(workItemId => { - return witapi.getWorkItem(workItemId); - }); + return this.webApi.getWorkItemTrackingApi() + .then(witApi => { + return this.commandArgs.workItemId.val().then(workItemId => { + return witApi.getWorkItem(workItemId); + }); + }); } public friendlyOutput(workItem: witContracts.WorkItem): void { diff --git a/app/exec/workitem/update.ts b/app/exec/workitem/update.ts index 586bf2d3..ddbfa786 100644 --- a/app/exec/workitem/update.ts +++ b/app/exec/workitem/update.ts @@ -3,8 +3,8 @@ import { TfCommand } from "../../lib/tfcommand"; import args = require("../../lib/arguments"); import trace = require("../../lib/trace"); import witBase = require("./default"); -import witClient = require("vso-node-api/WorkItemTrackingApi"); -import witContracts = require("vso-node-api/interfaces/WorkItemTrackingInterfaces"); +import witClient = require("azure-devops-node-api/WorkItemTrackingApi"); +import witContracts = require("azure-devops-node-api/interfaces/WorkItemTrackingInterfaces"); export function getCommand(args: string[]): WorkItemUpdate { return new WorkItemUpdate(args); @@ -19,22 +19,21 @@ export class WorkItemUpdate extends witBase.WorkItemBase } public exec(): Promise { - var witapi = this.webApi.getWorkItemTrackingApi(); - return Promise.all([ this.commandArgs.workItemId.val(), this.commandArgs.title.val(true), this.commandArgs.assignedTo.val(true), this.commandArgs.description.val(true), this.commandArgs.values.val(true), + this.webApi.getWorkItemTrackingApi() ]).then(promiseValues => { - const [workItemId, title, assignedTo, description, values] = promiseValues; + const [workItemId, title, assignedTo, description, values, witApi] = promiseValues; if (!title && !assignedTo && !description && (!values || Object.keys(values).length <= 0)) { throw new Error("At least one field value must be specified."); } var patchDoc = witBase.buildWorkItemPatchDoc(title, assignedTo, description, values); - return witapi.updateWorkItem(null, patchDoc, workItemId); + return witApi.updateWorkItem(null, patchDoc, workItemId); }); } diff --git a/app/lib/connection.ts b/app/lib/connection.ts index ddf441e0..712b288f 100644 --- a/app/lib/connection.ts +++ b/app/lib/connection.ts @@ -1,8 +1,8 @@ -import { BasicCredentialHandler } from "vso-node-api/handlers/basiccreds"; +import { BasicCredentialHandler } from "azure-devops-node-api/handlers/basiccreds"; import url = require("url"); -import apim = require("vso-node-api/WebApi"); -import apibasem = require("vso-node-api/interfaces/common/VsoBaseInterfaces"); +import apim = require("azure-devops-node-api/WebApi"); +import apibasem = require("azure-devops-node-api/interfaces/common/VsoBaseInterfaces"); import trace = require("./trace"); export class TfsConnection { diff --git a/app/lib/tfcommand.ts b/app/lib/tfcommand.ts index a5bbe7a6..1d63b83a 100644 --- a/app/lib/tfcommand.ts +++ b/app/lib/tfcommand.ts @@ -1,9 +1,9 @@ -import { BasicCredentialHandler } from "vso-node-api/handlers/basiccreds"; +import { BasicCredentialHandler } from "azure-devops-node-api/handlers/basiccreds"; import { DiskCache } from "../lib/diskcache"; import { getCredentialStore } from "../lib/credstore"; import { repeatStr } from "../lib/common"; import { TfsConnection } from "../lib/connection"; -import { WebApi, getBasicHandler } from "vso-node-api/WebApi"; +import { WebApi, getBasicHandler } from "azure-devops-node-api/WebApi"; import { EOL as eol } from "os"; import _ = require("lodash"); import args = require("./arguments"); diff --git a/docs/basicAuthEnabled.png b/docs/basicAuthEnabled.png index 62f9041c712dc8c412f97d97d4093ffe6cbdf4d7..f80db9c6122d5acb3c09f82585715565bb98f76f 100644 GIT binary patch delta 20 ccmdnFlx6!;7M9KcKlhES&$Tzd)jsnK09v&PdH?_b delta 23 fcmdnKlx62q7S_%HKX=}ZEYGzWc{jh-KJyF!Yt9Li diff --git a/docs/configureBasicAuthFeature.png b/docs/configureBasicAuthFeature.png index 65c12a7dd9a7f082b5e76b03b377473ff3ca7365..d26fb8c8505027b692edee005451810298992468 100644 GIT binary patch delta 18 ZcmaFT&hogOg{3pV&%Kd#D=XuDW&lNF26F%a delta 19 acmaFd&hn(4g|#!l&z-lCWh)EgeP#ek8wP&> diff --git a/docs/help-screen.png b/docs/help-screen.png index 6a78fae3ac59d7fe250a27bede8c9594c4559fed..ce01afd188d1649dd4a1194cd22fbf24a3169ab7 100644 GIT binary patch delta 13 UcmZ2cxxA94Gr-S%BkN)t04PueNdN!< delta 14 VcmZ2pxuTM_Gr-TCcO%PU8vray1y%q6 diff --git a/docs/tfsAuth.png b/docs/tfsAuth.png index 5e19137656813723d632444337c5ce941267e65b..75f898eb99f50b1cd9ff850db9338a2cfda02710 100644 GIT binary patch delta 18 Zcmdnr!M?A9ouxCt&%Kd#D=VYb5dc7o22B6} delta 19 acmdnj!M?wPowYN-&z-lCWh)D#)e!(i0R~wB diff --git a/package.json b/package.json index 9bdd3048..536e03fa 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "util.promisify": "^1.0.0", "uuid": "^3.0.1", "validator": "^3.43.0", - "vso-node-api": "^5.0.0", + "azure-devops-node-api": "^7.2.0", "winreg": "0.0.12", "xml2js": "^0.4.16" }, From 087c0ae3aed69f620b06658786ad312b5c6f7cd6 Mon Sep 17 00:00:00 2001 From: Trevor Gau Date: Mon, 8 Apr 2019 16:07:20 -0400 Subject: [PATCH 2/3] Update package-lock.json --- package-lock.json | 59 +++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a149435..d0802149 100644 --- a/package-lock.json +++ b/package-lock.json @@ -246,6 +246,24 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "azure-devops-node-api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", + "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", + "requires": { + "os": "0.1.1", + "tunnel": "0.0.4", + "typed-rest-client": "1.2.0", + "underscore": "1.8.3" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1975,6 +1993,11 @@ } } }, + "os": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", + "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=" + }, "os-browserify": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", @@ -2134,11 +2157,6 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -2530,6 +2548,22 @@ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" }, + "typed-rest-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", + "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + } + } + }, "typescript": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", @@ -2562,11 +2596,6 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -2661,16 +2690,6 @@ "indexof": "0.0.1" } }, - "vso-node-api": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/vso-node-api/-/vso-node-api-5.0.5.tgz", - "integrity": "sha1-eaFp6bvs2huEk9q58yOUbCqZ3EY=", - "requires": { - "q": "^1.0.1", - "tunnel": "0.0.4", - "underscore": "^1.8.3" - } - }, "walkdir": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", From 48904e34dffe61b90701f9bee96fec758a6f8ff4 Mon Sep 17 00:00:00 2001 From: Trevor Gau Date: Mon, 15 Apr 2019 16:56:52 -0400 Subject: [PATCH 3/3] Work around some rest clients being broken. --- app/exec/build/list.ts | 73 +++++++++---------- app/exec/build/queue.ts | 52 +++++++------ app/exec/build/show.ts | 15 ++-- app/exec/build/tasks/create.ts | 2 +- app/exec/build/tasks/delete.ts | 33 ++++----- app/exec/build/tasks/list.ts | 32 ++++---- app/exec/build/tasks/upload.ts | 24 +++--- app/exec/extension/_lib/extensioninfo.ts | 2 +- app/exec/extension/_lib/publish.ts | 93 ++++++++++++++++++++++-- app/exec/extension/create.ts | 2 +- app/exec/extension/install.ts | 18 ++++- app/exec/extension/publisher/create.ts | 7 +- app/exec/extension/publisher/delete.ts | 21 +++--- app/exec/extension/resources/create.ts | 2 +- app/exec/extension/share.ts | 52 ++++++------- app/exec/extension/show.ts | 16 ++-- app/exec/extension/unshare.ts | 50 ++++++------- app/exec/login.ts | 62 +++++----------- app/exec/logout.ts | 2 +- app/exec/reset.ts | 2 +- app/exec/version.ts | 2 +- app/exec/workitem/create.ts | 9 ++- app/exec/workitem/query.ts | 64 ++++++++-------- app/exec/workitem/show.ts | 12 ++- app/exec/workitem/update.ts | 9 ++- package-lock.json | 19 ++--- package.json | 2 +- 27 files changed, 357 insertions(+), 320 deletions(-) diff --git a/app/exec/build/list.ts b/app/exec/build/list.ts index 413c5b63..747f20b9 100644 --- a/app/exec/build/list.ts +++ b/app/exec/build/list.ts @@ -18,45 +18,42 @@ export class BuildGetList extends buildBase.BuildBase { + public async exec(): Promise { trace.debug("build-list.exec"); - - return this.webApi - .getBuildApi() - .then(buildApi => { - return Promise.all([ - this.commandArgs.project.val(), - this.commandArgs.definitionId.val(), - this.commandArgs.definitionName.val(), - this.commandArgs.status.val(), - this.commandArgs.top.val(), - ]).then(values => { - const [project, definitionId, definitionName, status, top] = values; - var definitions: number[] = null; - if (definitionId) { - definitions = [definitionId as number]; - } else if (definitionName) { - trace.debug("No definition Id provided, checking for definitions with name " + definitionName); - return buildApi - .getDefinitions(project as string, definitionName as string) - .then((defs: buildContracts.DefinitionReference[]) => { - if (defs.length > 0) { - definitions = [defs[0].id]; - return this._getBuilds( - buildApi, - project as string, - definitions, - buildContracts.BuildStatus[status], - top as number, - ); - } else { - trace.debug("No definition found with name " + definitionName); - throw new Error("No definition found with name " + definitionName); - } - }); - } - return this._getBuilds(buildApi, project as string, definitions, buildContracts.BuildStatus[status], top as number); - }); + var buildapi: buildClient.IBuildApi = await this.webApi.getBuildApi(); + + return Promise.all([ + this.commandArgs.project.val(), + this.commandArgs.definitionId.val(), + this.commandArgs.definitionName.val(), + this.commandArgs.status.val(), + this.commandArgs.top.val(), + ]).then(values => { + const [project, definitionId, definitionName, status, top] = values; + var definitions: number[] = null; + if (definitionId) { + definitions = [definitionId as number]; + } else if (definitionName) { + trace.debug("No definition Id provided, checking for definitions with name " + definitionName); + return buildapi + .getDefinitions(project as string, definitionName as string) + .then((defs: buildContracts.DefinitionReference[]) => { + if (defs.length > 0) { + definitions = [defs[0].id]; + return this._getBuilds( + buildapi, + project as string, + definitions, + buildContracts.BuildStatus[status], + top as number, + ); + } else { + trace.debug("No definition found with name " + definitionName); + throw new Error("No definition found with name " + definitionName); + } + }); + } + return this._getBuilds(buildapi, project as string, definitions, buildContracts.BuildStatus[status], top as number); }); } diff --git a/app/exec/build/queue.ts b/app/exec/build/queue.ts index 66c00ff5..803dddd2 100644 --- a/app/exec/build/queue.ts +++ b/app/exec/build/queue.ts @@ -21,34 +21,32 @@ export class BuildQueue extends buildBase.BuildBase { - return this.webApi - .getBuildApi() - .then(buildApi => { - return this.commandArgs.project.val().then(project => { - return this.commandArgs.definitionId.val(true).then(definitionId => { - let definitionPromise: Promise; - if (definitionId) { - definitionPromise = buildApi.getDefinition(definitionId, project); - } else { - definitionPromise = this.commandArgs.definitionName.val().then(definitionName => { - trace.debug("No definition id provided, Searching for definitions with name: " + definitionName); - return buildApi - .getDefinitions(project, definitionName) - .then((definitions: buildContracts.DefinitionReference[]) => { - if (definitions.length > 0) { - var definition = definitions[0]; - return definition; - } else { - trace.debug("No definition found with name " + definitionName); - throw new Error("No definition found with name " + definitionName); - } - }); - }); - } - return definitionPromise.then(definition => { - return this._queueBuild(buildApi, definition, project); + public async exec(): Promise { + var buildapi: buildClient.IBuildApi = await this.webApi.getBuildApi(); + + return this.commandArgs.project.val().then(project => { + return this.commandArgs.definitionId.val(true).then(definitionId => { + let definitionPromise: Promise; + if (definitionId) { + definitionPromise = buildapi.getDefinition(definitionId, project); + } else { + definitionPromise = this.commandArgs.definitionName.val().then(definitionName => { + trace.debug("No definition id provided, Searching for definitions with name: " + definitionName); + return buildapi + .getDefinitions(project, definitionName) + .then((definitions: buildContracts.DefinitionReference[]) => { + if (definitions.length > 0) { + var definition = definitions[0]; + return definition; + } else { + trace.debug("No definition found with name " + definitionName); + throw new Error("No definition found with name " + definitionName); + } + }); }); + } + return definitionPromise.then(definition => { + return this._queueBuild(buildapi, definition, project); }); }); }); diff --git a/app/exec/build/show.ts b/app/exec/build/show.ts index ba71a357..f32eed08 100644 --- a/app/exec/build/show.ts +++ b/app/exec/build/show.ts @@ -17,17 +17,14 @@ export class BuildShow extends buildBase.BuildBase { + public async exec(): Promise { trace.debug("build-show.exec"); - return this.webApi - .getBuildApi() - .then(buildApi => { - return this.commandArgs.project.val().then(project => { - return this.commandArgs.buildId.val().then(buildId => { - return buildApi.getBuild(buildId, project); - }); - }); + var buildapi: buildClient.IBuildApi = await this.webApi.getBuildApi(); + return this.commandArgs.project.val().then(project => { + return this.commandArgs.buildId.val().then(buildId => { + return buildapi.getBuild(buildId, project); }); + }); } public friendlyOutput(build: buildContracts.Build): void { diff --git a/app/exec/build/tasks/create.ts b/app/exec/build/tasks/create.ts index d6bd1eff..4640f50d 100644 --- a/app/exec/build/tasks/create.ts +++ b/app/exec/build/tasks/create.ts @@ -45,7 +45,7 @@ export class TaskCreate extends tasksBase.BuildTaskBase { return ["taskName", "friendlyName", "description", "author"]; } - public exec(): Promise { + public async exec(): Promise { trace.debug("build-create.exec"); return Promise.all([ diff --git a/app/exec/build/tasks/delete.ts b/app/exec/build/tasks/delete.ts index cd59c498..4fc2a99e 100644 --- a/app/exec/build/tasks/delete.ts +++ b/app/exec/build/tasks/delete.ts @@ -16,26 +16,23 @@ export class BuildTaskDelete extends tasksBase.BuildTaskBase { - return this.webApi - .getTaskAgentApi(this.connection.getCollectionUrl()) - .then(agentApi => { - return this.commandArgs.taskId.val().then(taskId => { - return agentApi.getTaskDefinitions(taskId).then(tasks => { - if (tasks && tasks.length > 0) { - trace.debug("Deleting task(s)..."); - return agentApi.deleteTaskDefinition(taskId).then(() => { - return { - id: taskId, - }; - }); - } else { - trace.debug("No such task."); - throw new Error("No task found with provided ID: " + taskId); - } + public async exec(): Promise { + let agentApi = await this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); + return this.commandArgs.taskId.val().then(taskId => { + return agentApi.getTaskDefinitions(taskId).then(tasks => { + if (tasks && tasks.length > 0) { + trace.debug("Deleting task(s)..."); + return agentApi.deleteTaskDefinition(taskId).then(() => { + return { + id: taskId, + }; }); - }); + } else { + trace.debug("No such task."); + throw new Error("No task found with provided ID: " + taskId); + } }); + }); } public friendlyOutput(data: agentContracts.TaskDefinition): void { diff --git a/app/exec/build/tasks/list.ts b/app/exec/build/tasks/list.ts index d62ebbbd..9216a25f 100644 --- a/app/exec/build/tasks/list.ts +++ b/app/exec/build/tasks/list.ts @@ -16,24 +16,22 @@ export class BuildTaskList extends tasksBase.BuildTaskBase { - return this.webApi - .getTaskAgentApi(this.connection.getCollectionUrl()) - .then(agentApi => { - trace.debug("Searching for build tasks..."); - return agentApi.getTaskDefinitions(null, ["build"], null).then(tasks => { - trace.debug("Retrieved " + tasks.length + " build tasks from server."); - return this.commandArgs.all.val().then(all => { - if (all) { - trace.debug("Listing all build tasks."); - return tasks; - } else { - trace.debug("Filtering build tasks to give only the latest versions."); - return this._getNewestTasks(tasks); - } - }); - }); + public async exec(): Promise { + var agentapi = await this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); + + trace.debug("Searching for build tasks..."); + return agentapi.getTaskDefinitions(null, ["build"], null).then(tasks => { + trace.debug("Retrieved " + tasks.length + " build tasks from server."); + return this.commandArgs.all.val().then(all => { + if (all) { + trace.debug("Listing all build tasks."); + return tasks; + } else { + trace.debug("Filtering build tasks to give only the latest versions."); + return this._getNewestTasks(tasks); + } }); + }); } /* diff --git a/app/exec/build/tasks/upload.ts b/app/exec/build/tasks/upload.ts index 14a7d9ab..aa5ba1fe 100644 --- a/app/exec/build/tasks/upload.ts +++ b/app/exec/build/tasks/upload.ts @@ -22,7 +22,7 @@ export class BuildTaskUpload extends tasksBase.BuildTaskBase { + public async exec(): Promise { return this.commandArgs.taskPath.val().then(taskPaths => { let taskPath = taskPaths[0]; return this.commandArgs.overwrite.val().then(overwrite => { @@ -30,7 +30,7 @@ export class BuildTaskUpload extends tasksBase.BuildTaskBase { + return vm.validate(tp, "no " + c_taskJsonFile + " in specified directory").then(async taskJson => { let archive = archiver("zip"); archive.on("error", function(error) { trace.debug("Archiving error: " + error.message); @@ -39,17 +39,15 @@ export class BuildTaskUpload extends tasksBase.BuildTaskBase { - archive.finalize(); - return agentApi.uploadTaskDefinition(null, archive, taskJson.id, overwrite).then(() => { - trace.debug("Success"); - return { - sourceLocation: taskPath, - }; - }); - }); + let agentApi = await this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); + + archive.finalize(); + return agentApi.uploadTaskDefinition(null, archive, taskJson.id, overwrite).then(() => { + trace.debug("Success"); + return { + sourceLocation: taskPath, + }; + }); }); }); }); diff --git a/app/exec/extension/_lib/extensioninfo.ts b/app/exec/extension/_lib/extensioninfo.ts index 63c63dc5..0b32be9f 100644 --- a/app/exec/extension/_lib/extensioninfo.ts +++ b/app/exec/extension/_lib/extensioninfo.ts @@ -20,7 +20,7 @@ export function getExtInfo( publisherName: string, cachedInfo?: CoreExtInfo, ): Promise { - trace.debug("extensioninfo.getExtInfo"); + trace.debug("extensioninfo.getExtInfo with vsixpath: " + vsixPath + ", extId: " + extensionId + ", publisher: " + publisherName); var vsixInfoPromise: Promise; if (cachedInfo) { return Promise.resolve(cachedInfo); diff --git a/app/exec/extension/_lib/publish.ts b/app/exec/extension/_lib/publish.ts index c633d6e2..602cdd86 100644 --- a/app/exec/extension/_lib/publish.ts +++ b/app/exec/extension/_lib/publish.ts @@ -239,7 +239,8 @@ export class SharingManager extends GalleryBase { return Promise.all( accounts.map(account => { trace.info("Sharing extension with %s.", account); - return this.galleryClient.shareExtension(extInfo.publisher, extInfo.id, account).catch(errHandler.httpErr); + return SharingManager.shareExtension(this.galleryClient, extInfo.publisher, extInfo.id, account).catch(errHandler.httpErr); + // return this.galleryClient.shareExtension(extInfo.publisher, extInfo.id, account).catch(errHandler.httpErr); }), ); }); @@ -266,6 +267,48 @@ export class SharingManager extends GalleryBase { return ext.sharedWith.map(acct => acct.name); }); } + + /******** TEMPORARY UNTIL REST CLIENT UPDATED ********/ + public static async shareExtension( + client: IGalleryApi, + publisherName: string, + extensionName: string, + accountName: string + ): Promise { + + return new Promise(async (resolve, reject) => { + let routeValues: any = { + publisherName: publisherName, + extensionName: extensionName, + accountName: accountName + }; + + try { + let verData = await client.vsoClient.getVersioningData( + "5.1-preview.1", + "gallery", + "a1e66d8f-f5de-4d16-8309-91a4e015ee46", + routeValues); + + let url: string = verData.requestUrl; + let options = client.createRequestOptions('application/json', + verData.apiVersion); + + const res = await client.rest.create(url, null, options); + + let ret = client.formatResponse(res.result, + null, + false); + + resolve(ret); + + } + catch (err) { + reject(err); + } + }); + } + /******** /TEMPORARY UNTIL REST CLIENT UPDATED ********/ } export class PackagePublisher extends GalleryBase { @@ -295,7 +338,9 @@ export class PackagePublisher extends GalleryBase { * @return Q.Promise that is resolved when publish is complete */ public publish(): Promise { - const extPackage = fs.createReadStream(this.settings.vsixPath); + const extPackage: GalleryInterfaces.ExtensionPackage = { + extensionManifest: fs.readFileSync(this.settings.vsixPath, "base64"), + }; trace.debug("Publishing %s", this.settings.vsixPath); // Check if the app is already published. If so, call the update endpoint. Otherwise, create. @@ -356,17 +401,19 @@ export class PackagePublisher extends GalleryBase { }); } - private createOrUpdateExtension(extPackage: NodeJS.ReadableStream): Promise { + private createOrUpdateExtension( + extPackage: GalleryInterfaces.ExtensionPackage, + ): Promise { return this.checkVsixPublished().then(extInfo => { let publishPromise; if (extInfo && extInfo.published) { trace.info("It is, %s the extension", colors.cyan("update").toString()); - publishPromise = this.galleryClient - .updateExtension(null, extPackage, extInfo.publisher, extInfo.id) + publishPromise = this + .updateExtension(extPackage as any, extInfo.publisher, extInfo.id, false) .catch(errHandler.httpErr); } else { trace.info("It isn't, %s a new extension.", colors.cyan("create").toString()); - publishPromise = this.galleryClient.createExtension(null, extPackage).catch(errHandler.httpErr); + publishPromise = this.updateExtension(extPackage as any, extInfo.publisher, extInfo.id, true).catch(errHandler.httpErr); } return publishPromise.then(() => { return this.galleryClient.getExtension( @@ -380,6 +427,40 @@ export class PackagePublisher extends GalleryBase { }); } + /******** TEMPORARY UNTIL REST CLIENT UPDATED ********/ + private async updateExtension( + content: any, + publisherName: string, + extensionName: string, + create: boolean, + ): Promise { + + let routeValues: any = { + publisherName: publisherName, + extensionName: extensionName + }; + + const queryValues: any = { + bypassScopeCheck: undefined + }; + + const verData = await this.galleryClient.vsoClient.getVersioningData( + "5.1-preview.2", + "gallery", + "e11ea35a-16fe-4b80-ab11-c4cab88a0966", + routeValues, + queryValues + ); + + const url = verData.requestUrl; + const options = this.galleryClient.createRequestOptions("application/json", verData.apiVersion); + options.additionalHeaders = { "Content-Type": "application/json" }; + + const response = await (create ? this.galleryClient.rest.create(url, content, options) : this.galleryClient.rest.replace(url, content, options)); + return this.galleryClient.formatResponse(response.result, GalleryInterfaces.TypeInfo.PublishedExtension, false); + } + /******** /TEMPORARY UNTIL REST CLIENT UPDATED ********/ + public waitForValidation( interval: number, maxInterval: number, diff --git a/app/exec/extension/create.ts b/app/exec/extension/create.ts index 434a4142..7bd348a4 100644 --- a/app/exec/extension/create.ts +++ b/app/exec/extension/create.ts @@ -61,7 +61,7 @@ export class ExtensionCreate extends extBase.ExtensionBase { ]; } - public exec(): Promise { + public async exec(): Promise { return this.getMergeSettings().then(mergeSettings => { return this.getPackageSettings().then(packageSettings => { return createExtension(mergeSettings, packageSettings); diff --git a/app/exec/extension/install.ts b/app/exec/extension/install.ts index 390b19d9..214d6180 100644 --- a/app/exec/extension/install.ts +++ b/app/exec/extension/install.ts @@ -9,6 +9,7 @@ import gallerym = require("azure-devops-node-api/GalleryApi"); import emsm = require("azure-devops-node-api/ExtensionManagementApi"); import EmsInterfaces = require("azure-devops-node-api/interfaces/ExtensionManagementInterfaces"); import https = require("https"); +import http = require("http"); import { realPromise } from "../../lib/promiseUtils"; @@ -87,11 +88,10 @@ export class ExtensionInstall extends extBase.ExtensionBase --token --publisher --extension-id ", ); } + trace.debug("Installing extension by name"); // Read extension info from arguments const result: ExtensionInstallResult = { accounts: {}, extension: null }; - const extensionInfo = await this._getExtensionInfo(); - const extInfo = await this._getExtensionInfo(); const itemId = `${extInfo.publisher}.${extInfo.id}`; @@ -101,6 +101,7 @@ export class ExtensionInstall extends extBase.ExtensionBase " - " + i).join("\n")}`; serviceUrl.replace(/\/$/, "") + "/DefaultCollection", ); + } else if (err.message.indexOf("TF1590010") >= 0) { + trace.warn("The given extension is already installed, so nothing happened."); } else { throw err; } @@ -162,10 +165,18 @@ ${installation.installState.installationIssues.map(i => " - " + i).join("\n")}`; } private static async getEmsAccountUrl(tfsAccountUrl: string): Promise { + trace.debug("Get ems account url for " + tfsAccountUrl); const acctUrlNoSlash = tfsAccountUrl.endsWith("/") ? tfsAccountUrl.substr(0, tfsAccountUrl.length - 1) : tfsAccountUrl; + + if (acctUrlNoSlash.indexOf("visualstudio.com") < 0 && acctUrlNoSlash.indexOf("dev.azure.com") < 0) { + return acctUrlNoSlash; + } + const url = `${acctUrlNoSlash}/_apis/resourceareas/6c2b0933-3600-42ae-bf8b-93d4f7e83594`; + const httpModule = url.indexOf("https://") >= 0 ? https : http; + const response = await new Promise((resolve, reject) => { - https + httpModule .get(url, resp => { let data = ""; resp.on("data", chunk => { @@ -179,6 +190,7 @@ ${installation.installState.installationIssues.map(i => " - " + i).join("\n")}`; reject(err); }); }); + trace.debug("response: " + response); const resourceArea = JSON.parse(response); return resourceArea.locationUrl; } diff --git a/app/exec/extension/publisher/create.ts b/app/exec/extension/publisher/create.ts index 7349579a..14d17d65 100644 --- a/app/exec/extension/publisher/create.ts +++ b/app/exec/extension/publisher/create.ts @@ -25,14 +25,15 @@ export class ExtensionPublisherCreate extends extPubBase.ExtensionPublisherBase< this.registerCommandArgument("publisher", "Publisher ID", "Use this as the publisher ID.", args.StringArgument); } - public exec(): Promise { + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); + return Promise.all([ this.commandArgs.publisher.val(), this.commandArgs.displayName.val(), this.commandArgs.description.val(), - this.webApi.getGalleryApi(this.webApi.serverUrl) ]).then(values => { - const [publisherName, displayName, description, galleryApi] = values; + const [publisherName, displayName, description] = values; return galleryApi.createPublisher({ publisherName: publisherName, displayName: displayName, diff --git a/app/exec/extension/publisher/delete.ts b/app/exec/extension/publisher/delete.ts index b7dc86c6..d759edc5 100644 --- a/app/exec/extension/publisher/delete.ts +++ b/app/exec/extension/publisher/delete.ts @@ -29,18 +29,15 @@ export class ExtensionPublisherDelete extends extPubBase.ExtensionPublisherBase< this.registerCommandArgument("publisher", "Publisher ID", "ID of Publisher to delete.", args.StringArgument); } - public exec(): Promise { - return this.webApi - .getGalleryApi(this.webApi.serverUrl) - .then(galleryApi => { - return this.commandArgs.publisher.val().then(publisherName => { - return galleryApi.deletePublisher(publisherName).then(() => { - return { - publisher: { - publisherName: publisherName, - }, - }; - }); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); + return this.commandArgs.publisher.val().then(publisherName => { + return galleryApi.deletePublisher(publisherName).then(() => { + return { + publisher: { + publisherName: publisherName, + }, + }; }); }); } diff --git a/app/exec/extension/resources/create.ts b/app/exec/extension/resources/create.ts index 1503eb6e..a29e5804 100644 --- a/app/exec/extension/resources/create.ts +++ b/app/exec/extension/resources/create.ts @@ -38,7 +38,7 @@ export class GenerateExtensionResources extends extBase.ExtensionBase { + public async exec(): Promise { return this.getMergeSettings().then(mergeSettings => { return this.getPackageSettings().then(packageSettings => { return new Merger(mergeSettings).merge().then(components => { diff --git a/app/exec/extension/share.ts b/app/exec/extension/share.ts index a944c99f..2b537d16 100644 --- a/app/exec/extension/share.ts +++ b/app/exec/extension/share.ts @@ -5,6 +5,8 @@ import extBase = require("./default"); import extInfo = require("./_lib/extensioninfo"); import trace = require("../../lib/trace"); +import { SharingManager } from "./_lib/publish"; + export function getCommand(args: string[]): TfCommand { return new ExtensionShare(args); } @@ -34,35 +36,33 @@ export class ExtensionShare extends extBase.ExtensionBase { return ["publisher", "extensionId", "vsix", "shareWith"]; } - public exec(): Promise { - return this.webApi - .getGalleryApi(this.webApi.serverUrl) - .then(galleryApi => { - return this.commandArgs.vsix.val(true).then(vsixPath => { - let extInfoPromise: Promise; - if (vsixPath !== null) { - extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); - } else { - extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< - extInfo.CoreExtInfo - >(values => { - const [publisher, extension] = values; - return extInfo.getExtInfo(null, extension, publisher); - }); - } - return extInfoPromise.then(extInfo => { - return this.commandArgs.shareWith.val().then(shareWith => { - let sharePromises: Promise[] = []; - shareWith.forEach(account => { - sharePromises.push(galleryApi.shareExtension(extInfo.publisher, extInfo.id, account)); - }); - return Promise.all(sharePromises).then(() => { - return shareWith; - }); - }); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); + + return this.commandArgs.vsix.val(true).then(vsixPath => { + let extInfoPromise: Promise; + if (vsixPath !== null) { + extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); + } else { + extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< + extInfo.CoreExtInfo + >(values => { + const [publisher, extension] = values; + return extInfo.getExtInfo(null, extension, publisher); + }); + } + return extInfoPromise.then(extInfo => { + return this.commandArgs.shareWith.val().then(shareWith => { + let sharePromises: Promise[] = []; + shareWith.forEach(account => { + sharePromises.push(SharingManager.shareExtension(galleryApi, extInfo.publisher, extInfo.id, account)); + }); + return Promise.all(sharePromises).then(() => { + return shareWith; }); }); }); + }); } protected friendlyOutput(data: string[]): void { diff --git a/app/exec/extension/show.ts b/app/exec/extension/show.ts index 1ec58da7..cf9e46e8 100644 --- a/app/exec/extension/show.ts +++ b/app/exec/extension/show.ts @@ -26,14 +26,12 @@ export class ExtensionShow extends extBase.ExtensionBase { - return this.webApi - .getGalleryApi(this.webApi.serverUrl) - .then(galleryApi => { - return this.identifyExtension().then(extInfo => { - let sharingMgr = new publishUtils.SharingManager({}, galleryApi, extInfo); - return sharingMgr.getExtensionInfo(); - }); - }); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); + + return this.identifyExtension().then(extInfo => { + let sharingMgr = new publishUtils.SharingManager({}, galleryApi, extInfo); + return sharingMgr.getExtensionInfo(); + }); } } diff --git a/app/exec/extension/unshare.ts b/app/exec/extension/unshare.ts index 8efed348..43295045 100644 --- a/app/exec/extension/unshare.ts +++ b/app/exec/extension/unshare.ts @@ -37,35 +37,33 @@ export class ExtensionShare extends extBase.ExtensionBase { return ["publisher", "extensionId", "vsix", "unshareWith"]; } - public exec(): Promise { - return this.webApi - .getGalleryApi(this.webApi.serverUrl) - .then(galleryApi => { - return this.commandArgs.vsix.val(true).then(vsixPath => { - let extInfoPromise: Promise; - if (vsixPath !== null) { - extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); - } else { - extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< - extInfo.CoreExtInfo - >(values => { - const [publisher, extension] = values; - return extInfo.getExtInfo(null, extension, publisher); - }); - } - return extInfoPromise.then(extInfo => { - return this.commandArgs.unshareWith.val().then(unshareWith => { - let sharePromises: Promise[] = []; - unshareWith.forEach(account => { - sharePromises.push(galleryApi.unshareExtension(extInfo.publisher, extInfo.id, account)); - }); - return Promise.all(sharePromises).then(() => { - return unshareWith; - }); - }); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); + + return this.commandArgs.vsix.val(true).then(vsixPath => { + let extInfoPromise: Promise; + if (vsixPath !== null) { + extInfoPromise = extInfo.getExtInfo(vsixPath[0], null, null); + } else { + extInfoPromise = Promise.all([this.commandArgs.publisher.val(), this.commandArgs.extensionId.val()]).then< + extInfo.CoreExtInfo + >(values => { + const [publisher, extension] = values; + return extInfo.getExtInfo(null, extension, publisher); + }); + } + return extInfoPromise.then(extInfo => { + return this.commandArgs.unshareWith.val().then(unshareWith => { + let sharePromises: Promise[] = []; + unshareWith.forEach(account => { + sharePromises.push(galleryApi.unshareExtension(extInfo.publisher, extInfo.id, account)); + }); + return Promise.all(sharePromises).then(() => { + return unshareWith; }); }); }); + }); } protected friendlyOutput(data: string[]): void { diff --git a/app/exec/login.ts b/app/exec/login.ts index ac2c472c..74c61241 100644 --- a/app/exec/login.ts +++ b/app/exec/login.ts @@ -21,51 +21,27 @@ export class Login extends TfCommand { protected description = "Login and cache credentials using a PAT or basic auth."; protected serverCommand = true; - public exec(): Promise { + public async exec(): Promise { trace.debug("Login.exec"); - let authHandler; - return this.commandArgs.serviceUrl.val().then(collectionUrl => { - return this.getCredentials(collectionUrl, false) - .then(handler => { - authHandler = handler; - return this.getWebApi(); - }) - .then(webApi => { - let agentApi = webApi.getTaskAgentApi(); + return this.commandArgs.serviceUrl.val().then(async collectionUrl => { + const authHandler = await this.getCredentials(collectionUrl, false); + const webApi = await this.getWebApi(); + const locationsApi = await webApi.getLocationsApi(); - return agentApi - .then(obj => { - let tfxCredStore = getCredentialStore("tfx"); - let tfxCache = new DiskCache("tfx"); - let credString; - if (authHandler.username === "OAuth") { - credString = "pat:" + authHandler.password; - } else { - credString = "basic:" + authHandler.username + ":" + authHandler.password; - } - return tfxCredStore.storeCredential(collectionUrl, "allusers", credString).then(() => { - return tfxCache - .setItem("cache", "connection", collectionUrl) - .then(() => ({ success: true } as LoginResult)); - }); - }) - .catch(err => { - if (err && err.statusCode && err.statusCode === 401) { - trace.debug("Connection failed: invalid credentials."); - throw new Error("Invalid credentials."); - } else if (err) { - trace.debug("Connection failed."); - throw new Error( - "Connection failed. Check your internet connection & collection URL." + - os.EOL + - "Message: " + - err.message, - ); - } else { - throw new Error("Unknown error logging in."); - } - }); - }); + try { + const connectionData = await locationsApi.getConnectionData(); + let tfxCredStore = getCredentialStore("tfx"); + let tfxCache = new DiskCache("tfx"); + let credString; + if (authHandler.username === "OAuth") { + credString = "pat:" + authHandler.password; + } else { + credString = "basic:" + authHandler.username + ":" + authHandler.password; + } + await tfxCredStore.storeCredential(collectionUrl, "allusers", credString); + await tfxCache.setItem("cache", "connection", collectionUrl); + return { success: true } as LoginResult; + } catch (err) {} }); } diff --git a/app/exec/logout.ts b/app/exec/logout.ts index 37416905..e64762bb 100644 --- a/app/exec/logout.ts +++ b/app/exec/logout.ts @@ -23,7 +23,7 @@ export class Reset extends TfCommand { super(args); } - public exec(): Promise { + public async exec(): Promise { return Promise.resolve(null); } diff --git a/app/exec/reset.ts b/app/exec/reset.ts index c0678312..5e5cedb9 100644 --- a/app/exec/reset.ts +++ b/app/exec/reset.ts @@ -37,7 +37,7 @@ export class Reset extends TfCommand { ); } - public exec(): Promise { + public async exec(): Promise { return Promise.resolve(null); } diff --git a/app/exec/version.ts b/app/exec/version.ts index b0445d3c..5c388d23 100644 --- a/app/exec/version.ts +++ b/app/exec/version.ts @@ -17,7 +17,7 @@ export class Version extends TfCommand { super(args); } - public exec(): Promise { + public async exec(): Promise { trace.debug("version.exec"); return version.getTfxVersion(); } diff --git a/app/exec/workitem/create.ts b/app/exec/workitem/create.ts index 7461e6a0..95ddd95f 100644 --- a/app/exec/workitem/create.ts +++ b/app/exec/workitem/create.ts @@ -18,7 +18,9 @@ export class WorkItemCreate extends witBase.WorkItemBase return ["workItemType", "title", "assignedTo", "description", "project", "values"]; } - public exec(): Promise { + public async exec(): Promise { + var witapi = await this.webApi.getWorkItemTrackingApi(); + return Promise.all([ this.commandArgs.workItemType.val(), this.commandArgs.project.val(), @@ -26,15 +28,14 @@ export class WorkItemCreate extends witBase.WorkItemBase this.commandArgs.assignedTo.val(true), this.commandArgs.description.val(true), this.commandArgs.values.val(true), - this.webApi.getWorkItemTrackingApi() ]).then(promiseValues => { - const [wiType, project, title, assignedTo, description, values, witApi] = promiseValues; + const [wiType, project, title, assignedTo, description, values] = promiseValues; if (!title && !assignedTo && !description && (!values || Object.keys(values).length <= 0)) { throw new Error("At least one field value must be specified."); } var patchDoc = witBase.buildWorkItemPatchDoc(title, assignedTo, description, values); - return witApi.createWorkItem(null, patchDoc, project, wiType); + return witapi.createWorkItem(null, patchDoc, project, wiType); }); } diff --git a/app/exec/workitem/query.ts b/app/exec/workitem/query.ts index 0e8a2205..41cf4943 100644 --- a/app/exec/workitem/query.ts +++ b/app/exec/workitem/query.ts @@ -20,41 +20,39 @@ export class WorkItemQuery extends witBase.WorkItemBase return ["project", "query"]; } - public exec(): Promise { - return this.webApi - .getWorkItemTrackingApi() - .then(witApi => { - return this.commandArgs.project.val(true).then(projectName => { - return this.commandArgs.query.val().then(query => { - let wiql: witContracts.Wiql = { query: query }; - return witApi.queryByWiql(wiql, { project: projectName }).then(result => { - let workItemIds: number[] = []; - - // Flat Query - if (result.queryType == witContracts.QueryType.Flat) { - workItemIds = result.workItems.map(val => val.id).slice(0, Math.min(200, result.workItems.length)); - } - - // Link Query - else { - let sourceIds = result.workItemRelations - .filter(relation => relation.source && relation.source.id) - .map(relation => relation.source.id); - let targetIds = result.workItemRelations - .filter(relation => relation.target && relation.target.id) - .map(relation => relation.target.id); - let allIds = sourceIds.concat(targetIds); - workItemIds = allIds.slice(0, Math.min(200, allIds.length)); - } - - let fieldRefs = result.columns.map(val => val.referenceName); - - fieldRefs = fieldRefs.slice(0, Math.min(20, result.columns.length)); - return workItemIds.length > 0 ? witApi.getWorkItems(workItemIds, fieldRefs) : []; - }); - }); + public async exec(): Promise { + var witApi: witClient.IWorkItemTrackingApi = await this.webApi.getWorkItemTrackingApi(); + + return this.commandArgs.project.val(true).then(projectName => { + return this.commandArgs.query.val().then(query => { + let wiql: witContracts.Wiql = { query: query }; + return witApi.queryByWiql(wiql, { project: projectName }).then(result => { + let workItemIds: number[] = []; + + // Flat Query + if (result.queryType == witContracts.QueryType.Flat) { + workItemIds = result.workItems.map(val => val.id).slice(0, Math.min(200, result.workItems.length)); + } + + // Link Query + else { + let sourceIds = result.workItemRelations + .filter(relation => relation.source && relation.source.id) + .map(relation => relation.source.id); + let targetIds = result.workItemRelations + .filter(relation => relation.target && relation.target.id) + .map(relation => relation.target.id); + let allIds = sourceIds.concat(targetIds); + workItemIds = allIds.slice(0, Math.min(200, allIds.length)); + } + + let fieldRefs = result.columns.map(val => val.referenceName); + + fieldRefs = fieldRefs.slice(0, Math.min(20, result.columns.length)); + return workItemIds.length > 0 ? witApi.getWorkItems(workItemIds, fieldRefs) : []; }); }); + }); } public friendlyOutput(data: witContracts.WorkItem[]): void { diff --git a/app/exec/workitem/show.ts b/app/exec/workitem/show.ts index 68f7e06a..8ccefb55 100644 --- a/app/exec/workitem/show.ts +++ b/app/exec/workitem/show.ts @@ -18,13 +18,11 @@ export class WorkItemShow extends witBase.WorkItemBase { return ["workItemId"]; } - public exec(): Promise { - return this.webApi.getWorkItemTrackingApi() - .then(witApi => { - return this.commandArgs.workItemId.val().then(workItemId => { - return witApi.getWorkItem(workItemId); - }); - }); + public async exec(): Promise { + var witapi: witClient.IWorkItemTrackingApi = await this.webApi.getWorkItemTrackingApi(); + return this.commandArgs.workItemId.val().then(workItemId => { + return witapi.getWorkItem(workItemId); + }); } public friendlyOutput(workItem: witContracts.WorkItem): void { diff --git a/app/exec/workitem/update.ts b/app/exec/workitem/update.ts index ddbfa786..59d70948 100644 --- a/app/exec/workitem/update.ts +++ b/app/exec/workitem/update.ts @@ -18,22 +18,23 @@ export class WorkItemUpdate extends witBase.WorkItemBase return ["workItemId", "title", "assignedTo", "description", "values"]; } - public exec(): Promise { + public async exec(): Promise { + var witapi = await this.webApi.getWorkItemTrackingApi(); + return Promise.all([ this.commandArgs.workItemId.val(), this.commandArgs.title.val(true), this.commandArgs.assignedTo.val(true), this.commandArgs.description.val(true), this.commandArgs.values.val(true), - this.webApi.getWorkItemTrackingApi() ]).then(promiseValues => { - const [workItemId, title, assignedTo, description, values, witApi] = promiseValues; + const [workItemId, title, assignedTo, description, values] = promiseValues; if (!title && !assignedTo && !description && (!values || Object.keys(values).length <= 0)) { throw new Error("At least one field value must be specified."); } var patchDoc = witBase.buildWorkItemPatchDoc(title, assignedTo, description, values); - return witApi.updateWorkItem(null, patchDoc, workItemId); + return witapi.updateWorkItem(null, patchDoc, workItemId); }); } diff --git a/package-lock.json b/package-lock.json index d0802149..aa37a758 100644 --- a/package-lock.json +++ b/package-lock.json @@ -255,13 +255,6 @@ "tunnel": "0.0.4", "typed-rest-client": "1.2.0", "underscore": "1.8.3" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } } }, "balanced-match": { @@ -2555,13 +2548,6 @@ "requires": { "tunnel": "0.0.4", "underscore": "1.8.3" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } } }, "typescript": { @@ -2596,6 +2582,11 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", diff --git a/package.json b/package.json index 536e03fa..bed2e2f1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "app-root-path": "1.0.0", "archiver": "2.0.3", "async": "^1.4.0", + "azure-devops-node-api": "~7.2.0", "clipboardy": "~1.2.3", "colors": "~1.3.0", "glob": "7.1.2", @@ -39,7 +40,6 @@ "util.promisify": "^1.0.0", "uuid": "^3.0.1", "validator": "^3.43.0", - "azure-devops-node-api": "^7.2.0", "winreg": "0.0.12", "xml2js": "^0.4.16" },