• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / brighterscript / #13835

26 Mar 2024 07:42PM UTC coverage: 87.41% (-0.5%) from 87.93%
#13835

push

TwitchBronBron
Bump to node16 so we can use ts-node in unit tests

6199 of 7518 branches covered (82.46%)

Branch coverage included in aggregate %.

8923 of 9782 relevant lines covered (91.22%)

1665.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.77
/src/PluginInterface.ts
1
import type { CompilerPlugin } from './interfaces';
2
import type { Logger } from './Logger';
3
import { LogLevel } from './Logger';
1✔
4

5
/*
6
 * we use `Required` everywhere here because we expect that the methods on plugin objects will
7
 * be optional, and we don't want to deal with `undefined`.
8
 * `extends (...args: any[]) => any` determines whether the thing we're dealing with is a function.
9
 * Returning `never` in the `as` clause of the `[key in object]` step deletes that key from the
10
 * resultant object.
11
 * on the right-hand side of the mapped type we are forced to use a conditional type a second time,
12
 * in order to be able to use the `Parameters` utility type on `Required<T>[K]`. This will always
13
 * be true because of the filtering done by the `[key in object]` clause, but TS requires the duplication.
14
 *
15
 * so put together: we iterate over all of the fields in T, deleting ones which are not (potentially
16
 * optional) functions. For the ones that are, we replace them with their parameters.
17
 *
18
 * this returns the type of an object whose keys are the names of the methods of T and whose values
19
 * are tuples containing the arguments that each method accepts.
20
 */
21
export type PluginEventArgs<T> = {
22
    [K in keyof Required<T> as Required<T>[K] extends (...args: any[]) => any ? K : never]:
23
    Required<T>[K] extends (...args: any[]) => any ? Parameters<Required<T>[K]> : never
24
};
25

26
export default class PluginInterface<T extends CompilerPlugin = CompilerPlugin> {
1✔
27

28
    /**
29
     * @deprecated use the `options` parameter pattern instead
30
     */
31
    constructor(
32
        plugins: CompilerPlugin[],
33
        logger: Logger
34
    );
35
    constructor(
36
        plugins: CompilerPlugin[],
37
        options: {
38
            logger: Logger;
39
            suppressErrors?: boolean;
40
        }
41
    );
42
    constructor(
43
        private plugins: CompilerPlugin[],
1,122✔
44
        options: {
45
            logger: Logger;
46
            suppressErrors?: boolean;
47
        } | Logger
48
    ) {
49
        if (options?.constructor.name === 'Logger') {
1,122!
50
            this.logger = options as unknown as Logger;
×
51
        } else {
52
            this.logger = (options as any)?.logger;
1,122!
53
            this.suppressErrors = (options as any)?.suppressErrors === false ? false : true;
1,122!
54
        }
55
    }
56

57
    private logger: Logger;
58

59
    /**
60
     * Should plugin errors cause the program to fail, or should they be caught and simply logged
61
     */
62
    private suppressErrors: boolean | undefined;
63

64
    /**
65
     * Call `event` on plugins
66
     */
67
    public emit<K extends keyof PluginEventArgs<T> & string>(event: K, ...args: PluginEventArgs<T>[K]) {
68
        for (let plugin of this.plugins) {
14,976✔
69
            if ((plugin as any)[event]) {
15,426✔
70
                try {
3,840✔
71
                    this.logger.time(LogLevel.debug, [plugin.name, event], () => {
3,840✔
72
                        (plugin as any)[event](...args);
3,840✔
73
                    });
74
                } catch (err) {
75
                    this.logger.error(`Error when calling plugin ${plugin.name}.${event}:`, err);
2✔
76
                    if (!this.suppressErrors) {
2!
77
                        throw err;
×
78
                    }
79
                }
80
            }
81
        }
82
    }
83

84
    /**
85
     * Add a plugin to the beginning of the list of plugins
86
     */
87
    public addFirst<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
88
        if (!this.has(plugin)) {
1,101!
89
            this.plugins.unshift(plugin);
1,101✔
90
        }
91
        return plugin;
1,101✔
92
    }
93

94
    /**
95
     * Add a plugin to the end of the list of plugins
96
     */
97
    public add<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
98
        if (!this.has(plugin)) {
51✔
99
            this.plugins.push(plugin);
50✔
100
        }
101
        return plugin;
51✔
102
    }
103

104
    public has(plugin: CompilerPlugin) {
105
        return this.plugins.includes(plugin);
1,157✔
106
    }
107

108
    public remove<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
109
        if (this.has(plugin)) {
2!
110
            this.plugins.splice(this.plugins.indexOf(plugin));
2✔
111
        }
112
        return plugin;
2✔
113
    }
114

115
    /**
116
     * Remove all plugins
117
     */
118
    public clear() {
119
        this.plugins = [];
×
120
    }
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc