Initial search command

This commit is contained in:
Morten Henriksen 2017-11-20 19:20:07 +01:00
parent bf162ac2bb
commit 9bc0052f7f
3 changed files with 62 additions and 1 deletions

View file

@ -2,6 +2,7 @@ import * as program from 'commander';
import { packageCommand, ls } from './package';
import { publish, list, unpublish } from './publish';
import { show } from './show';
import { search } from './search';
import { listPublishers, createPublisher, deletePublisher, loginPublisher, logoutPublisher } from './store';
import { getLatestVersion } from './npm';
import { CancellationToken, isCancelledError } from './util';
@ -119,6 +120,12 @@ module.exports = function (argv: string[]): void {
.description('Show extension metadata')
.action((extensionid, { json }) => main(show(extensionid, json)));
program
.command('search <text>')
.option('--json', 'Output result in json format', false)
.description('search extension gallery')
.action((text, { json }) => main(search(text, json)));
program
.command('*')
.action(() => program.help());

45
src/search.ts Normal file
View file

@ -0,0 +1,45 @@
import { getPublicGalleryAPI } from './util';
import { PublishedExtension, ExtensionQueryFilterType } from 'vso-node-api/interfaces/GalleryInterfaces';
import { tableView, wordTrim } from './viewutils';
const pageSize = 100;
export function search(searchText: string, json: boolean = false, pageNumber: number = 1): Promise<any> {
const flags = [];
return getPublicGalleryAPI()
.extensionQuery({
pageSize,
criteria: [
{ filterType: ExtensionQueryFilterType.SearchText, value: searchText },
],
flags,
})
.then(results => {
if (json) {
console.log(JSON.stringify(results, undefined, '\t'));
} else {
renderSearchView(searchText, results);
}
});
}
function renderSearchView(searchText: string, results: PublishedExtension[] = []) {
if (!results.length) {
console.log('No matching results');
return;
}
console.log([
`Search results:`,
'',
...tableView([
['<ExtensionId>', '<Description>'],
...results.map(({ publisher: { publisherName }, extensionName, shortDescription }) =>
[publisherName + '.' + extensionName, shortDescription.replace(/\n|\r|\t/g, ' ')]
)
]),
'',
'For more information on an extension use "vsce show <extensionId>"',
]
.map(line => wordTrim(line.replace(/\s+$/g, '')))
.join('\n'));
}

View file

@ -7,6 +7,8 @@ const format = {
time: { hour: 'numeric', minute: 'numeric', second: 'numeric' },
};
const columns = process.stdout.columns ? process.stdout.columns : 80;
export function formatDate(date) { return date.toLocaleString(fixedLocale, format.date); }
export function formatTime(date) { return date.toLocaleString(fixedLocale, format.time); }
export function formatDateTime(date) { return date.toLocaleString(fixedLocale, { ...format.date, ...format.time }); }
@ -30,7 +32,7 @@ export function tableView(table: ViewTable, spacing: number = 2): string[] {
return table.map(row => row.map((cell, i) => `${cell}${repeatString(' ', maxLen[i] - cell.length + spacing)}`).join(''));
}
export function wordWrap(text: string, width: number = 80): string {
export function wordWrap(text: string, width: number = columns): string {
const [indent = ''] = text.match(/^\s+/) || [];
const maxWidth = width - indent.length;
return text
@ -47,3 +49,10 @@ export function wordWrap(text: string, width: number = 80): string {
};
export function indentRow(row: string) { return ` ${row}`; };
export function wordTrim(text: string, width: number = columns, indicator = '...') {
if (text.length > width) {
return text.substr(0, width - indicator.length) + indicator;
}
return text;
}