Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/extensions/common/extensionQuery.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IExtensionGalleryManifest } from '../../../../platform/extensionManagement/common/extensionGalleryManifest.js';
7
import { FilterType, SortBy } from '../../../../platform/extensionManagement/common/extensionManagement.js';
8
import { EXTENSION_CATEGORIES } from '../../../../platform/extensions/common/extensions.js';
9
10
export class Query {
11
12
constructor(public value: string, public sortBy: string) {
13
this.value = value.trim();
14
}
15
16
static suggestions(query: string, galleryManifest: IExtensionGalleryManifest | null): string[] {
17
18
const commands = ['installed', 'updates', 'enabled', 'disabled', 'builtin'];
19
if (galleryManifest?.capabilities.extensionQuery?.filtering?.some(c => c.name === FilterType.Featured)) {
20
commands.push('featured');
21
}
22
23
commands.push(...['mcp', 'popular', 'recommended', 'recentlyPublished', 'workspaceUnsupported', 'deprecated', 'sort']);
24
const isCategoriesEnabled = galleryManifest?.capabilities.extensionQuery?.filtering?.some(c => c.name === FilterType.Category);
25
if (isCategoriesEnabled) {
26
commands.push('category');
27
}
28
29
commands.push(...['tag', 'ext', 'id', 'outdated', 'recentlyUpdated']);
30
const sortCommands = [];
31
if (galleryManifest?.capabilities.extensionQuery?.sorting?.some(c => c.name === SortBy.InstallCount)) {
32
sortCommands.push('installs');
33
}
34
if (galleryManifest?.capabilities.extensionQuery?.sorting?.some(c => c.name === SortBy.WeightedRating)) {
35
sortCommands.push('rating');
36
}
37
sortCommands.push('name', 'publishedDate', 'updateDate');
38
39
const subcommands = {
40
'sort': sortCommands,
41
'category': isCategoriesEnabled ? EXTENSION_CATEGORIES.map(c => `"${c.toLowerCase()}"`) : [],
42
'tag': [''],
43
'ext': [''],
44
'id': ['']
45
} as const;
46
47
const queryContains = (substr: string) => query.indexOf(substr) > -1;
48
const hasSort = subcommands.sort.some(subcommand => queryContains(`@sort:${subcommand}`));
49
const hasCategory = subcommands.category.some(subcommand => queryContains(`@category:${subcommand}`));
50
51
return commands.flatMap(command => {
52
if (hasSort && command === 'sort' || hasCategory && command === 'category') {
53
return [];
54
}
55
if (command in subcommands) {
56
return (subcommands as Record<string, readonly string[]>)[command]
57
.map(subcommand => `@${command}:${subcommand}${subcommand === '' ? '' : ' '}`);
58
}
59
else {
60
return queryContains(`@${command}`) ? [] : [`@${command} `];
61
}
62
});
63
}
64
65
static parse(value: string): Query {
66
let sortBy = '';
67
value = value.replace(/@sort:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
68
sortBy = by;
69
70
return '';
71
});
72
return new Query(value, sortBy);
73
}
74
75
toString(): string {
76
let result = this.value;
77
78
if (this.sortBy) {
79
result = `${result}${result ? ' ' : ''}@sort:${this.sortBy}`;
80
}
81
return result;
82
}
83
84
isValid(): boolean {
85
return !/@outdated/.test(this.value);
86
}
87
88
equals(other: Query): boolean {
89
return this.value === other.value && this.sortBy === other.sortBy;
90
}
91
}
92
93