gulp-ab-filter

gulp smart filter

Usage no npm install needed!

<script type="module">
  import gulpAbFilter from 'https://cdn.skypack.dev/gulp-ab-filter';
</script>

README

gulp-ab-filter

npm version Build status Downloads Use it for filtering and separating stream vinyl objects. Easy to connect plugins in the chain for each branch. Easy create custom handlers for objects.

Installation

$ npm i -D gulp-ab-filter

API

The main module

// Import
const gulp = require('gulp');
const abFilter = require('gulp-ab-filter');
abFilter(condition [, branches ] [, options])
         /            /               |
        /            +-> yes          +---{debug,               // enable debug mode to control the route of objects
       /             +-> yes, no           end(vinyl, cb, obj), // main close handler for all branches
      /              +-> namedBranch[]     flush(cb, obj),      // main flush handler for all branches
     /                   / | \             minimatch,           // options which apply for blob condition
    |  {n: Name, p: Pipe, stop: Boolean}   name                 // name for debug mode
    |                                     }
    |                     result
    +-> RegExp ---------> boolean
    +-> blob -----------> boolean
    +-> blob [] --------> boolean
    +-> function(vinyl)
    |      |
    |      +-> string --> branch name
    |      +-> other ---> boolean
    +-> other ----------> boolean

Condition

Possible types:

  • RegExp - regular expression.
  • blob string. If blob starts with ! this beginning is discarded, and the result is converted to the opposite.
  • Array blob strings. Only works the first match, the rest are ignored. If the array is used only blob with ! and and there are no matches then this is equivalent to true.
  • Function - user-defined function with vinyl argument. If function returns the string then used it as branch name else converted to a boolean.
  • Other is converted to boolean.

Notice: In the RegExp and blob is passed the function result relPath.

Branches

Parameter yes, no, namedBranch.p can be:

  • gulp plugin
  • function(vinyl, cb, obj)
  • an array containing the gulp plugins and functions in any combination.

NamedBranch

Array from objects with properties:

  • namedBranch.n - name branch
  • namedBranch.p - branch
  • namedBranch.stop - don'n push objects to out

Cb

Callback function that must be called with two parameters:: null or error and vinyl object. If the parameters are omitted, the object is not passed on.

Obj

A context object. It contains two properties: n - branch name and the s - link to the branch stream. Branch stream supports push. Possible to set custom properties.

End handler

Call for each branches for each objects when go out of branch.

Flush handler

Call for each branch, before closure.

The logic of the filter:

  1. Condition depending on its type is converted into result.
  2. If the parameter branches is missing then only push obj into empty branch yes. The branch no does not exist.
  3. If result === string then push obj into branch with the name = result. If this branch not exists then push obj into branch no.
  4. If result === true then push obj into branch yes.
  5. If result === false then push obj into branch no.

Examples of usage: see example.js

1. Stream filter vinyl objects.

gulp.src('./test/**/*.txt')
    .pipe(abFilter('!**/block*')); // Exclude block files

2. Stream filter vinyl objects and handlers.

gulp.src('./test/**/*.txt')
    .pipe(abFilter('**/b*.txt', {
        end: (object, cb, obj) => {
            if (obj._result === undefined) {
                obj._result = new Vinyl({
                    base: object.base,
                    path: object.base + '/result.txt',
                    contents: Buffer.from(object.contents)
                });
            } else {
                obj._result.contents = Buffer.concat([obj._result.contents, object.contents]);
            }
            cb(); // Don't push source files
        }, flush: (cb, obj) => {
            obj._result && obj.s.push(obj._result); // Push the result
            cb();
        }
    }));

3. Use as a separator stream vinyl objects with a standard branches yes and no.

const yes = [ // This set of plugins will be executed sequentially
    replaceP('r', '_'), // 1 gulp plugin
    (file, cb) => { // Function as 2 plugin
        // actions with the object, see examples in test.js
        file.contents = Buffer.from(String(file.contents).replace('_', '*'));
        cb(null, file); // Mandatory run the callback function
    },
    replaceP('*', '#') // 3 gulp plugin
]; // Re-use of yes is unacceptable!
const no = replaceP('b', 'B');

gulp.src('./test/**/*.txt')
    .pipe(abFilter('**/*t.txt', yes, no));

4. Separator stream vinyl objects with a standard branch yes and the handler end.

const end = (file, cb, obj) => {
    if (obj.n === 'Yes') {
        file.contents = Buffer.from(String(file.contents).replace('_', 'R'));
    } else {
        file.contents = Buffer.from(String(file.contents) + '=');
    }
    cb(null, file);
};

gulp.src('./test/**/*.txt')
    .pipe(abFilter('**/*t.txt', replaceP('r', '_'), {end: end}));

5. Use as a separator stream vinyl objects with array of named branches.

const path = require('path');
const pipe1 = (file, cb) => {
    file.contents = Buffer.from(String(file.contents) + '1');
    cb(null, file);
};
const pipe2 = (file, cb) => {
    file.contents = Buffer.from(String(file.contents) + '2');
    cb(null, file);
};

gulp.src('./test/**/*.txt')
    .pipe(abFilter(
        file => {
            const relPathParts = abFilter.relPath(file).split(path.posix.sep);
            return relPathParts.length > 2 ? relPathParts[relPathParts.length-2] : '';
        }, // get last segment of path
        [{n: 'block1', p: pipe1}, {n: 'txt', p: pipe2}]));

6. Two ways for flush stream.

See example.js

abFilter.relPath(vinyl)

Returns the relative path to the vinyl including the object name using the posix separators without the current directory.

abFilter.match(vinyl, condition [, minimathOptions])

Returns a value which depends on the type condition.

Contribute

Please send your improvements and enhancements. To begin, you must perform preparatory steps:

git clone https://github.com/talipoff/gulp-ab-filter
cd gulp-ab-filter
npm i

After you need to run the tests:

npm run -s test-src
npm run -s test-logic