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 | const fn = path => reg.test(path);
|
40 | fn.toString = () => reg;
|
41 | return fn;
|
42 | };
|
43 |
|
44 | Rule.prototype.wrapMatch = function(rule) {
|
45 | const reg = new minimatch.Minimatch(rule.slice(1), {
|
46 | dot: this.option.dot
|
47 | });
|
48 | const fn = path => reg.match(path);
|
49 | fn.toString = () => reg;
|
50 | return fn;
|
51 | };
|
52 |
|
53 | Rule.prototype.wrapAlias = function (rule) {
|
54 | const index = rule.indexOf('/');
|
55 | const key = index > -1 ? rule.slice(1, index) : rule.slice(1);
|
56 | const sub = index > -1 ? rule.slice(index + 1) : '';
|
57 | const alias = this.option.alias[key];
|
58 | if (typeof alias !== 'string') {
|
59 | throw new Error(`alias ${key} not exist`);
|
60 | }
|
61 | return this.wrapPath(path.join(alias, sub));
|
62 | };
|
63 |
|
64 | Rule.prototype.wrapPath = function (rule) {
|
65 | rule = '/' + rule.replace(/^\//, '');
|
66 |
|
67 | const option = this.option;
|
68 | const symbol = option.symbol;
|
69 | let fn;
|
70 | if (rule.charAt(rule.length - 1) === symbol.file) {
|
71 | rule = rule.slice(0, rule.length - 1);
|
72 | fn = path => path === rule;
|
73 | } else {
|
74 | rule = rule.replace(/\/$/, '') + '/';
|
75 | fn = path => path.indexOf(rule) === 0;
|
76 | }
|
77 | fn.toString = () => rule;
|
78 | return fn;
|
79 | };
|
80 |
|
81 | Rule.prototype.setNegation = function (negation) {
|
82 | this.negation = !!negation;
|
83 | };
|
84 |
|
85 | Rule.prototype.toString = function () {
|
86 | return this.reg && this.reg.toString ? this.reg.toString() : this.rule;
|
87 | };
|
88 |
|
89 | exports = module.exports = Rule;
|