update deps to azure-devops-node-api

fixes #332
This commit is contained in:
Joao Moreno 2019-05-03 12:39:27 +02:00
parent 165f96d2dd
commit 3502fba665
9 changed files with 65 additions and 88 deletions

View file

@ -34,6 +34,7 @@
"node": ">= 8"
},
"dependencies": {
"azure-devops-node-api": "^7.2.0",
"chalk": "^2.4.2",
"cheerio": "^1.0.0-rc.1",
"commander": "^2.8.1",
@ -49,8 +50,8 @@
"read": "^1.0.7",
"semver": "^5.1.0",
"tmp": "0.0.29",
"typed-rest-client": "1.2.0",
"url-join": "^1.1.0",
"vso-node-api": "6.1.2-preview",
"yauzl": "^2.3.1",
"yazl": "^2.2.2"
},

View file

@ -1,6 +1,6 @@
import * as program from 'commander';
import { packageCommand, ls } from './package';
import { publish, list, unpublish } from './publish';
import { publish, unpublish } from './publish';
import { show } from './show';
import { search } from './search';
import { listPublishers, createPublisher, deletePublisher, loginPublisher, logoutPublisher } from './store';
@ -88,11 +88,6 @@ module.exports = function (argv: string[]): void {
.option('-p, --pat <token>', 'Personal Access Token')
.action((id, { pat }) => main(unpublish({ id, pat })));
program
.command('list <publisher>')
.description('Lists all extensions published by the given publisher')
.action(publisher => main(list(publisher)));
program
.command('ls-publishers')
.description('List all known publishers')

View file

@ -1,8 +1,10 @@
import { HttpClient, HttpClientResponse } from 'vso-node-api/HttpClient';
import { PublishedExtension, ExtensionQueryFlags, FilterCriteria, SortOrderType,
SortByType, ExtensionQueryFilterType, TypeInfo} from 'vso-node-api/interfaces/GalleryInterfaces';
import { IHeaders } from 'vso-node-api/interfaces/common/VsoBaseInterfaces';
import { ContractSerializer } from 'vso-node-api/Serialization';
import { HttpClient, HttpClientResponse } from 'typed-rest-client/HttpClient';
import {
PublishedExtension, ExtensionQueryFlags, FilterCriteria, SortOrderType,
SortByType, ExtensionQueryFilterType, TypeInfo
} from 'azure-devops-node-api/interfaces/GalleryInterfaces';
import { IHeaders } from 'azure-devops-node-api/interfaces/common/VsoBaseInterfaces';
import { ContractSerializer } from 'azure-devops-node-api/Serialization';
export interface ExtensionQuery {
pageNumber?: number;
@ -21,7 +23,7 @@ export class PublicGalleryAPI {
this.client = new HttpClient('vsce');
}
post(url: string, data: string, additionalHeaders?: IHeaders): Promise<HttpClientResponse> {
private post(url: string, data: string, additionalHeaders?: IHeaders): Promise<HttpClientResponse> {
return this.client.post(`${this.baseUrl}/_apis/public${url}`, data, additionalHeaders);
}
@ -35,17 +37,17 @@ export class PublicGalleryAPI {
assetTypes = [],
}: ExtensionQuery): Promise<PublishedExtension[]> {
return this.post('/gallery/extensionquery', JSON.stringify({
filters: [{pageNumber, pageSize, criteria}],
filters: [{ pageNumber, pageSize, criteria }],
assetTypes,
flags: flags.reduce((memo, flag) => memo | flag, 0)
}), {
Accept: `application/json;api-version=${this.apiVersion}`,
'Content-Type': 'application/json',
})
Accept: `application/json;api-version=${this.apiVersion}`,
'Content-Type': 'application/json',
})
.then(res => res.readBody())
.then(data => JSON.parse(data))
.then(({results: [result = {}] = []}) => result)
.then(({extensions = []}) =>
.then(({ results: [result = {}] = [] }) => result)
.then(({ extensions = [] }) =>
ContractSerializer.deserialize(extensions, TypeInfo.PublishedExtension, false, false)
);
}
@ -55,9 +57,9 @@ export class PublicGalleryAPI {
criteria: [{ filterType: ExtensionQueryFilterType.Name, value: extensionId }],
flags,
})
.then(result => result.filter(({publisher: {publisherName}, extensionName}) =>
extensionId.toLowerCase() === `${publisherName}.${extensionName}`.toLowerCase())
)
.then(([extension]) => extension);
.then(result => result.filter(({ publisher: { publisherName }, extensionName }) =>
extensionId.toLowerCase() === `${publisherName}.${extensionName}`.toLowerCase())
)
.then(([extension]) => extension);
}
}

