@rushstack/heft
Version:
Build all your JavaScript projects the same way: A way that works.
75 lines • 3.83 kB
JavaScript
;
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.HeftPluginHost = void 0;
const tapable_1 = require("tapable");
const node_core_library_1 = require("@rushstack/node-core-library");
class HeftPluginHost {
constructor() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this._pluginAccessRequestHooks = new Map();
this._pluginsApplied = false;
}
async applyPluginsAsync(terminal) {
if (this._pluginsApplied) {
// No need to apply them a second time.
return;
}
terminal.writeVerboseLine('Applying plugins');
await this.applyPluginsInternalAsync();
this._pluginsApplied = true;
}
/**
* Registers a callback used to provide access to a requested plugin via the plugin accessor.
*/
requestAccessToPluginByName(requestorName, pluginToAccessPackage, pluginToAccessName, accessorCallback) {
if (this._pluginsApplied) {
throw new Error(`Requestor ${JSON.stringify(requestorName)} cannot request access to plugin ` +
`${JSON.stringify(pluginToAccessName)} from package ${JSON.stringify(pluginToAccessPackage)} ` +
`after plugins have been applied.`);
}
const pluginHookName = this.getPluginHookName(pluginToAccessPackage, pluginToAccessName);
let pluginAccessRequestHook = this._pluginAccessRequestHooks.get(pluginHookName);
if (!pluginAccessRequestHook) {
pluginAccessRequestHook = new tapable_1.SyncHook(['pluginAccessor']);
this._pluginAccessRequestHooks.set(pluginHookName, pluginAccessRequestHook);
}
if (pluginAccessRequestHook.taps.some((t) => t.name === requestorName)) {
throw new Error(`Plugin ${JSON.stringify(pluginToAccessName)} from ${JSON.stringify(pluginToAccessPackage)} has ` +
`already been accessed by ${JSON.stringify(requestorName)}.`);
}
pluginAccessRequestHook.tap(requestorName, accessorCallback);
}
/**
* Gets the name of the hook that is registered with the plugin access request hook.
*/
getPluginHookName(pluginPackageName, pluginName) {
return `${pluginPackageName};${pluginName}`;
}
/**
* Resolves all plugin requests for the specified plugin. All plugins that requested access to the
* specified plugin will have their callbacks invoked, and will be provided with the accessor for
* the specified plugin.
*/
resolvePluginAccessRequests(plugin, pluginDefinition) {
if (this._pluginsApplied) {
throw new node_core_library_1.InternalError('Cannot resolve plugin access requests after plugins have been applied.');
}
const pluginHookName = this.getPluginHookName(pluginDefinition.pluginPackageName, pluginDefinition.pluginName);
const pluginAccessRequestHook = this._pluginAccessRequestHooks.get(pluginHookName);
if (pluginAccessRequestHook === null || pluginAccessRequestHook === void 0 ? void 0 : pluginAccessRequestHook.isUsed()) {
const accessor = plugin.accessor;
if (accessor) {
pluginAccessRequestHook.call(accessor);
}
else {
throw new Error(`Plugin ${JSON.stringify(pluginDefinition.pluginName)} from package ` +
`${JSON.stringify(pluginDefinition.pluginPackageName)} does not provide an accessor property, ` +
`so it does not provide access to other plugins.`);
}
}
}
}
exports.HeftPluginHost = HeftPluginHost;
//# sourceMappingURL=HeftPluginHost.js.map