<commit_before># function-middleware-decorator

Decorates functions with middleware functionality

[![Travis build status](http://img.shields.io/travis/thefabulousdev/function-middleware-decorator.svg?style=flat)](https://travis-ci.org/thefabulousdev/function-middleware-decorator)
[![Code Climate](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator/badges/gpa.svg)](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator)
[![Test Coverage](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator/badges/coverage.svg)](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator)
[![Dependency Status](https://david-dm.org/thefabulousdev/function-middleware-decorator.svg)](https://david-dm.org/thefabulousdev/function-middleware-decorator)
[![devDependency Status](https://david-dm.org/thefabulousdev/function-middleware-decorator/dev-status.svg)](https://david-dm.org/thefabulousdev/function-middleware-decorator#info=devDependencies)

## Demo

### Given

The module has been imported with your favorite loader as `functionMiddlewareDecorator` and the following function is available

```js
function getPrice(){
    return 10;
}
```

### Then

#### Decorate with a synchronous middleware

```js
getPrice = functionMiddlewareDecorator(getPrice);

function halfPriceMiddleware(price){
    return price / 2;
}

getPrice.use(halfPriceMiddleware);

console.log(getPrice()); // 5

```

#### Decorate with an asynchronous middleware

```js
getPrice = functionMiddlewareDecorator.async(getPrice);

function halfPriceMiddleware(price, done){
    setTimeout(()=>{
        done(price / 2);
    }, 2000);
}

getPrice.use(halfPriceMiddleware);

getPrice().cb((price)=>{
    console.log(price()); // 5
});

```

#### Decorate with a promised middleware

```js
getPrice = functionMiddlewareDecorator.promised(getPrice);

// Can return any value, if it's a promise, next middleware won't get executed till resolved
function halfPriceMiddleware(price){
    return hasHalfPriceDiscount().then((hasHalfPriceDiscount)=>{
        return hasHalfPriceDiscount ? price / 2 : price;
    });
}

getPrice.use(halfPriceMiddleware);

getPrice().then((price)=>{
    console.log(price()); // 5
});

```

## Installation

### npm
```sh
    npm install function-middleware-decorator
```

### bower
```sh
    bower install function-middleware-decorator
```


## API

### (originalFunction: Function) : Function

Takes a function as argument and returns it's decorated version

```js
decoratedFunction = functionMiddlewareDecorator(originalFunction);
```

### decoratedFunction.use(middleware: Function)

Adds a middleware to the decorated function

```js
decoratedFunction.use((originalFunctionOutput) => {
    console.log(`I'm a middleware!`);
    return originalFunctionOutput;
});
```

### decoratedFunction(...args);

Calls the original function with the given arguments and runs it's output through the registered middleware

```js
decoratedFunction(arg1, arg2);
```

## Contributing

#### Clone the repository

``` sh
git clone git@github.com:thefabulousdev/function-middleware-decorator.git
```


#### Install dependencies
``` sh
npm install
```

#### Use npm scripts

- `npm test` - Lint the library and tests, then run the unit tests
- `npm run lint` - Lint the source and unit tests<commit_msg>doc(README): add full API<commit_after># function-middleware-decorator

Decorates functions with middleware functionality.

[![Travis build status](http://img.shields.io/travis/thefabulousdev/function-middleware-decorator.svg?style=flat)](https://travis-ci.org/thefabulousdev/function-middleware-decorator)
[![Code Climate](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator/badges/gpa.svg)](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator)
[![Test Coverage](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator/badges/coverage.svg)](https://codeclimate.com/github/thefabulousdev/function-middleware-decorator)
[![Dependency Status](https://david-dm.org/thefabulousdev/function-middleware-decorator.svg)](https://david-dm.org/thefabulousdev/function-middleware-decorator)
[![devDependency Status](https://david-dm.org/thefabulousdev/function-middleware-decorator/dev-status.svg)](https://david-dm.org/thefabulousdev/function-middleware-decorator#info=devDependencies)

## Features

- Synchronous, asynchronous and promised middleware runners
- No dependencies
- UMD Module
- Tiny

## Installation

### npm
```sh
    npm install function-middleware-decorator
```

### bower
```sh
    bower install function-middleware-decorator
```

## Demo

### Given

The module has been imported with your favorite loader as `functionMiddlewareDecorator` and the following function is available

```js
function getPrice(){
    return 10;
}
```

### Then

#### Decorate with a synchronous middleware

```js
getPrice = functionMiddlewareDecorator(getPrice);

function halfPriceMiddleware(price){
    return price / 2;
}

getPrice.use(halfPriceMiddleware);

console.log(getPrice()); // 5

```

#### Decorate with an asynchronous middleware

```js
getPrice = functionMiddlewareDecorator.async(getPrice);

function halfPriceMiddleware(price, done){
    setTimeout(()=>{
        done(price / 2);
    }, 2000);
}

getPrice.use(halfPriceMiddleware);

getPrice().cb((price)=>{
    console.log(price()); // 5
});

```

#### Decorate with a promised middleware

```js
getPrice = functionMiddlewareDecorator.promised(getPrice);

// Can return any value, if it's a promise, next middleware won't get executed till resolved
function halfPriceMiddleware(price){
    return hasHalfPriceDiscount().then((hasHalfPriceDiscount)=>{
        return hasHalfPriceDiscount ? price / 2 : price;
    });
}

getPrice.use(halfPriceMiddleware);

getPrice().then((price)=>{
    console.log(price()); // 5
});

```

## API

### Module

#### (originalFunction: Function) : SynchronousMiddlewareRunner

Takes a function as argument and returns a synchronous middleware runner

```js
synchronousMiddlewareRunner = functionMiddlewareDecorator(originalFunction);
```


#### promised(originalFunction: Function) : PromisedMiddlewareRunner

Takes a function as argument and returns a promised middleware runner

```js
promisedMiddlewareRunner = functionMiddlewareDecorator(originalFunction);
```

#### async(originalFunction: Function) : AsynchronousMiddlewareRunner

Takes a function as argument and returns an asynchronous middleware runner

```js
asynchronousMiddlewareRunner = functionMiddlewareDecorator(originalFunction);
```

### synchronousMiddlewareRunner

#### synchronousMiddlewareRunner.use(synchronousMiddleware: Function)

Adds a synchronous middleware

```js
synchronousMiddlewareRunner.use((middlewareOutput) => {
    return middlewareOutput;
});
```

#### synchronousMiddlewareRunner(...args);

Calls the original function with the given arguments and runs it's output through the registered synchronous middleware

```js
synchronousMiddlewareRunner(arg1, arg2);
```

### asynchronousMiddlewareRunner

#### asynchronousMiddlewareRunner.use(asynchronousMiddleware: Function)

Adds an asynchronous middleware

```js
asynchronousMiddlewareRunner.use((middlewareOutput, done) => {
    done(middlewareOutput);
});
```

#### asynchronousMiddlewareRunner(...args).cb(callback: Function);

Calls the original function with the given arguments and runs it's output through the registered middleware, when done, calls the provided callback

```js
asynchronousMiddlewareRunner(arg1, arg2).cb((middlewareOutput)=>{
    console.log(`Done with ${middlewareOutput}`);
});
```

### promisedMiddlewareRunner

#### promisedMiddlewareRunner.use(promisedMiddleware: Function)

Adds a promised middleware

```js
promisedMiddlewareRunner.use((middlewareOutput) => {
    return new Promise((resolve, reject) => {
        resolve(middlewareOutput);
    });
});
```

#### promisedMiddlewareRunner(...args).then(promiseHandler: Function);

Calls the original function with the given arguments and runs it's output through the registered middleware, when done, calls the provided callback

```js
promisedMiddlewareRunner(arg1, arg2).then((middlewareOutput)=>{
    console.log(`Done with ${middlewareOutput}`);
});
```

## Contributing

#### Clone the repository

``` sh
git clone <EMAIL>:thefabulousdev/function-middleware-decorator.git
```


#### Install dependencies
``` sh
npm install
```

#### Use npm scripts

- `npm test` - Lint the library and tests, then run the unit tests
- `npm run lint` - Lint the source and unit tests
{'fraction_non_alphanumeric': 0.13376759334651622, 'fraction_numerical': 0.0037222286844247996, 'mean_word_length': 5.759433962264151, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 19, 'https://': 18, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6213629', 'n_tokens_mistral': 2600, 'n_tokens_neox': 2492, 'n_words': 561}