plugins_release_banner.js
/**
* @file plugins/release/banner.js
* @copyright Scott P Meesseman 2024
* @author Scott Meesseman @spmeesseman
*//** */
const WpwPlugin = require("../base");
const { extname } = require("@spmhome/cmn-utils");
const { apply, isObject } = require("@spmhome/type-utils");
/**
* @augments WpwPlugin
*/
class WpwBannerPlugin extends WpwPlugin
{
/**
* @param {WpwPluginOptions} options Plugin options to be applied
*/
constructor(options)
{
super(options);
this.buildOptions = /** @type {WpwBuildOptionsPluginConfig<"banner">} */(this.buildOptions);
}
/**
* @override
* @param {WpwBuild} b
*/
static create = (b) => WpwBannerPlugin.wrap.call(this, b, b.type === "app");
/**
* @override
* @returns {WpwPluginTapOptions<any, void, false> | undefined}
*/
onApply()
{
/** @type {WpwPluginTapOptions<any, void, false>} */
const config =
{
addBannerToEntryAsset:
{
hook: "compilation",
stage: "ADDITIONS",
statsProperty: "banner",
hookCompilation: "processAssets",
// hookCompilation: "afterOptimizeAssets",
callback: this.addBannerToEntryAsset.bind(this)
}
};
return config;
}
/**
* @private
* @param {WebpackCompilationAssets} assets
*/
addBannerToEntryAsset = (assets) =>
{
const dt = new Date(), b = this.build, l = this.hookstart(),
info = (/** @type {WebpackAssetInfo} */ info) => apply({ ...(info || {}) }, { banner: true }),
author = (isObject(b.pkgJson.author) ? b.pkgJson.author.name : b.pkgJson.name);
// const banner = (this.buildOptions.text || "Copyright \x00\xA9 #{COMPANY} #{DATE_STAMP_YEAR}")
const banner = (this.buildOptions.text || "Copyright #{COMPANY} #{DATE_STAMP_YEAR}")
.replace(new RegExp("[#\\$]?\\{(?:DATE_STAMP_)?YEAR\\}", "g"), dt.getFullYear().toString())
.replace(new RegExp("[#\\$]?\\{(?:DATE_STAMP_)?MONTH\\}", "g"), (dt.getMonth() + 1).toString())
.replace(new RegExp("[#\\$]?\\{(?:DATE_STAMP_)?DAY\\}", "g"), (dt.getDay()).toString())
.replace(new RegExp("[#\\$]?{COMPANY\\}", "g"), b.wrapper.settings.project.company || "SPMHome")
.replace(new RegExp("[#\\$]?{AUTHOR\\}", "g"), author);
Object.keys(assets).filter((f) => this.isOutputAsset(f, true) && !this._types_.isMediaExt(extname(f))).forEach((file) =>
{
l.write(` add banner to '${file}'`, 1);
this.compilation.updateAsset(file, (source) => this.addBannerToSource(file, banner, source), info.bind(this));
});
this.hookdone();
};
/**
* @private
* @param {string} file
* @param {string} banner
* @param {WebpackSource} sourceInfo
* @returns {WebpackSource}
*/
addBannerToSource(file, banner, sourceInfo)
{
const { source, map } = sourceInfo.sourceAndMap(),
srcCode = `/* ${banner} */\n` + source.toString().trimStart().replace(/^.*?copyright.+?[\r\n]/i, "");
return (map && this.build.options.devtool?.enabled) ?
new this.build.wp.sources.SourceMapSource(srcCode, file, map, source) :
new this.build.wp.sources.RawSource(srcCode);
}
}
module.exports = WpwBannerPlugin.create;