1 | const path = require('path');
|
2 | const minimatch = require('minimatch');
|
3 |
|
4 |
|
5 | function Rule(rule, option) {
|
6 | const symbol = option.symbol
|
7 |
|
8 | this.option = option;
|
9 | this.rule = rule;
|
10 | this.negation = rule.charAt(0) === symbol.negation;
|
11 | this.reg = this.wrap(rule.replace(new RegExp(`^\\${symbol.negation}`), ''));
|
12 | }
|
13 |
|
14 | Rule.prototype.test = function (path) {
|
15 | return this.reg(path)
|
16 | ? this.negation
|
17 | ? 0
|
18 | : 1
|
19 | : -1;
|
20 | };
|
21 |
|
22 | Rule.prototype.wrap = function (rule) {
|
23 | const option = this.option;
|
24 | const symbol = option.symbol
|
25 | switch (rule.charAt(0)) {
|
26 | case symbol.regexp:
|
27 | return this.wrapRegExp(rule);
|
28 | case symbol.match:
|
29 | return this.wrapMatch(rule);
|
30 | case symbol.alias:
|
31 | return this.wrapAlias(rule);
|
32 | default:
|
33 | return this.wrapPath(rule);
|
34 | }
|
35 | };
|
36 |
|
37 | Rule.prototype.wrapRegExp = function (rule) {
|
38 | const reg = new RegExp(rule.slice(1))
|
39 | return path => reg.test(path);
|
40 | };
|
41 |
|
42 | Rule.prototype.wrapMatch = function(rule) {
|
43 | const reg = new minimatch.Minimatch(rule.slice(1), {
|
44 | dot: this.option.dot
|
45 | });
|
46 | return path => reg.match(path);
|
47 | };
|
48 |
|
49 | Rule.prototype.wrapAlias = function (rule) {
|
50 | const index = rule.indexOf('/');
|
51 | const key = index > -1 ? rule.slice(1, index) : rule.slice(1);
|
52 | const sub = index > -1 ? rule.slice(index + 1) : '';
|
53 | const alias = this.option.alias[key];
|
54 | if (typeof alias !== 'string') {
|
55 | throw new Error(`alias ${key} not exist`);
|
56 | }
|
57 | return this.wrapPath(path.join(alias, sub));
|
58 | };
|
59 |
|
60 | Rule.prototype.wrapPath = function (rule) {
|
61 | const option = this.option;
|
62 | const symbol = option.symbol;
|
63 | rule = '/' + rule.replace(/^\//, '');
|
64 | if (rule.charAt(rule.length - 1) === symbol.file) {
|
65 | rule = rule.slice(0, rule.length - 1);
|
66 | } else {
|
67 | rule = rule.replace(/\/$/, '') + '/';
|
68 | }
|
69 | const length = rule.length;
|
70 | return path => path.indexOf(rule) === 0;
|
71 | };
|
72 |
|
73 | Rule.prototype.setNegation = function (negation) {
|
74 | this.negation = !!negation;
|
75 | };
|
76 |
|
77 | Rule.prototype.toString = function () {
|
78 | return this.rule;
|
79 | };
|
80 |
|
81 | exports = module.exports = Rule;
|