aboutsummaryrefslogtreecommitdiff
path: root/node_modules/webpack-chain/src/Rule.js
blob: 45e1695547f7d32c560143fbf7227345ce4d7852 (plain)
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
const ChainedMap = require('./ChainedMap');
const ChainedSet = require('./ChainedSet');
const Use = require('./Use');

module.exports = class Rule extends ChainedMap {
  constructor(parent, name) {
    super(parent);
    this.name = name;
    this.names = [];

    let rule = this;
    while (rule instanceof Rule) {
      this.names.unshift(rule.name);
      rule = rule.parent;
    }

    this.uses = new ChainedMap(this);
    this.include = new ChainedSet(this);
    this.exclude = new ChainedSet(this);
    this.oneOfs = new ChainedMap(this);
    this.extend([
      'enforce',
      'issuer',
      'parser',
      'resource',
      'resourceQuery',
      'sideEffects',
      'test',
      'type',
    ]);
  }

  use(name) {
    return this.uses.getOrCompute(name, () => new Use(this, name));
  }

  oneOf(name) {
    return this.oneOfs.getOrCompute(name, () => new Rule(this, name));
  }

  pre() {
    return this.enforce('pre');
  }

  post() {
    return this.enforce('post');
  }

  toConfig() {
    const config = this.clean(
      Object.assign(this.entries() || {}, {
        include: this.include.values(),
        exclude: this.exclude.values(),
        oneOf: this.oneOfs.values().map(oneOf => oneOf.toConfig()),
        use: this.uses.values().map(use => use.toConfig()),
      })
    );

    Object.defineProperties(config, {
      __ruleNames: { value: this.names },
    });

    return config;
  }

  merge(obj, omit = []) {
    if (!omit.includes('include') && 'include' in obj) {
      this.include.merge(obj.include);
    }

    if (!omit.includes('exclude') && 'exclude' in obj) {
      this.exclude.merge(obj.exclude);
    }

    if (!omit.includes('use') && 'use' in obj) {
      Object.keys(obj.use).forEach(name => this.use(name).merge(obj.use[name]));
    }

    if (!omit.includes('oneOf') && 'oneOf' in obj) {
      Object.keys(obj.oneOf).forEach(name =>
        this.oneOf(name).merge(obj.oneOf[name])
      );
    }

    if (!omit.includes('test') && 'test' in obj) {
      this.test(obj.test instanceof RegExp ? obj.test : new RegExp(obj.test));
    }

    return super.merge(obj, [
      ...omit,
      'include',
      'exclude',
      'use',
      'oneOf',
      'test',
    ]);
  }
};