UNPKG

2.47 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(obj.test instanceof RegExp ? obj.test : new RegExp(obj.test));
91 }
92
93 return super.merge(obj, [
94 ...omit,
95 'include',
96 'exclude',
97 'use',
98 'oneOf',
99 'test',
100 ]);
101 }
102 }
103);
104
105module.exports = Rule;