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

View file

@ -1,6 +1,6 @@
import * as program from 'commander'; import * as program from 'commander';
import { packageCommand, ls } from './package'; import { packageCommand, ls } from './package';
import { publish, list, unpublish } from './publish'; import { publish, unpublish } from './publish';
import { show } from './show'; import { show } from './show';
import { search } from './search'; import { search } from './search';
import { listPublishers, createPublisher, deletePublisher, loginPublisher, logoutPublisher } from './store'; 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') .option('-p, --pat <token>', 'Personal Access Token')
.action((id, { pat }) => main(unpublish({ id, pat }))); .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 program
.command('ls-publishers') .command('ls-publishers')
.description('List all known publishers') .description('List all known publishers')

View file

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

View file

@ -1,5 +1,5 @@
import * as fs from 'fs'; 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 { pack, readManifest, IPackage } from './package';
import * as tmp from 'tmp'; import * as tmp from 'tmp';
import { getPublisher } from './store'; import { getPublisher } from './store';
@ -52,8 +52,8 @@ function readManifestFromPackage(packagePath: string): Promise<Manifest> {
}); });
} }
function _publish(packagePath: string, pat: string, manifest: Manifest): Promise<void> { async function _publish(packagePath: string, pat: string, manifest: Manifest): Promise<void> {
const api = getGalleryAPI(pat); const api = await getGalleryAPI(pat);
const packageStream = fs.createReadStream(packagePath); const packageStream = fs.createReadStream(packagePath);
@ -61,7 +61,7 @@ function _publish(packagePath: string, pat: string, manifest: Manifest): Promise
const fullName = `${name}@${manifest.version}`; const fullName = `${name}@${manifest.version}`;
console.log(`Publishing ${fullName}...`); 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)) .catch<PublishedExtension>(err => err.statusCode === 404 ? null : Promise.reject(err))
.then(extension => { .then(extension => {
if (extension && extension.versions.some(v => v.version === manifest.version)) { 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 { export interface IUnpublishOptions extends IPublishOptions {
id?: string; id?: string;
} }

View file

@ -1,5 +1,5 @@
import { getPublicGalleryAPI } from './util'; 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'; import { tableView, wordTrim } from './viewutils';
const pageSize = 100; const pageSize = 100;

View file

@ -1,5 +1,5 @@
import { getPublicGalleryAPI, log } from './util'; 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'; import { ViewTable, formatDate, formatDateTime, ratingStars, tableView, indentRow, wordWrap, icons } from './viewutils';
const limitVersions = 6; 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 // If the caller of the `getRoleAssignments` API has any of the roles
// (Creator, Owner, Contributor, Reader) on the publisher, we get a 200, // (Creator, Owner, Contributor, Reader) on the publisher, we get a 200,
// otherwise we get a 403. // otherwise we get a 403.
const api = getSecurityRolesAPI(pat); const api = await getSecurityRolesAPI(pat);
await api.getRoleAssignments('gallery.publisher', publisherName); await api.getRoleAssignments('gallery.publisher', publisherName);
return await addPublisherToStore(store, { name: publisherName, pat }); 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(`Publisher human-friendly name: `, { default: publisherName }).then(displayName => {
return read(`E-mail: `).then(email => { return read(`E-mail: `).then(email => {
return read(`Personal Access Token:`, { silent: true, replace: '*' }) return read(`Personal Access Token:`, { silent: true, replace: '*' })
.then(pat => { .then(async pat => {
const api = getGalleryAPI(pat); const api = await getGalleryAPI(pat);
const raw = { const raw = {
publisherName, publisherName,
displayName, displayName,
@ -127,8 +127,8 @@ export function createPublisher(publisherName: string): Promise<any> {
emailAddress: [email] emailAddress: [email]
}; };
return api.createPublisher(raw) await api.createPublisher(raw);
.then(() => ({ name: publisherName, pat })); return { name: publisherName, pat };
}) })
.then(publisher => load().then(store => addPublisherToStore(store, publisher))); .then(publisher => load().then(store => addPublisherToStore(store, publisher)));
}); });

View file

@ -1,10 +1,10 @@
import * as _read from 'read'; import * as _read from 'read';
import { WebApi, getBasicHandler } from 'vso-node-api/WebApi'; import { WebApi, getPersonalAccessTokenHandler } from 'azure-devops-node-api/WebApi';
import { IGalleryApi } from 'vso-node-api/GalleryApi'; import { IGalleryApi, GalleryApi } from 'azure-devops-node-api/GalleryApi';
import * as denodeify from 'denodeify'; import * as denodeify from 'denodeify';
import chalk from 'chalk'; import chalk from 'chalk';
import { PublicGalleryAPI } from './publicgalleryapi'; 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); const __read = denodeify<_read.Options, string>(_read);
export function read(prompt: string, options: _read.Options = {}): Promise<string> { 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}`; return `${marketplaceUrl}/items?itemName=${extension}`;
} }
export function getGalleryAPI(pat: string): IGalleryApi { export async function getGalleryAPI(pat: string): Promise<IGalleryApi> {
const authHandler = getBasicHandler('oauth', pat); // from https://github.com/Microsoft/tfs-cli/blob/master/app/exec/extension/default.ts#L287-L292
const vsoapi = new WebApi('oauth', authHandler); const authHandler = getPersonalAccessTokenHandler(pat);
return vsoapi.getGalleryApi(marketplaceUrl); return new GalleryApi(marketplaceUrl, [authHandler]);
// const vsoapi = new WebApi(marketplaceUrl, authHandler);
// return await vsoapi.getGalleryApi();
} }
export function getSecurityRolesAPI(pat: string): ISecurityRolesApi { export async function getSecurityRolesAPI(pat: string): Promise<ISecurityRolesApi> {
const authHandler = getBasicHandler('oauth', pat); const authHandler = getPersonalAccessTokenHandler(pat);
const vsoapi = new WebApi('oauth', authHandler); const vsoapi = new WebApi(marketplaceUrl, authHandler);
return vsoapi.getSecurityRolesApi(marketplaceUrl); return await vsoapi.getSecurityRolesApi();
} }
export function getPublicGalleryAPI() { 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" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== 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: babel-runtime@^6.9.2:
version "6.26.0" version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 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" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 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: osenv@^0.1.3, osenv@^0.1.4:
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 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" end-of-stream "^1.1.0"
once "^1.3.1" 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: randomatic@^3.0.0:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" 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" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.4.tgz#2d3785a158c174c9a16dc2c046ec5fc5f1742213"
integrity sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM= integrity sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=
typed-rest-client@^0.9.0: typed-rest-client@1.2.0:
version "0.9.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-0.9.0.tgz#f768cc0dc3f4e950f06e04825c36b3e7834aa1f2" resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.2.0.tgz#723085d203f38d7d147271e5ed3a75488eb44a02"
integrity sha1-92jMDcP06VDwbgSCXDaz54NKofI= integrity sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==
dependencies: dependencies:
tunnel "0.0.4" tunnel "0.0.4"
underscore "1.8.3" underscore "1.8.3"
@ -2237,11 +2247,6 @@ underscore@1.8.3:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= 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: union-value@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" 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-correct "^3.0.0"
spdx-expression-parse "^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: which-module@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"