1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 | const $ = require('./utils');
|
6 |
|
7 | function dispatch(options, files, run) {
|
8 | const cb = [];
|
9 | const src = [];
|
10 | const unknown = [];
|
11 | const filters = this;
|
12 |
|
13 | files.forEach(file => {
|
14 | for (const k in filters) {
|
15 | if (filters[k].matches(file.src)) {
|
16 | if (!src[k]) {
|
17 | cb[k] = filters[k].finish;
|
18 | src[k] = [];
|
19 | }
|
20 |
|
21 | if (typeof options.rename === 'function') {
|
22 | options.rename(file);
|
23 | }
|
24 |
|
25 | src[k].push(file);
|
26 | return;
|
27 | }
|
28 | }
|
29 |
|
30 | unknown.push(file);
|
31 | });
|
32 |
|
33 |
|
34 | run(unknown, next =>
|
35 | Promise.all(cb.map((task, k) =>
|
36 | new Promise((resolve, reject) => {
|
37 | const retval = task.call(null, src[k], (err, data) => {
|
38 | if (err) {
|
39 | reject(err);
|
40 | } else {
|
41 | resolve(data);
|
42 | }
|
43 | });
|
44 |
|
45 | if (retval && typeof retval.then === 'function') {
|
46 | retval.then(resolve).catch(next);
|
47 | }
|
48 | })))
|
49 | .then(result => next(undefined, $.flatten(result)))
|
50 | .catch(error => next(error)));
|
51 | }
|
52 |
|
53 | function filter(expr, cb) {
|
54 | this.push({
|
55 | matches: $.makeFilter(true, $.toArray(expr)),
|
56 | finish: cb,
|
57 | });
|
58 | }
|
59 |
|
60 | function emit(hook) {
|
61 | if (this[hook]) {
|
62 |
|
63 |
|
64 | return this[hook].reduce((prev, cur) =>
|
65 | prev.then(() => cur.apply(null, Array.prototype.slice.call(arguments, 1))), Promise.resolve());
|
66 | }
|
67 | }
|
68 |
|
69 | function dist(obj) {
|
70 | const run = () => {
|
71 | switch (obj.type) {
|
72 | case 'concat':
|
73 | $.write(obj.dest, obj.src.map(file => {
|
74 | return $.read(file);
|
75 | }).join('\n'));
|
76 | break;
|
77 |
|
78 | case 'delete':
|
79 | if (!$.isFile(obj.src) && $.isFile(obj.dest)) {
|
80 | $.unlink(obj.dest);
|
81 | }
|
82 | break;
|
83 |
|
84 | case 'unlink':
|
85 | if ($.isFile(obj.dest)) {
|
86 | $.unlink(obj.dest);
|
87 | }
|
88 | break;
|
89 |
|
90 | case 'write':
|
91 | $.write(obj.dest, obj.data);
|
92 | break;
|
93 |
|
94 | case 'copy':
|
95 | $.copy(obj.src, obj.dest);
|
96 | break;
|
97 |
|
98 | default:
|
99 | throw new Error(`Unsupported action: ${obj.type}`);
|
100 | }
|
101 | };
|
102 |
|
103 | if (!obj.quiet) {
|
104 | this(obj, run);
|
105 | } else {
|
106 | run();
|
107 | }
|
108 | }
|
109 |
|
110 | function on(hook, cb) {
|
111 | if (!this[hook]) {
|
112 | this[hook] = [];
|
113 | }
|
114 |
|
115 | this[hook].push(cb);
|
116 | }
|
117 |
|
118 | module.exports = (_logger, options) => {
|
119 | const hooks = {};
|
120 | const filters = [];
|
121 |
|
122 | return {
|
123 | util: $,
|
124 | opts: options,
|
125 | logger: _logger,
|
126 | on: on.bind(hooks),
|
127 | emit: emit.bind(hooks),
|
128 | dist: dist.bind(_logger),
|
129 | filter: filter.bind(filters),
|
130 | dispatch: dispatch.bind(filters),
|
131 | };
|
132 | };
|