Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/extensionManagement/common/extensionFeatures.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 { IMarkdownString } from '../../../../base/common/htmlContent.js';
7
import { Event } from '../../../../base/common/event.js';
8
import { ExtensionIdentifier, IExtensionManifest } from '../../../../platform/extensions/common/extensions.js';
9
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
10
import { Registry } from '../../../../platform/registry/common/platform.js';
11
import { IDisposable } from '../../../../base/common/lifecycle.js';
12
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
13
import Severity from '../../../../base/common/severity.js';
14
import { IStringDictionary } from '../../../../base/common/collections.js';
15
import { ResolvedKeybinding } from '../../../../base/common/keybindings.js';
16
import { Color } from '../../../../base/common/color.js';
17
import { ThemeIcon } from '../../../../base/common/themables.js';
18
19
export namespace Extensions {
20
export const ExtensionFeaturesRegistry = 'workbench.registry.extensionFeatures';
21
}
22
23
export interface IExtensionFeatureRenderer extends IDisposable {
24
type: string;
25
shouldRender(manifest: IExtensionManifest): boolean;
26
render(manifest: IExtensionManifest): IDisposable;
27
}
28
29
export interface IRenderedData<T> extends IDisposable {
30
readonly data: T;
31
readonly onDidChange?: Event<T>;
32
}
33
34
export interface IExtensionFeatureMarkdownRenderer extends IExtensionFeatureRenderer {
35
type: 'markdown';
36
render(manifest: IExtensionManifest): IRenderedData<IMarkdownString>;
37
}
38
39
export type IRowData = string | IMarkdownString | ResolvedKeybinding | Color | ReadonlyArray<ResolvedKeybinding | IMarkdownString | Color>;
40
41
export interface ITableData {
42
headers: string[];
43
rows: IRowData[][];
44
}
45
46
export interface IExtensionFeatureTableRenderer extends IExtensionFeatureRenderer {
47
type: 'table';
48
render(manifest: IExtensionManifest): IRenderedData<ITableData>;
49
}
50
51
export interface IExtensionFeatureMarkdownAndTableRenderer extends IExtensionFeatureRenderer {
52
type: 'markdown+table';
53
render(manifest: IExtensionManifest): IRenderedData<Array<IMarkdownString | ITableData>>;
54
}
55
56
export interface IExtensionFeatureDescriptor {
57
readonly id: string;
58
readonly label: string;
59
// label of the access data, if different from the feature title.
60
// This is useful when the feature is a part of a larger feature and the access data is not about the larger feature.
61
// This is shown in the access chart like "There were ${accessCount} ${accessLabel} requests from this extension".
62
readonly accessDataLabel?: string;
63
readonly description?: string;
64
readonly icon?: ThemeIcon;
65
readonly access: {
66
readonly canToggle?: boolean;
67
readonly requireUserConsent?: boolean;
68
readonly extensionsList?: IStringDictionary<boolean>;
69
};
70
readonly renderer?: SyncDescriptor<IExtensionFeatureRenderer>;
71
}
72
73
export interface IExtensionFeaturesRegistry {
74
75
registerExtensionFeature(descriptor: IExtensionFeatureDescriptor): IDisposable;
76
getExtensionFeature(id: string): IExtensionFeatureDescriptor | undefined;
77
getExtensionFeatures(): ReadonlyArray<IExtensionFeatureDescriptor>;
78
}
79
80
export interface IExtensionFeatureAccessData {
81
readonly current?: {
82
readonly accessTimes: Date[];
83
readonly lastAccessed: Date;
84
readonly status?: { readonly severity: Severity; readonly message: string };
85
};
86
readonly accessTimes: Date[];
87
}
88
89
export const IExtensionFeaturesManagementService = createDecorator<IExtensionFeaturesManagementService>('IExtensionFeaturesManagementService');
90
export interface IExtensionFeaturesManagementService {
91
readonly _serviceBrand: undefined;
92
93
readonly onDidChangeEnablement: Event<{ readonly extension: ExtensionIdentifier; readonly featureId: string; readonly enabled: boolean }>;
94
isEnabled(extension: ExtensionIdentifier, featureId: string): boolean;
95
setEnablement(extension: ExtensionIdentifier, featureId: string, enabled: boolean): void;
96
getEnablementData(featureId: string): { readonly extension: ExtensionIdentifier; readonly enabled: boolean }[];
97
98
getAccess(extension: ExtensionIdentifier, featureId: string, justification?: string): Promise<boolean>;
99
100
readonly onDidChangeAccessData: Event<{ readonly extension: ExtensionIdentifier; readonly featureId: string; readonly accessData: IExtensionFeatureAccessData }>;
101
getAllAccessDataForExtension(extension: ExtensionIdentifier): Map<string, IExtensionFeatureAccessData>;
102
getAccessData(extension: ExtensionIdentifier, featureId: string): IExtensionFeatureAccessData | undefined;
103
setStatus(extension: ExtensionIdentifier, featureId: string, status: { readonly severity: Severity; readonly message: string } | undefined): void;
104
}
105
106
class ExtensionFeaturesRegistry implements IExtensionFeaturesRegistry {
107
108
private readonly extensionFeatures = new Map<string, IExtensionFeatureDescriptor>();
109
110
registerExtensionFeature(descriptor: IExtensionFeatureDescriptor): IDisposable {
111
if (this.extensionFeatures.has(descriptor.id)) {
112
throw new Error(`Extension feature with id '${descriptor.id}' already exists`);
113
}
114
this.extensionFeatures.set(descriptor.id, descriptor);
115
return {
116
dispose: () => this.extensionFeatures.delete(descriptor.id)
117
};
118
}
119
120
getExtensionFeature(id: string): IExtensionFeatureDescriptor | undefined {
121
return this.extensionFeatures.get(id);
122
}
123
124
getExtensionFeatures(): ReadonlyArray<IExtensionFeatureDescriptor> {
125
return Array.from(this.extensionFeatures.values());
126
}
127
}
128
129
Registry.add(Extensions.ExtensionFeaturesRegistry, new ExtensionFeaturesRegistry());
130
131