Path: blob/main/src/vs/platform/extensionManagement/common/extensionManagement.ts
5251 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 { PolicyCategory } from '../../../base/common/policy.js';12import { URI } from '../../../base/common/uri.js';13import { localize, localize2 } from '../../../nls.js';14import { ConfigurationScope, Extensions, IConfigurationRegistry } from '../../configuration/common/configurationRegistry.js';15import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from '../../extensions/common/extensions.js';16import { FileOperationError, FileOperationResult, IFileService, IFileStat } from '../../files/common/files.js';17import { createDecorator } from '../../instantiation/common/instantiation.js';18import { Registry } from '../../registry/common/platform.js';19import { IExtensionGalleryManifest } from './extensionGalleryManifest.js';2021export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$';22export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN);23export const WEB_EXTENSION_TAG = '__web_extension';24export const EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT = 'skipWalkthrough';25export const EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT = 'skipPublisherTrust';26export const EXTENSION_INSTALL_SOURCE_CONTEXT = 'extensionInstallSource';27export const EXTENSION_INSTALL_DEP_PACK_CONTEXT = 'dependecyOrPackExtensionInstall';28export const EXTENSION_INSTALL_CLIENT_TARGET_PLATFORM_CONTEXT = 'clientTargetPlatform';2930export const enum ExtensionInstallSource {31COMMAND = 'command',32SETTINGS_SYNC = 'settingsSync',33}3435export interface IProductVersion {36readonly version: string;37readonly date?: string;38}3940export function TargetPlatformToString(targetPlatform: TargetPlatform) {41switch (targetPlatform) {42case TargetPlatform.WIN32_X64: return 'Windows 64 bit';43case TargetPlatform.WIN32_ARM64: return 'Windows ARM';4445case TargetPlatform.LINUX_X64: return 'Linux 64 bit';46case TargetPlatform.LINUX_ARM64: return 'Linux ARM 64';47case TargetPlatform.LINUX_ARMHF: return 'Linux ARM';4849case TargetPlatform.ALPINE_X64: return 'Alpine Linux 64 bit';50case TargetPlatform.ALPINE_ARM64: return 'Alpine ARM 64';5152case TargetPlatform.DARWIN_X64: return 'Mac';53case TargetPlatform.DARWIN_ARM64: return 'Mac Silicon';5455case TargetPlatform.WEB: return 'Web';5657case TargetPlatform.UNIVERSAL: return TargetPlatform.UNIVERSAL;58case TargetPlatform.UNKNOWN: return TargetPlatform.UNKNOWN;59case TargetPlatform.UNDEFINED: return TargetPlatform.UNDEFINED;60}61}6263export function toTargetPlatform(targetPlatform: string): TargetPlatform {64switch (targetPlatform) {65case TargetPlatform.WIN32_X64: return TargetPlatform.WIN32_X64;66case TargetPlatform.WIN32_ARM64: return TargetPlatform.WIN32_ARM64;6768case TargetPlatform.LINUX_X64: return TargetPlatform.LINUX_X64;69case TargetPlatform.LINUX_ARM64: return TargetPlatform.LINUX_ARM64;70case TargetPlatform.LINUX_ARMHF: return TargetPlatform.LINUX_ARMHF;7172case TargetPlatform.ALPINE_X64: return TargetPlatform.ALPINE_X64;73case TargetPlatform.ALPINE_ARM64: return TargetPlatform.ALPINE_ARM64;7475case TargetPlatform.DARWIN_X64: return TargetPlatform.DARWIN_X64;76case TargetPlatform.DARWIN_ARM64: return TargetPlatform.DARWIN_ARM64;7778case TargetPlatform.WEB: return TargetPlatform.WEB;7980case TargetPlatform.UNIVERSAL: return TargetPlatform.UNIVERSAL;81default: return TargetPlatform.UNKNOWN;82}83}8485export function getTargetPlatform(platform: Platform | 'alpine', arch: string | undefined): TargetPlatform {86switch (platform) {87case Platform.Windows:88if (arch === 'x64') {89return TargetPlatform.WIN32_X64;90}91if (arch === 'arm64') {92return TargetPlatform.WIN32_ARM64;93}94return TargetPlatform.UNKNOWN;9596case Platform.Linux:97if (arch === 'x64') {98return TargetPlatform.LINUX_X64;99}100if (arch === 'arm64') {101return TargetPlatform.LINUX_ARM64;102}103if (arch === 'arm') {104return TargetPlatform.LINUX_ARMHF;105}106return TargetPlatform.UNKNOWN;107108case 'alpine':109if (arch === 'x64') {110return TargetPlatform.ALPINE_X64;111}112if (arch === 'arm64') {113return TargetPlatform.ALPINE_ARM64;114}115return TargetPlatform.UNKNOWN;116117case Platform.Mac:118if (arch === 'x64') {119return TargetPlatform.DARWIN_X64;120}121if (arch === 'arm64') {122return TargetPlatform.DARWIN_ARM64;123}124return TargetPlatform.UNKNOWN;125126case Platform.Web: return TargetPlatform.WEB;127}128}129130export function isNotWebExtensionInWebTargetPlatform(allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {131// Not a web extension in web target platform132return productTargetPlatform === TargetPlatform.WEB && !allTargetPlatforms.includes(TargetPlatform.WEB);133}134135export function isTargetPlatformCompatible(extensionTargetPlatform: TargetPlatform, allTargetPlatforms: TargetPlatform[], productTargetPlatform: TargetPlatform): boolean {136// Not compatible when extension is not a web extension in web target platform137if (isNotWebExtensionInWebTargetPlatform(allTargetPlatforms, productTargetPlatform)) {138return false;139}140141// Compatible when extension target platform is not defined142if (extensionTargetPlatform === TargetPlatform.UNDEFINED) {143return true;144}145146// Compatible when extension target platform is universal147if (extensionTargetPlatform === TargetPlatform.UNIVERSAL) {148return true;149}150151// Not compatible when extension target platform is unknown152if (extensionTargetPlatform === TargetPlatform.UNKNOWN) {153return false;154}155156// Compatible when extension and product target platforms matches157if (extensionTargetPlatform === productTargetPlatform) {158return true;159}160161return false;162}163164export interface IGalleryExtensionProperties {165dependencies?: string[];166extensionPack?: string[];167engine?: string;168enabledApiProposals?: string[];169localizedLanguages?: string[];170targetPlatform: TargetPlatform;171isPreReleaseVersion: boolean;172executesCode?: boolean;173}174175export interface IGalleryExtensionAsset {176uri: string;177fallbackUri: string;178}179180export interface IGalleryExtensionAssets {181manifest: IGalleryExtensionAsset | null;182readme: IGalleryExtensionAsset | null;183changelog: IGalleryExtensionAsset | null;184license: IGalleryExtensionAsset | null;185repository: IGalleryExtensionAsset | null;186download: IGalleryExtensionAsset;187icon: IGalleryExtensionAsset | null;188signature: IGalleryExtensionAsset | null;189coreTranslations: [string, IGalleryExtensionAsset][];190}191192export function isIExtensionIdentifier(obj: unknown): obj is IExtensionIdentifier {193const thing = obj as IExtensionIdentifier | undefined;194return !!thing195&& typeof thing === 'object'196&& typeof thing.id === 'string'197&& (!thing.uuid || typeof thing.uuid === 'string');198}199200export interface IExtensionIdentifier {201id: string;202uuid?: string;203}204205export interface IGalleryExtensionIdentifier extends IExtensionIdentifier {206uuid: string;207}208209export interface IGalleryExtensionVersion {210version: string;211date: string;212isPreReleaseVersion: boolean;213targetPlatforms: TargetPlatform[];214}215216export interface IGalleryExtension {217type: 'gallery';218name: string;219identifier: IGalleryExtensionIdentifier;220version: string;221displayName: string;222publisherId: string;223publisher: string;224publisherDisplayName: string;225publisherDomain?: { link: string; verified: boolean };226publisherLink?: string;227publisherSponsorLink?: string;228description: string;229installCount: number;230rating: number;231ratingCount: number;232categories: readonly string[];233tags: readonly string[];234releaseDate: number;235lastUpdated: number;236preview: boolean;237private: boolean;238hasPreReleaseVersion: boolean;239hasReleaseVersion: boolean;240isSigned: boolean;241allTargetPlatforms: TargetPlatform[];242assets: IGalleryExtensionAssets;243properties: IGalleryExtensionProperties;244detailsLink?: string;245ratingLink?: string;246supportLink?: string;247telemetryData?: IStringDictionary<unknown>;248queryContext?: IStringDictionary<unknown>;249}250251export type InstallSource = 'gallery' | 'vsix' | 'resource';252253export interface IGalleryMetadata {254id: string;255publisherId: string;256private: boolean;257publisherDisplayName: string;258isPreReleaseVersion: boolean;259targetPlatform?: TargetPlatform;260}261262export type Metadata = Partial<IGalleryMetadata & {263isApplicationScoped: boolean;264isMachineScoped: boolean;265isBuiltin: boolean;266isSystem: boolean;267updated: boolean;268preRelease: boolean;269hasPreReleaseVersion: boolean;270installedTimestamp: number;271pinned: boolean;272source: InstallSource;273size: number;274}>;275276export interface ILocalExtension extends IExtension {277isWorkspaceScoped: boolean;278isMachineScoped: boolean;279isApplicationScoped: boolean;280publisherId: string | null;281installedTimestamp?: number;282isPreReleaseVersion: boolean;283hasPreReleaseVersion: boolean;284private: boolean;285preRelease: boolean;286updated: boolean;287pinned: boolean;288source: InstallSource;289size: number;290}291292export const enum SortBy {293NoneOrRelevance = 'NoneOrRelevance',294LastUpdatedDate = 'LastUpdatedDate',295Title = 'Title',296PublisherName = 'PublisherName',297InstallCount = 'InstallCount',298PublishedDate = 'PublishedDate',299AverageRating = 'AverageRating',300WeightedRating = 'WeightedRating'301}302303export const enum SortOrder {304Default = 0,305Ascending = 1,306Descending = 2307}308309export const enum FilterType {310Category = 'Category',311ExtensionId = 'ExtensionId',312ExtensionName = 'ExtensionName',313ExcludeWithFlags = 'ExcludeWithFlags',314Featured = 'Featured',315SearchText = 'SearchText',316Tag = 'Tag',317Target = 'Target',318}319320export interface IQueryOptions {321text?: string;322exclude?: string[];323pageSize?: number;324sortBy?: SortBy;325sortOrder?: SortOrder;326source?: string;327includePreRelease?: boolean;328productVersion?: IProductVersion;329}330331export const enum StatisticType {332Install = 'install',333Uninstall = 'uninstall'334}335336export interface IDeprecationInfo {337readonly disallowInstall?: boolean;338readonly extension?: {339readonly id: string;340readonly displayName: string;341readonly autoMigrate?: {342readonly storage: boolean;343readonly donotDisable?: boolean;344};345readonly preRelease?: boolean;346};347readonly settings?: readonly string[];348readonly additionalInfo?: string;349}350351export interface ISearchPrefferedResults {352readonly query?: string;353readonly preferredResults?: string[];354}355356export type MaliciousExtensionInfo = {357readonly extensionOrPublisher: IExtensionIdentifier | string;358readonly learnMoreLink?: string;359};360361export interface IExtensionsControlManifest {362readonly malicious: ReadonlyArray<MaliciousExtensionInfo>;363readonly deprecated: IStringDictionary<IDeprecationInfo>;364readonly search: ISearchPrefferedResults[];365readonly autoUpdate?: IStringDictionary<string>;366}367368export const enum InstallOperation {369None = 1,370Install,371Update,372Migrate,373}374375export interface ITranslation {376contents: { [key: string]: {} };377}378379export interface IExtensionInfo extends IExtensionIdentifier {380version?: string;381preRelease?: boolean;382hasPreRelease?: boolean;383}384385export interface IExtensionQueryOptions {386targetPlatform?: TargetPlatform;387productVersion?: IProductVersion;388compatible?: boolean;389queryAllVersions?: boolean;390source?: string;391}392393export interface IExtensionGalleryCapabilities {394readonly query: {395readonly sortBy: readonly SortBy[];396readonly filters: readonly FilterType[];397};398readonly allRepositorySigned: boolean;399}400401export const IExtensionGalleryService = createDecorator<IExtensionGalleryService>('extensionGalleryService');402403/**404* Service to interact with the Visual Studio Code Marketplace to get extensions.405* @throws Error if the Marketplace is not enabled or not reachable.406*/407export interface IExtensionGalleryService {408readonly _serviceBrand: undefined;409isEnabled(): boolean;410query(options: IQueryOptions, token: CancellationToken): Promise<IPager<IGalleryExtension>>;411getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, token: CancellationToken): Promise<IGalleryExtension[]>;412getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, options: IExtensionQueryOptions, token: CancellationToken): Promise<IGalleryExtension[]>;413isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<boolean>;414getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform, productVersion?: IProductVersion): Promise<IGalleryExtension | null>;415getAllCompatibleVersions(extensionIdentifier: IExtensionIdentifier, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtensionVersion[]>;416getAllVersions(extensionIdentifier: IExtensionIdentifier): Promise<IGalleryExtensionVersion[]>;417download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise<void>;418downloadSignatureArchive(extension: IGalleryExtension, location: URI): Promise<void>;419reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise<void>;420getReadme(extension: IGalleryExtension, token: CancellationToken): Promise<string>;421getManifest(extension: IGalleryExtension, token: CancellationToken): Promise<IExtensionManifest | null>;422getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise<string>;423getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise<ITranslation | null>;424getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;425}426427export interface InstallExtensionEvent {428readonly identifier: IExtensionIdentifier;429readonly source: URI | IGalleryExtension;430readonly profileLocation: URI;431readonly applicationScoped?: boolean;432readonly workspaceScoped?: boolean;433}434435export interface InstallExtensionResult {436readonly identifier: IExtensionIdentifier;437readonly operation: InstallOperation;438readonly source?: URI | IGalleryExtension;439readonly local?: ILocalExtension;440readonly error?: Error;441readonly context?: IStringDictionary<unknown>;442readonly profileLocation: URI;443readonly applicationScoped?: boolean;444readonly workspaceScoped?: boolean;445}446447export interface UninstallExtensionEvent {448readonly identifier: IExtensionIdentifier;449readonly profileLocation: URI;450readonly applicationScoped?: boolean;451readonly workspaceScoped?: boolean;452}453454export interface DidUninstallExtensionEvent {455readonly identifier: IExtensionIdentifier;456readonly error?: string;457readonly profileLocation: URI;458readonly applicationScoped?: boolean;459readonly workspaceScoped?: boolean;460}461462export interface DidUpdateExtensionMetadata {463readonly profileLocation: URI;464readonly local: ILocalExtension;465}466467export const enum ExtensionGalleryErrorCode {468Timeout = 'Timeout',469Cancelled = 'Cancelled',470ClientError = 'ClientError',471ServerError = 'ServerError',472Failed = 'Failed',473DownloadFailedWriting = 'DownloadFailedWriting',474Offline = 'Offline',475}476477export class ExtensionGalleryError extends Error {478constructor(message: string, readonly code: ExtensionGalleryErrorCode) {479super(message);480this.name = code;481}482}483484export const enum ExtensionManagementErrorCode {485NotFound = 'NotFound',486Unsupported = 'Unsupported',487Deprecated = 'Deprecated',488Malicious = 'Malicious',489Incompatible = 'Incompatible',490IncompatibleApi = 'IncompatibleApi',491IncompatibleTargetPlatform = 'IncompatibleTargetPlatform',492ReleaseVersionNotFound = 'ReleaseVersionNotFound',493Invalid = 'Invalid',494Download = 'Download',495DownloadSignature = 'DownloadSignature',496DownloadFailedWriting = ExtensionGalleryErrorCode.DownloadFailedWriting,497UpdateMetadata = 'UpdateMetadata',498Extract = 'Extract',499Scanning = 'Scanning',500ScanningExtension = 'ScanningExtension',501ReadRemoved = 'ReadRemoved',502UnsetRemoved = 'UnsetRemoved',503Delete = 'Delete',504Rename = 'Rename',505IntializeDefaultProfile = 'IntializeDefaultProfile',506AddToProfile = 'AddToProfile',507InstalledExtensionNotFound = 'InstalledExtensionNotFound',508PostInstall = 'PostInstall',509CorruptZip = 'CorruptZip',510IncompleteZip = 'IncompleteZip',511PackageNotSigned = 'PackageNotSigned',512SignatureVerificationInternal = 'SignatureVerificationInternal',513SignatureVerificationFailed = 'SignatureVerificationFailed',514NotAllowed = 'NotAllowed',515Gallery = 'Gallery',516Cancelled = 'Cancelled',517Unknown = 'Unknown',518Internal = 'Internal',519}520521export enum ExtensionSignatureVerificationCode {522'NotSigned' = 'NotSigned',523'Success' = 'Success',524'RequiredArgumentMissing' = 'RequiredArgumentMissing', // A required argument is missing.525'InvalidArgument' = 'InvalidArgument', // An argument is invalid.526'PackageIsUnreadable' = 'PackageIsUnreadable', // The extension package is unreadable.527'UnhandledException' = 'UnhandledException', // An unhandled exception occurred.528'SignatureManifestIsMissing' = 'SignatureManifestIsMissing', // The extension is missing a signature manifest file (.signature.manifest).529'SignatureManifestIsUnreadable' = 'SignatureManifestIsUnreadable', // The signature manifest is unreadable.530'SignatureIsMissing' = 'SignatureIsMissing', // The extension is missing a signature file (.signature.p7s).531'SignatureIsUnreadable' = 'SignatureIsUnreadable', // The signature is unreadable.532'CertificateIsUnreadable' = 'CertificateIsUnreadable', // The certificate is unreadable.533'SignatureArchiveIsUnreadable' = 'SignatureArchiveIsUnreadable',534'FileAlreadyExists' = 'FileAlreadyExists', // The output file already exists.535'SignatureArchiveIsInvalidZip' = 'SignatureArchiveIsInvalidZip',536'SignatureArchiveHasSameSignatureFile' = 'SignatureArchiveHasSameSignatureFile', // The signature archive has the same signature file.537'PackageIntegrityCheckFailed' = 'PackageIntegrityCheckFailed', // The package integrity check failed.538'SignatureIsInvalid' = 'SignatureIsInvalid', // The extension has an invalid signature file (.signature.p7s).539'SignatureManifestIsInvalid' = 'SignatureManifestIsInvalid', // The extension has an invalid signature manifest file (.signature.manifest).540'SignatureIntegrityCheckFailed' = 'SignatureIntegrityCheckFailed', // The extension's signature integrity check failed. Extension integrity is suspect.541'EntryIsMissing' = 'EntryIsMissing', // An entry referenced in the signature manifest was not found in the extension.542'EntryIsTampered' = 'EntryIsTampered', // The integrity check for an entry referenced in the signature manifest failed.543'Untrusted' = 'Untrusted', // An X.509 certificate in the extension signature is untrusted.544'CertificateRevoked' = 'CertificateRevoked', // An X.509 certificate in the extension signature has been revoked.545'SignatureIsNotValid' = 'SignatureIsNotValid', // The extension signature is invalid.546'UnknownError' = 'UnknownError', // An unknown error occurred.547'PackageIsInvalidZip' = 'PackageIsInvalidZip', // The extension package is not valid ZIP format.548'SignatureArchiveHasTooManyEntries' = 'SignatureArchiveHasTooManyEntries', // The signature archive has too many entries.549}550551export class ExtensionManagementError extends Error {552constructor(message: string, readonly code: ExtensionManagementErrorCode) {553super(message);554this.name = code;555}556}557558export interface InstallExtensionSummary {559failed: {560id: string;561installOptions: InstallOptions;562}[];563}564565export type InstallOptions = {566isBuiltin?: boolean;567isWorkspaceScoped?: boolean;568isMachineScoped?: boolean;569isApplicationScoped?: boolean;570pinned?: boolean;571donotIncludePackAndDependencies?: boolean;572installGivenVersion?: boolean;573preRelease?: boolean;574installPreReleaseVersion?: boolean;575donotVerifySignature?: boolean;576operation?: InstallOperation;577profileLocation?: URI;578productVersion?: IProductVersion;579keepExisting?: boolean;580downloadExtensionsLocally?: boolean;581/**582* Context passed through to InstallExtensionResult583*/584context?: IStringDictionary<unknown>;585};586587export type UninstallOptions = {588readonly profileLocation?: URI;589readonly donotIncludePack?: boolean;590readonly donotCheckDependents?: boolean;591readonly versionOnly?: boolean;592readonly remove?: boolean;593};594595export interface IExtensionManagementParticipant {596postInstall(local: ILocalExtension, source: URI | IGalleryExtension, options: InstallOptions, token: CancellationToken): Promise<void>;597postUninstall(local: ILocalExtension, options: UninstallOptions, token: CancellationToken): Promise<void>;598}599600export type InstallExtensionInfo = { readonly extension: IGalleryExtension; readonly options: InstallOptions };601export type UninstallExtensionInfo = { readonly extension: ILocalExtension; readonly options?: UninstallOptions };602603export const IExtensionManagementService = createDecorator<IExtensionManagementService>('extensionManagementService');604export interface IExtensionManagementService {605readonly _serviceBrand: undefined;606607readonly preferPreReleases: boolean;608609onInstallExtension: Event<InstallExtensionEvent>;610onDidInstallExtensions: Event<readonly InstallExtensionResult[]>;611onUninstallExtension: Event<UninstallExtensionEvent>;612onDidUninstallExtension: Event<DidUninstallExtensionEvent>;613onDidUpdateExtensionMetadata: Event<DidUpdateExtensionMetadata>;614615zip(extension: ILocalExtension): Promise<URI>;616getManifest(vsix: URI): Promise<IExtensionManifest>;617install(vsix: URI, options?: InstallOptions): Promise<ILocalExtension>;618canInstall(extension: IGalleryExtension): Promise<true | IMarkdownString>;619installFromGallery(extension: IGalleryExtension, options?: InstallOptions): Promise<ILocalExtension>;620installGalleryExtensions(extensions: InstallExtensionInfo[]): Promise<InstallExtensionResult[]>;621installFromLocation(location: URI, profileLocation: URI): Promise<ILocalExtension>;622installExtensionsFromProfile(extensions: IExtensionIdentifier[], fromProfileLocation: URI, toProfileLocation: URI): Promise<ILocalExtension[]>;623uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise<void>;624uninstallExtensions(extensions: UninstallExtensionInfo[]): Promise<void>;625toggleApplicationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise<ILocalExtension>;626getInstalled(type?: ExtensionType, profileLocation?: URI, productVersion?: IProductVersion, language?: string): Promise<ILocalExtension[]>;627getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;628copyExtensions(fromProfileLocation: URI, toProfileLocation: URI): Promise<void>;629updateMetadata(local: ILocalExtension, metadata: Partial<Metadata>, profileLocation: URI): Promise<ILocalExtension>;630resetPinnedStateForAllUserExtensions(pinned: boolean): Promise<void>;631632download(extension: IGalleryExtension, operation: InstallOperation, donotVerifySignature: boolean): Promise<URI>;633634registerParticipant(pariticipant: IExtensionManagementParticipant): void;635getTargetPlatform(): Promise<TargetPlatform>;636637cleanUp(): Promise<void>;638}639640export const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/disabled';641export const ENABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/enabled';642export const IGlobalExtensionEnablementService = createDecorator<IGlobalExtensionEnablementService>('IGlobalExtensionEnablementService');643644export interface IGlobalExtensionEnablementService {645readonly _serviceBrand: undefined;646readonly onDidChangeEnablement: Event<{ readonly extensions: IExtensionIdentifier[]; readonly source?: string }>;647648getDisabledExtensions(): IExtensionIdentifier[];649enableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;650disableExtension(extension: IExtensionIdentifier, source?: string): Promise<boolean>;651652}653654export type IConfigBasedExtensionTip = {655readonly extensionId: string;656readonly extensionName: string;657readonly isExtensionPack: boolean;658readonly configName: string;659readonly important: boolean;660readonly whenNotInstalled?: string[];661};662663export type IExecutableBasedExtensionTip = {664readonly extensionId: string;665readonly extensionName: string;666readonly isExtensionPack: boolean;667readonly exeName: string;668readonly exeFriendlyName: string;669readonly windowsPath?: string;670readonly whenNotInstalled?: string[];671};672673export const IExtensionTipsService = createDecorator<IExtensionTipsService>('IExtensionTipsService');674export interface IExtensionTipsService {675readonly _serviceBrand: undefined;676677getConfigBasedTips(folder: URI): Promise<IConfigBasedExtensionTip[]>;678getImportantExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;679getOtherExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]>;680}681682export type AllowedExtensionsConfigValueType = IStringDictionary<boolean | string | string[]>;683684export const IAllowedExtensionsService = createDecorator<IAllowedExtensionsService>('IAllowedExtensionsService');685export interface IAllowedExtensionsService {686readonly _serviceBrand: undefined;687688readonly allowedExtensionsConfigValue: AllowedExtensionsConfigValueType | undefined;689readonly onDidChangeAllowedExtensionsConfigValue: Event<void>;690691isAllowed(extension: IGalleryExtension | IExtension): true | IMarkdownString;692isAllowed(extension: { id: string; publisherDisplayName: string | undefined; version?: string; prerelease?: boolean; targetPlatform?: TargetPlatform }): true | IMarkdownString;693}694695export async function computeSize(location: URI, fileService: IFileService): Promise<number> {696let stat: IFileStat;697try {698stat = await fileService.resolve(location);699} catch (e) {700if ((<FileOperationError>e).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {701return 0;702}703throw e;704}705if (stat.children) {706const sizes = await Promise.all(stat.children.map(c => computeSize(c.resource, fileService)));707return sizes.reduce((r, s) => r + s, 0);708}709return stat.size ?? 0;710}711712export const ExtensionsLocalizedLabel = localize2('extensions', "Extensions");713export const PreferencesLocalizedLabel = localize2('preferences', 'Preferences');714export const AllowedExtensionsConfigKey = 'extensions.allowed';715export const VerifyExtensionSignatureConfigKey = 'extensions.verifySignature';716export const ExtensionRequestsTimeoutConfigKey = 'extensions.requestTimeout';717718Registry.as<IConfigurationRegistry>(Extensions.Configuration)719.registerConfiguration({720id: 'extensions',721order: 30,722title: localize('extensionsConfigurationTitle', "Extensions"),723type: 'object',724properties: {725[AllowedExtensionsConfigKey]: {726// Note: Type is set only to object because to support policies generation during build time, where single type is expected.727type: 'object',728markdownDescription: 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."),729default: '*',730defaultSnippets: [{731body: {},732description: localize('extensions.allowed.none', "No extensions are allowed."),733}, {734body: {735'*': true736},737description: localize('extensions.allowed.all', "All extensions are allowed."),738}],739scope: ConfigurationScope.APPLICATION,740policy: {741name: 'AllowedExtensions',742category: PolicyCategory.Extensions,743minimumVersion: '1.96',744localization: {745description: {746key: 'extensions.allowed.policy',747value: 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"),748}749}750},751additionalProperties: false,752patternProperties: {753'([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$': {754anyOf: [755{756type: ['boolean', 'string'],757enum: [true, false, 'stable'],758description: localize('extensions.allow.description', "Allow or disallow the extension."),759enumDescriptions: [760localize('extensions.allowed.enable.desc', "Extension is allowed."),761localize('extensions.allowed.disable.desc', "Extension is not allowed."),762localize('extensions.allowed.disable.stable.desc', "Allow only stable versions of the extension."),763],764},765{766type: 'array',767items: {768type: 'string',769},770description: 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`"),771},772]773},774'([a-z0-9A-Z][a-z0-9-A-Z]*)$': {775type: ['boolean', 'string'],776enum: [true, false, 'stable'],777description: localize('extension.publisher.allow.description', "Allow or disallow all extensions from the publisher."),778enumDescriptions: [779localize('extensions.publisher.allowed.enable.desc', "All extensions from the publisher are allowed."),780localize('extensions.publisher.allowed.disable.desc', "All extensions from the publisher are not allowed."),781localize('extensions.publisher.allowed.disable.stable.desc', "Allow only stable versions of the extensions from the publisher."),782],783},784'\\*': {785type: 'boolean',786enum: [true, false],787description: localize('extensions.allow.all.description', "Allow or disallow all extensions."),788enumDescriptions: [789localize('extensions.allow.all.enable', "Allow all extensions."),790localize('extensions.allow.all.disable', "Disallow all extensions.")791],792}793}794}795}796});797798export function shouldRequireRepositorySignatureFor(isPrivate: boolean, galleryManifest: IExtensionGalleryManifest | null): boolean {799if (isPrivate) {800return galleryManifest?.capabilities.signing?.allPrivateRepositorySigned === true;801}802return galleryManifest?.capabilities.signing?.allPublicRepositorySigned === true;803}804805806807