plugins_script_runscripts.js

/**
 * @file plugins/script/runscripts.js
 * @copyright @spmhome @_2025
 * @author Scott Meesseman @spmeesseman
 *//** */

const WpwPlugin = require("../base");
const { apply, cleanPrototype } = require("@spmhome/type-utils");
const { isWpwWebpackCompilationHook, isWpwWebpackCompilerHook } = require("../../utils");


/**
 * @augments WpwPlugin
 */
class WpwRunScriptsPlugin extends WpwPlugin
{
    /**
     * @param {WpwPluginOptions} options Plugin options to be applied
     */
	constructor(options)
	{
		super(options);
        this.buildOptions = /** @type {WpwBuildOptionsPluginConfig<"runscripts">} */(this.buildOptions);
	}


	/**
     * @override
     */
	static create = WpwRunScriptsPlugin.wrap.bind(this);


    /**
     * @override
     * @returns {WpwPluginTapOptions<any, void, boolean> | undefined}
     */
    onApply()
    {
        const o = this.buildOptions,
              async = this.isAsyncHook(o.hook) && o.hookAsync === true,
              execFn = async ? this.runScriptsAsync : this.runScriptsSync;

        const config =
        {   runScripts:
            {   async, hook: o.hook,
                callback: execFn.bind(this),
                statsProperty: o.assets?.tag || this.optionsKey
            }
        };

        if (o.stage)
        {
            apply(config.runScripts, {
                hook: "compilation", hookCompilation: "processAssets", stage: o.stage.toUpperCase()
            });
        }
        else if (isWpwWebpackCompilationHook(o.hookCompilation))
        {
            apply(config.runScripts, { hook: "compilation", hookCompilation: o.hookCompilation });
        }
        else if (isWpwWebpackCompilerHook(o.hook))
        {
            apply(config.runScripts, { hook: o.hook });
            cleanPrototype(o, "hookCompilation", "stage");
        }

        if (config.hookCompilation === "processAssets" && !config.stage)
        {
            throw new Error("compilation hook is 'processAssets' but `stage` is not defined")
        }

        return config;
    }


    /**
     * @private
     * @param {WpwPluginConfigRunScripts} def
	 * @returns {Promise<void>}
     */
    async runScriptsAsync(def)
    {
        this.hookstart();
        try {
            await this.execScriptsAsync(def, "   ");
        }
        catch (e)
        {   this.addMessage({
                exception: e,
                message: "execute runscripts_async failed",
                code: this.MsgCode.ERROR_SCRIPT_FAILED
            }, true);
        }
        finally {
            this.hookdone();
        }
    }


    /**
     * @param {WpwPluginConfigRunScripts} def
     */
    runScriptsSync(def)
    {
        this.hookstart();
        try {
            this.execScriptsSync(def, "   ");
        }
        catch (e)
        {   this.addMessage({
                exception: e,
                message: "execute runscripts_sync failed",
                code: this.MsgCode.ERROR_SCRIPT_FAILED
            }, true);
        }
        finally {
            this.hookdone();
        }
    }
}


module.exports = WpwRunScriptsPlugin.create;