hybridables/redolent

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# redolent [![NPM version](https://img.shields.io/npm/v/redolent.svg?style=flat)](https://www.npmjs.com/package/redolent) [![mit license][license-img]][license-url] [![NPM monthly downloads](https://img.shields.io/npm/dm/redolent.svg?style=flat)](https://npmjs.org/package/redolent) [![npm total downloads][downloads-img]][downloads-url]

> Simple promisify with sane defaults, works on node 0.10 if you provide custom Promise through options

[![code climate][codeclimate-img]][codeclimate-url] 
[![code style][standard-img]][standard-url] 
[![linux build][travis-img]][travis-url] 
[![windows build][appveyor-img]][appveyor-url] 
[![code coverage][coverage-img]][coverage-url] 
[![dependency status][david-img]][david-url]
[![paypal donate][paypalme-img]][paypalme-url] 

You might also be interested in [always-done](https://github.com/hybridables/always-done#readme).

## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [API](#api)
  * [redolent](#redolent)
  * [Detecting Promise](#detecting-promise)
- [Related](#related)
- [Contributing](#contributing)
- [Building docs](#building-docs)
- [Running tests](#running-tests)
- [Author](#author)
- [License](#license)

_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_

## Install
Install with [npm](https://www.npmjs.com/)

```
$ npm install redolent --save
```

or install using [yarn](https://yarnpkg.com)

```
$ yarn add redolent
```

## Usage
> For more use-cases see the [tests](test.js)

```js
const redolent = require('redolent')
```

## API

### [redolent](index.js#L82)
> Will try to promisify `fn` with native Promise, otherwise you can give different promise module to `opts.Promise`, for example [pinkie][] or [bluebird][]. If `fn` [is-async-function][] it will be passed with `done` callback as last argument - always concatenated with the other provided args through `opts.args`.

**Note:** Uses [native-or-another][] for detection, so it will always will use the
native Promise, otherwise will try to load some of the common promise libraries
and as last resort if can't find one of them installed, then throws an Error!

**Params**

* `<fn>` **{Function}**: a function to be promisified    
* `[opts]` **{Object}**: optional options, also passed to [native-or-another][]    
* `[opts.args]` **{Array}**: additional arguments to be passed to `fn`, all args from `opts.args` and these that are passed to promisifed function are concatenated    
* `[opts.context]` **{Object}**: what context to be applied to `fn`, by default it is smart enough and applies the `this` context of redolent call or the call of the promisified function    
* `[opts.Promise]` **{Function}**: custom Promise constructor for versions `< v0.12`, like [bluebird][] for example, by default it **always** uses the native Promise in newer node versions    
* `[opts.global]` **{Boolean}**: defaults to `true`, pass false if you don't want to attach/add/register the given promise to the `global` scope, when node `< v0.12`    
* `returns` **{Function}**: promisified function  

**Example**

```js
const fs = require('fs')
const request = require('request')
const redolent = require('redolent')

redolent(fs.readFile)('package.json', 'utf-8').then(data => {
  console.log(JSON.parse(data).name)
})

// handles multiple arguments by default
redolent(request)('http://www.tunnckocore.tk/').then(result => {
  const [httpResponse, body] = result
})

// `a` and `b` arguments comes from `opts.args`
// `c` and `d` comes from the call of the promisified function
const fn = redolent((a, b, c, d, done) => {
  console.log(typeof done) // => 'function'
  done(null, a + b + c + d)
}, {
  args: [1, 2]
})

fn(3, 5).then((res) => {
  console.log(res) // => 11
})
```

**Tip:** You can use `require('native-or-another/register')` instead of passing
a promise to `opts.Promise`, it exposes a function that accepts same
options object, `{ Promise: MyPromise }` for example.

### Detecting Promise
> For testing and such purposes you may want to detect which promise is used. Because of that
the returned promise has `promise.___nativePromise` which will be `true` if native Promise
is available on the environment or `promise.___customPromise === true` if custom Promise
constructor is passed through `opts.Promise`

```js
const fs = require('fs')
const redolent = require('redolent')

// use Bluebird Promise
const readFile = redolent(fs.readFile, {
  Promise: require('bluebird')
})

const promise = readFile('package.json', 'utf-8').then(data => {
  console.log(JSON.parse(data).name)
})

console.log(promise.___customPromise) // => true
console.log(promise.___nativePromise) // => false
```

## Related
- [always-done](https://www.npmjs.com/package/always-done): Handle completion and errors with elegance! Support for streams, callbacks, promises, child processes, async/await and sync functions. A drop-in replacement… [more](https://github.com/hybridables/always-done#readme) | [homepage](https://github.com/hybridables/always-done#readme "Handle completion and errors with elegance! Support for streams, callbacks, promises, child processes, async/await and sync functions. A drop-in replacement for [async-done][] - pass 100% of its tests plus more")
- [always-promise](https://www.npmjs.com/package/always-promise): Promisify, basically, everything. Generator function, callback-style or synchronous function; sync function that returns child process, stream or observable; directly passed… [more](https://github.com/hybridables/always-promise#readme) | [homepage](https://github.com/hybridables/always-promise#readme "Promisify, basically, everything. Generator function, callback-style or synchronous function; sync function that returns child process, stream or observable; directly passed promise, stream or child process.")
- [always-thunk](https://www.npmjs.com/package/always-thunk): Create thunk from async or sync function. Works like `thunkify`. | [homepage](https://github.com/tunnckocore/always-thunk#readme "Create thunk from async or sync function. Works like `thunkify`.")
- [arr-includes](https://www.npmjs.com/package/arr-includes): Return positive value if any of passed values exists in array, or optionally an index. | [homepage](https://github.com/tunnckocore/arr-includes#readme "Return positive value if any of passed values exists in array, or optionally an index.")
- [dush](https://www.npmjs.com/package/dush): Microscopic & functional event emitter in ~260 bytes, extensible through plugins. | [homepage](https://github.com/tunnckocore/dush#readme "Microscopic & functional event emitter in ~260 bytes, extensible through plugins.")
- [letta](https://www.npmjs.com/package/letta): Promisify sync, async or generator function, using [relike][]. Kind of promisify, but lower level. Full compatibility with [co][]4 and passing… [more](https://github.com/hybridables/letta#readme) | [homepage](https://github.com/hybridables/letta#readme "Promisify sync, async or generator function, using [relike][]. Kind of promisify, but lower level. Full compatibility with [co][]4 and passing 100% of its tests.")
- [minibase](https://www.npmjs.com/package/minibase): Minimalist alternative for Base. Build complex APIs with small units called plugins. Works well with most of the already existing… [more](https://github.com/node-minibase/minibase#readme) | [homepage](https://github.com/node-minibase/minibase#readme "Minimalist alternative for Base. Build complex APIs with small units called plugins. Works well with most of the already existing [base][] plugins.")
- [native-promise](https://www.npmjs.com/package/native-promise): Get native `Promise` or falsey value if not available. | [homepage](https://github.com/tunnckocore/native-promise#readme "Get native `Promise` or falsey value if not available.")
- [relike-value](https://www.npmjs.com/package/relike-value): Create promise from sync, async, string, number, array and so on. Handle completion (results) and errors gracefully! Built on top… [more](https://github.com/hybridables/relike-value#readme) | [homepage](https://github.com/hybridables/relike-value#readme "Create promise from sync, async, string, number, array and so on. Handle completion (results) and errors gracefully! Built on top of `relike`, used by `redolent` to build robust (hybrid) APIs.")
- [try-catch-core](https://www.npmjs.com/package/try-catch-core): Low-level package to handle completion and errors of sync or asynchronous functions, using [once][] and [dezalgo][] libs. Useful for and… [more](https://github.com/hybridables/try-catch-core#readme) | [homepage](https://github.com/hybridables/try-catch-core#readme "Low-level package to handle completion and errors of sync or asynchronous functions, using [once][] and [dezalgo][] libs. Useful for and used in higher-level libs such as [always-done][] to handle completion of anything.")

## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/hybridables/redolent/issues/new).  
Please read the [contributing guidelines](CONTRIBUTING.md) for advice on opening issues, pull requests, and coding standards.  
If you need some help and can spent some cash, feel free to [contact me at CodeMentor.io](https://www.codementor.io/tunnckocore?utm_source=github&utm_medium=button&utm_term=tunnckocore&utm_campaign=github) too.

**In short:** If you want to contribute to that project, please follow these things

1. Please DO NOT edit [README.md](README.md), [CHANGELOG.md](CHANGELOG.md) and [.verb.md](.verb.md) files. See ["Building docs"](#building-docs) section.
2. Ensure anything is okey by installing the dependencies and run the tests. See ["Running tests"](#running-tests) section.
3. Always use `npm run commit` to commit changes instead of `git commit`, because it is interactive and user-friendly. It uses [commitizen][] behind the scenes, which follows Conventional Changelog idealogy.
4. Do NOT bump the version in package.json. For that we use `npm run release`, which is [standard-version][] and follows Conventional Changelog idealogy.

Thanks a lot! :)

## Building docs
Documentation and that readme is generated using [verb-generate-readme][], which is a [verb][] generator, so you need to install both of them and then run `verb` command like that

```
$ npm install verbose/verb#dev verb-generate-readme --global && verb
```

_Please don't edit the README directly. Any changes to the readme must be made in [.verb.md](.verb.md)._

## Running tests
Clone repository and run the following in that cloned directory

```
$ npm install && npm test
```

## Author
**Charlike Mike Reagent**

+ [github/tunnckoCore](https://github.com/tunnckoCore)
+ [twitter/tunnckoCore](https://twitter.com/tunnckoCore)
+ [codementor/tunnckoCore](https://codementor.io/tunnckoCore)

## License
Copyright © 2015, 2017, [Charlike Mike Reagent](https://i.am.charlike.online). Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 19, 2017._  
_Project scaffolded using [charlike][] cli._

[always-done]: https://github.com/hybridables/always-done
[async-done]: https://github.com/gulpjs/async-done
[base]: https://github.com/node-base/base
[bluebird]: https://github.com/petkaantonov/bluebird
[charlike]: https://github.com/tunnckocore/charlike
[co]: https://github.com/tj/co
[commitizen]: https://github.com/commitizen/cz-cli
[dezalgo]: https://github.com/npm/dezalgo
[is-async-function]: https://github.com/tunnckocore/is-async-function
[once]: https://github.com/isaacs/once
[pinkie]: https://github.com/floatdrop/pinkie
[relike]: https://github.com/hybridables/relike
[standard-version]: https://github.com/conventional-changelog/standard-version
[verb-generate-readme]: https://github.com/verbose/verb-generate-readme
[verb]: https://github.com/verbose/verb

[license-url]: https://www.npmjs.com/package/redolent
[license-img]: https://img.shields.io/npm/l/redolent.svg

[downloads-url]: https://www.npmjs.com/package/redolent
[downloads-img]: https://img.shields.io/npm/dt/redolent.svg

[codeclimate-url]: https://codeclimate.com/github/hybridables/redolent
[codeclimate-img]: https://img.shields.io/codeclimate/github/hybridables/redolent.svg

[travis-url]: https://travis-ci.org/hybridables/redolent
[travis-img]: https://img.shields.io/travis/hybridables/redolent/master.svg?label=linux

[appveyor-url]: https://ci.appveyor.com/project/tunnckoCore/redolent
[appveyor-img]: https://img.shields.io/appveyor/ci/tunnckoCore/redolent/master.svg?label=windows

[coverage-url]: https://codecov.io/gh/hybridables/redolent
[coverage-img]: https://img.shields.io/codecov/c/github/hybridables/redolent/master.svg

[david-url]: https://david-dm.org/hybridables/redolent
[david-img]: https://img.shields.io/david/hybridables/redolent.svg

[standard-url]: https://github.com/feross/standard
[standard-img]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg

[paypalme-url]: https://www.paypal.me/tunnckoCore
[paypalme-img]: https://img.shields.io/badge/paypal-donate-brightgreen.svg

[native-or-another]: https://github.com/tunnckocore/native-or-another