Fix dependabot vulnerabilities

This adds some forced resolutions to ensure that vulnerable versions
of packages are not installed.
This commit is contained in:
Andrew Eisenberg
2021-07-14 14:35:34 -07:00
parent 14deaf67e9
commit ae97d8f96d
81 changed files with 727 additions and 7406 deletions

View File

@@ -1,35 +0,0 @@
'use strict';
var errorEx = require('error-ex');
var fallback = require('./vendor/parse');
var JSONError = errorEx('JSONError', {
fileName: errorEx.append('in %s')
});
module.exports = function (x, reviver, filename) {
if (typeof reviver === 'string') {
filename = reviver;
reviver = null;
}
try {
try {
return JSON.parse(x, reviver);
} catch (err) {
fallback.parse(x, {
mode: 'json',
reviver: reviver
});
throw err;
}
} catch (err) {
var jsonErr = new JSONError(err);
if (filename) {
jsonErr.fileName = filename;
}
throw jsonErr;
}
};

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,46 +0,0 @@
{
"name": "parse-json",
"version": "2.2.0",
"description": "Parse JSON with more helpful errors",
"license": "MIT",
"repository": "sindresorhus/parse-json",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "xo && node test.js"
},
"files": [
"index.js",
"vendor"
],
"keywords": [
"parse",
"json",
"graceful",
"error",
"message",
"humanize",
"friendly",
"helpful",
"string",
"str"
],
"dependencies": {
"error-ex": "^1.2.0"
},
"devDependencies": {
"ava": "0.0.4",
"xo": "*"
},
"xo": {
"ignores": [
"vendor/**"
]
}
}

View File

