extensionManagement.ts ×10

Frontier kind: Code frontier

unlabeled · c_4704cb13ac96

1952 tests · 9550 LOC · 40 files · introduces 0 tests · 660 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
10 ranges660 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1036 ranges9550 lines · 40 files · Browse complete extent
All tests (intent)
1952 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 660 introduced LOC across 10 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/extensionManagement/common/extensionManagement.ts 660 introduced LOC · 10 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- extensionManagement.ts
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 { CancellationToken } from '../../../base/common/cancellation.js';
7 > import { IStringDictionary } from '../../../base/common/collections.js';
8 > import { Event } from '../../../base/common/event.js';
9 > import { IMarkdownString } from '../../../base/common/htmlContent.js';
10 > import { IPager } from '../../../base/common/paging.js';
11 > import { Platform } from '../../../base/common/platform.js';
12 > import { PolicyCategory } from '../../../base/common/policy.js';
13 > import { URI } from '../../../base/common/uri.js';
14 > import { localize, localize2 } from '../../../nls.js';
15 > import { ConfigurationScope, Extensions, IConfigurationRegistry } from '../../configuration/common/configurationRegistry.js';
16 > import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from '../../extensions/common/extensions.js';
17 > import { FileOperationError, FileOperationResult, IFileService, IFileStat } from '../../files/common/files.js';
18 > import { createDecorator } from '../../instantiation/common/instantiation.js';
19 > import { Registry } from '../../registry/common/platform.js';
20 > import { IExtensionGalleryManifest } from './extensionGalleryManifest.js';
21 >
22 > export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$';
23 > export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN);
24 > export const WEB_EXTENSION_TAG = '__web_extension';
25 > export const LANGUAGE_MODEL_CHAT_PROVIDER_EXTENSION_TAG = 'language-models';
26 > export const EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT = 'skipWalkthrough';
27 > export const EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT = 'skipPublisherTrust';
28 > export const EXTENSION_INSTALL_SOURCE_CONTEXT = 'extensionInstallSource';
29 > export const EXTENSION_INSTALL_DEP_PACK_CONTEXT = 'dependecyOrPackExtensionInstall';
30 > export const EXTENSION_INSTALL_CLIENT_TARGET_PLATFORM_CONTEXT = 'clientTargetPlatform';
31 >
32 > export const enum ExtensionInstallSource {
33 > COMMAND = 'command',
34 > SETTINGS_SYNC = 'settingsSync',
35 > }
36 >
37 > export interface IProductVersion {
38 > readonly version: string;
39 > readonly date?: string;
40 > }
41 >
42 > export function TargetPlatformToString(targetPlatform: TargetPlatform) {
43 switch (targetPlatform) {
44 case TargetPlatform.WIN32_X64: return 'Windows 64 bit';
62 }
63 }
65 > export function toTargetPlatform(targetPlatform: string): TargetPlatform {
66 switch (targetPlatform) {
67 case TargetPlatform.WIN32_X64: return TargetPlatform.WIN32_X64;
84 }
85 }
87 > export function getTargetPlatform(platform: Platform | 'alpine', arch: string | undefined): TargetPlatform {
88 switch (platform) {
89 case Platform.Windows:
129 }
130 }
132 > export function isNotWebExtensionInWebTargetPlatform(allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {
133 // Not a web extension in web target platform
134 return productTargetPlatform === TargetPlatform.WEB && !allTargetPlatforms.includes(TargetPlatform.WEB);
135 }
137 > export function isTargetPlatformCompatible(extensionTargetPlatform: TargetPlatform, allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {
138 // Not compatible when extension is not a web extension in web target platform
139 if (isNotWebExtensionInWebTargetPlatform(allTargetPlatforms, productTargetPlatform)) {
163 return false;
164 }
166 > export interface IGalleryExtensionProperties {
167 > dependencies?: string[];
168 > extensionPack?: string[];
169 > engine?: string;
170 > enabledApiProposals?: string[];
171 > localizedLanguages?: string[];
172 > targetPlatform: TargetPlatform;
173 > isPreReleaseVersion: boolean;
174 > executesCode?: boolean;
175 > }
176 >
177 > export interface IGalleryExtensionAsset {
178 > uri: string;
179 > fallbackUri: string;
180 > }
181 >
182 > export interface IGalleryExtensionAssets {
183 > manifest: IGalleryExtensionAsset | null;
184 > readme: IGalleryExtensionAsset | null;
185 > changelog: IGalleryExtensionAsset | null;
186 > license: IGalleryExtensionAsset | null;
187 > repository: IGalleryExtensionAsset | null;
188 > download: IGalleryExtensionAsset;
189 > icon: IGalleryExtensionAsset | null;
190 > signature: IGalleryExtensionAsset | null;
191 > coreTranslations: [string, IGalleryExtensionAsset][];
192 > }
193 >
194 > export function isIExtensionIdentifier(obj: unknown): obj is IExtensionIdentifier {
195 const thing = obj as IExtensionIdentifier | undefined;
196 return !!thing
199 && (!thing.uuid || typeof thing.uuid === 'string');
200 }
202 > export interface IExtensionIdentifier {
203 > id: string;
204 > uuid?: string;
205 > }
206 >
207 > export interface IGalleryExtensionIdentifier extends IExtensionIdentifier {
208 > uuid: string;
209 > }
210 >
211 > export interface IGalleryExtensionVersion {
212 > version: string;
213 > date: string;
214 > isPreReleaseVersion: boolean;
215 > targetPlatforms: TargetPlatform[];
216 > }
217 >
218 > export interface IGalleryExtension {
219 > type: 'gallery';
220 > name: string;
221 > identifier: IGalleryExtensionIdentifier;
222 > version: string;
223 > displayName: string;
224 > publisherId: string;
225 > publisher: string;
226 > publisherDisplayName: string;
227 > publisherDomain?: { link: string; verified: boolean };
228 > publisherLink?: string;
229 > publisherSponsorLink?: string;
230 > description: string;
231 > installCount: number;
232 > rating: number;
233 > ratingCount: number;
234 > categories: readonly string[];
235 > tags: readonly string[];
236 > releaseDate: number;
237 > lastUpdated: number;
238 > preview: boolean;
239 > private: boolean;
240 > hasPreReleaseVersion: boolean;
241 > hasReleaseVersion: boolean;
242 > isSigned: boolean;
243 > allTargetPlatforms: TargetPlatform[];
244 > assets: IGalleryExtensionAssets;
245 > properties: IGalleryExtensionProperties;
246 > detailsLink?: string;
247 > ratingLink?: string;
248 > supportLink?: string;
249 > telemetryData?: IStringDictionary<unknown>;
250 > queryContext?: IStringDictionary<unknown>;
251 > }
252 >
253 > export type InstallSource = 'gallery' | 'vsix' | 'resource';
254 >
255 > export interface IGalleryMetadata {
256 > id: string;
257 > publisherId: string;
258 > private: boolean;
259 > publisherDisplayName: string;
260 > isPreReleaseVersion: boolean;
261 > targetPlatform?: TargetPlatform;
262 > }
263 >
264 > export type Metadata = Partial<IGalleryMetadata & {
265 > isApplicationScoped: boolean;
266 > isMachineScoped: boolean;
267 > isBuiltin: boolean;
268 > isSystem: boolean;
269 > updated: boolean;
270 > preRelease: boolean;
271 > hasPreReleaseVersion: boolean;
272 > installedTimestamp: number;
273 > pinned: boolean;
274 > source: InstallSource;
275 > size: number;
276 > }>;
277 >
278 > export interface ILocalExtension extends IExtension {
279 > isWorkspaceScoped: boolean;
280 > isMachineScoped: boolean;
281 > isApplicationScoped: boolean;
282 > publisherId: string | null;
283 > installedTimestamp?: number;
284 > isPreReleaseVersion: boolean;
285 > hasPreReleaseVersion: boolean;
286 > private: boolean;
287 > preRelease: boolean;
288 > updated: boolean;
289 > pinned: boolean;
290 > forceAutoUpdate: boolean;
291 > source: InstallSource;
292 > size: number;
293 > }
294 >
295 > export const enum SortBy {
296 > NoneOrRelevance = 'NoneOrRelevance',
297 > LastUpdatedDate = 'LastUpdatedDate',
298 > Title = 'Title',
299 > PublisherName = 'PublisherName',
300 > InstallCount = 'InstallCount',
301 > PublishedDate = 'PublishedDate',
302 > AverageRating = 'AverageRating',
303 > WeightedRating = 'WeightedRating'
304 > }
305 >
306 > export const enum SortOrder {
307 > Default = 0,
308 > Ascending = 1,
309 > Descending = 2
310 > }
311 >
312 > export const enum FilterType {
313 > Category = 'Category',
314 > ExtensionId = 'ExtensionId',
315 > ExtensionName = 'ExtensionName',
316 > ExcludeWithFlags = 'ExcludeWithFlags',
317 > Featured = 'Featured',
318 > SearchText = 'SearchText',
319 > Tag = 'Tag',
320 > Target = 'Target',
321 > }
322 >
323 > export interface IQueryOptions {
324 > text?: string;
325 > exclude?: string[];
326 > pageSize?: number;
327 > sortBy?: SortBy;
328 > sortOrder?: SortOrder;
329 > source?: string;
330 > includePreRelease?: boolean;
331 > productVersion?: IProductVersion;
332 > }
333 >
334 > export const enum StatisticType {
335 > Install = 'install',
336 > Uninstall = 'uninstall'
337 > }
338 >
339 > export interface IDeprecationInfo {
340 > readonly disallowInstall?: boolean;
341 > readonly extension?: {
342 > readonly id: string;
343 > readonly displayName: string;
344 > readonly autoMigrate?: {
345 > readonly storage: boolean;
346 > readonly donotDisable?: boolean;
347 > };
348 > readonly preRelease?: boolean;
349 > };
350 > readonly settings?: readonly string[];
351 > readonly additionalInfo?: string;
352 > }
353 >
354 > export interface ISearchPrefferedResults {
355 > readonly query?: string;
356 > readonly preferredResults?: string[];
357 > }
358 >
359 > export type MaliciousExtensionInfo = {
360 > readonly extensionOrPublisher: IExtensionIdentifier | string;
361 > readonly learnMoreLink?: string;
362 > };
363 >
364 > export interface IExtensionsControlManifest {
365 > readonly malicious: ReadonlyArray<MaliciousExtensionInfo>;
366 > readonly deprecated: IStringDictionary<IDeprecationInfo>;
367 > readonly search: ISearchPrefferedResults[];
368 > readonly autoUpdate?: IStringDictionary<string>;
369 > }
370 >
371 > export const enum InstallOperation {
372 > None = 1,
373 > Install,
374 > Update,
375 > Migrate,
376 > }
377 >
378 > export interface ITranslation {
379 > contents: { [key: string]: {} };
380 > }
381 >
382 > export interface IExtensionInfo extends IExtensionIdentifier {
383 > version?: string;
384 > preRelease?: boolean;
385 > hasPreRelease?: boolean;
386 > currentVersion?: string;
387 > }
388 >
389 > export interface IExtensionQueryOptions {
390 > targetPlatform?: TargetPlatform;
391 > productVersion?: IProductVersion;
392 > compatible?: boolean;
393 > queryAllVersions?: boolean;
394 > source?: string;
395 > }
396 >
397 > export interface IExtensionGalleryCapabilities {
398 > readonly query: {
399 > readonly sortBy: readonly SortBy[];
400 > readonly filters: readonly FilterType[];
401 > };
402 > readonly allRepositorySigned: boolean;
403 > }
404 >
405 > export const IExtensionGalleryService = createDecorator<IExtensionGalleryService>('extensionGalleryService');
406 >
407 > /**
408 > * Service to interact with the Visual Studio Code Marketplace to get extensions.
409 > * @throws Error if the Marketplace is not enabled or not reachable.
410 > */
411 > export interface IExtensionGalleryService {
412 > readonly _serviceBrand: undefined;
413 > isEnabled(): boolean;
414 > query(options: IQueryOptions, token: CancellationToken): Promise<IPager<IGalleryExtension>>;
415 > getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, token: CancellationToken): Promise<IGalleryExtension[]>;
416 > getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, options: IExtensionQueryOptions, token: CancellationToken): Promise<IGalleryExtension[]>;
417 > isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<boolean>;
418 > getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<IGalleryExtension | null>;
419 > getAllCompatibleVersions(extensionIdentifier: IExtensionIdentifier, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtensionVersion[]>;
420 > getAllVersions(extensionIdentifier: IExtensionIdentifier): Promise<IGalleryExtensionVersion[]>;
421 > download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise<void>;
422 > downloadSignatureArchive(extension: IGalleryExtension, location: URI): Promise<void>;
423 > reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise<void>;
424 > getReadme(extension: IGalleryExtension, token: CancellationToken): Promise<string>;
425 > getManifest(extension: IGalleryExtension, token: CancellationToken): Promise<IExtensionManifest | null>;
426 > getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise<string>;
427 > getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise<ITranslation | null>;
428 > getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;
429 > }
430 >
431 > export interface InstallExtensionEvent {
432 > readonly identifier: IExtensionIdentifier;
433 > readonly source: URI | IGalleryExtension;
434 > readonly profileLocation: URI;
435 > readonly applicationScoped?: boolean;
436 > readonly workspaceScoped?: boolean;
437 > }
438 >
439 > export interface InstallExtensionResult {
440 > readonly identifier: IExtensionIdentifier;
441 > readonly operation: InstallOperation;
442 > readonly source?: URI | IGalleryExtension;
443 > readonly local?: ILocalExtension;
444 > readonly error?: Error;
445 > readonly context?: IStringDictionary<unknown>;
446 > readonly profileLocation: URI;
447 > readonly applicationScoped?: boolean;
448 > readonly workspaceScoped?: boolean;
449 > }
450 >
451 > export interface UninstallExtensionEvent {
452 > readonly identifier: IExtensionIdentifier;
453 > readonly profileLocation: URI;
454 > readonly applicationScoped?: boolean;
455 > readonly workspaceScoped?: boolean;
456 > }
457 >
458 > export interface DidUninstallExtensionEvent {
459 > readonly identifier: IExtensionIdentifier;
460 > readonly error?: string;
461 > readonly profileLocation: URI;
462 > readonly applicationScoped?: boolean;
463 > readonly workspaceScoped?: boolean;
464 > }
465 >
466 > export interface DidUpdateExtensionMetadata {
467 > readonly profileLocation: URI;
468 > readonly local: ILocalExtension;
469 > }
470 >
471 > export const enum ExtensionGalleryErrorCode {
472 > Timeout = 'Timeout',
473 > Cancelled = 'Cancelled',
474 > ClientError = 'ClientError',
475 > ServerError = 'ServerError',
476 > Failed = 'Failed',
477 > DownloadFailedWriting = 'DownloadFailedWriting',
478 > Offline = 'Offline',
479 > }
480 >
481 > export class ExtensionGalleryError extends Error {
482 > constructor(message: string, readonly code: ExtensionGalleryErrorCode) {
483 super(message);
484 this.name = code;
485 }
487 >
488 > export const enum ExtensionManagementErrorCode {
489 > NotFound = 'NotFound',
490 > Unsupported = 'Unsupported',
491 > Deprecated = 'Deprecated',
492 > Malicious = 'Malicious',
493 > Incompatible = 'Incompatible',
494 > IncompatibleApi = 'IncompatibleApi',
495 > IncompatibleTargetPlatform = 'IncompatibleTargetPlatform',
496 > ReleaseVersionNotFound = 'ReleaseVersionNotFound',
497 > Invalid = 'Invalid',
498 > Download = 'Download',
499 > DownloadSignature = 'DownloadSignature',
500 > DownloadFailedWriting = ExtensionGalleryErrorCode.DownloadFailedWriting,
501 > UpdateMetadata = 'UpdateMetadata',
502 > Extract = 'Extract',
503 > Scanning = 'Scanning',
504 > ScanningExtension = 'ScanningExtension',
505 > ReadRemoved = 'ReadRemoved',
506 > UnsetRemoved = 'UnsetRemoved',
507 > Delete = 'Delete',
508 > Rename = 'Rename',
509 > IntializeDefaultProfile = 'IntializeDefaultProfile',
510 > AddToProfile = 'AddToProfile',
511 > InstalledExtensionNotFound = 'InstalledExtensionNotFound',
512 > PostInstall = 'PostInstall',
513 > CorruptZip = 'CorruptZip',
514 > IncompleteZip = 'IncompleteZip',
515 > PackageNotSigned = 'PackageNotSigned',
516 > SignatureVerificationInternal = 'SignatureVerificationInternal',
517 > SignatureVerificationFailed = 'SignatureVerificationFailed',
518 > NotAllowed = 'NotAllowed',
519 > Gallery = 'Gallery',
520 > Cancelled = 'Cancelled',
521 > Unknown = 'Unknown',
522 > Internal = 'Internal',
523 > }
524 >
525 > export enum ExtensionSignatureVerificationCode {
526 > 'NotSigned' = 'NotSigned',
527 > 'Success' = 'Success',
528 > 'RequiredArgumentMissing' = 'RequiredArgumentMissing', // A required argument is missing.
529 > 'InvalidArgument' = 'InvalidArgument', // An argument is invalid.
530 > 'PackageIsUnreadable' = 'PackageIsUnreadable', // The extension package is unreadable.
531 > 'UnhandledException' = 'UnhandledException', // An unhandled exception occurred.
532 > 'SignatureManifestIsMissing' = 'SignatureManifestIsMissing', // The extension is missing a signature manifest file (.signature.manifest).
533 > 'SignatureManifestIsUnreadable' = 'SignatureManifestIsUnreadable', // The signature manifest is unreadable.
534 > 'SignatureIsMissing' = 'SignatureIsMissing', // The extension is missing a signature file (.signature.p7s).
535 > 'SignatureIsUnreadable' = 'SignatureIsUnreadable', // The signature is unreadable.
536 > 'CertificateIsUnreadable' = 'CertificateIsUnreadable', // The certificate is unreadable.
537 > 'SignatureArchiveIsUnreadable' = 'SignatureArchiveIsUnreadable',
538 > 'FileAlreadyExists' = 'FileAlreadyExists', // The output file already exists.
539 > 'SignatureArchiveIsInvalidZip' = 'SignatureArchiveIsInvalidZip',
540 > 'SignatureArchiveHasSameSignatureFile' = 'SignatureArchiveHasSameSignatureFile', // The signature archive has the same signature file.
541 > 'PackageIntegrityCheckFailed' = 'PackageIntegrityCheckFailed', // The package integrity check failed.
542 > 'SignatureIsInvalid' = 'SignatureIsInvalid', // The extension has an invalid signature file (.signature.p7s).
543 > 'SignatureManifestIsInvalid' = 'SignatureManifestIsInvalid', // The extension has an invalid signature manifest file (.signature.manifest).
544 > 'SignatureIntegrityCheckFailed' = 'SignatureIntegrityCheckFailed', // The extension's signature integrity check failed. Extension integrity is suspect.
545 > 'EntryIsMissing' = 'EntryIsMissing', // An entry referenced in the signature manifest was not found in the extension.
546 > 'EntryIsTampered' = 'EntryIsTampered', // The integrity check for an entry referenced in the signature manifest failed.
547 > 'Untrusted' = 'Untrusted', // An X.509 certificate in the extension signature is untrusted.
548 > 'CertificateRevoked' = 'CertificateRevoked', // An X.509 certificate in the extension signature has been revoked.
549 > 'SignatureIsNotValid' = 'SignatureIsNotValid', // The extension signature is invalid.
550 > 'UnknownError' = 'UnknownError', // An unknown error occurred.
551 > 'PackageIsInvalidZip' = 'PackageIsInvalidZip', // The extension package is not valid ZIP format.
552 > 'SignatureArchiveHasTooManyEntries' = 'SignatureArchiveHasTooManyEntries', // The signature archive has too many entries.
553 > }
554 >
555 > export class ExtensionManagementError extends Error {
556 > constructor(message: string, readonly code: ExtensionManagementErrorCode) {
557 super(message);
558 this.name = code;
559 }
561 >
562 > export interface InstallExtensionSummary {
563 > failed: {
564 > id: string;
565 > installOptions: InstallOptions;
566 > }[];
567 > }
568 >
569 > export type InstallOptions = {
570 > isBuiltin?: boolean;
571 > isWorkspaceScoped?: boolean;
572 > isMachineScoped?: boolean;
573 > isApplicationScoped?: boolean;
574 > pinned?: boolean;
575 > donotIncludePackAndDependencies?: boolean;
576 > installGivenVersion?: boolean;
577 > preRelease?: boolean;
578 > installPreReleaseVersion?: boolean;
579 > donotVerifySignature?: boolean;
580 > operation?: InstallOperation;
581 > profileLocation?: URI;
582 > productVersion?: IProductVersion;
583 > keepExisting?: boolean;
584 > downloadExtensionsLocally?: boolean;
585 > /**
586 > * Context passed through to InstallExtensionResult
587 > */
588 > context?: IStringDictionary<unknown>;
589 > };
590 >
591 > export type UninstallOptions = {
592 > readonly profileLocation?: URI;
593 > readonly donotIncludePack?: boolean;
594 > readonly donotCheckDependents?: boolean;
595 > readonly versionOnly?: boolean;
596 > readonly remove?: boolean;
597 > };
598 >
599 > export interface IExtensionManagementParticipant {
600 > postInstall(local: ILocalExtension, source: URI | IGalleryExtension, options: InstallOptions, token: CancellationToken): Promise<void>;
601 > postUninstall(local: ILocalExtension, options: UninstallOptions, token: CancellationToken): Promise<void>;
602 > }
603 >
604 > export type InstallExtensionInfo = { readonly extension: IGalleryExtension; readonly options: InstallOptions };
605 > export type UninstallExtensionInfo = { readonly extension: ILocalExtension; readonly options?: UninstallOptions };
606 >
607 > export const IExtensionManagementService = createDecorator<IExtensionManagementService>('extensionManagementService');
608 > export interface IExtensionManagementService {
609 > readonly _serviceBrand: undefined;
610 >
611 > readonly preferPreReleases: boolean;
612 >
613 > onInstallExtension: Event<InstallExtensionEvent>;
614 > onDidInstallExtensions: Event<readonly InstallExtensionResult[]>;
615 > onUninstallExtension: Event<UninstallExtensionEvent>;
616 > onDidUninstallExtension: Event<DidUninstallExtensionEvent>;
617 > onDidUpdateExtensionMetadata: Event<DidUpdateExtensionMetadata>;
618 >
619 > zip(extension: ILocalExtension): Promise<URI>;
620 > getManifest(vsix: URI): Promise<IExtensionManifest>;
621 > install(vsix: URI, options?: InstallOptions): Promise<ILocalExtension>;
622 > canInstall(extension: IGalleryExtension): Promise<true | IMarkdownString>;
623 > installFromGallery(extension: IGalleryExtension, options?: InstallOptions): Promise<ILocalExtension>;
624 > installGalleryExtensions(extensions: InstallExtensionInfo[]): Promise<InstallExtensionResult[]>;
625 > installFromLocation(location: URI, profileLocation: URI): Promise<ILocalExtension>;
626 > installExtensionsFromProfile(extensions: IExtensionIdentifier[], fromProfileLocation: URI, toProfileLocation: URI): Promise<ILocalExtension[]>;
627 > uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise<void>;
628 > uninstallExtensions(extensions: UninstallExtensionInfo[]): Promise<void>;
629 > toggleApplicationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise<ILocalExtension>;
630 > getInstalled(type?: ExtensionType, profileLocation?: URI, productVersion?: IProductVersion, language?: string): Promise<ILocalExtension[]>;
631 > getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;
632 > copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise<void>;
633 > updateMetadata(local: ILocalExtension, metadata: Partial<Metadata>, profileLocation: URI): Promise<ILocalExtension>;
634 > resetPinnedStateForAllUserExtensions(pinned: boolean): Promise<void>;
635 >
636 > download(extension: IGalleryExtension, operation: InstallOperation, donotVerifySignature: boolean): Promise<URI>;
637 >
638 > registerParticipant(pariticipant: IExtensionManagementParticipant): void;
639 > getTargetPlatform(): Promise<TargetPlatform>;
640 >
641 > cleanUp(): Promise<void>;
642 > }
643 >
644 > export const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/disabled';
645 > export const ENABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/enabled';
646 > export const IGlobalExtensionEnablementService = createDecorator<IGlobalExtensionEnablementService>('IGlobalExtensionEnablementService');
647 >
648 > export interface IGlobalExtensionEnablementService {
649 > readonly _serviceBrand: undefined;
650 > readonly onDidChangeEnablement: Event<{ readonly extensions: IExtensionIdentifier[]; readonly source?: string }>;
651 >
652 > getDisabledExtensions(): IExtensionIdentifier[];
653 > enableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;
654 > disableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;
655 >
656 > }
657 >
658 > export type IConfigBasedExtensionTip = {
659 > readonly extensionId: string;
660 > readonly extensionName: string;
661 > readonly isExtensionPack: boolean;
662 > readonly configName: string;
663 > readonly important: boolean;
664 > readonly whenNotInstalled?: string[];
665 > };
666 >
667 > export type IExecutableBasedExtensionTip = {
668 > readonly extensionId: string;
669 > readonly extensionName: string;
670 > readonly isExtensionPack: boolean;
671 > readonly exeName: string;
672 > readonly exeFriendlyName: string;
673 > readonly windowsPath?: string;
674 > readonly whenNotInstalled?: string[];
675 > };
676 >
677 > export const IExtensionTipsService = createDecorator<IExtensionTipsService>('IExtensionTipsService');
678 > export interface IExtensionTipsService {
679 > readonly _serviceBrand: undefined;
680 >
681 > getConfigBasedTips(folder: URI): Promise<IConfigBasedExtensionTip[]>;
682 > getImportantExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;
683 > getOtherExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;
684 > }
685 >
686 > export type AllowedExtensionsConfigValueType = IStringDictionary<boolean | string | string[]>;
687 >
688 > export const IAllowedExtensionsService = createDecorator<IAllowedExtensionsService>('IAllowedExtensionsService');
689 > export interface IAllowedExtensionsService {
690 > readonly _serviceBrand: undefined;
691 >
692 > readonly allowedExtensionsConfigValue: AllowedExtensionsConfigValueType | undefined;
693 > readonly onDidChangeAllowedExtensionsConfigValue: Event<void>;
694 >
695 > isAllowed(extension: IGalleryExtension | IExtension): true | IMarkdownString;
696 > isAllowed(extension: { id: string; publisherDisplayName: string | undefined; version?: string; prerelease?: boolean; targetPlatform?: TargetPlatform }): true | IMarkdownString;
697 > }
698 >
699 export async function computeSize(location: URI, fileService: IFileService): Promise<number> {
700 let stat: IFileStat;
713 return stat.size ?? 0;
714 }
716 > export const ExtensionsLocalizedLabel = localize2('extensions', "Extensions");
717 > export const PreferencesLocalizedLabel = localize2('preferences', 'Preferences');
718 > export const AllowedExtensionsConfigKey = 'extensions.allowed';
719 > export const VerifyExtensionSignatureConfigKey = 'extensions.verifySignature';
720 > export const ExtensionRequestsTimeoutConfigKey = 'extensions.requestTimeout';
721 >
722 > Registry.as<IConfigurationRegistry>(Extensions.Configuration)
723 > .registerConfiguration({
724 > id: 'extensions',
725 > order: 30,
726 > title: localize('extensionsConfigurationTitle', "Extensions"),
727 > type: 'object',
728 > properties: {
729 > [AllowedExtensionsConfigKey]: {
730 > // Note: Type is set only to object because to support policies generation during build time, where single type is expected.
731 > type: 'object',
732 > markdownDescription: localize('extensions.allowed', "Specify a list of extensions that are allowed to use. This helps maintain a secure and consistent development environment by restricting the use of unauthorized extensions. For more information on how to configure this setting, please visit the [Configure Allowed Extensions](https://aka.ms/vscode/enterprise/extensions/allowed) section."),
733 > default: '*',
734 > defaultSnippets: [{
735 > body: {},
736 > description: localize('extensions.allowed.none', "No extensions are allowed."),
737 > }, {
738 > body: {
739 > '*': true
740 > },
741 > description: localize('extensions.allowed.all', "All extensions are allowed."),
742 > }],
743 > scope: ConfigurationScope.APPLICATION,
744 > policy: {
745 > name: 'AllowedExtensions',
746 > category: PolicyCategory.Extensions,
747 > minimumVersion: '1.96',
748 > localization: {
749 > description: {
750 > key: 'extensions.allowed.policy',
751 > value: localize('extensions.allowed.policy', "Specify a list of extensions that are allowed to use. This helps maintain a secure and consistent development environment by restricting the use of unauthorized extensions. More information: https://aka.ms/vscode/enterprise/extensions/allowed"),
752 > }
753 > }
754 > },
755 > additionalProperties: false,
756 > patternProperties: {
757 > '([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$': {
758 > anyOf: [
759 > {
760 > type: ['boolean', 'string'],
761 > enum: [true, false, 'stable'],
762 > description: localize('extensions.allow.description', "Allow or disallow the extension."),
763 > enumDescriptions: [
764 > localize('extensions.allowed.enable.desc', "Extension is allowed."),
765 > localize('extensions.allowed.disable.desc', "Extension is not allowed."),
766 > localize('extensions.allowed.disable.stable.desc', "Allow only stable versions of the extension."),
767 > ],
768 > },
769 > {
770 > type: 'array',
771 > items: {
772 > type: 'string',
773 > },
774 > description: localize('extensions.allow.version.description', "Allow or disallow specific versions of the extension. To specifcy a platform specific version, use the format `[email protected]`, e.g. `[email protected]`. Supported platforms are `win32-x64`, `win32-arm64`, `linux-x64`, `linux-arm64`, `linux-armhf`, `alpine-x64`, `alpine-arm64`, `darwin-x64`, `darwin-arm64`"),
775 > },
776 > ]
777 > },
778 > '([a-z0-9A-Z][a-z0-9-A-Z]*)$': {
779 > type: ['boolean', 'string'],
780 > enum: [true, false, 'stable'],
781 > description: localize('extension.publisher.allow.description', "Allow or disallow all extensions from the publisher."),
782 > enumDescriptions: [
783 > localize('extensions.publisher.allowed.enable.desc', "All extensions from the publisher are allowed."),
784 > localize('extensions.publisher.allowed.disable.desc', "All extensions from the publisher are not allowed."),
785 > localize('extensions.publisher.allowed.disable.stable.desc', "Allow only stable versions of the extensions from the publisher."),
786 > ],
787 > },
788 > '\\*': {
789 > type: 'boolean',
790 > enum: [true, false],
791 > description: localize('extensions.allow.all.description', "Allow or disallow all extensions."),
792 > enumDescriptions: [
793 > localize('extensions.allow.all.enable', "Allow all extensions."),
794 > localize('extensions.allow.all.disable', "Disallow all extensions.")
795 > ],
796 > }
797 > }
798 > }
799 > }
800 > });
801 >
802 > export function shouldRequireRepositorySignatureFor(isPrivate: boolean, galleryManifest: IExtensionGalleryManifest | null): boolean {
803 if (isPrivate) {
804 return galleryManifest?.capabilities.signing?.allPrivateRepositorySigned === true;