UNPKG

2.67 kBJavaScriptView Raw
1'use strict';
2
3/* eslint-disable no-restricted-syntax */
4
5const $ = require('./utils');
6
7function 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 // process subtasks
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
53function filter(expr, cb) {
54 this.push({
55 matches: $.makeFilter(true, $.toArray(expr)),
56 finish: cb,
57 });
58}
59
60function emit(hook) {
61 if (this[hook]) {
62 /* eslint-disable prefer-spread */
63 /* eslint-disable prefer-rest-params */
64 return this[hook].reduce((prev, cur) =>
65 prev.then(() => cur.apply(null, Array.prototype.slice.call(arguments, 1))), Promise.resolve());
66 }
67}
68
69function 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
110function on(hook, cb) {
111 if (!this[hook]) {
112 this[hook] = [];
113 }
114
115 this[hook].push(cb);
116}
117
118module.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};