@@ -1,83 +0,0 @@
# parse-json [![Build Status](https://travis-ci.org/sindresorhus/parse-json.svg?branch=master)](https://travis-ci.org/sindresorhus/parse-json)
> Parse JSON with more helpful errors
## Install
```
$ npm install --save parse-json
```
## Usage
```js
var parseJson = require('parse-json');
var json = '{\n\t"foo": true,\n}';
JSON.parse(json);
/*
undefined:3
}
^
SyntaxError: Unexpected token }
*/
parseJson(json);
/*
JSONError: Trailing comma in object at 3:1
}
^
*/
parseJson(json, 'foo.json');
/*
JSONError: Trailing comma in object at 3:1 in foo.json
}
^
*/
// you can also add the filename at a later point
try {
parseJson(json);
} catch (err) {
err.fileName = 'foo.json';
throw err;
}
/*
JSONError: Trailing comma in object at 3:1 in foo.json
}
^
*/
```
## API
### parseJson(input, [reviver], [filename])
#### input
Type: `string`
#### reviver
Type: `function`
Prescribes how the value originally produced by parsing is transformed, before being returned. See [`JSON.parse` docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter
) for more.
#### filename
Type: `string`
Filename displayed in the error message.
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@@ -1,752 +0,0 @@
/*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
// RTFM: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
var Uni = require('./unicode')
function isHexDigit(x) {
return (x >= '0' && x <= '9')
|| (x >= 'A' && x <= 'F')
|| (x >= 'a' && x <= 'f')
}
function isOctDigit(x) {
return x >= '0' && x <= '7'
}
function isDecDigit(x) {
return x >= '0' && x <= '9'
}
var unescapeMap = {
'\'': '\'',
'"' : '"',
'\\': '\\',
'b' : '\b',
'f' : '\f',
'n' : '\n',
'r' : '\r',
't' : '\t',
'v' : '\v',
'/' : '/',
}
function formatError(input, msg, position, lineno, column, json5) {
var result = msg + ' at ' + (lineno + 1) + ':' + (column + 1)
, tmppos = position - column - 1
, srcline = ''
, underline = ''
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
// output no more than 70 characters before the wrong ones
if (tmppos < position - 70) {
tmppos = position - 70
}
while (1) {
var chr = input[++tmppos]
if (isLineTerminator(chr) || tmppos === input.length) {
if (position >= tmppos) {
// ending line error, so show it after the last char
underline += '^'
}
break
}
srcline += chr
if (position === tmppos) {
underline += '^'
} else if (position > tmppos) {
underline += input[tmppos] === '\t' ? '\t' : ' '
}
// output no more than 78 characters on the string
if (srcline.length > 78) break
}
return result + '\n' + srcline + '\n' + underline
}
function parse(input, options) {
// parse as a standard JSON mode
var json5 = !(options.mode === 'json' || options.legacy)
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
var isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
var length = input.length
, lineno = 0
, linestart = 0
, position = 0
, stack = []
var tokenStart = function() {}
var tokenEnd = function(v) {return v}
/* tokenize({
raw: '...',
type: 'whitespace'|'comment'|'key'|'literal'|'separator'|'newline',
value: 'number'|'string'|'whatever',
path: [...],
})
*/
if (options._tokenize) {
;(function() {
var start = null
tokenStart = function() {
if (start !== null) throw Error('internal error, token overlap')
start = position
}
tokenEnd = function(v, type) {
if (start != position) {
var hash = {
raw: input.substr(start, position-start),
type: type,
stack: stack.slice(0),
}
if (v !== undefined) hash.value = v
options._tokenize.call(null, hash)
}
start = null
return v
}
})()
}
function fail(msg) {
var column = position - linestart
if (!msg) {
if (position < length) {
var token = '\'' +
JSON
.stringify(input[position])
.replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
+ '\''
if (!msg) msg = 'Unexpected token ' + token
} else {
if (!msg) msg = 'Unexpected end of input'
}
}
var error = SyntaxError(formatError(input, msg, position, lineno, column, json5))
error.row = lineno + 1
error.column = column + 1
throw error
}
function newline(chr) {
// account for <cr><lf>
if (chr === '\r' && input[position] === '\n') position++
linestart = position
lineno++
}
function parseGeneric() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'literal')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '-'
|| chr === '.'
|| isDecDigit(chr)
// + number Infinity NaN
|| (json5 && (chr === '+' || chr === 'I' || chr === 'N'))
) {
return tokenEnd(parseNumber(), 'literal')
} else if (chr === 'n') {
parseKeyword('null')
return tokenEnd(null, 'literal')
} else if (chr === 't') {
parseKeyword('true')
return tokenEnd(true, 'literal')
} else if (chr === 'f') {
parseKeyword('false')
return tokenEnd(false, 'literal')
} else {
position--
return tokenEnd(undefined)
}
}
}
function parseKey() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'key')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '.'
|| isDecDigit(chr)
) {
return tokenEnd(parseNumber(true), 'key')
} else if (json5
&& Uni.isIdentifierStart(chr) || (chr === '\\' && input[position] === 'u')) {
// unicode char or a unicode sequence
var rollback = position - 1
var result = parseIdentifier()
if (result === undefined) {
position = rollback
return tokenEnd(undefined)
} else {
return tokenEnd(result, 'key')
}
} else {
position--
return tokenEnd(undefined)
}
}
}
function skipWhiteSpace() {
tokenStart()
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
newline(chr)
tokenEnd(undefined, 'newline')
tokenStart()
} else if (isWhiteSpace(chr)) {
// nothing
} else if (chr === '/'
&& json5
&& (input[position] === '/' || input[position] === '*')
) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
skipComment(input[position++] === '*')
tokenEnd(undefined, 'comment')
tokenStart()
} else {
position--
break
}
}
return tokenEnd(undefined, 'whitespace')
}
function skipComment(multi) {
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
// LineTerminator is an end of singleline comment
if (!multi) {
// let parent function deal with newline
position--
return
}
newline(chr)
} else if (chr === '*' && multi) {
// end of multiline comment
if (input[position] === '/') {
position++
return
}
} else {
// nothing
}
}
if (multi) {
fail('Unclosed multiline comment')
}
}
function parseKeyword(keyword) {
// keyword[0] is not checked because it should've checked earlier
var _pos = position
var len = keyword.length
for (var i=1; i<len; i++) {
if (position >= length || keyword[i] != input[position]) {
position = _pos-1
fail()
}
position++
}
}
function parseObject() {
var result = options.null_prototype ? Object.create(null) : {}
, empty_object = {}
, is_non_empty = false
while (position < length) {
skipWhiteSpace()
var item1 = parseKey()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === '}' && item1 === undefined) {
if (!json5 && is_non_empty) {
position--
fail('Trailing comma in object')
}
return result
} else if (chr === ':' && item1 !== undefined) {
skipWhiteSpace()
stack.push(item1)
var item2 = parseGeneric()
stack.pop()
if (item2 === undefined) fail('No value found for key ' + item1)
if (typeof(item1) !== 'string') {
if (!json5 || typeof(item1) !== 'number') {
fail('Wrong key type: ' + item1)
}
}
if ((item1 in empty_object || empty_object[item1] != null) && options.reserved_keys !== 'replace') {
if (options.reserved_keys === 'throw') {
fail('Reserved key: ' + item1)
} else {
// silently ignore it
}
} else {
if (typeof(options.reviver) === 'function') {
item2 = options.reviver.call(null, item1, item2)
}
if (item2 !== undefined) {
is_non_empty = true
Object.defineProperty(result, item1, {
value: item2,
enumerable: true,
configurable: true,
writable: true,
})
}
}
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === ',') {
continue
} else if (chr === '}') {
return result
} else {
fail()
}
} else {
position--
fail()
}
}
fail()
}
function parseArray() {
var result = []
while (position < length) {
skipWhiteSpace()
stack.push(result.length)
var item = parseGeneric()
stack.pop()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (item !== undefined) {
if (typeof(options.reviver) === 'function') {
item = options.reviver.call(null, String(result.length), item)
}
if (item === undefined) {
result.length++
item = true // hack for check below, not included into result
} else {
result.push(item)
}
}
if (chr === ',') {
if (item === undefined) {
fail('Elisions are not supported')
}
} else if (chr === ']') {
if (!json5 && item === undefined && result.length) {
position--
fail('Trailing comma in array')
}
return result
} else {
position--
fail()
}
}
}
function parseNumber() {
// rewind because we don't know first char
position--
var start = position
, chr = input[position++]
, t
var to_num = function(is_octal) {
var str = input.substr(start, position - start)
if (is_octal) {
var result = parseInt(str.replace(/^0o?/, ''), 8)
} else {
var result = Number(str)
}
if (Number.isNaN(result)) {
position--
fail('Bad numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else if (!json5 && !str.match(/^-?(0|[1-9][0-9]*)(\.[0-9]+)?(e[+-]?[0-9]+)?$/i)) {
// additional restrictions imposed by json
position--
fail('Non-json numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else {
return result
}
}
// ex: -5982475.249875e+29384
// ^ skipping this
if (chr === '-' || (chr === '+' && json5)) chr = input[position++]
if (chr === 'N' && json5) {
parseKeyword('NaN')
return NaN
}
if (chr === 'I' && json5) {
parseKeyword('Infinity')
// returning +inf or -inf
return to_num()
}
if (chr >= '1' && chr <= '9') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// special case for leading zero: 0.123456
if (chr === '0') {
chr = input[position++]
// new syntax, "0o777" old syntax, "0777"
var is_octal = chr === 'o' || chr === 'O' || isOctDigit(chr)
var is_hex = chr === 'x' || chr === 'X'
if (json5 && (is_octal || is_hex)) {
while (position < length
&& (is_hex ? isHexDigit : isOctDigit)( input[position] )
) position++
var sign = 1
if (input[start] === '-') {
sign = -1
start++
} else if (input[start] === '+') {
start++
}
return sign * to_num(is_octal)
}
}
if (chr === '.') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
if (chr === 'e' || chr === 'E') {
chr = input[position++]
if (chr === '-' || chr === '+') position++
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// we have char in the buffer, so count for it
position--
return to_num()
}
function parseIdentifier() {
// rewind because we don't know first char
position--
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === '\\'
&& input[position] === 'u'
&& isHexDigit(input[position+1])
&& isHexDigit(input[position+2])
&& isHexDigit(input[position+3])
&& isHexDigit(input[position+4])
) {
// UnicodeEscapeSequence
chr = String.fromCharCode(parseInt(input.substr(position+1, 4), 16))
position += 5
}
if (result.length) {
// identifier started
if (Uni.isIdentifierPart(chr)) {
result += chr
} else {
position--
return result
}
} else {
if (Uni.isIdentifierStart(chr)) {
result += chr
} else {
return undefined
}
}
}
fail()
}
function parseString(endChar) {
// 7.8.4 of ES262 spec
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === endChar) {
return result
} else if (chr === '\\') {
if (position >= length) fail()
chr = input[position++]
if (unescapeMap[chr] && (json5 || (chr != 'v' && chr != "'"))) {
result += unescapeMap[chr]
} else if (json5 && isLineTerminator(chr)) {
// line continuation
newline(chr)
} else if (chr === 'u' || (chr === 'x' && json5)) {
// unicode/character escape sequence
var off = chr === 'u' ? 4 : 2
// validation for \uXXXX
for (var i=0; i<off; i++) {
if (position >= length) fail()
if (!isHexDigit(input[position])) fail('Bad escape sequence')
position++
}
result += String.fromCharCode(parseInt(input.substr(position-off, off), 16))
} else if (json5 && isOctDigit(chr)) {
if (chr < '4' && isOctDigit(input[position]) && isOctDigit(input[position+1])) {
// three-digit octal
var digits = 3
} else if (isOctDigit(input[position])) {
// two-digit octal
var digits = 2
} else {
var digits = 1
}
position += digits - 1
result += String.fromCharCode(parseInt(input.substr(position-digits, digits), 8))
/*if (!isOctDigit(input[position])) {
// \0 is allowed still
result += '\0'
} else {
fail('Octal literals are not supported')
}*/
} else if (json5) {
// \X -> x
result += chr
} else {
position--
fail()
}
} else if (isLineTerminator(chr)) {
fail()
} else {
if (!json5 && chr.charCodeAt(0) < 32) {
position--
fail('Unexpected control character')
}
// SourceCharacter but not one of " or \ or LineTerminator
result += chr
}
}
fail()
}
skipWhiteSpace()
var return_value = parseGeneric()
if (return_value !== undefined || position < length) {
skipWhiteSpace()
if (position >= length) {
if (typeof(options.reviver) === 'function') {
return_value = options.reviver.call(null, '', return_value)
}
return return_value
} else {
fail()
}
} else {
if (position) {
fail('No data, only a whitespace')
} else {
fail('No data, empty input')
}
}
}
/*
* parse(text, options)
* or
* parse(text, reviver)
*
* where:
* text - string
* options - object
* reviver - function
*/
module.exports.parse = function parseJSON(input, options) {
// support legacy functions
if (typeof(options) === 'function') {
options = {
reviver: options
}
}
if (input === undefined) {
// parse(stringify(x)) should be equal x
// with JSON functions it is not 'cause of undefined
// so we're fixing it
return undefined
}
// JSON.parse compat
if (typeof(input) !== 'string') input = String(input)
if (options == null) options = {}
if (options.reserved_keys == null) options.reserved_keys = 'ignore'
if (options.reserved_keys === 'throw' || options.reserved_keys === 'ignore') {
if (options.null_prototype == null) {
options.null_prototype = true
}
}
try {
return parse(input, options)
} catch(err) {
// jju is a recursive parser, so JSON.parse("{{{{{{{") could blow up the stack
//
// this catch is used to skip all those internal calls
if (err instanceof SyntaxError && err.row != null && err.column != null) {
var old_err = err
err = SyntaxError(old_err.message)
err.column = old_err.column
err.row = old_err.row
}
throw err
}
}
module.exports.tokenize = function tokenizeJSON(input, options) {
if (options == null) options = {}
options._tokenize = function(smth) {
if (options._addstack) smth.stack.unshift.apply(smth.stack, options._addstack)
tokens.push(smth)
}
var tokens = []
tokens.data = module.exports.parse(input, options)
return tokens
}