View file

@ -1,5 +1,5 @@
import * as fs from 'fs';
import { ExtensionQueryFlags, PublishedExtension, ExtensionQueryFilterType, PagingDirection, SortByType, SortOrderType } from 'vso-node-api/interfaces/GalleryInterfaces';
import { ExtensionQueryFlags, PublishedExtension, ExtensionQueryFilterType, PagingDirection, SortByType, SortOrderType } from 'azure-devops-node-api/interfaces/GalleryInterfaces';
import { pack, readManifest, IPackage } from './package';
import * as tmp from 'tmp';
import { getPublisher } from './store';
@ -52,8 +52,8 @@ function readManifestFromPackage(packagePath: string): Promise<Manifest> {
});
}
function _publish(packagePath: string, pat: string, manifest: Manifest): Promise<void> {
const api = getGalleryAPI(pat);
async function _publish(packagePath: string, pat: string, manifest: Manifest): Promise<void> {
const api = await getGalleryAPI(pat);
const packageStream = fs.createReadStream(packagePath);
@ -61,7 +61,7 @@ function _publish(packagePath: string, pat: string, manifest: Manifest): Promise
const fullName = `${name}@${manifest.version}`;
console.log(`Publishing ${fullName}...`);
return api.getExtension(manifest.publisher, manifest.name, null, ExtensionQueryFlags.IncludeVersions)
return api.getExtension(null, manifest.publisher, manifest.name, null, ExtensionQueryFlags.IncludeVersions)
.catch<PublishedExtension>(err => err.statusCode === 404 ? null : Promise.reject(err))
.then(extension => {
if (extension && extension.versions.some(v => v.version === manifest.version)) {
@ -164,25 +164,6 @@ export function publish(options: IPublishOptions = {}): Promise<any> {
});
}
export function list(publisher: string): Promise<any> {
validatePublisher(publisher);
return getPublisher(publisher)
.then(p => p.pat)
.then(getGalleryAPI)
.then(api => {
const criteria = [{ filterType: ExtensionQueryFilterType.InstallationTarget, value: 'Microsoft.VisualStudio.Code' }];
const filters = [{ criteria, direction: PagingDirection.Forward, pageNumber: 0, pageSize: 1000, pagingToken: null, sortBy: SortByType.Relevance, sortOrder: SortOrderType.Default }];
const query = { filters, flags: ExtensionQueryFlags.IncludeLatestVersionOnly | ExtensionQueryFlags.IncludeVersionProperties, assetTypes: [] };
return api.queryExtensions(query).then(result => {
return result.results[0].extensions
.filter(e => e.publisher.publisherName === publisher)
.forEach(e => console.log(`${e.extensionName} @ ${e.versions[0].version}`));
});
});
}
export interface IUnpublishOptions extends IPublishOptions {
id?: string;
}

View file

@ -1,5 +1,5 @@
import { getPublicGalleryAPI } from './util';
import { ExtensionQueryFilterType } from 'vso-node-api/interfaces/GalleryInterfaces';
import { ExtensionQueryFilterType } from 'azure-devops-node-api/interfaces/GalleryInterfaces';
import { tableView, wordTrim } from './viewutils';
const pageSize = 100;

View file

@ -1,5 +1,5 @@
import { getPublicGalleryAPI, log } from './util';
import { ExtensionQueryFlags, PublishedExtension } from 'vso-node-api/interfaces/GalleryInterfaces';
import { ExtensionQueryFlags, PublishedExtension } from 'azure-devops-node-api/interfaces/GalleryInterfaces';
import { ViewTable, formatDate, formatDateTime, ratingStars, tableView, indentRow, wordWrap, icons } from './viewutils';
const limitVersions = 6;

View file

@ -60,7 +60,7 @@ async function requestPAT(store: IStore, publisherName: string): Promise<IPublis
// If the caller of the `getRoleAssignments` API has any of the roles
// (Creator, Owner, Contributor, Reader) on the publisher, we get a 200,
// otherwise we get a 403.
const api = getSecurityRolesAPI(pat);
const api = await getSecurityRolesAPI(pat);
await api.getRoleAssignments('gallery.publisher', publisherName);
return await addPublisherToStore(store, { name: publisherName, pat });
@ -113,8 +113,8 @@ export function createPublisher(publisherName: string): Promise<any> {
return read(`Publisher human-friendly name: `, { default: publisherName }).then(displayName => {
return read(`E-mail: `).then(email => {
return read(`Personal Access Token:`, { silent: true, replace: '*' })
.then(pat => {
const api = getGalleryAPI(pat);
.then(async pat => {
const api = await getGalleryAPI(pat);
const raw = {
publisherName,
displayName,
@ -127,8 +127,8 @@ export function createPublisher(publisherName: string): Promise<any> {
emailAddress: [email]
};
return api.createPublisher(raw)
.then(() => ({ name: publisherName, pat }));
await api.createPublisher(raw);
return { name: publisherName, pat };
})
.then(publisher => load().then(store => addPublisherToStore(store, publisher)));
});

View file

@ -1,10 +1,10 @@
import * as _read from 'read';
import { WebApi, getBasicHandler } from 'vso-node-api/WebApi';
import { IGalleryApi } from 'vso-node-api/GalleryApi';
import { WebApi, getPersonalAccessTokenHandler } from 'azure-devops-node-api/WebApi';
import { IGalleryApi, GalleryApi } from 'azure-devops-node-api/GalleryApi';
import * as denodeify from 'denodeify';
import chalk from 'chalk';
import { PublicGalleryAPI } from './publicgalleryapi';
import { ISecurityRolesApi } from 'vso-node-api/SecurityRolesApi';
import { ISecurityRolesApi } from 'azure-devops-node-api/SecurityRolesApi';
const __read = denodeify<_read.Options, string>(_read);
export function read(prompt: string, options: _read.Options = {}): Promise<string> {
@ -21,16 +21,19 @@ export function getPublishedUrl(extension: string): string {
return `${marketplaceUrl}/items?itemName=${extension}`;
}
export function getGalleryAPI(pat: string): IGalleryApi {
const authHandler = getBasicHandler('oauth', pat);
const vsoapi = new WebApi('oauth', authHandler);
return vsoapi.getGalleryApi(marketplaceUrl);
export async function getGalleryAPI(pat: string): Promise<IGalleryApi> {
// from https://github.com/Microsoft/tfs-cli/blob/master/app/exec/extension/default.ts#L287-L292
const authHandler = getPersonalAccessTokenHandler(pat);
return new GalleryApi(marketplaceUrl, [authHandler]);
// const vsoapi = new WebApi(marketplaceUrl, authHandler);
// return await vsoapi.getGalleryApi();
}
export function getSecurityRolesAPI(pat: string): ISecurityRolesApi {
const authHandler = getBasicHandler('oauth', pat);
const vsoapi = new WebApi('oauth', authHandler);
return vsoapi.getSecurityRolesApi(marketplaceUrl);
export async function getSecurityRolesAPI(pat: string): Promise<ISecurityRolesApi> {
const authHandler = getPersonalAccessTokenHandler(pat);
const vsoapi = new WebApi(marketplaceUrl, authHandler);
return await vsoapi.getSecurityRolesApi();
}
export function getPublicGalleryAPI() {

View file

@ -202,6 +202,16 @@ atob@^2.1.1:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
azure-devops-node-api@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz#131d4e01cf12ebc6e45569b5e0c5c249e4114d6d"
integrity sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==
dependencies:
os "0.1.1"
tunnel "0.0.4"
typed-rest-client "1.2.0"
underscore "1.8.3"
babel-runtime@^6.9.2:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
@ -1592,6 +1602,11 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.1:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
os@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/os/-/os-0.1.1.tgz#208845e89e193ad4d971474b93947736a56d13f3"
integrity sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=
osenv@^0.1.3, osenv@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
@ -1724,11 +1739,6 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
q@^1.0.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
randomatic@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
@ -2214,10 +2224,10 @@ tunnel@0.0.4:
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.4.tgz#2d3785a158c174c9a16dc2c046ec5fc5f1742213"
integrity sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=
typed-rest-client@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-0.9.0.tgz#f768cc0dc3f4e950f06e04825c36b3e7834aa1f2"
integrity sha1-92jMDcP06VDwbgSCXDaz54NKofI=
typed-rest-client@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.2.0.tgz#723085d203f38d7d147271e5ed3a75488eb44a02"
integrity sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==
dependencies:
tunnel "0.0.4"
underscore "1.8.3"
@ -2237,11 +2247,6 @@ underscore@1.8.3:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
underscore@^1.8.3:
version "1.9.1"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
union-value@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
@ -2288,16 +2293,6 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vso-node-api@6.1.2-preview:
version "6.1.2-preview"
resolved "https://registry.yarnpkg.com/vso-node-api/-/vso-node-api-6.1.2-preview.tgz#aab3546df2451ecd894e071bb99b5df19c5fa78f"
integrity sha1-qrNUbfJFHs2JTgcbuZtd8Zxfp48=
dependencies:
q "^1.0.1"
tunnel "0.0.4"
typed-rest-client "^0.9.0"
underscore "^1.8.3"
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"