/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as strings from '../../../../vs/base/common/strings'; // import { ILocalization } from '../../../../vs/platform/localizations/common/localizations'; import { URI } from '../../../../vs/base/common/uri'; import { createDecorator } from '../../../../vs/platform/instantiation/common/instantiation'; export const MANIFEST_CACHE_FOLDER = 'CachedExtensions'; export const USER_MANIFEST_CACHE_FILE = 'user'; export const BUILTIN_MANIFEST_CACHE_FILE = 'builtin'; export interface ICommand { command: string; title: string; category?: string; } export interface IConfigurationProperty { description: string; type: string | string[]; default?: any; } export interface IConfiguration { properties: { [key: string]: IConfigurationProperty }; } export interface IDebugger { label?: string; type: string; runtime?: string; } export interface IGrammar { language: string; } export interface IJSONValidation { fileMatch: string | string[]; url: string; } export interface IKeyBinding { command: string; key: string; when?: string; mac?: string; linux?: string; win?: string; } export interface ILanguage { id: string; extensions: string[]; aliases: string[]; } export interface IMenu { command: string; alt?: string; when?: string; group?: string; } export interface ISnippet { language: string; } export interface ITheme { label: string; } export interface IViewContainer { id: string; title: string; } export interface IView { id: string; name: string; } export interface IColor { id: string; description: string; defaults: { light: string; dark: string; highContrast: string }; } export interface IWebviewEditor { readonly viewType: string; readonly priority: string; readonly selector: readonly { readonly filenamePattern?: string; }[]; } export interface ICodeActionContributionAction { readonly kind: string; readonly title: string; readonly description?: string; } export interface ICodeActionContribution { readonly languages: readonly string[]; readonly actions: readonly ICodeActionContributionAction[]; } export interface IAuthenticationContribution { readonly id: string; readonly label: string; } export interface IWalkthroughStep { readonly id: string; readonly title: string; readonly description: string | undefined; readonly media: | { image: string | { dark: string; light: string; hc: string }; altText: string; markdown?: never; } | { markdown: string; image?: never }; readonly completionEvents?: string[]; /** @deprecated use `completionEvents: 'onCommand:...'` */ readonly doneOn?: { command: string }; readonly when?: string; } export interface IWalkthrough { readonly id: string; readonly title: string; readonly description: string; readonly steps: IWalkthroughStep[]; readonly when?: string; } export interface IStartEntry { readonly title: string; readonly description: string; readonly command: string; readonly type?: 'sample-folder' | 'sample-notebook' | string; readonly when?: string; } export interface IExtensionContributions { commands?: ICommand[]; configuration?: IConfiguration | IConfiguration[]; debuggers?: IDebugger[]; grammars?: IGrammar[]; jsonValidation?: IJSONValidation[]; keybindings?: IKeyBinding[]; languages?: ILanguage[]; menus?: { [context: string]: IMenu[] }; snippets?: ISnippet[]; themes?: ITheme[]; iconThemes?: ITheme[]; productIconThemes?: ITheme[]; viewsContainers?: { [location: string]: IViewContainer[] }; views?: { [location: string]: IView[] }; colors?: IColor[]; // localizations?: ILocalization[]; readonly customEditors?: readonly IWebviewEditor[]; readonly codeActions?: readonly ICodeActionContribution[]; authentication?: IAuthenticationContribution[]; walkthroughs?: IWalkthrough[]; startEntries?: IStartEntry[]; } export interface IExtensionCapabilities { readonly virtualWorkspaces?: ExtensionVirtualWorkpaceSupport; readonly untrustedWorkspaces?: ExtensionUntrustedWorkspaceSupport; } export type ExtensionKind = 'ui' | 'workspace' | 'web'; export type LimitedWorkpaceSupportType = 'limited'; export type ExtensionUntrustedWorkpaceSupportType = | boolean | LimitedWorkpaceSupportType; export type ExtensionUntrustedWorkspaceSupport = | { supported: true } | { supported: false; description: string } | { supported: LimitedWorkpaceSupportType; description: string; restrictedConfigurations?: string[]; }; export type ExtensionVirtualWorkpaceSupportType = | boolean | LimitedWorkpaceSupportType; export type ExtensionVirtualWorkpaceSupport = | boolean | { supported: true } | { supported: false | LimitedWorkpaceSupportType; description: string }; export function getWorkpaceSupportTypeMessage( supportType: | ExtensionUntrustedWorkspaceSupport | ExtensionVirtualWorkpaceSupport | undefined ): string | undefined { if (typeof supportType === 'object' && supportType !== null) { if (supportType.supported !== true) { return supportType.description; } } return undefined; } export function isIExtensionIdentifier( thing: any ): thing is IExtensionIdentifier { return ( thing && typeof thing === 'object' && typeof thing.id === 'string' && (!thing.uuid || typeof thing.uuid === 'string') ); } export interface IExtensionIdentifier { id: string; uuid?: string; } export const EXTENSION_CATEGORIES = [ 'Azure', 'Data Science', 'Debuggers', 'Extension Packs', 'Education', 'Formatters', 'Keymaps', 'Language Packs', 'Linters', 'Machine Learning', 'Notebooks', 'Programming Languages', 'SCM Providers', 'Snippets', 'Testing', 'Themes', 'Visualization', 'Other', ]; export interface IExtensionManifest { readonly name: string; readonly displayName?: string; readonly publisher: string; readonly version: string; readonly engines: { readonly vscode: string }; readonly description?: string; readonly main?: string; readonly browser?: string; readonly icon?: string; readonly categories?: string[]; readonly keywords?: string[]; readonly activationEvents?: string[]; readonly extensionDependencies?: string[]; readonly extensionPack?: string[]; readonly extensionKind?: ExtensionKind | ExtensionKind[]; readonly contributes?: IExtensionContributions; readonly repository?: { url: string }; readonly bugs?: { url: string }; readonly enableProposedApi?: boolean; readonly api?: string; readonly scripts?: { [key: string]: string }; readonly capabilities?: IExtensionCapabilities; } export const enum ExtensionType { System, User, } export interface IExtension { readonly type: ExtensionType; readonly isBuiltin: boolean; readonly identifier: IExtensionIdentifier; readonly manifest: IExtensionManifest; readonly location: URI; readonly readmeUrl?: URI; readonly changelogUrl?: URI; } /** * **!Do not construct directly!** * * **!Only static methods because it gets serialized!** * * This represents the "canonical" version for an extension identifier. Extension ids * have to be case-insensitive (due to the marketplace), but we must ensure case * preservation because the extension API is already public at this time. * * For example, given an extension with the publisher `"Hello"` and the name `"World"`, * its canonical extension identifier is `"Hello.World"`. This extension could be * referenced in some other extension's dependencies using the string `"hello.world"`. * * To make matters more complicated, an extension can optionally have an UUID. When two * extensions have the same UUID, they are considered equal even if their identifier is different. */ export class ExtensionIdentifier { public readonly value: string; private readonly _lower: string; constructor(value: string) { this.value = value; this._lower = value.toLowerCase(); } public static equals( a: ExtensionIdentifier | string | null | undefined, b: ExtensionIdentifier | string | null | undefined ) { if (typeof a === 'undefined' || a === null) { return typeof b === 'undefined' || b === null; } if (typeof b === 'undefined' || b === null) { return false; } if (typeof a === 'string' || typeof b === 'string') { // At least one of the arguments is an extension id in string form, // so we have to use the string comparison which ignores case. let aValue = typeof a === 'string' ? a : a.value; let bValue = typeof b === 'string' ? b : b.value; return strings.equalsIgnoreCase(aValue, bValue); } // Now we know both arguments are ExtensionIdentifier return a._lower === b._lower; } /** * Gives the value by which to index (for equality). */ public static toKey(id: ExtensionIdentifier | string): string { if (typeof id === 'string') { return id.toLowerCase(); } return id._lower; } } export interface IExtensionDescription extends IExtensionManifest { readonly identifier: ExtensionIdentifier; readonly uuid?: string; readonly isBuiltin: boolean; readonly isUserBuiltin: boolean; readonly isUnderDevelopment: boolean; readonly extensionLocation: URI; enableProposedApi?: boolean; } // export function isLanguagePackExtension(manifest: IExtensionManifest): boolean { // return manifest.contributes && manifest.contributes.localizations ? manifest.contributes.localizations.length > 0 : false; // } export function isAuthenticaionProviderExtension( manifest: IExtensionManifest ): boolean { return manifest.contributes && manifest.contributes.authentication ? manifest.contributes.authentication.length > 0 : false; } export interface IScannedExtension { readonly identifier: IExtensionIdentifier; readonly location: URI; readonly type: ExtensionType; readonly packageJSON: IExtensionManifest; readonly packageNLS?: any; readonly packageNLSUrl?: URI; readonly readmeUrl?: URI; readonly changelogUrl?: URI; readonly isUnderDevelopment: boolean; } export interface ITranslatedScannedExtension { readonly identifier: IExtensionIdentifier; readonly location: URI; readonly type: ExtensionType; readonly packageJSON: IExtensionManifest; readonly readmeUrl?: URI; readonly changelogUrl?: URI; readonly isUnderDevelopment: boolean; } export const IBuiltinExtensionsScannerService = createDecorator( 'IBuiltinExtensionsScannerService' ); export interface IBuiltinExtensionsScannerService { readonly _serviceBrand: undefined; scanBuiltinExtensions(): Promise; }