UNPKG

@storm-stack/core

Version:

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

321 lines (315 loc) 13.6 kB
'use strict'; var chunkBSS5D7NX_cjs = require('./chunk-BSS5D7NX.cjs'); var chunkUO7WZABO_cjs = require('./chunk-UO7WZABO.cjs'); var chunkU7VT5A6F_cjs = require('./chunk-U7VT5A6F.cjs'); var chunkZQM2CFMT_cjs = require('./chunk-ZQM2CFMT.cjs'); var chunkT5XYNP42_cjs = require('./chunk-T5XYNP42.cjs'); var chunkOVI63CJL_cjs = require('./chunk-OVI63CJL.cjs'); var chunkHWHNTZRT_cjs = require('./chunk-HWHNTZRT.cjs'); var chunkJ7ICWR23_cjs = require('./chunk-J7ICWR23.cjs'); var chunkUTUPUYE6_cjs = require('./chunk-UTUPUYE6.cjs'); var chunk3ONWID2V_cjs = require('./chunk-3ONWID2V.cjs'); var types = require('@storm-software/config-tools/types'); var install = require('@stryke/fs/install'); var packageFns = require('@stryke/fs/package-fns'); var camelCase = require('@stryke/string-format/camel-case'); var isError = require('@stryke/type-checks/is-error'); var isNumber = require('@stryke/type-checks/is-number'); var isSetObject = require('@stryke/type-checks/is-set-object'); var chalk = require('chalk'); var defu = require('defu'); var hookable = require('hookable'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var chalk__default = /*#__PURE__*/_interopDefault(chalk); var defu__default = /*#__PURE__*/_interopDefault(defu); var Engine = class { static { chunk3ONWID2V_cjs.__name(this, "Engine"); } inlineConfig; workspaceConfig; #initialized = false; /** * The engine hooks - these allow the plugins to hook into the engines processing */ #hooks; /** * The plugins provided in the options */ #plugins = []; /** * The options provided to Storm Stack */ // protected options: TOptions; /** * The resolved options provided to Storm Stack */ context; /** * Create a new Storm Stack Engine instance * * @param inlineConfig - The inline configuration for the Storm Stack engine * @param workspaceConfig - The workspace configuration for the Storm Stack engine */ constructor(inlineConfig, workspaceConfig) { this.inlineConfig = inlineConfig; this.workspaceConfig = workspaceConfig; } /** * Initialize the engine */ async init(inlineConfig) { this.#hooks = hookable.createHooks(); this.context = await chunkUTUPUYE6_cjs.createContext(defu__default.default(inlineConfig, this.inlineConfig), this.workspaceConfig); this.context.log(types.LogLevelLabel.TRACE, "Initializing Storm Stack engine"); for (const plugin of this.context.options.userConfig.plugins ?? []) { await this.addPlugin(plugin); } if (this.#plugins.length === 0) { this.context.log(types.LogLevelLabel.WARN, "No Storm Stack plugins or presets were specified in the options. Please ensure this is correct, as it is generally not recommended."); } else { for (const plugin of this.#plugins) { plugin.addHooks(this.#hooks); } } await chunkT5XYNP42_cjs.init(this.context, this.#hooks); this.context.log(types.LogLevelLabel.INFO, "Storm Stack engine has been initialized"); this.#initialized = true; return this.context; } /** * Create a new Storm Stack project * * @remarks * This method will create a new Storm Stack project in the current directory. * * @param inlineConfig - The inline configuration for the new command * @returns A promise that resolves when the project has been created */ async new(inlineConfig = { command: "new" }) { if (!this.#initialized) { await this.init(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "\u{1F195} Creating a new Storm Stack project"); await chunkHWHNTZRT_cjs._new(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack - New command completed"); } /** * Clean any previously prepared artifacts * * @remarks * This method will remove the previous Storm Stack artifacts from the project. * * @param inlineConfig - The inline configuration for the clean command * @returns A promise that resolves when the clean command has completed */ async clean(inlineConfig = { command: "clean" }) { if (!this.#initialized) { await this.init(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "\u{1F9F9} Cleaning the previous Storm Stack artifacts"); await chunkUO7WZABO_cjs.clean(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack - Clean command completed"); } /** * Prepare the Storm Stack project prior to building * * @remarks * This method will create the necessary directories, and write the artifacts files to the project. * * @param inlineConfig - The inline configuration for the prepare command * @returns A promise that resolves when the prepare command has completed */ async prepare(inlineConfig = { command: "prepare" }) { if (!this.#initialized) { await this.init(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "Preparing the Storm Stack project"); await chunkJ7ICWR23_cjs.prepare(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack preparation completed"); } /** * Lint the project * * @param inlineConfig - The inline configuration for the lint command * @returns A promise that resolves when the lint command has completed */ async lint(inlineConfig = { command: "lint" }) { if (!this.#initialized) { await this.init(inlineConfig); } if (this.context.persistedMeta?.checksum !== this.context.meta.checksum) { this.context.log(types.LogLevelLabel.INFO, "The Storm Stack project has been modified since the last time `prepare` was ran. Re-preparing the project."); await this.prepare(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "Linting the Storm Stack project"); await chunkOVI63CJL_cjs.lint(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack linting completed"); } /** * Build the project * * @remarks * This method will build the Storm Stack project, generating the necessary artifacts. * * @param inlineConfig - The inline configuration for the build command * @returns A promise that resolves when the build command has completed */ async build(inlineConfig = { command: "build" }) { if (!this.#initialized) { await this.init(inlineConfig); } const persistedMeta = await chunkUTUPUYE6_cjs.getPersistedMeta(this.context); const checksum = await chunkUTUPUYE6_cjs.getChecksum(this.context.options.projectRoot); if (persistedMeta?.checksum !== checksum) { this.context.log(types.LogLevelLabel.INFO, "The Storm Stack project has been modified since the last time `prepare` was ran. Re-preparing the project."); await this.prepare(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "Building the Storm Stack project"); await chunkBSS5D7NX_cjs.build(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack build completed"); } /** * Generate the documentation for the project * * @param inlineConfig - The inline configuration for the docs command * @returns A promise that resolves when the documentation generation has completed */ async docs(inlineConfig = { command: "docs" }) { if (!this.#initialized) { await this.init(inlineConfig); } if (this.context.persistedMeta?.checksum !== this.context.meta.checksum) { this.context.log(types.LogLevelLabel.INFO, "The Storm Stack project has been modified since the last time `prepare` was ran. Re-preparing the project."); await this.prepare(inlineConfig); } this.context.log(types.LogLevelLabel.INFO, "Generating documentation for the Storm Stack project"); await chunkU7VT5A6F_cjs.docs(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack documentation generation completed"); } /** * Finalization process * * @remarks * This step includes any final processes or clean up required by Storm Stack. It will be run after each Storm Stack command. * * @param inlineConfig - The inline configuration for the Storm Stack engine * @returns A promise that resolves when the finalization process has completed */ async finalize(inlineConfig) { if (!this.#initialized) { await this.init(inlineConfig); } this.context.log(types.LogLevelLabel.TRACE, "Storm Stack finalize execution started"); await chunkZQM2CFMT_cjs.finalize(this.context, this.#hooks); this.context.log(types.LogLevelLabel.TRACE, "Storm Stack finalize execution completed"); } /** * Add a Storm Stack plugin used in the build process * * @param config - The import path of the plugin to add */ async addPlugin(config) { if (config) { const instance = await this.initPlugin(config); if (!instance) { return; } if (instance.dependencies) { for (const dependency of instance.dependencies) { await this.addPlugin(dependency); } } this.context.log(types.LogLevelLabel.DEBUG, `Successfully initialized the ${chalk__default.default.bold.cyanBright(instance.name)} plugin`); this.#plugins.push(instance); } } /** * Initialize a Storm Stack plugin * * @param plugin - The import path of the plugin to add */ async initPlugin(plugin) { const pluginConfig = typeof plugin === "string" ? [ plugin, {} ] : plugin; let installPath = pluginConfig[0]; if (installPath.startsWith("@") && installPath.split("/").filter(Boolean).length > 2) { const splits = installPath.split("/").filter(Boolean); installPath = `${splits[0]}/${splits[1]}`; } const isInstalled = packageFns.isPackageExists(installPath, { paths: [ this.context.options.workspaceConfig.workspaceRoot, this.context.options.projectRoot ] }); if (!isInstalled && this.context.options.skipInstalls !== true) { this.context.log(types.LogLevelLabel.WARN, `The plugin package "${installPath}" is not installed. It will be installed automatically.`); const result = await install.install(installPath, { cwd: this.context.options.projectRoot }); if (isNumber.isNumber(result.exitCode) && result.exitCode > 0) { this.context.log(types.LogLevelLabel.ERROR, result.stderr); throw new Error(`An error occurred while installing the build plugin package "${installPath}" `); } } let pluginInstance; try { const module = await this.context.resolver.import(this.context.resolver.esmResolve(pluginConfig[0])); const PluginConstructor = module.default; pluginInstance = new PluginConstructor({ ...pluginConfig[1] ?? {}, log: this.context.log }); } catch (error) { if (!isInstalled) { throw new Error(`The plugin package "${pluginConfig[0]}" is not installed. Please install the package using the command: "npm install ${pluginConfig[0]} --save-dev"`); } else { throw new Error(`An error occurred while importing the build plugin package "${pluginConfig[0]}": ${isError.isError(error) ? error.message : String(error)} Note: Please ensure the plugin package's default export is a class that extends \`Plugin\` with a constructor that excepts a single arguments of type \`PluginOptions\`.`); } } if (!pluginInstance) { throw new Error(`The plugin package "${pluginConfig[0]}" does not export a valid module.`); } if (!pluginInstance.name) { throw new Error(`The module in the build plugin package "${pluginConfig[0]}" must export a \`name\` string value.`); } if (!pluginInstance.identifier) { throw new Error(`The module in the build plugin package "${pluginConfig[0]}" must export a \`identifier\` string value.`); } if (!pluginInstance.addHooks) { throw new Error(`The module in the build plugin package "${pluginConfig[0]}" must export a \`addHooks\` function value.`); } pluginInstance.options ??= pluginConfig[1] ?? {}; this.context.options.plugins[pluginInstance.identifier] = defu__default.default(pluginInstance.options ?? {}, isSetObject.isSetObject(this.context.options.plugins[pluginInstance.identifier]) ? this.context.options.plugins[pluginInstance.identifier] : {}, camelCase.camelCase(pluginInstance.name) !== camelCase.camelCase(pluginInstance.identifier) && isSetObject.isSetObject(this.context.options.plugins[pluginInstance.name]) ? this.context.options.plugins[pluginInstance.name] : {}); pluginInstance.options = this.context.options.plugins[pluginInstance.identifier]; const duplicatePlugin = this.#plugins.find((plugin2) => plugin2.isSame(pluginInstance)); if (duplicatePlugin) { this.context.log(types.LogLevelLabel.TRACE, `Duplicate ${chalk__default.default.bold.cyanBright(duplicatePlugin.identifier)} plugin dependency detected - Skipping initialization.`); duplicatePlugin.options = defu__default.default(duplicatePlugin.options ?? {}, this.context.options.plugins[pluginInstance.identifier]); this.context.options.plugins[duplicatePlugin.identifier] = duplicatePlugin.options; return null; } this.context.log(types.LogLevelLabel.TRACE, `Initializing the ${chalk__default.default.bold.cyanBright(pluginInstance.name)} plugin...`); return pluginInstance; } }; exports.Engine = Engine; //# sourceMappingURL=chunk-BLQS5HQJ.cjs.map //# sourceMappingURL=chunk-BLQS5HQJ.cjs.map