File diff suppressed because one or more lines are too long

View File

@@ -1,68 +0,0 @@
'use strict';
var processFn = function (fn, P, opts) {
return function () {
var that = this;
var args = new Array(arguments.length);
for (var i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
return new P(function (resolve, reject) {
args.push(function (err, result) {
if (err) {
reject(err);
} else if (opts.multiArgs) {
var results = new Array(arguments.length - 1);
for (var i = 1; i < arguments.length; i++) {
results[i - 1] = arguments[i];
}
resolve(results);
} else {
resolve(result);
}
});
fn.apply(that, args);
});
};
};
var pify = module.exports = function (obj, P, opts) {
if (typeof P !== 'function') {
opts = P;
P = Promise;
}
opts = opts || {};
opts.exclude = opts.exclude || [/.+Sync$/];
var filter = function (key) {
var match = function (pattern) {
return typeof pattern === 'string' ? key === pattern : pattern.test(key);
};
return opts.include ? opts.include.some(match) : !opts.exclude.some(match);
};
var ret = typeof obj === 'function' ? function () {
if (opts.excludeMain) {
return obj.apply(this, arguments);
}
return processFn(obj, P, opts).apply(this, arguments);
} : {};
return Object.keys(obj).reduce(function (ret, key) {
var x = obj[key];
ret[key] = typeof x === 'function' && filter(key) ? processFn(x, P, opts) : x;
return ret;
}, ret);
};
pify.all = pify;

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,48 +0,0 @@
{
"name": "pify",
"version": "2.3.0",
"description": "Promisify a callback-style function",
"license": "MIT",
"repository": "sindresorhus/pify",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "xo && ava && npm run optimization-test",
"optimization-test": "node --allow-natives-syntax optimization-test.js"
},
"files": [
"index.js"
],
"keywords": [
"promise",
"promises",
"promisify",
"denodify",
"denodeify",
"callback",
"cb",
"node",
"then",
"thenify",
"convert",
"transform",
"wrap",
"wrapper",
"bind",
"to",
"async",
"es2015"
],
"devDependencies": {
"ava": "*",
"pinkie-promise": "^1.0.0",
"v8-natives": "0.0.2",
"xo": "*"
}
}

