UNPKG

1.73 kBJavaScriptView Raw
1import process from 'node:process';
2import path from 'node:path';
3import PluginError from 'plugin-error';
4import multimatch from 'multimatch';
5import streamfilter from 'streamfilter';
6import toAbsoluteGlob from 'to-absolute-glob';
7import slash from 'slash';
8
9export default function plugin(pattern, options = {}) {
10 pattern = typeof pattern === 'string' ? [pattern] : pattern;
11
12 if (!Array.isArray(pattern) && typeof pattern !== 'function') {
13 throw new PluginError('gulp-filter', '`pattern` should be a string, array, or function');
14 }
15
16 // TODO: Use `readableStream.filter()` when targeting Node.js 18.
17 return streamfilter((file, encoding, callback) => {
18 let match;
19
20 if (typeof pattern === 'function') {
21 match = pattern(file);
22 } else {
23 const base = path.dirname(file.path);
24
25 let patterns = pattern.map(pattern => {
26 // Filename only matching glob, prepend full path.
27 if (!pattern.includes('/')) {
28 if (pattern[0] === '!') {
29 return '!' + path.resolve(base, pattern.slice(1));
30 }
31
32 return path.resolve(base, pattern);
33 }
34
35 pattern = toAbsoluteGlob(pattern, {cwd: file.cwd, root: options.root});
36
37 // Calling `path.resolve` after `toAbsoluteGlob` is required for removing `..` from path.
38 // This is useful for `../A/B` cases.
39 if (pattern[0] === '!') {
40 return '!' + path.resolve(pattern.slice(1));
41 }
42
43 return path.resolve(pattern);
44 });
45
46 if (process.platform === 'win32') {
47 patterns = patterns.map(pattern => slash(pattern));
48 }
49
50 match = multimatch(path.resolve(file.cwd, file.path), patterns, options).length > 0;
51 }
52
53 callback(!match);
54 }, {
55 objectMode: true,
56 passthrough: options.passthrough !== false,
57 restore: options.restore,
58 });
59}