Path: blob/main/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.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 { IBuiltinExtensionsScannerService, ExtensionType, IExtensionManifest, TargetPlatform, IExtension } from '../../../../platform/extensions/common/extensions.js';6import { isWeb, Language } from '../../../../base/common/platform.js';7import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js';8import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';9import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';10import { getGalleryExtensionId } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js';11import { builtinExtensionsPath, FileAccess } from '../../../../base/common/network.js';12import { URI } from '../../../../base/common/uri.js';13import { IExtensionResourceLoaderService } from '../../../../platform/extensionResourceLoader/common/extensionResourceLoader.js';14import { IProductService } from '../../../../platform/product/common/productService.js';15import { ITranslations, localizeManifest } from '../../../../platform/extensionManagement/common/extensionNls.js';16import { ILogService } from '../../../../platform/log/common/log.js';17import { mainWindow } from '../../../../base/browser/window.js';1819interface IBundledExtension {20extensionPath: string;21packageJSON: IExtensionManifest;22packageNLS?: any;23readmePath?: string;24changelogPath?: string;25}2627export class BuiltinExtensionsScannerService implements IBuiltinExtensionsScannerService {2829declare readonly _serviceBrand: undefined;3031private readonly builtinExtensionsPromises: Promise<IExtension>[] = [];3233private nlsUrl: URI | undefined;3435constructor(36@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,37@IUriIdentityService uriIdentityService: IUriIdentityService,38@IExtensionResourceLoaderService private readonly extensionResourceLoaderService: IExtensionResourceLoaderService,39@IProductService productService: IProductService,40@ILogService private readonly logService: ILogService41) {42if (isWeb) {43const nlsBaseUrl = productService.extensionsGallery?.nlsBaseUrl;44// Only use the nlsBaseUrl if we are using a language other than the default, English.45if (nlsBaseUrl && productService.commit && !Language.isDefaultVariant()) {46this.nlsUrl = URI.joinPath(URI.parse(nlsBaseUrl), productService.commit, productService.version, Language.value());47}4849const builtinExtensionsServiceUrl = FileAccess.asBrowserUri(builtinExtensionsPath);50if (builtinExtensionsServiceUrl) {51let bundledExtensions: IBundledExtension[] = [];5253if (environmentService.isBuilt) {54// Built time configuration (do NOT modify)55bundledExtensions = [/*BUILD->INSERT_BUILTIN_EXTENSIONS*/];56} else {57// Find builtin extensions by checking for DOM58const builtinExtensionsElement = mainWindow.document.getElementById('vscode-workbench-builtin-extensions');59const builtinExtensionsElementAttribute = builtinExtensionsElement ? builtinExtensionsElement.getAttribute('data-settings') : undefined;60if (builtinExtensionsElementAttribute) {61try {62bundledExtensions = JSON.parse(builtinExtensionsElementAttribute);63} catch (error) { /* ignore error*/ }64}65}6667this.builtinExtensionsPromises = bundledExtensions.map(async e => {68const id = getGalleryExtensionId(e.packageJSON.publisher, e.packageJSON.name);69return {70identifier: { id },71location: uriIdentityService.extUri.joinPath(builtinExtensionsServiceUrl, e.extensionPath),72type: ExtensionType.System,73isBuiltin: true,74manifest: e.packageNLS ? await this.localizeManifest(id, e.packageJSON, e.packageNLS) : e.packageJSON,75readmeUrl: e.readmePath ? uriIdentityService.extUri.joinPath(builtinExtensionsServiceUrl, e.readmePath) : undefined,76changelogUrl: e.changelogPath ? uriIdentityService.extUri.joinPath(builtinExtensionsServiceUrl, e.changelogPath) : undefined,77targetPlatform: TargetPlatform.WEB,78validations: [],79isValid: true,80preRelease: false,81};82});83}84}85}8687async scanBuiltinExtensions(): Promise<IExtension[]> {88return [...await Promise.all(this.builtinExtensionsPromises)];89}9091private async localizeManifest(extensionId: string, manifest: IExtensionManifest, fallbackTranslations: ITranslations): Promise<IExtensionManifest> {92if (!this.nlsUrl) {93return localizeManifest(this.logService, manifest, fallbackTranslations);94}95// the `package` endpoint returns the translations in a key-value format similar to the package.nls.json file.96const uri = URI.joinPath(this.nlsUrl, extensionId, 'package');97try {98const res = await this.extensionResourceLoaderService.readExtensionResource(uri);99const json = JSON.parse(res.toString());100return localizeManifest(this.logService, manifest, json, fallbackTranslations);101} catch (e) {102this.logService.error(e);103return localizeManifest(this.logService, manifest, fallbackTranslations);104}105}106}107108registerSingleton(IBuiltinExtensionsScannerService, BuiltinExtensionsScannerService, InstantiationType.Delayed);109110111