View File

@@ -1,119 +0,0 @@
# pify [![Build Status](https://travis-ci.org/sindresorhus/pify.svg?branch=master)](https://travis-ci.org/sindresorhus/pify)
> Promisify a callback-style function
## Install
```
$ npm install --save pify
```
## Usage
```js
const fs = require('fs');
const pify = require('pify');
// promisify a single function
pify(fs.readFile)('package.json', 'utf8').then(data => {
console.log(JSON.parse(data).name);
//=> 'pify'
});
// or promisify all methods in a module
pify(fs).readFile('package.json', 'utf8').then(data => {
console.log(JSON.parse(data).name);
//=> 'pify'
});
```
## API
### pify(input, [promiseModule], [options])
Returns a promise wrapped version of the supplied function or module.
#### input
Type: `function`, `object`
Callback-style function or module whose methods you want to promisify.
#### promiseModule
Type: `function`
Custom promise module to use instead of the native one.
Check out [`pinkie-promise`](https://github.com/floatdrop/pinkie-promise) if you need a tiny promise polyfill.
#### options
##### multiArgs
Type: `boolean`
Default: `false`
By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like `request` that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument.
```js
const request = require('request');
const pify = require('pify');
pify(request, {multiArgs: true})('https://sindresorhus.com').then(result => {
const [httpResponse, body] = result;
});
```
##### include
Type: `array` of (`string`|`regex`)
Methods in a module to promisify. Remaining methods will be left untouched.
##### exclude
Type: `array` of (`string`|`regex`)
Default: `[/.+Sync$/]`
Methods in a module **not** to promisify. Methods with names ending with `'Sync'` are excluded by default.
##### excludeMain
Type: `boolean`
Default: `false`
By default, if given module is a function itself, this function will be promisified. Turn this option on if you want to promisify only methods of the module.
```js
const pify = require('pify');
function fn() {
return true;
}
fn.method = (data, callback) => {
setImmediate(() => {
callback(data, null);
});
};
// promisify methods but not fn()
const promiseFn = pify(fn, {excludeMain: true});
if (promiseFn()) {
promiseFn.method('hi').then(data => {
console.log(data);
});
}
```
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)