@storm-stack/core
Version:
A build toolkit and runtime used by Storm Software in TypeScript applications
159 lines (154 loc) • 5.35 kB
JavaScript
'use strict';
var chunkSFV4P2MX_cjs = require('./chunk-SFV4P2MX.cjs');
var chunk3ONWID2V_cjs = require('./chunk-3ONWID2V.cjs');
var types = require('@storm-software/config-tools/types');
var camelCase = require('@stryke/string-format/camel-case');
var kebabCase = require('@stryke/string-format/kebab-case');
var titleCase = require('@stryke/string-format/title-case');
var defu = require('defu');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var defu__default = /*#__PURE__*/_interopDefault(defu);
var Plugin = class {
static {
chunk3ONWID2V_cjs.__name(this, "Plugin");
}
#log;
#primaryKeyFields = [];
/**
* A list of plugin modules required as dependencies by the current Plugin.
*
* @remarks
* These plugins will be called prior to the current Plugin.
*/
dependencies = [];
/**
* The configuration options for the plugin
*
* @remarks
* This is used to store the configuration options for the plugin, which can be accessed by the plugin's methods.
*/
options;
/**
* A list of dependencies that are required for the plugin to work. These dependencies will be installed when Storm Stack CLI is run.
*/
packageDeps = {};
/**
* A property to override the plugin's {@link name} field.
*
* @remarks
* This is useful for plugins that need to have a different name than the default one derived from the class name.
*/
get overrideName() {
return void 0;
}
/**
* The name of the plugin
*
* @remarks
* This is used to identify the plugin's name used in {@link Context.options}, logs, and other output.
*/
get name() {
let name = kebabCase.kebabCase(this.overrideName || this.constructor.name);
if (name.startsWith("plugin-")) {
name = name.replace(/^plugin-/g, "").trim();
}
if (name.endsWith("-plugin")) {
name = name.replace(/-plugin$/g, "").trim();
}
return name;
}
/**
* The primary keys for the plugin's options.
*
* @remarks
* This is used to identify when a two instances of the plugin are the same and can be de-duplicated.
*/
get primaryKeys() {
return this.primaryKeyFields.map((primaryKeyField) => this.options[primaryKeyField]);
}
/**
* Returns true if the plugin is a singleton. Singleton plugins can only be instantiated once (so whenever other plugins specify them as dependencies, they will be de-duplicated).
*
* @remarks
* A plugin is considered a singleton if it has zero primary key option fields defined.
*/
get isSingleton() {
return this.primaryKeyFields.length === 0;
}
/**
* A list of primary keys for the plugin's options.
*
* @remarks
* This is used to identify when a two instances of the plugin are the same and can be de-duplicated.
*/
get primaryKeyFields() {
return this.#primaryKeyFields ?? [];
}
/**
* The identifier for the plugin used in the {@link isSame} method
*
* @remarks
* Child plugins can override this to provide a more or less specific identifier. This is used to identify the plugin's options in {@link Context.options}.
*/
get identifier() {
return camelCase.camelCase(`${this.name}${this.isSingleton ? "" : `-${this.primaryKeys.join("-")}`}`);
}
/**
* The logger function to use
*/
get log() {
if (!this.#log) {
this.#log = this.options.log ? chunkSFV4P2MX_cjs.extendLog(this.options.log, `${titleCase.titleCase(this.name)} Plugin`) : chunkSFV4P2MX_cjs.createLog(`${titleCase.titleCase(this.name)} Plugin`);
}
return this.#log;
}
/**
* The constructor for the plugin
*
* @param options - The configuration options for the plugin
*/
constructor(options) {
this.options = options;
}
/**
* Checks if the current plugin is the same as another plugin based on primary key fields.
*
* @param plugin - The plugin to compare with.
* @returns `true` if the plugins are the same, `false` otherwise.
*/
isSame(plugin) {
return this.identifier === plugin.identifier || this.name === plugin.name && this.isSingleton && plugin.isSingleton;
}
/**
* Adds hooks to the engine's hook system.
*
* @param hooks - The hooks to add to the engine.
*/
addHooks(hooks) {
hooks.addHooks({
"init:begin": this.#initBegin.bind(this)
});
}
/**
* Initializes the plugin's context with required installations.
*
* @param context - The context to initialize.
*/
async #initBegin(context) {
this.log(types.LogLevelLabel.TRACE, `Adding required installations for the project.`);
this.options = defu__default.default(this.options, context.options.plugins[this.identifier] ?? {});
if (Object.keys(this.packageDeps).length > 0) {
Object.keys(this.packageDeps).forEach((dependency) => {
if (this.packageDeps[dependency] && (this.packageDeps[dependency] === "devDependency" || context.options.projectType === "application")) {
if (dependency.lastIndexOf("@") > 0 && dependency.substring(0, dependency.lastIndexOf("@")) in context.packageDeps) {
delete context.packageDeps[dependency.substring(0, dependency.lastIndexOf("@"))];
}
context.packageDeps[dependency] = this.packageDeps[dependency];
}
});
}
}
};
exports.Plugin = Plugin;
//# sourceMappingURL=chunk-IVUZGPD7.cjs.map
//# sourceMappingURL=chunk-IVUZGPD7.cjs.map