@codingame/monaco-vscode-extensions-service-override
Version:
VSCode public API plugged on the monaco editor - extensions service-override
121 lines (117 loc) • 6.86 kB
JavaScript
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
import { isNonEmptyArray } from '@codingame/monaco-vscode-api/vscode/vs/base/common/arrays';
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
import { ExtensionIdentifier } from '@codingame/monaco-vscode-api/vscode/vs/platform/extensions/common/extensions';
import { allApiProposals } from '@codingame/monaco-vscode-api/vscode/vs/platform/extensions/common/extensionsApiProposals';
import { SyncDescriptor } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/descriptors';
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
import { IProductService } from '@codingame/monaco-vscode-api/vscode/vs/platform/product/common/productService.service';
import { Registry } from '@codingame/monaco-vscode-api/vscode/vs/platform/registry/common/platform';
import { IWorkbenchEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/environment/common/environmentService.service';
import { Extensions } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/extensionManagement/common/extensionFeatures';
import { MarkdownString } from '@codingame/monaco-vscode-api/vscode/vs/base/common/htmlContent';
let ExtensionsProposedApi = class ExtensionsProposedApi {
constructor(_logService, _environmentService, productService) {
this._logService = _logService;
this._environmentService = _environmentService;
this._envEnabledExtensions = ( new Set(( (_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)))));
this._envEnablesProposedApiForAll =
!_environmentService.isBuilt || (_environmentService.isExtensionDevelopment && productService.quality !== "stable") || (this._envEnabledExtensions.size === 0 && Array.isArray(_environmentService.extensionEnabledProposedApi));
this._productEnabledExtensions = ( new Map());
if (productService.extensionEnabledApiProposals) {
for (const [k, value] of Object.entries(productService.extensionEnabledApiProposals)) {
const key = ExtensionIdentifier.toKey(k);
const proposalNames = value.filter(name => {
if (!allApiProposals[name]) {
_logService.warn(
`Via 'product.json#extensionEnabledApiProposals' extension '${key}' wants API proposal '${name}' but that proposal DOES NOT EXIST. Likely, the proposal has been finalized (check 'vscode.d.ts') or was abandoned.`
);
return false;
}
return true;
});
this._productEnabledExtensions.set(key, proposalNames);
}
}
}
updateEnabledApiProposals(extensions) {
for (const extension of extensions) {
this.doUpdateEnabledApiProposals(extension);
}
}
doUpdateEnabledApiProposals(extension) {
const key = ExtensionIdentifier.toKey(extension.identifier);
if (isNonEmptyArray(extension.enabledApiProposals)) {
extension.enabledApiProposals = extension.enabledApiProposals.filter(name => {
const result = Boolean(allApiProposals[name]);
if (!result) {
this._logService.error(
`Extension '${key}' wants API proposal '${name}' but that proposal DOES NOT EXIST. Likely, the proposal has been finalized (check 'vscode.d.ts') or was abandoned.`
);
}
return result;
});
}
if (( this._productEnabledExtensions.has(key))) {
const productEnabledProposals = this._productEnabledExtensions.get(key);
const productSet = ( new Set(productEnabledProposals));
const extensionSet = ( new Set(extension.enabledApiProposals));
const diff = ( new Set([...extensionSet].filter(a => !( productSet.has(a)))));
if (diff.size > 0) {
this._logService.error(
`Extension '${key}' appears in product.json but enables LESS API proposals than the extension wants.\npackage.json (LOSES): ${[...extensionSet].join("\n")}\nproduct.json (WINS): ${[...productSet].join("\n")}\nDELTA: ${[...diff].join("\n")}`
);
if (this._environmentService.isExtensionDevelopment) {
this._logService.error(
`Proceeding with EXTRA proposals (${[...diff].join(", ")}) because extension is in development mode. Still, this EXTENSION WILL BE BROKEN unless product.json is updated.`
);
productEnabledProposals.push(...diff);
}
}
extension.enabledApiProposals = productEnabledProposals;
return;
}
if (this._envEnablesProposedApiForAll || ( this._envEnabledExtensions.has(key))) {
return;
}
if (!extension.isBuiltin && isNonEmptyArray(extension.enabledApiProposals)) {
this._logService.error(
`Extension '${extension.identifier.value} CANNOT USE these API proposals '${extension.enabledApiProposals?.join(", ") || "*"}'. You MUST start in extension development mode or use the --enable-proposed-api command line flag`
);
extension.enabledApiProposals = [];
}
}
};
ExtensionsProposedApi = ( __decorate([( __param(0, ILogService)), ( __param(1, IWorkbenchEnvironmentService)), ( __param(2, IProductService))], ExtensionsProposedApi));
class ApiProposalsMarkdowneRenderer extends Disposable {
constructor() {
super(...arguments);
this.type = "markdown";
}
shouldRender(manifest) {
return !!manifest.originalEnabledApiProposals?.length || !!manifest.enabledApiProposals?.length;
}
render(manifest) {
const enabledApiProposals = manifest.originalEnabledApiProposals ?? manifest.enabledApiProposals ?? [];
const data = ( new MarkdownString());
if (enabledApiProposals.length) {
for (const proposal of enabledApiProposals) {
data.appendMarkdown(`- \`${proposal}\`\n`);
}
}
return {
data,
dispose: () => {}
};
}
}
( Registry.as(Extensions.ExtensionFeaturesRegistry)).registerExtensionFeature({
id: "enabledApiProposals",
label: ( localize(16644, "API Proposals")),
access: {
canToggle: false
},
renderer: ( new SyncDescriptor(ApiProposalsMarkdowneRenderer))
});
export { ExtensionsProposedApi };