# gulp-ab-filter

> gulp smart filter

Latest version **1.2.2** (published 2019-11-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install gulp-ab-filter
pnpm add gulp-ab-filter
yarn add gulp-ab-filter
bun add gulp-ab-filter
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.2 |
| Published | 2019-11-26 |
| First published | 2017-06-07 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=5 |
| Dependencies | 1 |
| Unpacked size | 15.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Dmitry Talipov |
| Maintainers | talipoff |
| Keywords | gulp, gulpplugin, conditional, ternary, filter, fork, if, else, ignory, exclude, match |

## Links

- npm: https://www.npmjs.com/package/gulp-ab-filter
- Repository: https://github.com/talipoff/gulp-ab-filter
- Homepage: https://github.com/talipoff/gulp-ab-filter#readme
- Issues: https://github.com/talipoff/gulp-ab-filter/issues
- npm.io page: https://npm.io/package/gulp-ab-filter

## Dependencies (1)

- [minimatch](https://npm.io/package/minimatch.md) ^3.0.4

## Alternatives

- [update-check](https://npm.io/package/update-check.md) — 4.0M weekly downloads
- [react-native-onesignal](https://npm.io/package/react-native-onesignal.md) — 134.5K weekly downloads
- [react-redux-toastr](https://npm.io/package/react-redux-toastr.md) — 33.7K weekly downloads
- [@nocobase/plugin-notification-manager](https://npm.io/package/@nocobase/plugin-notification-manager.md) — 2.0K weekly downloads
- [react-simple-toasts](https://npm.io/package/react-simple-toasts.md) — 1.9K weekly downloads

## Recent versions

- 1.2.2 (latest) — 2019-11-26
- 1.2.1 — 2018-02-18
- 1.1.1 — 2018-01-29
- 1.1.0 — 2018-01-29
- 1.0.0 — 2018-01-21
- 0.1.0 — 2018-01-21
- 0.0.6 — 2017-06-15
- 0.0.5 — 2017-06-08
- 0.0.4 — 2017-06-08
- 0.0.3 — 2017-06-08
- 0.0.2 — 2017-06-07
- 0.0.1 — 2017-06-07

## README

# gulp-ab-filter
[![npm version][npm-image]][npm-url]
[![Build status][travis-image]][travis-url]
[![Downloads][downloads-image]][downloads-url]
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
```sh
$ npm i -D gulp-ab-filter
```

## API

### The main module
```javascript
// 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](#branches) name else converted to a boolean.
* Other is converted to boolean.

Notice: In the [RegExp] and [blob] is passed the function result [relPath](#relPath).

#### Branches
Parameter yes, no, namedBranch.p can be:
* gulp plugin
* function([vinyl], [cb](#cb), [obj](#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](#branches)
* 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](#branches) name and the s - link to the [branch](#branches) stream.
[Branch](#branches) 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](#condition) depending on its type is converted into `result`.
2) If the parameter [branches](#branches) is missing then only push [obj](#obj) into empty [branch](#branches) *yes*.
The [branch](#branches) *no* does not exist.
3) If `result` === string then push [obj](#obj) into [branch](#branches) with the name = `result`.
If this [branch](#branches) not exists then push [obj](#obj) into [branch](#branches) *no*.
4) If `result` === true then push [obj](#obj) into [branch](#branches) *yes*.
5) If `result` === false then push [obj](#obj) into [branch](#branches) *no*.

#### Examples of usage: see [example.js]

#### 1. Stream filter [vinyl] objects.
```javascript
gulp.src('./test/**/*.txt')
	.pipe(abFilter('!**/block*')); // Exclude block files
```

#### 2. Stream filter [vinyl] objects and handlers.
```javascript
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](#branches) *yes* and *no*.
```javascript
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](#branches) *yes* and the handler end.
```javascript
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](#branches).
```javascript
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](#condition) [, [minimathOptions]])
Returns a value which depends on the type [condition](#condition).

## Contribute
Please send your improvements and enhancements. To begin, you must perform preparatory steps:
```sh
git clone https://github.com/talipoff/gulp-ab-filter
cd gulp-ab-filter
npm i
```

After you need to run the tests:
```sh
npm run -s test-src
npm run -s test-logic
```

[example.js]:test/example.js
[vinyl]:https://github.com/gulpjs/vinyl
[Blob]:https://github.com/isaacs/node-glob
[minimatch]:https://github.com/isaacs/minimatch
[minimathOptions]:https://github.com/isaacs/minimatch#options
[RegExp]:https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[npm-image]: https://img.shields.io/npm/v/gulp-ab-filter.svg
[npm-url]: https://npmjs.org/package/gulp-ab-filter
[travis-image]: https://img.shields.io/travis/talipoff/gulp-ab-filter.svg
[travis-url]: https://travis-ci.org/talipoff/gulp-ab-filter
[downloads-image]: http://img.shields.io/npm/dm/gulp-ab-filter.svg
[downloads-url]: https://npmjs.org/package/gulp-ab-filter

---
_Source: https://npm.io/package/gulp-ab-filter · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
