UNPKG

@storm-stack/core

Version:

A build toolkit and runtime used by Storm Software in TypeScript applications

153 lines (151 loc) 5.08 kB
import { extendLog, createLog } from './chunk-RDCOIWVB.js'; import { __name } from './chunk-43IZMM3W.js'; import { LogLevelLabel } from '@storm-software/config-tools/types'; import { camelCase } from '@stryke/string-format/camel-case'; import { kebabCase } from '@stryke/string-format/kebab-case'; import { titleCase } from '@stryke/string-format/title-case'; import defu from 'defu'; var Plugin = class { static { __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(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(`${this.name}${this.isSingleton ? "" : `-${this.primaryKeys.join("-")}`}`); } /** * The logger function to use */ get log() { if (!this.#log) { this.#log = this.options.log ? extendLog(this.options.log, `${titleCase(this.name)} Plugin`) : createLog(`${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(LogLevelLabel.TRACE, `Adding required installations for the project.`); this.options = defu(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]; } }); } } }; export { Plugin }; //# sourceMappingURL=chunk-CM2TQ3NN.js.map //# sourceMappingURL=chunk-CM2TQ3NN.js.map