Path: blob/main/src/vs/platform/extensionManagement/common/extensionManagement.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CancellationToken } from '../../../base/common/cancellation.js';6import { IStringDictionary } from '../../../base/common/collections.js';7import { Event } from '../../../base/common/event.js';8import { IMarkdownString } from '../../../base/common/htmlContent.js';9import { IPager } from '../../../base/common/paging.js';10import { Platform } from '../../../base/common/platform.js';11import { URI } from '../../../base/common/uri.js';12import { localize, localize2 } from '../../../nls.js';13import { ConfigurationScope, Extensions, IConfigurationRegistry } from '../../configuration/common/configurationRegistry.js';14import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from '../../extensions/common/extensions.js';15import { FileOperationError, FileOperationResult, IFileService, IFileStat } from '../../files/common/files.js';16import { createDecorator } from '../../instantiation/common/instantiation.js';17import { Registry } from '../../registry/common/platform.js';18import { IExtensionGalleryManifest } from './extensionGalleryManifest.js';1920export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$';21export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN);22export const WEB_EXTENSION_TAG = '__web_extension';23export const EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT = 'skipWalkthrough';24export const EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT = 'skipPublisherTrust';25export const EXTENSION_INSTALL_SOURCE_CONTEXT = 'extensionInstallSource';26export const EXTENSION_INSTALL_DEP_PACK_CONTEXT = 'dependecyOrPackExtensionInstall';27export const EXTENSION_INSTALL_CLIENT_TARGET_PLATFORM_CONTEXT = 'clientTargetPlatform';2829export const enum ExtensionInstallSource {30COMMAND = 'command',31SETTINGS_SYNC = 'settingsSync',32}3334export interface IProductVersion {35readonly version: string;36readonly date?: string;37}3839export function TargetPlatformToString(targetPlatform: TargetPlatform) {40switch (targetPlatform) {41case TargetPlatform.WIN32_X64: return 'Windows 64 bit';42case TargetPlatform.WIN32_ARM64: return 'Windows ARM';4344case TargetPlatform.LINUX_X64: return 'Linux 64 bit';45case TargetPlatform.LINUX_ARM64: return 'Linux ARM 64';46case TargetPlatform.LINUX_ARMHF: return 'Linux ARM';4748case TargetPlatform.ALPINE_X64: return 'Alpine Linux 64 bit';49case TargetPlatform.ALPINE_ARM64: return 'Alpine ARM 64';5051case TargetPlatform.DARWIN_X64: return 'Mac';52case TargetPlatform.DARWIN_ARM64: return 'Mac Silicon';5354case TargetPlatform.WEB: return 'Web';5556case TargetPlatform.UNIVERSAL: return TargetPlatform.UNIVERSAL;57case TargetPlatform.UNKNOWN: return TargetPlatform.UNKNOWN;58case TargetPlatform.UNDEFINED: return TargetPlatform.UNDEFINED;59}60}6162export function toTargetPlatform(targetPlatform: string): TargetPlatform {63switch (targetPlatform) {64case TargetPlatform.WIN32_X64: return TargetPlatform.WIN32_X64;65case TargetPlatform.WIN32_ARM64: return TargetPlatform.WIN32_ARM64;6667case TargetPlatform.LINUX_X64: return TargetPlatform.LINUX_X64;68case TargetPlatform.LINUX_ARM64: return TargetPlatform.LINUX_ARM64;69case TargetPlatform.LINUX_ARMHF: return TargetPlatform.LINUX_ARMHF;7071case TargetPlatform.ALPINE_X64: return TargetPlatform.ALPINE_X64;72case TargetPlatform.ALPINE_ARM64: return TargetPlatform.ALPINE_ARM64;7374case TargetPlatform.DARWIN_X64: return TargetPlatform.DARWIN_X64;75case TargetPlatform.DARWIN_ARM64: return TargetPlatform.DARWIN_ARM64;7677case TargetPlatform.WEB: return TargetPlatform.WEB;7879case TargetPlatform.UNIVERSAL: return TargetPlatform.UNIVERSAL;80default: return TargetPlatform.UNKNOWN;81}82}8384export function getTargetPlatform(platform: Platform | 'alpine', arch: string | undefined): TargetPlatform {85switch (platform) {86case Platform.Windows:87if (arch === 'x64') {88return TargetPlatform.WIN32_X64;89}90if (arch === 'arm64') {91return TargetPlatform.WIN32_ARM64;92}93return TargetPlatform.UNKNOWN;9495case Platform.Linux:96if (arch === 'x64') {97return TargetPlatform.LINUX_X64;98}99if (arch === 'arm64') {100return TargetPlatform.LINUX_ARM64;101}102if (arch === 'arm') {103return TargetPlatform.LINUX_ARMHF;104}105return TargetPlatform.UNKNOWN;106107case 'alpine':108if (arch === 'x64') {109return TargetPlatform.ALPINE_X64;110}111if (arch === 'arm64') {112return TargetPlatform.ALPINE_ARM64;113}114return TargetPlatform.UNKNOWN;115116case Platform.Mac:117if (arch === 'x64') {118return TargetPlatform.DARWIN_X64;119}120if (arch === 'arm64') {121return TargetPlatform.DARWIN_ARM64;122}123return TargetPlatform.UNKNOWN;124125case Platform.Web: return TargetPlatform.WEB;126}127}128129export function isNotWebExtensionInWebTargetPlatform(allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {130// Not a web extension in web target platform131return productTargetPlatform === TargetPlatform.WEB && !allTargetPlatforms.includes(TargetPlatform.WEB);132}133134export function isTargetPlatformCompatible(extensionTargetPlatform: TargetPlatform, allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {135// Not compatible when extension is not a web extension in web target platform136if (isNotWebExtensionInWebTargetPlatform(allTargetPlatforms, productTargetPlatform)) {137return false;138}139140// Compatible when extension target platform is not defined141if (extensionTargetPlatform === TargetPlatform.UNDEFINED) {142return true;143}144145// Compatible when extension target platform is universal146if (extensionTargetPlatform === TargetPlatform.UNIVERSAL) {147return true;148}149150// Not compatible when extension target platform is unknown151if (extensionTargetPlatform === TargetPlatform.UNKNOWN) {152return false;153}154155// Compatible when extension and product target platforms matches156if (extensionTargetPlatform === productTargetPlatform) {157return true;158}159160return false;161}162163export interface IGalleryExtensionProperties {164dependencies?: string[];165extensionPack?: string[];166engine?: string;167enabledApiProposals?: string[];168localizedLanguages?: string[];169targetPlatform: TargetPlatform;170isPreReleaseVersion: boolean;171executesCode?: boolean;172}173174export interface IGalleryExtensionAsset {175uri: string;176fallbackUri: string;177}178179export interface IGalleryExtensionAssets {180manifest: IGalleryExtensionAsset | null;181readme: IGalleryExtensionAsset | null;182changelog: IGalleryExtensionAsset | null;183license: IGalleryExtensionAsset | null;184repository: IGalleryExtensionAsset | null;185download: IGalleryExtensionAsset;186icon: IGalleryExtensionAsset | null;187signature: IGalleryExtensionAsset | null;188coreTranslations: [string, IGalleryExtensionAsset][];189}190191export function isIExtensionIdentifier(thing: any): thing is IExtensionIdentifier {192return thing193&& typeof thing === 'object'194&& typeof thing.id === 'string'195&& (!thing.uuid || typeof thing.uuid === 'string');196}197198export interface IExtensionIdentifier {199id: string;200uuid?: string;201}202203export interface IGalleryExtensionIdentifier extends IExtensionIdentifier {204uuid: string;205}206207export interface IGalleryExtensionVersion {208version: string;209date: string;210isPreReleaseVersion: boolean;211targetPlatforms: TargetPlatform[];212}213214export interface IGalleryExtension {215type: 'gallery';216name: string;217identifier: IGalleryExtensionIdentifier;218version: string;219displayName: string;220publisherId: string;221publisher: string;222publisherDisplayName: string;223publisherDomain?: { link: string; verified: boolean };224publisherLink?: string;225publisherSponsorLink?: string;226description: string;227installCount: number;228rating: number;229ratingCount: number;230categories: readonly string[];231tags: readonly string[];232releaseDate: number;233lastUpdated: number;234preview: boolean;235private: boolean;236hasPreReleaseVersion: boolean;237hasReleaseVersion: boolean;238isSigned: boolean;239allTargetPlatforms: TargetPlatform[];240assets: IGalleryExtensionAssets;241properties: IGalleryExtensionProperties;242detailsLink?: string;243ratingLink?: string;244supportLink?: string;245telemetryData?: any;246queryContext?: IStringDictionary<any>;247}248249export type InstallSource = 'gallery' | 'vsix' | 'resource';250251export interface IGalleryMetadata {252id: string;253publisherId: string;254private: boolean;255publisherDisplayName: string;256isPreReleaseVersion: boolean;257targetPlatform?: TargetPlatform;258}259260export type Metadata = Partial<IGalleryMetadata & {261isApplicationScoped: boolean;262isMachineScoped: boolean;263isBuiltin: boolean;264isSystem: boolean;265updated: boolean;266preRelease: boolean;267hasPreReleaseVersion: boolean;268installedTimestamp: number;269pinned: boolean;270source: InstallSource;271size: number;272}>;273274export interface ILocalExtension extends IExtension {275isWorkspaceScoped: boolean;276isMachineScoped: boolean;277isApplicationScoped: boolean;278publisherId: string | null;279installedTimestamp?: number;280isPreReleaseVersion: boolean;281hasPreReleaseVersion: boolean;282private: boolean;283preRelease: boolean;284updated: boolean;285pinned: boolean;286source: InstallSource;287size: number;288}289290export const enum SortBy {291NoneOrRelevance = 'NoneOrRelevance',292LastUpdatedDate = 'LastUpdatedDate',293Title = 'Title',294PublisherName = 'PublisherName',295InstallCount = 'InstallCount',296PublishedDate = 'PublishedDate',297AverageRating = 'AverageRating',298WeightedRating = 'WeightedRating'299}300301export const enum SortOrder {302Default = 0,303Ascending = 1,304Descending = 2305}306307export const enum FilterType {308Category = 'Category',309ExtensionId = 'ExtensionId',310ExtensionName = 'ExtensionName',311ExcludeWithFlags = 'ExcludeWithFlags',312Featured = 'Featured',313SearchText = 'SearchText',314Tag = 'Tag',315Target = 'Target',316}317318export interface IQueryOptions {319text?: string;320exclude?: string[];321pageSize?: number;322sortBy?: SortBy;323sortOrder?: SortOrder;324source?: string;325includePreRelease?: boolean;326productVersion?: IProductVersion;327}328329export const enum StatisticType {330Install = 'install',331Uninstall = 'uninstall'332}333334export interface IDeprecationInfo {335readonly disallowInstall?: boolean;336readonly extension?: {337readonly id: string;338readonly displayName: string;339readonly autoMigrate?: { readonly storage: boolean };340readonly preRelease?: boolean;341};342readonly settings?: readonly string[];343readonly additionalInfo?: string;344}345346export interface ISearchPrefferedResults {347readonly query?: string;348readonly preferredResults?: string[];349}350351export type MaliciousExtensionInfo = {352readonly extensionOrPublisher: IExtensionIdentifier | string;353readonly learnMoreLink?: string;354};355356export interface IExtensionsControlManifest {357readonly malicious: ReadonlyArray<MaliciousExtensionInfo>;358readonly deprecated: IStringDictionary<IDeprecationInfo>;359readonly search: ISearchPrefferedResults[];360readonly autoUpdate?: IStringDictionary<string>;361}362363export const enum InstallOperation {364None = 1,365Install,366Update,367Migrate,368}369370export interface ITranslation {371contents: { [key: string]: {} };372}373374export interface IExtensionInfo extends IExtensionIdentifier {375version?: string;376preRelease?: boolean;377hasPreRelease?: boolean;378}379380export interface IExtensionQueryOptions {381targetPlatform?: TargetPlatform;382productVersion?: IProductVersion;383compatible?: boolean;384queryAllVersions?: boolean;385source?: string;386}387388export interface IExtensionGalleryCapabilities {389readonly query: {390readonly sortBy: readonly SortBy[];391readonly filters: readonly FilterType[];392};393readonly allRepositorySigned: boolean;394}395396export const IExtensionGalleryService = createDecorator<IExtensionGalleryService>('extensionGalleryService');397398/**399* Service to interact with the Visual Studio Code Marketplace to get extensions.400* @throws Error if the Marketplace is not enabled or not reachable.401*/402export interface IExtensionGalleryService {403readonly _serviceBrand: undefined;404isEnabled(): boolean;405query(options: IQueryOptions, token: CancellationToken): Promise<IPager<IGalleryExtension>>;406getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, token: CancellationToken): Promise<IGalleryExtension[]>;407getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, options: IExtensionQueryOptions, token: CancellationToken): Promise<IGalleryExtension[]>;408isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<boolean>;409getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<IGalleryExtension | null>;410getAllCompatibleVersions(extensionIdentifier: IExtensionIdentifier, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtensionVersion[]>;411getAllVersions(extensionIdentifier: IExtensionIdentifier): Promise<IGalleryExtensionVersion[]>;412download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise<void>;413downloadSignatureArchive(extension: IGalleryExtension, location: URI): Promise<void>;414reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise<void>;415getReadme(extension: IGalleryExtension, token: CancellationToken): Promise<string>;416getManifest(extension: IGalleryExtension, token: CancellationToken): Promise<IExtensionManifest | null>;417getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise<string>;418getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise<ITranslation | null>;419getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;420}421422export interface InstallExtensionEvent {423readonly identifier: IExtensionIdentifier;424readonly source: URI | IGalleryExtension;425readonly profileLocation: URI;426readonly applicationScoped?: boolean;427readonly workspaceScoped?: boolean;428}429430export interface InstallExtensionResult {431readonly identifier: IExtensionIdentifier;432readonly operation: InstallOperation;433readonly source?: URI | IGalleryExtension;434readonly local?: ILocalExtension;435readonly error?: Error;436readonly context?: IStringDictionary<any>;437readonly profileLocation: URI;438readonly applicationScoped?: boolean;439readonly workspaceScoped?: boolean;440}441442export interface UninstallExtensionEvent {443readonly identifier: IExtensionIdentifier;444readonly profileLocation: URI;445readonly applicationScoped?: boolean;446readonly workspaceScoped?: boolean;447}448449export interface DidUninstallExtensionEvent {450readonly identifier: IExtensionIdentifier;451readonly error?: string;452readonly profileLocation: URI;453readonly applicationScoped?: boolean;454readonly workspaceScoped?: boolean;455}456457export interface DidUpdateExtensionMetadata {458readonly profileLocation: URI;459readonly local: ILocalExtension;460}461462export const enum ExtensionGalleryErrorCode {463Timeout = 'Timeout',464Cancelled = 'Cancelled',465ClientError = 'ClientError',466ServerError = 'ServerError',467Failed = 'Failed',468DownloadFailedWriting = 'DownloadFailedWriting',469Offline = 'Offline',470}471472export class ExtensionGalleryError extends Error {473constructor(message: string, readonly code: ExtensionGalleryErrorCode) {474super(message);475this.name = code;476}477}478479export const enum ExtensionManagementErrorCode {480NotFound = 'NotFound',481Unsupported = 'Unsupported',482Deprecated = 'Deprecated',483Malicious = 'Malicious',484Incompatible = 'Incompatible',485IncompatibleApi = 'IncompatibleApi',486IncompatibleTargetPlatform = 'IncompatibleTargetPlatform',487ReleaseVersionNotFound = 'ReleaseVersionNotFound',488Invalid = 'Invalid',489Download = 'Download',490DownloadSignature = 'DownloadSignature',491DownloadFailedWriting = ExtensionGalleryErrorCode.DownloadFailedWriting,492UpdateMetadata = 'UpdateMetadata',493Extract = 'Extract',494Scanning = 'Scanning',495ScanningExtension = 'ScanningExtension',496ReadRemoved = 'ReadRemoved',497UnsetRemoved = 'UnsetRemoved',498Delete = 'Delete',499Rename = 'Rename',500IntializeDefaultProfile = 'IntializeDefaultProfile',501AddToProfile = 'AddToProfile',502InstalledExtensionNotFound = 'InstalledExtensionNotFound',503PostInstall = 'PostInstall',504CorruptZip = 'CorruptZip',505IncompleteZip = 'IncompleteZip',506PackageNotSigned = 'PackageNotSigned',507SignatureVerificationInternal = 'SignatureVerificationInternal',508SignatureVerificationFailed = 'SignatureVerificationFailed',509NotAllowed = 'NotAllowed',510Gallery = 'Gallery',511Cancelled = 'Cancelled',512Unknown = 'Unknown',513Internal = 'Internal',514}515516export enum ExtensionSignatureVerificationCode {517'NotSigned' = 'NotSigned',518'Success' = 'Success',519'RequiredArgumentMissing' = 'RequiredArgumentMissing', // A required argument is missing.520'InvalidArgument' = 'InvalidArgument', // An argument is invalid.521'PackageIsUnreadable' = 'PackageIsUnreadable', // The extension package is unreadable.522'UnhandledException' = 'UnhandledException', // An unhandled exception occurred.523'SignatureManifestIsMissing' = 'SignatureManifestIsMissing', // The extension is missing a signature manifest file (.signature.manifest).524'SignatureManifestIsUnreadable' = 'SignatureManifestIsUnreadable', // The signature manifest is unreadable.525'SignatureIsMissing' = 'SignatureIsMissing', // The extension is missing a signature file (.signature.p7s).526'SignatureIsUnreadable' = 'SignatureIsUnreadable', // The signature is unreadable.527'CertificateIsUnreadable' = 'CertificateIsUnreadable', // The certificate is unreadable.528'SignatureArchiveIsUnreadable' = 'SignatureArchiveIsUnreadable',529'FileAlreadyExists' = 'FileAlreadyExists', // The output file already exists.530'SignatureArchiveIsInvalidZip' = 'SignatureArchiveIsInvalidZip',531'SignatureArchiveHasSameSignatureFile' = 'SignatureArchiveHasSameSignatureFile', // The signature archive has the same signature file.532'PackageIntegrityCheckFailed' = 'PackageIntegrityCheckFailed', // The package integrity check failed.533'SignatureIsInvalid' = 'SignatureIsInvalid', // The extension has an invalid signature file (.signature.p7s).534'SignatureManifestIsInvalid' = 'SignatureManifestIsInvalid', // The extension has an invalid signature manifest file (.signature.manifest).535'SignatureIntegrityCheckFailed' = 'SignatureIntegrityCheckFailed', // The extension's signature integrity check failed. Extension integrity is suspect.536'EntryIsMissing' = 'EntryIsMissing', // An entry referenced in the signature manifest was not found in the extension.537'EntryIsTampered' = 'EntryIsTampered', // The integrity check for an entry referenced in the signature manifest failed.538'Untrusted' = 'Untrusted', // An X.509 certificate in the extension signature is untrusted.539'CertificateRevoked' = 'CertificateRevoked', // An X.509 certificate in the extension signature has been revoked.540'SignatureIsNotValid' = 'SignatureIsNotValid', // The extension signature is invalid.541'UnknownError' = 'UnknownError', // An unknown error occurred.542'PackageIsInvalidZip' = 'PackageIsInvalidZip', // The extension package is not valid ZIP format.543'SignatureArchiveHasTooManyEntries' = 'SignatureArchiveHasTooManyEntries', // The signature archive has too many entries.544}545546export class ExtensionManagementError extends Error {547constructor(message: string, readonly code: ExtensionManagementErrorCode) {548super(message);549this.name = code;550}551}552553export interface InstallExtensionSummary {554failed: {555id: string;556installOptions: InstallOptions;557}[];558}559560export type InstallOptions = {561isBuiltin?: boolean;562isWorkspaceScoped?: boolean;563isMachineScoped?: boolean;564isApplicationScoped?: boolean;565pinned?: boolean;566donotIncludePackAndDependencies?: boolean;567installGivenVersion?: boolean;568preRelease?: boolean;569installPreReleaseVersion?: boolean;570donotVerifySignature?: boolean;571operation?: InstallOperation;572profileLocation?: URI;573productVersion?: IProductVersion;574keepExisting?: boolean;575downloadExtensionsLocally?: boolean;576/**577* Context passed through to InstallExtensionResult578*/579context?: IStringDictionary<any>;580};581582export type UninstallOptions = {583readonly profileLocation?: URI;584readonly donotIncludePack?: boolean;585readonly donotCheckDependents?: boolean;586readonly versionOnly?: boolean;587readonly remove?: boolean;588};589590export interface IExtensionManagementParticipant {591postInstall(local: ILocalExtension, source: URI | IGalleryExtension, options: InstallOptions, token: CancellationToken): Promise<void>;592postUninstall(local: ILocalExtension, options: UninstallOptions, token: CancellationToken): Promise<void>;593}594595export type InstallExtensionInfo = { readonly extension: IGalleryExtension; readonly options: InstallOptions };596export type UninstallExtensionInfo = { readonly extension: ILocalExtension; readonly options?: UninstallOptions };597598export const IExtensionManagementService = createDecorator<IExtensionManagementService>('extensionManagementService');599export interface IExtensionManagementService {600readonly _serviceBrand: undefined;601602readonly preferPreReleases: boolean;603604onInstallExtension: Event<InstallExtensionEvent>;605onDidInstallExtensions: Event<readonly InstallExtensionResult[]>;606onUninstallExtension: Event<UninstallExtensionEvent>;607onDidUninstallExtension: Event<DidUninstallExtensionEvent>;608onDidUpdateExtensionMetadata: Event<DidUpdateExtensionMetadata>;609610zip(extension: ILocalExtension): Promise<URI>;611getManifest(vsix: URI): Promise<IExtensionManifest>;612install(vsix: URI, options?: InstallOptions): Promise<ILocalExtension>;613canInstall(extension: IGalleryExtension): Promise<true | IMarkdownString>;614installFromGallery(extension: IGalleryExtension, options?: InstallOptions): Promise<ILocalExtension>;615installGalleryExtensions(extensions: InstallExtensionInfo[]): Promise<InstallExtensionResult[]>;616installFromLocation(location: URI, profileLocation: URI): Promise<ILocalExtension>;617installExtensionsFromProfile(extensions: IExtensionIdentifier[], fromProfileLocation: URI, toProfileLocation: URI): Promise<ILocalExtension[]>;618uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise<void>;619uninstallExtensions(extensions: UninstallExtensionInfo[]): Promise<void>;620toggleApplicationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise<ILocalExtension>;621getInstalled(type?: ExtensionType, profileLocation?: URI, productVersion?: IProductVersion, language?: string): Promise<ILocalExtension[]>;622getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;623copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise<void>;624updateMetadata(local: ILocalExtension, metadata: Partial<Metadata>, profileLocation: URI): Promise<ILocalExtension>;625resetPinnedStateForAllUserExtensions(pinned: boolean): Promise<void>;626627download(extension: IGalleryExtension, operation: InstallOperation, donotVerifySignature: boolean): Promise<URI>;628629registerParticipant(pariticipant: IExtensionManagementParticipant): void;630getTargetPlatform(): Promise<TargetPlatform>;631632cleanUp(): Promise<void>;633}634635export const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/disabled';636export const ENABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/enabled';637export const IGlobalExtensionEnablementService = createDecorator<IGlobalExtensionEnablementService>('IGlobalExtensionEnablementService');638639export interface IGlobalExtensionEnablementService {640readonly _serviceBrand: undefined;641readonly onDidChangeEnablement: Event<{ readonly extensions: IExtensionIdentifier[]; readonly source?: string }>;642643getDisabledExtensions(): IExtensionIdentifier[];644enableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;645disableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;646647}648649export type IConfigBasedExtensionTip = {650readonly extensionId: string;651readonly extensionName: string;652readonly isExtensionPack: boolean;653readonly configName: string;654readonly important: boolean;655readonly whenNotInstalled?: string[];656};657658export type IExecutableBasedExtensionTip = {659readonly extensionId: string;660readonly extensionName: string;661readonly isExtensionPack: boolean;662readonly exeName: string;663readonly exeFriendlyName: string;664readonly windowsPath?: string;665readonly whenNotInstalled?: string[];666};667668export const IExtensionTipsService = createDecorator<IExtensionTipsService>('IExtensionTipsService');669export interface IExtensionTipsService {670readonly _serviceBrand: undefined;671672getConfigBasedTips(folder: URI): Promise<IConfigBasedExtensionTip[]>;673getImportantExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;674getOtherExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;675}676677export type AllowedExtensionsConfigValueType = IStringDictionary<boolean | string | string[]>;678679export const IAllowedExtensionsService = createDecorator<IAllowedExtensionsService>('IAllowedExtensionsService');680export interface IAllowedExtensionsService {681readonly _serviceBrand: undefined;682683readonly allowedExtensionsConfigValue: AllowedExtensionsConfigValueType | undefined;684readonly onDidChangeAllowedExtensionsConfigValue: Event<void>;685686isAllowed(extension: IGalleryExtension | IExtension): true | IMarkdownString;687isAllowed(extension: { id: string; publisherDisplayName: string | undefined; version?: string; prerelease?: boolean; targetPlatform?: TargetPlatform }): true | IMarkdownString;688}689690export async function computeSize(location: URI, fileService: IFileService): Promise<number> {691let stat: IFileStat;692try {693stat = await fileService.resolve(location);694} catch (e) {695if ((<FileOperationError>e).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {696return 0;697}698throw e;699}700if (stat.children) {701const sizes = await Promise.all(stat.children.map(c => computeSize(c.resource, fileService)));702return sizes.reduce((r, s) => r + s, 0);703}704return stat.size ?? 0;705}706707export const ExtensionsLocalizedLabel = localize2('extensions', "Extensions");708export const PreferencesLocalizedLabel = localize2('preferences', 'Preferences');709export const AllowedExtensionsConfigKey = 'extensions.allowed';710export const VerifyExtensionSignatureConfigKey = 'extensions.verifySignature';711712Registry.as<IConfigurationRegistry>(Extensions.Configuration)713.registerConfiguration({714id: 'extensions',715order: 30,716title: localize('extensionsConfigurationTitle', "Extensions"),717type: 'object',718properties: {719[AllowedExtensionsConfigKey]: {720// Note: Type is set only to object because to support policies generation during build time, where single type is expected.721type: 'object',722markdownDescription: 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://code.visualstudio.com/docs/setup/enterprise#_configure-allowed-extensions) section."),723default: '*',724defaultSnippets: [{725body: {},726description: localize('extensions.allowed.none', "No extensions are allowed."),727}, {728body: {729'*': true730},731description: localize('extensions.allowed.all', "All extensions are allowed."),732}],733scope: ConfigurationScope.APPLICATION,734policy: {735name: 'AllowedExtensions',736minimumVersion: '1.96',737description: 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://code.visualstudio.com/docs/setup/enterprise#_configure-allowed-extensions"),738},739additionalProperties: false,740patternProperties: {741'([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$': {742anyOf: [743{744type: ['boolean', 'string'],745enum: [true, false, 'stable'],746description: localize('extensions.allow.description', "Allow or disallow the extension."),747enumDescriptions: [748localize('extensions.allowed.enable.desc', "Extension is allowed."),749localize('extensions.allowed.disable.desc', "Extension is not allowed."),750localize('extensions.allowed.disable.stable.desc', "Allow only stable versions of the extension."),751],752},753{754type: 'array',755items: {756type: 'string',757},758description: 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`"),759},760]761},762'([a-z0-9A-Z][a-z0-9-A-Z]*)$': {763type: ['boolean', 'string'],764enum: [true, false, 'stable'],765description: localize('extension.publisher.allow.description', "Allow or disallow all extensions from the publisher."),766enumDescriptions: [767localize('extensions.publisher.allowed.enable.desc', "All extensions from the publisher are allowed."),768localize('extensions.publisher.allowed.disable.desc', "All extensions from the publisher are not allowed."),769localize('extensions.publisher.allowed.disable.stable.desc', "Allow only stable versions of the extensions from the publisher."),770],771},772'\\*': {773type: 'boolean',774enum: [true, false],775description: localize('extensions.allow.all.description', "Allow or disallow all extensions."),776enumDescriptions: [777localize('extensions.allow.all.enable', "Allow all extensions."),778localize('extensions.allow.all.disable', "Disallow all extensions.")779],780}781}782}783}784});785786export function shouldRequireRepositorySignatureFor(isPrivate: boolean, galleryManifest: IExtensionGalleryManifest | null): boolean {787if (isPrivate) {788return galleryManifest?.capabilities.signing?.allPrivateRepositorySigned === true;789}790return galleryManifest?.capabilities.signing?.allPublicRepositorySigned === true;791}792793794795