diff --git a/app/exec/build/list.ts b/app/exec/build/list.ts index c0fb612e..747f20b9 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"); @@ -18,9 +18,9 @@ export class BuildGetList extends buildBase.BuildBase { + public async exec(): Promise { trace.debug("build-list.exec"); - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); + var buildapi: buildClient.IBuildApi = await this.webApi.getBuildApi(); return Promise.all([ this.commandArgs.project.val(), diff --git a/app/exec/build/queue.ts b/app/exec/build/queue.ts index f70860bd..803dddd2 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 { @@ -21,8 +21,8 @@ export class BuildQueue extends buildBase.BuildBase { - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); + 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 => { diff --git a/app/exec/build/show.ts b/app/exec/build/show.ts index c8c6967c..f32eed08 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 { @@ -17,9 +17,9 @@ export class BuildShow extends buildBase.BuildBase { + public async exec(): Promise { trace.debug("build-show.exec"); - var buildapi: buildClient.IBuildApi = this.webApi.getBuildApi(); + 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); diff --git a/app/exec/build/tasks/_resources/icon.png b/app/exec/build/tasks/_resources/icon.png index 2a4c1dde..45fbc0d5 100644 Binary files a/app/exec/build/tasks/_resources/icon.png and b/app/exec/build/tasks/_resources/icon.png differ 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 15bc6b69..4fc2a99e 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"); @@ -16,8 +16,8 @@ export class BuildTaskDelete extends tasksBase.BuildTaskBase { - let agentApi = this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); + 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) { diff --git a/app/exec/build/tasks/list.ts b/app/exec/build/tasks/list.ts index 2dc0d309..9216a25f 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"); @@ -16,8 +16,8 @@ export class BuildTaskList extends tasksBase.BuildTaskBase { - var agentapi = this.webApi.getTaskAgentApi(this.connection.getCollectionUrl()); + 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 => { diff --git a/app/exec/build/tasks/upload.ts b/app/exec/build/tasks/upload.ts index a391d601..aa5ba1fe 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"); @@ -23,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 => { @@ -31,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); @@ -40,7 +39,7 @@ export class BuildTaskUpload extends tasksBase.BuildTaskBasearchive, taskJson.id, overwrite).then(() => { 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 b6ec10bb..602cdd86 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, @@ -237,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); }), ); }); @@ -264,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 { @@ -275,7 +320,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,8 +338,8 @@ 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: GalleryInterfaces.ExtensionPackage = { + extensionManifest: fs.readFileSync(this.settings.vsixPath, "base64"), }; trace.debug("Publishing %s", this.settings.vsixPath); @@ -363,15 +408,16 @@ export class PackagePublisher extends GalleryBase { 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) + 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(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( + null, extInfo.publisher, extInfo.id, null, @@ -381,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/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..214d6180 100644 --- a/app/exec/extension/install.ts +++ b/app/exec/extension/install.ts @@ -4,11 +4,12 @@ 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 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}`; @@ -99,8 +99,9 @@ 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/isvalid.ts b/app/exec/extension/isvalid.ts index 817429a8..6d050f13 100644 --- a/app/exec/extension/isvalid.ts +++ b/app/exec/extension/isvalid.ts @@ -3,7 +3,7 @@ import args = require("../../lib/arguments"); import colors = require("colors"); import extBase = require("./default"); import extInfo = require("./_lib/extensioninfo"); -import galleryContracts = require("vso-node-api/interfaces/GalleryInterfaces"); +import galleryContracts = require("azure-devops-node-api/interfaces/GalleryInterfaces"); import publishUtils = require("./_lib/publish"); import trace = require("../../lib/trace"); @@ -38,7 +38,7 @@ export class ExtensionIsValid 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..14d17d65 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"); @@ -25,8 +25,8 @@ export class ExtensionPublisherCreate extends extPubBase.ExtensionPublisherBase< this.registerCommandArgument("publisher", "Publisher ID", "Use this as the publisher ID.", args.StringArgument); } - public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); return Promise.all([ this.commandArgs.publisher.val(), diff --git a/app/exec/extension/publisher/delete.ts b/app/exec/extension/publisher/delete.ts index 0c3ed740..d759edc5 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"); @@ -29,8 +29,8 @@ export class ExtensionPublisherDelete extends extPubBase.ExtensionPublisherBase< this.registerCommandArgument("publisher", "Publisher ID", "ID of Publisher to delete.", args.StringArgument); } - public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + 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 { 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 f9667c0c..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,8 +36,8 @@ export class ExtensionShare extends extBase.ExtensionBase { return ["publisher", "extensionId", "vsix", "shareWith"]; } - public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); return this.commandArgs.vsix.val(true).then(vsixPath => { let extInfoPromise: Promise; @@ -53,7 +55,7 @@ export class ExtensionShare extends extBase.ExtensionBase { return this.commandArgs.shareWith.val().then(shareWith => { let sharePromises: Promise[] = []; shareWith.forEach(account => { - sharePromises.push(galleryApi.shareExtension(extInfo.publisher, extInfo.id, account)); + sharePromises.push(SharingManager.shareExtension(galleryApi, extInfo.publisher, extInfo.id, account)); }); return Promise.all(sharePromises).then(() => { return shareWith; diff --git a/app/exec/extension/show.ts b/app/exec/extension/show.ts index c12369af..cf9e46e8 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 { @@ -26,8 +26,8 @@ export class ExtensionShow extends extBase.ExtensionBase { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + 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); diff --git a/app/exec/extension/unshare.ts b/app/exec/extension/unshare.ts index d011dc91..43295045 100644 --- a/app/exec/extension/unshare.ts +++ b/app/exec/extension/unshare.ts @@ -37,8 +37,8 @@ export class ExtensionShare extends extBase.ExtensionBase { return ["publisher", "extensionId", "vsix", "unshareWith"]; } - public exec(): Promise { - let galleryApi = this.webApi.getGalleryApi(this.webApi.serverUrl); + public async exec(): Promise { + let galleryApi = await this.webApi.getGalleryApi(this.webApi.serverUrl); return this.commandArgs.vsix.val(true).then(vsixPath => { let extInfoPromise: Promise; diff --git a/app/exec/login.ts b/app/exec/login.ts index d47a6227..74c61241 100644 --- a/app/exec/login.ts +++ b/app/exec/login.ts @@ -21,52 +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 - .connect() - .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 c66023c6..95ddd95f 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); @@ -18,8 +18,8 @@ export class WorkItemCreate extends witBase.WorkItemBase return ["workItemType", "title", "assignedTo", "description", "project", "values"]; } - public exec(): Promise { - var witapi = this.webApi.getWorkItemTrackingApi(); + public async exec(): Promise { + var witapi = await this.webApi.getWorkItemTrackingApi(); return Promise.all([ this.commandArgs.workItemType.val(), 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..41cf4943 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); @@ -20,8 +20,8 @@ export class WorkItemQuery extends witBase.WorkItemBase return ["project", "query"]; } - public exec(): Promise { - var witApi: witClient.IWorkItemTrackingApi = this.webApi.getWorkItemTrackingApi(); + 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 => { diff --git a/app/exec/workitem/show.ts b/app/exec/workitem/show.ts index 990d3d01..8ccefb55 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); @@ -18,8 +18,8 @@ export class WorkItemShow extends witBase.WorkItemBase { return ["workItemId"]; } - public exec(): Promise { - var witapi: witClient.IWorkItemTrackingApi = this.webApi.getWorkItemTrackingApi(); + public async exec(): Promise { + var witapi: witClient.IWorkItemTrackingApi = await this.webApi.getWorkItemTrackingApi(); return this.commandArgs.workItemId.val().then(workItemId => { return witapi.getWorkItem(workItemId); }); diff --git a/app/exec/workitem/update.ts b/app/exec/workitem/update.ts index 586bf2d3..59d70948 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); @@ -18,8 +18,8 @@ export class WorkItemUpdate extends witBase.WorkItemBase return ["workItemId", "title", "assignedTo", "description", "values"]; } - public exec(): Promise { - var witapi = this.webApi.getWorkItemTrackingApi(); + public async exec(): Promise { + var witapi = await this.webApi.getWorkItemTrackingApi(); return Promise.all([ this.commandArgs.workItemId.val(), 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 62f9041c..f80db9c6 100644 Binary files a/docs/basicAuthEnabled.png and b/docs/basicAuthEnabled.png differ diff --git a/docs/configureBasicAuthFeature.png b/docs/configureBasicAuthFeature.png index 65c12a7d..d26fb8c8 100644 Binary files a/docs/configureBasicAuthFeature.png and b/docs/configureBasicAuthFeature.png differ diff --git a/docs/help-screen.png b/docs/help-screen.png index 6a78fae3..ce01afd1 100644 Binary files a/docs/help-screen.png and b/docs/help-screen.png differ diff --git a/docs/tfsAuth.png b/docs/tfsAuth.png index 5e191376..75f898eb 100644 Binary files a/docs/tfsAuth.png and b/docs/tfsAuth.png differ diff --git a/package-lock.json b/package-lock.json index 3a149435..aa37a758 100644 --- a/package-lock.json +++ b/package-lock.json @@ -246,6 +246,17 @@ "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" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1975,6 +1986,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 +2150,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 +2541,15 @@ "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" + } + }, "typescript": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", @@ -2563,9 +2583,9 @@ "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==" + "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", @@ -2661,16 +2681,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", diff --git a/package.json b/package.json index 9bdd3048..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", - "vso-node-api": "^5.0.0", "winreg": "0.0.12", "xml2js": "^0.4.16" },