UNPKG

2.55 kBJavaScriptView Raw
1const ChainedMap = require('./ChainedMap');
2const ChainedSet = require('./ChainedSet');
3const Orderable = require('./Orderable');
4const Use = require('./Use');
5
6const Rule = Orderable(
7 class extends ChainedMap {
8 constructor(parent, name) {
9 super(parent);
10 this.name = name;
11 this.names = [];
12
13 let rule = this;
14 while (rule instanceof Rule) {
15 this.names.unshift(rule.name);
16 rule = rule.parent;
17 }
18
19 this.uses = new ChainedMap(this);
20 this.include = new ChainedSet(this);
21 this.exclude = new ChainedSet(this);
22 this.oneOfs = new ChainedMap(this);
23 this.extend([
24 'enforce',
25 'issuer',
26 'parser',
27 'resource',
28 'resourceQuery',
29 'sideEffects',
30 'test',
31 'type',
32 ]);
33 }
34
35 use(name) {
36 return this.uses.getOrCompute(name, () => new Use(this, name));
37 }
38
39 oneOf(name) {
40 return this.oneOfs.getOrCompute(name, () => new Rule(this, name));
41 }
42
43 pre() {
44 return this.enforce('pre');
45 }
46
47 post() {
48 return this.enforce('post');
49 }
50
51 toConfig() {
52 const config = this.clean(
53 Object.assign(this.entries() || {}, {
54 include: this.include.values(),
55 exclude: this.exclude.values(),
56 oneOf: this.oneOfs.values().map(oneOf => oneOf.toConfig()),
57 use: this.uses.values().map(use => use.toConfig()),
58 }),
59 );
60
61 Object.defineProperties(config, {
62 __ruleNames: { value: this.names },
63 });
64
65 return config;
66 }
67
68 merge(obj, omit = []) {
69 if (!omit.includes('include') && 'include' in obj) {
70 this.include.merge(obj.include);
71 }
72
73 if (!omit.includes('exclude') && 'exclude' in obj) {
74 this.exclude.merge(obj.exclude);
75 }
76
77 if (!omit.includes('use') && 'use' in obj) {
78 Object.keys(obj.use).forEach(name =>
79 this.use(name).merge(obj.use[name]),
80 );
81 }
82
83 if (!omit.includes('oneOf') && 'oneOf' in obj) {
84 Object.keys(obj.oneOf).forEach(name =>
85 this.oneOf(name).merge(obj.oneOf[name]),
86 );
87 }
88
89 if (!omit.includes('test') && 'test' in obj) {
90 this.test(
91 obj.test instanceof RegExp || typeof obj.test === 'function'
92 ? obj.test
93 : new RegExp(obj.test),
94 );
95 }
96
97 return super.merge(obj, [
98 ...omit,
99 'include',
100 'exclude',
101 'use',
102 'oneOf',
103 'test',
104 ]);
105 }
106 },
107);
108
109module.exports = Rule;