webpack-build-notifier
Version:
A Webpack plugin that generates OS notifications for build steps using node-notifier.
247 lines (245 loc) • 9.89 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
default: () => WebpackBuildNotifierPlugin
});
module.exports = __toCommonJS(src_exports);
var import_path = __toESM(require("path"), 1);
var import_process = __toESM(require("process"), 1);
var import_os = __toESM(require("os"), 1);
var import_node_notifier = __toESM(require("node-notifier"), 1);
var import_strip_ansi = __toESM(require("strip-ansi"), 1);
var import_child_process = require("child_process");
var DEFAULT_ICON_PATH = import_path.default.resolve(__dirname, "icons");
var WebpackBuildNotifierPlugin = class {
constructor(cfg) {
this.appName = void 0;
this.buildSuccessful = false;
this.hasRun = false;
// config options
this.title = "Webpack Build";
this.sound = "Submarine";
this.suppressSuccess = false;
this.suppressWarning = false;
this.suppressCompileStart = true;
this.activateTerminalOnError = false;
this.showDuration = false;
this.successIcon = import_path.default.join(DEFAULT_ICON_PATH, "success.png");
this.warningIcon = import_path.default.join(DEFAULT_ICON_PATH, "warning.png");
this.failureIcon = import_path.default.join(DEFAULT_ICON_PATH, "failure.png");
this.compileIcon = import_path.default.join(DEFAULT_ICON_PATH, "compile.png");
this.onClick = () => this.activateTerminalWindow;
// eslint-disable-next-line class-methods-use-this
this.activateTerminalWindow = () => {
if (import_process.default.platform === "darwin") {
(0, import_child_process.exec)(
'TERM="$TERM_PROGRAM"; [[ "$TERM" == "Apple_Terminal" ]] && TERM="Terminal"; [[ "$TERM" == "vscode" ]] && TERM="Visual Studio Code"; osascript -e "tell application \\"$TERM\\" to activate"'
);
} else if (import_process.default.platform === "win32") {
}
};
// formats the error/warning message
this.formatMessage = (error, filepath, status, errorCount) => {
let message;
if (this.messageFormatter) {
message = this.messageFormatter(error, filepath, status, errorCount);
} else {
message = error.message || error.details;
if (message && error.module && error.module.resource) {
message = `${filepath}${import_os.default.EOL}${message.replace(
error.module.resource,
""
)}`;
}
}
if (message === void 0) {
return "Unknown";
}
if (typeof message === "string") {
return message.substr(0, 256);
}
throw new Error(`Invalid message type '${typeof message}'; messageFormatter must return a string.`);
};
this.onCompilationDone = (results) => {
var _a, _b, _c;
let notify = false;
let title = `${this.title} - `;
let msg = (_b = (_a = this.formatSuccess) == null ? void 0 : _a.call(this)) != null ? _b : "Build successful!";
let icon = this.successIcon;
let sound = this.successSound;
let compilationStatus = "success" /* SUCCESS */;
if (this.getWarningOrErrorCount(results.compilation, "errors") >= 1) {
const error = this.getFirstWarningOrError(results.compilation, "errors");
const errorFilePath = error.module && error.module.resource ? error.module.resource : "";
notify = true;
compilationStatus = "error" /* ERROR */;
title += "Error";
msg = this.formatMessage(
error,
errorFilePath,
compilationStatus,
this.getWarningOrErrorCount(results.compilation, "errors")
);
icon = this.failureIcon;
sound = this.failureSound;
this.buildSuccessful = false;
} else if (!this.suppressWarning && this.getWarningOrErrorCount(results.compilation, "warnings") >= 1) {
const warning = this.getFirstWarningOrError(
results.compilation,
"warnings"
);
const warningFilePath = warning.module && warning.module.resource ? warning.module.resource : "";
notify = true;
compilationStatus = "warning" /* WARNING */;
title += "Warning";
msg = this.formatMessage(
warning,
warningFilePath,
compilationStatus,
this.getWarningOrErrorCount(results.compilation, "warnings")
);
icon = this.warningIcon;
sound = this.warningSound;
this.buildSuccessful = false;
} else {
title += "Success";
if (this.showDuration) {
msg += ` [${results.endTime - results.startTime} ms]`;
}
if (this.suppressSuccess === "always" || this.suppressSuccess === "initial" && !this.hasRun) {
notify = false;
} else if (this.suppressSuccess === false || !this.buildSuccessful) {
notify = true;
}
this.buildSuccessful = true;
}
const notifyOptions = (_c = typeof this.notifyOptions === "function" ? this.notifyOptions(compilationStatus) : this.notifyOptions) != null ? _c : {};
if (notify) {
import_node_notifier.default.notify(
Object.assign(notifyOptions, {
title,
sound,
icon,
appName: this.appName,
message: (0, import_strip_ansi.default)(msg),
contentImage: this.logo,
wait: !this.buildSuccessful
})
);
if (this.onComplete) {
this.onComplete(results.compilation, compilationStatus);
}
}
if (this.activateTerminalOnError && !this.buildSuccessful) {
this.activateTerminalWindow();
}
this.hasRun = true;
};
this.onCompilationWatchRun = (compiler, callback) => {
import_node_notifier.default.notify({
appName: this.appName,
title: this.title,
message: "Compilation started...",
contentImage: this.logo,
icon: this.compileIcon,
sound: this.compilationSound
});
if (this.onCompileStart) {
this.onCompileStart(compiler);
}
callback();
};
this.registerSnoreToast = () => {
if (import_process.default.platform === "win32") {
const versionParts = import_os.default.release().split(".");
const winVer = +`${versionParts[0]}.${versionParts[1]}`;
if (winVer >= 6.2) {
const snoreToast = import_path.default.join(
require.resolve("node-notifier"),
"../vendor/snoreToast",
`snoretoast-${import_process.default.arch === "x64" ? "x64" : "x86"}.exe`
);
try {
(0, import_child_process.execFileSync)(snoreToast, [
"-appID",
"Snore.DesktopToasts",
"-install",
"SnoreToast.lnk",
snoreToast,
"Snore.DesktopToasts"
]);
this.appName = "Snore.DesktopToasts";
} catch (e) {
console.error(
"An error occurred while attempting to install the SnoreToast AppID!",
e
);
}
}
}
};
// eslint-disable-next-line class-methods-use-this
this.getFirstWarningOrError = (compilation, type) => {
var _a, _b;
if (type === "warnings")
return (_a = compilation.getWarnings()) == null ? void 0 : _a[0];
return (_b = compilation.getErrors()) == null ? void 0 : _b[0];
};
// eslint-disable-next-line class-methods-use-this
this.getWarningOrErrorCount = (compilation, type) => {
if (type === "warnings")
return compilation.getWarnings().length;
return compilation.getErrors().length;
};
var _a, _b, _c, _d;
Object.assign(this, cfg);
if (this.sound) {
this.successSound = (_a = this.successSound) != null ? _a : this.sound;
this.warningSound = (_b = this.warningSound) != null ? _b : this.sound;
this.failureSound = (_c = this.failureSound) != null ? _c : this.sound;
this.compilationSound = (_d = this.compilationSound) != null ? _d : this.sound;
}
this.registerSnoreToast();
import_node_notifier.default.on("click", this.onClick);
if (this.onTimeout) {
import_node_notifier.default.on("timeout", this.onTimeout);
}
}
apply(compiler) {
if (!this.suppressCompileStart) {
compiler.hooks.watchRun.tapAsync(
"webpack-build-notifier",
this.onCompilationWatchRun
);
}
compiler.hooks.done.tap("webpack-build-notifier", this.onCompilationDone);
}
};
module.exports = module.exports.default;