-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.ts
120 lines (105 loc) · 3.41 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import path from 'path';
import notifier from 'node-notifier';
import util from 'util';
import forkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import type { Issue } from 'fork-ts-checker-webpack-plugin/lib/issue';
import type { Compiler } from 'webpack';
interface Options {
/** Title prefix shown in the notifications. */
title?: string;
/** If set to `true`, warnings will not cause a notification. */
excludeWarnings?: boolean;
/** Trigger a notification every time. Call it "noisy-mode". */
alwaysNotify?: boolean;
/** Do not notify on the first build. This allows you to receive notifications on subsequent incremental builds without being notified on the initial build. */
skipFirstNotification?: boolean;
/** Skip notifications for successful builds. */
skipSuccessful?: boolean;
}
class ForkTsCheckerNotifierWebpackPlugin {
options: Options;
lastBuildSucceeded: boolean;
isFirstBuild: boolean;
titlePrefix: string;
constructor(options?: Options) {
this.options = options ?? {};
this.lastBuildSucceeded = false;
this.isFirstBuild = true;
this.titlePrefix = this.options.title ? this.options.title + ' - ' : '';
}
buildNotification(issues: Issue[]) {
if (this.isFirstBuild) {
this.isFirstBuild = false;
if (this.options.skipFirstNotification) {
return undefined;
}
}
const firstError = issues.find((issue) => issue.severity === 'error');
const firstWarning = issues.find((issue) => issue.severity === 'warning');
if (firstError) {
this.lastBuildSucceeded = false;
return {
title: util.format(
'%s%s',
this.titlePrefix,
'Error in ' + path.basename(firstError.file ?? ''),
),
message: firstError.message,
icon: path.join(__dirname, 'images/error.png'),
};
}
if (firstWarning && !this.options.excludeWarnings) {
this.lastBuildSucceeded = false;
return {
title: util.format(
'%s%s',
this.titlePrefix,
'Warning in ' + path.basename(firstWarning.file ?? ''),
),
message: firstWarning.message,
icon: path.join(__dirname, 'images/warning.png'),
};
}
if (
!this.options.skipSuccessful &&
(!this.lastBuildSucceeded || this.options.alwaysNotify)
) {
this.lastBuildSucceeded = true;
return {
title: util.format('%sType check succeeded', this.titlePrefix),
message: util.format(
'%s%s',
'No type errors!',
firstWarning ? ' See warning(s) in console!' : '',
),
icon: path.join(__dirname, 'images/built.png'),
};
}
}
compilationDone = (issues: Issue[]): Issue[] => {
const notification = this.buildNotification(issues);
if (notification) {
notifier.notify(notification);
}
return issues;
};
apply(compiler: Compiler) {
// webpack 4+
try {
forkTsCheckerWebpackPlugin
.getCompilerHooks(compiler)
.issues.tap(
'fork-ts-checker-notifier-webpack-plugin',
this.compilationDone,
);
} catch (error) {
console.error(`
Something went wrong in accessing the hooks.
Most likely the order of plugins is wrong.\n
Check the documentation for "fork-ts-checker-notifier-webpack-plugin"\n
`);
throw Error(`Error: ${error}`);
}
}
}
export = ForkTsCheckerNotifierWebpackPlugin;