From b3edc4e3173430308ea7d304926cd8c424997d0f Mon Sep 17 00:00:00 2001 From: tunnckoCore Date: Sun, 19 Mar 2017 07:06:41 +0200 Subject: [PATCH] fix(deps): switch to use "native-or-another" may break in old envs. calling redolent() now throws if no promise found by the native-or-another detection - before it was throwing from the promisified function, now it throws earlier --- README.md | 19 +- dist/redolent.common.js | 1435 ++++++++++++++++++++++++++++++++++++++- dist/redolent.es.js | 1435 ++++++++++++++++++++++++++++++++++++++- index.js | 52 +- package.json | 5 +- test.js | 42 +- yarn.lock | 198 +++--- 7 files changed, 3021 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index 02c602d..9be581d 100644 --- a/README.md +++ b/README.md @@ -49,16 +49,24 @@ const redolent = require('redolent') ## API -### [redolent](index.js#L71) +### [redolent](index.js#L86) 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!_ +**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. + **Params** * `` **{Function}**: a function to be promisified -* `[opts]` **{Object}**: optional options - like `.args`, `.context`, `.Promise` +* `[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 function, like [bluebird][] for example, by default uses the native Promise +* `[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** @@ -119,7 +127,7 @@ console.log(promise.___nativePromise) // => false - [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 | [homepage](https://github.com/tunnckocore/dush#readme "Microscopic & functional event emitter") +- [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.") @@ -168,7 +176,7 @@ Copyright © 2015, 2017, [Charlike Mike Reagent](https://i.am.charlike.online). *** -_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 11, 2017._ +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 17, 2017._ _Project scaffolded using [charlike][] cli._ [always-done]: https://github.com/hybridables/always-done @@ -214,3 +222,4 @@ _Project scaffolded using [charlike][] cli._ [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 \ No newline at end of file diff --git a/dist/redolent.common.js b/dist/redolent.common.js index 3433132..201cee4 100644 --- a/dist/redolent.common.js +++ b/dist/redolent.common.js @@ -86,11 +86,1383 @@ function hasOwn(obj, key) { var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); +} + + + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var semver = createCommonjsModule(function (module, exports) { +exports = module.exports = SemVer; + +// The debug function is excluded entirely from the minified version. +/* nomin */ var debug; +/* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ { debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; } +/* nomin */ else + /* nomin */ { debug = function() {}; } + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0'; + +var MAX_LENGTH = 256; +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// The actual regexps go on exports.re +var re = exports.re = []; +var src = exports.src = []; +var R = 0; + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++; +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; +var NUMERICIDENTIFIERLOOSE = R++; +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++; +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++; +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + +var MAINVERSIONLOOSE = R++; +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++; +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + +var PRERELEASEIDENTIFIERLOOSE = R++; +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++; +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + +var PRERELEASELOOSE = R++; +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++; +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++; +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++; +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + +src[FULL] = '^' + FULLPLAIN + '$'; + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + +var LOOSE = R++; +src[LOOSE] = '^' + LOOSEPLAIN + '$'; + +var GTLT = R++; +src[GTLT] = '((?:<|>)?=?)'; + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++; +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; +var XRANGEIDENTIFIER = R++; +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + +var XRANGEPLAIN = R++; +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGEPLAINLOOSE = R++; +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGE = R++; +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; +var XRANGELOOSE = R++; +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++; +src[LONETILDE] = '(?:~>?)'; + +var TILDETRIM = R++; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; + +var TILDE = R++; +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; +var TILDELOOSE = R++; +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++; +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; +var COMPARATOR = R++; +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++; +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); +var comparatorTrimReplace = '$1$2$3'; + + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++; +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + +var HYPHENRANGELOOSE = R++; +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + +// Star ranges basically just allow anything at all. +var STAR = R++; +src[STAR] = '(<|>)?=?\\s*\\*'; + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + { re[i] = new RegExp(src[i]); } +} + +exports.parse = parse; +function parse(version, loose) { + if (version instanceof SemVer) + { return version; } + + if (typeof version !== 'string') + { return null; } + + if (version.length > MAX_LENGTH) + { return null; } + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + { return null; } + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } +} + +exports.valid = valid; +function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; +} + + +exports.clean = clean; +function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; +} + +exports.SemVer = SemVer; + +function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + { return version; } + else + { version = version.version; } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + { throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') } + + if (!(this instanceof SemVer)) + { return new SemVer(version, loose); } + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + { throw new TypeError('Invalid Version: ' + version); } + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + { throw new TypeError('Invalid major version') } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + { throw new TypeError('Invalid minor version') } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + { throw new TypeError('Invalid patch version') } + + // numberify any prerelease numeric ids + if (!m[4]) + { this.prerelease = []; } + else + { this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) + { return num; } + } + return id; + }); } + + this.build = m[5] ? m[5].split('.') : []; + this.format(); +} + +SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + { this.version += '-' + this.prerelease.join('.'); } + return this.version; +}; + +SemVer.prototype.toString = function() { + return this.version; +}; + +SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + return this.compareMain(other) || this.comparePre(other); +}; + +SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); +}; + +SemVer.prototype.comparePre = function(other) { + var this$1 = this; + + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + { return -1; } + else if (!this.prerelease.length && other.prerelease.length) + { return 1; } + else if (!this.prerelease.length && !other.prerelease.length) + { return 0; } + + var i = 0; + do { + var a = this$1.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + { return 0; } + else if (b === undefined) + { return 1; } + else if (a === undefined) + { return -1; } + else if (a === b) + { continue; } + else + { return compareIdentifiers(a, b); } + } while (++i); +}; + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function(release, identifier) { + var this$1 = this; + + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + { this.inc('patch', identifier); } + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + { this.major++; } + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + { this.minor++; } + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + { this.patch++; } + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + { this.prerelease = [0]; } + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this$1.prerelease[i] === 'number') { + this$1.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + { this.prerelease.push(0); } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + { this.prerelease = [identifier, 0]; } + } else + { this.prerelease = [identifier, 0]; } + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; +}; + +exports.inc = inc; +function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } +} + +exports.diff = diff; +function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } +} + +exports.compareIdentifiers = compareIdentifiers; + +var numeric = /^[0-9]+$/; +function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; +} + +exports.rcompareIdentifiers = rcompareIdentifiers; +function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); +} + +exports.major = major; +function major(a, loose) { + return new SemVer(a, loose).major; +} + +exports.minor = minor; +function minor(a, loose) { + return new SemVer(a, loose).minor; +} + +exports.patch = patch; +function patch(a, loose) { + return new SemVer(a, loose).patch; +} + +exports.compare = compare; +function compare(a, b, loose) { + return new SemVer(a, loose).compare(b); +} + +exports.compareLoose = compareLoose; +function compareLoose(a, b) { + return compare(a, b, true); +} + +exports.rcompare = rcompare; +function rcompare(a, b, loose) { + return compare(b, a, loose); +} + +exports.sort = sort; +function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); +} + +exports.rsort = rsort; +function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); +} + +exports.gt = gt; +function gt(a, b, loose) { + return compare(a, b, loose) > 0; +} + +exports.lt = lt; +function lt(a, b, loose) { + return compare(a, b, loose) < 0; +} + +exports.eq = eq; +function eq(a, b, loose) { + return compare(a, b, loose) === 0; +} + +exports.neq = neq; +function neq(a, b, loose) { + return compare(a, b, loose) !== 0; +} + +exports.gte = gte; +function gte(a, b, loose) { + return compare(a, b, loose) >= 0; +} + +exports.lte = lte; +function lte(a, b, loose) { + return compare(a, b, loose) <= 0; +} + +exports.cmp = cmp; +function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') { a = a.version; } + if (typeof b === 'object') { b = b.version; } + ret = a === b; + break; + case '!==': + if (typeof a === 'object') { a = a.version; } + if (typeof b === 'object') { b = b.version; } + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; +} + +exports.Comparator = Comparator; +function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + { return comp; } + else + { comp = comp.value; } + } + + if (!(this instanceof Comparator)) + { return new Comparator(comp, loose); } + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + { this.value = ''; } + else + { this.value = this.operator + this.semver.version; } + + debug('comp', this); +} + +var ANY = {}; +Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + { throw new TypeError('Invalid comparator: ' + comp); } + + this.operator = m[1]; + if (this.operator === '=') + { this.operator = ''; } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + { this.semver = ANY; } + else + { this.semver = new SemVer(m[2], this.loose); } +}; + +Comparator.prototype.toString = function() { + return this.value; +}; + +Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + { return true; } + + if (typeof version === 'string') + { version = new SemVer(version, this.loose); } + + return cmp(version, this.operator, this.semver, this.loose); +}; + + +exports.Range = Range; +function Range(range, loose) { + if ((range instanceof Range) && range.loose === loose) + { return range; } + + if (!(this instanceof Range)) + { return new Range(range, loose); } + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); +} + +Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; +}; + +Range.prototype.toString = function() { + return this.range; +}; + +Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; +}; + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators; +function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; +} + +function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); +} + +function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + { ret = ''; } + else if (isX(m)) + { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; } + else if (isX(p)) + // ~1.2 == >=1.2.0 <1.3.0 + { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; } + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + { pr = '-' + pr; } + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; } + + debug('tilde return', ret); + return ret; + }); +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + { ret = ''; } + else if (isX(m)) + { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; } + else if (isX(p)) { + if (M === '0') + { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; } + else + { ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; } + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + { pr = '-' + pr; } + if (M === '0') { + if (m === '0') + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); } + else + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; } + } else + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; } + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); } + else + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; } + } else + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; } + } + + debug('caret return', ret); + return ret; + }); +} + +function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); +} + +function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + { gtlt = ''; } + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; + } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + { m = 0; } + if (xp) + { p = 0; } + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<'; + if (xm) + { M = +M + 1; } + else + { m = +m + 1; } + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + { from = ''; } + else if (isX(fm)) + { from = '>=' + fM + '.0.0'; } + else if (isX(fp)) + { from = '>=' + fM + '.' + fm + '.0'; } + else + { from = '>=' + from; } + + if (isX(tM)) + { to = ''; } + else if (isX(tm)) + { to = '<' + (+tM + 1) + '.0.0'; } + else if (isX(tp)) + { to = '<' + tM + '.' + (+tm + 1) + '.0'; } + else if (tpr) + { to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; } + else + { to = '<=' + to; } + + return (from + ' ' + to).trim(); +} + + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function(version) { + var this$1 = this; + + if (!version) + { return false; } + + if (typeof version === 'string') + { version = new SemVer(version, this.loose); } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this$1.set[i], version)) + { return true; } + } + return false; +}; + +function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + { return false; } + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + { continue; } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + { return true; } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; +} + +exports.satisfies = satisfies; +function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); +} + +exports.maxSatisfying = maxSatisfying; +function maxSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return rcompare(a, b, loose); + })[0] || null; +} + +exports.minSatisfying = minSatisfying; +function minSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return compare(a, b, loose); + })[0] || null; +} + +exports.validRange = validRange; +function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr; +function ltr(version, range, loose) { + return outside(version, range, '<', loose); +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr; +function gtr(version, range, loose) { + return outside(version, range, '>', loose); +} + +exports.outside = outside; +function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0'); + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; +} + +exports.prerelease = prerelease; +function prerelease(version, loose) { + var parsed = parse(version, loose); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; +} +}); + var index$10 = typeof commonjsGlobal === 'object' && commonjsGlobal.Promise || typeof window === 'object' && window.Promise || typeof Promise !== 'undefined' && Promise || false; +/** + * > Pass a synchronous `fn` that returns some + * result and handle completion or errors in `cb` + * if given, otherwise it returns thunk which accepts + * that `cb`. It's possible to not work in "async mode", + * if that's the case try to use [try-catch-core][] for + * your case, which guarantees that `cb` is called only + * once and always in next tick, using [dezalgo][] and [once][]. + * + * **Example** + * + * ```js + * var tryCatch = require('try-catch-callback') + * + * tryCatch(function () { + * return 'fox qux' + * }, function done (err, res) { + * if (err) return console.error(err) + * console.log(res) // => 'fox qux' + * }) + * ``` + * + * @param {Function} `` function to be called. + * @param {Object} `[opts]` optional options, such as `context` and `args` + * @param {Object} `[opts.context]` context to be passed to `fn` + * @param {Array} `[opts.args]` custom argument(s) to be pass to `fn`, given value is arrayified + * @param {Boolean} `[opts.passCallback]` pass `true` if you want `cb` to be passed to `fn` args + * @param {Boolean} `[opts.return]` if `true` returns error/value and does not calls `cb` + * @param {Function} `[cb]` callback with `cb(err, res)` signature. + * @return {Function} `thunk` if `cb` not given. + * @throws {TypError} if `fn` not a function. + * @throws {TypError} if no function is passed to `thunk`. + * @api public + */ + +var index$12 = function tryCatchCallback (fn, opts, cb) { + if (typeof fn !== 'function') { + throw new TypeError('try-catch-callback: expect `fn` to be a function') + } + if (typeof opts === 'function') { + cb = opts; + opts = false; + } + opts = index$6({}, opts); + + if (opts.return || typeof cb === 'function') { + return tryCatch.call(this, fn, opts, cb) + } + return function thunk (done) { + opts.thunk = true; + tryCatch.call(this, fn, opts, done); + } +}; + +function tryCatch (fn, opts, cb) { + if (opts.thunk && typeof cb !== 'function') { + throw new TypeError('try-catch-callback: expect `cb` to be a function') + } + var args = arrayify(opts.args); + var ctx = opts.context || this; + var ret = null; + + try { + ret = fn.apply(ctx, opts.passCallback ? args.concat(cb) : args); + } catch (err) { + return opts.return ? err : cb(err) + } + + if (opts.return) { return ret } + if (!opts.passCallback) { cb(null, ret); } +} + +function arrayify (val) { + if (!val) { return [] } + if (Array.isArray(val)) { return val } + return [val] +} + +var commonPromiseLibs = [ + 'es6-promise', + 'promise', + 'native-promise-only', + 'bluebird', + 'rsvp', + 'when', + 'q', + 'pinkie', + 'lie', + 'vow' +]; + +var register = function register (opts) { + // won't load native Promise if < v0.12, since it is buggy + /* istanbul ignore next */ + if (index$10 && semver.gte(process.version, '0.12.0')) { + index$10.___nativePromise = true; + return index$10 + } + if (typeof opts === 'function') { + opts = { Promise: opts, global: opts.global }; + } + + var options = index$6({ global: true }, opts); + var PromiseCtor = options.Promise || tryLoadCommon(); + PromiseCtor.___customPromise = true; + + if (options.global === false) { + return PromiseCtor + } + + commonjsGlobal.Promise = PromiseCtor; + return commonjsGlobal.Promise +}; + +function tryLoadCommon () { + var len = commonPromiseLibs.length; + var i = -1; + + while (i++ < len) { + var lib = commonPromiseLibs[i]; + var ret = index$12(function () { + var ret = commonjsRequire(lib); + return ret.Promise || ret + }, { return: true }); + + if (ret instanceof Error) { + if ((i + 1) < len) { + continue + } else { + var msg = [ + 'No native Promise support nor other promise were found.', + 'These promise libraries are supported by default: ' + commonPromiseLibs.join(', ') + '.', + 'This means that if one of them is installed it will be loaded automatically.', + 'Otherwise you should give a promise implementation through opts.Promise!' + ].join(' '); + + throw new Error(msg) + } + } else { + return ret + } + } +} + +var commonPromiseLibs_1 = commonPromiseLibs; + +register.commonPromiseLibs = commonPromiseLibs_1; + +var index$14 = register({ global: false }); + /** * > Check any of `values` exists on `arr`. * @@ -128,7 +1500,7 @@ var index$10 = typeof commonjsGlobal === 'object' && commonjsGlobal.Promise || * @api public */ -var index$14 = function arrIncludes (arr, values) { +var index$18 = function arrIncludes (arr, values) { if (!Array.isArray(values)) { return inArray(arr, values) } var len = values.length; var i = -1; @@ -163,7 +1535,7 @@ function inArray (arr, val) { * Released under the MIT license. */ -var index$16 = [ +var index$20 = [ 'callback', 'callback_', 'cb', @@ -202,7 +1574,7 @@ var index$16 = [ * @api public */ -var index$18 = function functionArguments (fn) { +var index$22 = function functionArguments (fn) { if (typeof fn !== 'function') { throw new TypeError('function-arguments expect a function') } @@ -267,7 +1639,7 @@ var index$18 = function functionArguments (fn) { * @api public */ -var index$12 = function isAsyncFunction (fn, names, strict) { +var index$16 = function isAsyncFunction (fn, names, strict) { if (typeof fn !== 'function') { throw new TypeError('is-async-function expect a function') } @@ -277,9 +1649,9 @@ var index$12 = function isAsyncFunction (fn, names, strict) { names = typeof names === 'boolean' ? null : names; names = Array.isArray(names) ? names : index$2(names); - names = names.length ? names : index$16; + names = names.length ? names : index$20; - var idx = index$14(names, index$18(fn)); + var idx = index$18(names, index$22(fn)); return strict ? Boolean(idx) : idx }; @@ -291,6 +1663,14 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * 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!_ + * + * **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. + * * **Example** * * ```js @@ -323,7 +1703,7 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * * @name redolent * @param {Function} `` a function to be promisified - * @param {Object} `[opts]` optional options - like `.args`, `.context`, `.Promise` + * @param {Object} `[opts]` optional options, also passed to [native-or-another][] * @param {Array} `[opts.args]` additional arguments to be passed to `fn`, * all args from `opts.args` and these that are * passed to promisifed function are concatenated @@ -331,10 +1711,16 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * by default it is smart enough and applies * the `this` context of redolent call or the call * of the promisified function - * @param {Function} `[opts.Promise]` custom Promise constructor function, - * like [bluebird][] for example, - * by default uses the native Promise + * @param {Function} `[opts.Promise]` custom Promise constructor for versions `< v0.12`, + * like [bluebird][] for example, by default + * it **always** uses the native Promise in newer + * node versions + * @param {Boolean} `[opts.global]` 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` * @return {Function} promisified function + * @throws {TypeError} If `fn` is not a function + * @throws {TypeError} If no promise is found * @api public */ @@ -343,19 +1729,22 @@ var index = function redolent (fn, opts) { throw new TypeError('redolent: expect `fn` to be a function') } - opts = index$6({ - context: this, - Promise: index$10 - }, opts); + opts = index$6({ context: this, Promise: index$14 }, opts); + opts.Promise = register(opts); + + // we can't test that here, because some + // of our devDeps has some Promise library, + // so it's loaded by `native-or-another` automatically + /* istanbul ignore next */ + if (typeof opts.Promise !== 'function') { + var msg = 'no native Promise support nor other promise were found'; + throw new TypeError('redolent: ' + msg) + } return function () { opts.context = this || opts.context; opts.args = index$2(opts.args).concat(index$4(arguments)); - if (typeof opts.Promise !== 'function') { - throw new TypeError('redolent: no native Promise support and no opts.Promise') - } - var promise = new opts.Promise(function (resolve, reject) { var called = false; @@ -370,7 +1759,7 @@ var index = function redolent (fn, opts) { return resolve(res) } - var isAsyncFn = index$12(fn); + var isAsyncFn = index$16(fn); opts.args = isAsyncFn ? opts.args.concat(done) : opts.args; var syncResult = fn.apply(opts.context, opts.args); @@ -380,13 +1769,13 @@ var index = function redolent (fn, opts) { } }); - return normalize(promise, index$10) + return normalize(promise, opts.Promise) } }; -function normalize (promise, isNativeSupported) { - promise.___nativePromise = Boolean(isNativeSupported); - promise.___customPromise = !promise.___nativePromise; +function normalize (promise, Ctor) { + promise.___nativePromise = Boolean(Ctor.___nativePromise); + promise.___customPromise = Boolean(Ctor.___customPromise); return promise } diff --git a/dist/redolent.es.js b/dist/redolent.es.js index 0c5917c..1f799c3 100644 --- a/dist/redolent.es.js +++ b/dist/redolent.es.js @@ -84,11 +84,1383 @@ function hasOwn(obj, key) { var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); +} + + + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var semver = createCommonjsModule(function (module, exports) { +exports = module.exports = SemVer; + +// The debug function is excluded entirely from the minified version. +/* nomin */ var debug; +/* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ { debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; } +/* nomin */ else + /* nomin */ { debug = function() {}; } + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0'; + +var MAX_LENGTH = 256; +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// The actual regexps go on exports.re +var re = exports.re = []; +var src = exports.src = []; +var R = 0; + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++; +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; +var NUMERICIDENTIFIERLOOSE = R++; +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++; +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++; +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + +var MAINVERSIONLOOSE = R++; +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++; +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + +var PRERELEASEIDENTIFIERLOOSE = R++; +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++; +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + +var PRERELEASELOOSE = R++; +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++; +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++; +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++; +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + +src[FULL] = '^' + FULLPLAIN + '$'; + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + +var LOOSE = R++; +src[LOOSE] = '^' + LOOSEPLAIN + '$'; + +var GTLT = R++; +src[GTLT] = '((?:<|>)?=?)'; + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++; +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; +var XRANGEIDENTIFIER = R++; +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + +var XRANGEPLAIN = R++; +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGEPLAINLOOSE = R++; +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGE = R++; +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; +var XRANGELOOSE = R++; +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++; +src[LONETILDE] = '(?:~>?)'; + +var TILDETRIM = R++; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; + +var TILDE = R++; +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; +var TILDELOOSE = R++; +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++; +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; +var COMPARATOR = R++; +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++; +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); +var comparatorTrimReplace = '$1$2$3'; + + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++; +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + +var HYPHENRANGELOOSE = R++; +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + +// Star ranges basically just allow anything at all. +var STAR = R++; +src[STAR] = '(<|>)?=?\\s*\\*'; + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + { re[i] = new RegExp(src[i]); } +} + +exports.parse = parse; +function parse(version, loose) { + if (version instanceof SemVer) + { return version; } + + if (typeof version !== 'string') + { return null; } + + if (version.length > MAX_LENGTH) + { return null; } + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + { return null; } + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } +} + +exports.valid = valid; +function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; +} + + +exports.clean = clean; +function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; +} + +exports.SemVer = SemVer; + +function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + { return version; } + else + { version = version.version; } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + { throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') } + + if (!(this instanceof SemVer)) + { return new SemVer(version, loose); } + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + { throw new TypeError('Invalid Version: ' + version); } + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + { throw new TypeError('Invalid major version') } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + { throw new TypeError('Invalid minor version') } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + { throw new TypeError('Invalid patch version') } + + // numberify any prerelease numeric ids + if (!m[4]) + { this.prerelease = []; } + else + { this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) + { return num; } + } + return id; + }); } + + this.build = m[5] ? m[5].split('.') : []; + this.format(); +} + +SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + { this.version += '-' + this.prerelease.join('.'); } + return this.version; +}; + +SemVer.prototype.toString = function() { + return this.version; +}; + +SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + return this.compareMain(other) || this.comparePre(other); +}; + +SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); +}; + +SemVer.prototype.comparePre = function(other) { + var this$1 = this; + + if (!(other instanceof SemVer)) + { other = new SemVer(other, this.loose); } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + { return -1; } + else if (!this.prerelease.length && other.prerelease.length) + { return 1; } + else if (!this.prerelease.length && !other.prerelease.length) + { return 0; } + + var i = 0; + do { + var a = this$1.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + { return 0; } + else if (b === undefined) + { return 1; } + else if (a === undefined) + { return -1; } + else if (a === b) + { continue; } + else + { return compareIdentifiers(a, b); } + } while (++i); +}; + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function(release, identifier) { + var this$1 = this; + + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + { this.inc('patch', identifier); } + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + { this.major++; } + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + { this.minor++; } + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + { this.patch++; } + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + { this.prerelease = [0]; } + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this$1.prerelease[i] === 'number') { + this$1.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + { this.prerelease.push(0); } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + { this.prerelease = [identifier, 0]; } + } else + { this.prerelease = [identifier, 0]; } + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; +}; + +exports.inc = inc; +function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } +} + +exports.diff = diff; +function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } +} + +exports.compareIdentifiers = compareIdentifiers; + +var numeric = /^[0-9]+$/; +function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; +} + +exports.rcompareIdentifiers = rcompareIdentifiers; +function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); +} + +exports.major = major; +function major(a, loose) { + return new SemVer(a, loose).major; +} + +exports.minor = minor; +function minor(a, loose) { + return new SemVer(a, loose).minor; +} + +exports.patch = patch; +function patch(a, loose) { + return new SemVer(a, loose).patch; +} + +exports.compare = compare; +function compare(a, b, loose) { + return new SemVer(a, loose).compare(b); +} + +exports.compareLoose = compareLoose; +function compareLoose(a, b) { + return compare(a, b, true); +} + +exports.rcompare = rcompare; +function rcompare(a, b, loose) { + return compare(b, a, loose); +} + +exports.sort = sort; +function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); +} + +exports.rsort = rsort; +function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); +} + +exports.gt = gt; +function gt(a, b, loose) { + return compare(a, b, loose) > 0; +} + +exports.lt = lt; +function lt(a, b, loose) { + return compare(a, b, loose) < 0; +} + +exports.eq = eq; +function eq(a, b, loose) { + return compare(a, b, loose) === 0; +} + +exports.neq = neq; +function neq(a, b, loose) { + return compare(a, b, loose) !== 0; +} + +exports.gte = gte; +function gte(a, b, loose) { + return compare(a, b, loose) >= 0; +} + +exports.lte = lte; +function lte(a, b, loose) { + return compare(a, b, loose) <= 0; +} + +exports.cmp = cmp; +function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') { a = a.version; } + if (typeof b === 'object') { b = b.version; } + ret = a === b; + break; + case '!==': + if (typeof a === 'object') { a = a.version; } + if (typeof b === 'object') { b = b.version; } + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; +} + +exports.Comparator = Comparator; +function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + { return comp; } + else + { comp = comp.value; } + } + + if (!(this instanceof Comparator)) + { return new Comparator(comp, loose); } + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + { this.value = ''; } + else + { this.value = this.operator + this.semver.version; } + + debug('comp', this); +} + +var ANY = {}; +Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + { throw new TypeError('Invalid comparator: ' + comp); } + + this.operator = m[1]; + if (this.operator === '=') + { this.operator = ''; } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + { this.semver = ANY; } + else + { this.semver = new SemVer(m[2], this.loose); } +}; + +Comparator.prototype.toString = function() { + return this.value; +}; + +Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + { return true; } + + if (typeof version === 'string') + { version = new SemVer(version, this.loose); } + + return cmp(version, this.operator, this.semver, this.loose); +}; + + +exports.Range = Range; +function Range(range, loose) { + if ((range instanceof Range) && range.loose === loose) + { return range; } + + if (!(this instanceof Range)) + { return new Range(range, loose); } + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); +} + +Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; +}; + +Range.prototype.toString = function() { + return this.range; +}; + +Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; +}; + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators; +function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; +} + +function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); +} + +function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + { ret = ''; } + else if (isX(m)) + { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; } + else if (isX(p)) + // ~1.2 == >=1.2.0 <1.3.0 + { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; } + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + { pr = '-' + pr; } + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; } + + debug('tilde return', ret); + return ret; + }); +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + { ret = ''; } + else if (isX(m)) + { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; } + else if (isX(p)) { + if (M === '0') + { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; } + else + { ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; } + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + { pr = '-' + pr; } + if (M === '0') { + if (m === '0') + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); } + else + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; } + } else + { ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; } + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); } + else + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; } + } else + { ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; } + } + + debug('caret return', ret); + return ret; + }); +} + +function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); +} + +function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + { gtlt = ''; } + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; + } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + { m = 0; } + if (xp) + { p = 0; } + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<'; + if (xm) + { M = +M + 1; } + else + { m = +m + 1; } + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + { from = ''; } + else if (isX(fm)) + { from = '>=' + fM + '.0.0'; } + else if (isX(fp)) + { from = '>=' + fM + '.' + fm + '.0'; } + else + { from = '>=' + from; } + + if (isX(tM)) + { to = ''; } + else if (isX(tm)) + { to = '<' + (+tM + 1) + '.0.0'; } + else if (isX(tp)) + { to = '<' + tM + '.' + (+tm + 1) + '.0'; } + else if (tpr) + { to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; } + else + { to = '<=' + to; } + + return (from + ' ' + to).trim(); +} + + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function(version) { + var this$1 = this; + + if (!version) + { return false; } + + if (typeof version === 'string') + { version = new SemVer(version, this.loose); } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this$1.set[i], version)) + { return true; } + } + return false; +}; + +function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + { return false; } + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + { continue; } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + { return true; } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; +} + +exports.satisfies = satisfies; +function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); +} + +exports.maxSatisfying = maxSatisfying; +function maxSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return rcompare(a, b, loose); + })[0] || null; +} + +exports.minSatisfying = minSatisfying; +function minSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return compare(a, b, loose); + })[0] || null; +} + +exports.validRange = validRange; +function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr; +function ltr(version, range, loose) { + return outside(version, range, '<', loose); +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr; +function gtr(version, range, loose) { + return outside(version, range, '>', loose); +} + +exports.outside = outside; +function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0'); + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; +} + +exports.prerelease = prerelease; +function prerelease(version, loose) { + var parsed = parse(version, loose); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; +} +}); + var index$10 = typeof commonjsGlobal === 'object' && commonjsGlobal.Promise || typeof window === 'object' && window.Promise || typeof Promise !== 'undefined' && Promise || false; +/** + * > Pass a synchronous `fn` that returns some + * result and handle completion or errors in `cb` + * if given, otherwise it returns thunk which accepts + * that `cb`. It's possible to not work in "async mode", + * if that's the case try to use [try-catch-core][] for + * your case, which guarantees that `cb` is called only + * once and always in next tick, using [dezalgo][] and [once][]. + * + * **Example** + * + * ```js + * var tryCatch = require('try-catch-callback') + * + * tryCatch(function () { + * return 'fox qux' + * }, function done (err, res) { + * if (err) return console.error(err) + * console.log(res) // => 'fox qux' + * }) + * ``` + * + * @param {Function} `` function to be called. + * @param {Object} `[opts]` optional options, such as `context` and `args` + * @param {Object} `[opts.context]` context to be passed to `fn` + * @param {Array} `[opts.args]` custom argument(s) to be pass to `fn`, given value is arrayified + * @param {Boolean} `[opts.passCallback]` pass `true` if you want `cb` to be passed to `fn` args + * @param {Boolean} `[opts.return]` if `true` returns error/value and does not calls `cb` + * @param {Function} `[cb]` callback with `cb(err, res)` signature. + * @return {Function} `thunk` if `cb` not given. + * @throws {TypError} if `fn` not a function. + * @throws {TypError} if no function is passed to `thunk`. + * @api public + */ + +var index$12 = function tryCatchCallback (fn, opts, cb) { + if (typeof fn !== 'function') { + throw new TypeError('try-catch-callback: expect `fn` to be a function') + } + if (typeof opts === 'function') { + cb = opts; + opts = false; + } + opts = index$6({}, opts); + + if (opts.return || typeof cb === 'function') { + return tryCatch.call(this, fn, opts, cb) + } + return function thunk (done) { + opts.thunk = true; + tryCatch.call(this, fn, opts, done); + } +}; + +function tryCatch (fn, opts, cb) { + if (opts.thunk && typeof cb !== 'function') { + throw new TypeError('try-catch-callback: expect `cb` to be a function') + } + var args = arrayify(opts.args); + var ctx = opts.context || this; + var ret = null; + + try { + ret = fn.apply(ctx, opts.passCallback ? args.concat(cb) : args); + } catch (err) { + return opts.return ? err : cb(err) + } + + if (opts.return) { return ret } + if (!opts.passCallback) { cb(null, ret); } +} + +function arrayify (val) { + if (!val) { return [] } + if (Array.isArray(val)) { return val } + return [val] +} + +var commonPromiseLibs = [ + 'es6-promise', + 'promise', + 'native-promise-only', + 'bluebird', + 'rsvp', + 'when', + 'q', + 'pinkie', + 'lie', + 'vow' +]; + +var register = function register (opts) { + // won't load native Promise if < v0.12, since it is buggy + /* istanbul ignore next */ + if (index$10 && semver.gte(process.version, '0.12.0')) { + index$10.___nativePromise = true; + return index$10 + } + if (typeof opts === 'function') { + opts = { Promise: opts, global: opts.global }; + } + + var options = index$6({ global: true }, opts); + var PromiseCtor = options.Promise || tryLoadCommon(); + PromiseCtor.___customPromise = true; + + if (options.global === false) { + return PromiseCtor + } + + commonjsGlobal.Promise = PromiseCtor; + return commonjsGlobal.Promise +}; + +function tryLoadCommon () { + var len = commonPromiseLibs.length; + var i = -1; + + while (i++ < len) { + var lib = commonPromiseLibs[i]; + var ret = index$12(function () { + var ret = commonjsRequire(lib); + return ret.Promise || ret + }, { return: true }); + + if (ret instanceof Error) { + if ((i + 1) < len) { + continue + } else { + var msg = [ + 'No native Promise support nor other promise were found.', + 'These promise libraries are supported by default: ' + commonPromiseLibs.join(', ') + '.', + 'This means that if one of them is installed it will be loaded automatically.', + 'Otherwise you should give a promise implementation through opts.Promise!' + ].join(' '); + + throw new Error(msg) + } + } else { + return ret + } + } +} + +var commonPromiseLibs_1 = commonPromiseLibs; + +register.commonPromiseLibs = commonPromiseLibs_1; + +var index$14 = register({ global: false }); + /** * > Check any of `values` exists on `arr`. * @@ -126,7 +1498,7 @@ var index$10 = typeof commonjsGlobal === 'object' && commonjsGlobal.Promise || * @api public */ -var index$14 = function arrIncludes (arr, values) { +var index$18 = function arrIncludes (arr, values) { if (!Array.isArray(values)) { return inArray(arr, values) } var len = values.length; var i = -1; @@ -161,7 +1533,7 @@ function inArray (arr, val) { * Released under the MIT license. */ -var index$16 = [ +var index$20 = [ 'callback', 'callback_', 'cb', @@ -200,7 +1572,7 @@ var index$16 = [ * @api public */ -var index$18 = function functionArguments (fn) { +var index$22 = function functionArguments (fn) { if (typeof fn !== 'function') { throw new TypeError('function-arguments expect a function') } @@ -265,7 +1637,7 @@ var index$18 = function functionArguments (fn) { * @api public */ -var index$12 = function isAsyncFunction (fn, names, strict) { +var index$16 = function isAsyncFunction (fn, names, strict) { if (typeof fn !== 'function') { throw new TypeError('is-async-function expect a function') } @@ -275,9 +1647,9 @@ var index$12 = function isAsyncFunction (fn, names, strict) { names = typeof names === 'boolean' ? null : names; names = Array.isArray(names) ? names : index$2(names); - names = names.length ? names : index$16; + names = names.length ? names : index$20; - var idx = index$14(names, index$18(fn)); + var idx = index$18(names, index$22(fn)); return strict ? Boolean(idx) : idx }; @@ -289,6 +1661,14 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * 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!_ + * + * **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. + * * **Example** * * ```js @@ -321,7 +1701,7 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * * @name redolent * @param {Function} `` a function to be promisified - * @param {Object} `[opts]` optional options - like `.args`, `.context`, `.Promise` + * @param {Object} `[opts]` optional options, also passed to [native-or-another][] * @param {Array} `[opts.args]` additional arguments to be passed to `fn`, * all args from `opts.args` and these that are * passed to promisifed function are concatenated @@ -329,10 +1709,16 @@ var index$12 = function isAsyncFunction (fn, names, strict) { * by default it is smart enough and applies * the `this` context of redolent call or the call * of the promisified function - * @param {Function} `[opts.Promise]` custom Promise constructor function, - * like [bluebird][] for example, - * by default uses the native Promise + * @param {Function} `[opts.Promise]` custom Promise constructor for versions `< v0.12`, + * like [bluebird][] for example, by default + * it **always** uses the native Promise in newer + * node versions + * @param {Boolean} `[opts.global]` 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` * @return {Function} promisified function + * @throws {TypeError} If `fn` is not a function + * @throws {TypeError} If no promise is found * @api public */ @@ -341,19 +1727,22 @@ var index = function redolent (fn, opts) { throw new TypeError('redolent: expect `fn` to be a function') } - opts = index$6({ - context: this, - Promise: index$10 - }, opts); + opts = index$6({ context: this, Promise: index$14 }, opts); + opts.Promise = register(opts); + + // we can't test that here, because some + // of our devDeps has some Promise library, + // so it's loaded by `native-or-another` automatically + /* istanbul ignore next */ + if (typeof opts.Promise !== 'function') { + var msg = 'no native Promise support nor other promise were found'; + throw new TypeError('redolent: ' + msg) + } return function () { opts.context = this || opts.context; opts.args = index$2(opts.args).concat(index$4(arguments)); - if (typeof opts.Promise !== 'function') { - throw new TypeError('redolent: no native Promise support and no opts.Promise') - } - var promise = new opts.Promise(function (resolve, reject) { var called = false; @@ -368,7 +1757,7 @@ var index = function redolent (fn, opts) { return resolve(res) } - var isAsyncFn = index$12(fn); + var isAsyncFn = index$16(fn); opts.args = isAsyncFn ? opts.args.concat(done) : opts.args; var syncResult = fn.apply(opts.context, opts.args); @@ -378,13 +1767,13 @@ var index = function redolent (fn, opts) { } }); - return normalize(promise, index$10) + return normalize(promise, opts.Promise) } }; -function normalize (promise, isNativeSupported) { - promise.___nativePromise = Boolean(isNativeSupported); - promise.___customPromise = !promise.___nativePromise; +function normalize (promise, Ctor) { + promise.___nativePromise = Boolean(Ctor.___nativePromise); + promise.___customPromise = Boolean(Ctor.___customPromise); return promise } diff --git a/index.js b/index.js index de9c7c9..11816c1 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,8 @@ var arrify = require('arrify') var sliced = require('sliced') var extend = require('extend-shallow') -var Native = require('native-promise') +var register = require('native-or-another/register') +var Promize = require('native-or-another') var isAsync = require('is-async-function') /** @@ -21,6 +22,14 @@ var isAsync = require('is-async-function') * 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!_ + * + * **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. + * * **Example** * * ```js @@ -53,7 +62,7 @@ var isAsync = require('is-async-function') * * @name redolent * @param {Function} `` a function to be promisified - * @param {Object} `[opts]` optional options - like `.args`, `.context`, `.Promise` + * @param {Object} `[opts]` optional options, also passed to [native-or-another][] * @param {Array} `[opts.args]` additional arguments to be passed to `fn`, * all args from `opts.args` and these that are * passed to promisifed function are concatenated @@ -61,10 +70,16 @@ var isAsync = require('is-async-function') * by default it is smart enough and applies * the `this` context of redolent call or the call * of the promisified function - * @param {Function} `[opts.Promise]` custom Promise constructor function, - * like [bluebird][] for example, - * by default uses the native Promise + * @param {Function} `[opts.Promise]` custom Promise constructor for versions `< v0.12`, + * like [bluebird][] for example, by default + * it **always** uses the native Promise in newer + * node versions + * @param {Boolean} `[opts.global]` 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` * @return {Function} promisified function + * @throws {TypeError} If `fn` is not a function + * @throws {TypeError} If no promise is found * @api public */ @@ -73,19 +88,22 @@ module.exports = function redolent (fn, opts) { throw new TypeError('redolent: expect `fn` to be a function') } - opts = extend({ - context: this, - Promise: Native - }, opts) + opts = extend({ context: this, Promise: Promize }, opts) + opts.Promise = register(opts) + + // we can't test that here, because some + // of our devDeps has some Promise library, + // so it's loaded by `native-or-another` automatically + /* istanbul ignore next */ + if (typeof opts.Promise !== 'function') { + var msg = 'no native Promise support nor other promise were found' + throw new TypeError('redolent: ' + msg) + } return function () { opts.context = this || opts.context opts.args = arrify(opts.args).concat(sliced(arguments)) - if (typeof opts.Promise !== 'function') { - throw new TypeError('redolent: no native Promise support and no opts.Promise') - } - var promise = new opts.Promise(function (resolve, reject) { var called = false @@ -110,12 +128,12 @@ module.exports = function redolent (fn, opts) { } }) - return normalize(promise, Native) + return normalize(promise, opts.Promise) } } -function normalize (promise, isNativeSupported) { - promise.___nativePromise = Boolean(isNativeSupported) - promise.___customPromise = !promise.___nativePromise +function normalize (promise, Ctor) { + promise.___nativePromise = Boolean(Ctor.___nativePromise) + promise.___customPromise = Boolean(Ctor.___customPromise) return promise } diff --git a/package.json b/package.json index a6d16f1..513c69d 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "cz-conventional-changelog": "1.1.5", "extend-shallow": "^2.0.1", "is-async-function": "^1.2.3", - "mukla": "^0.4.8", - "native-promise": "^1.0.1", + "mukla": "^0.4.9", + "native-or-another": "^5.0.1", "npm-run-all": "~3.1.2", "nyc": "^10.1.2", "pinkie": "^2.0.4", @@ -49,6 +49,7 @@ "standard-version": "^4.0.0" }, "files": [ + "index.js", "dist/" ], "keywords": [ diff --git a/test.js b/test.js index 9b2383c..fd5fd8e 100644 --- a/test.js +++ b/test.js @@ -160,30 +160,38 @@ function factory (promisify) { }) } -function factoryNoPromise (fn, opts) { - test('should throw TypeError from promisified function if no Promise', function (done) { - function fixture () { - fn(function () { - return 123 - }, opts)() - } - - test.throws(fixture, TypeError) - test.throws(fixture, /no native Promise support and no opts\.Promise/) - done() - }) -} - -if (semver.lt(process.version, '0.11.13')) { +if (semver.lt(process.version, '0.12.0')) { factory(function (fn, opts) { return redolent(fn, extend({ Promise: Pinkie }, opts)) }) - factoryNoPromise(redolent) + test('should autoload some custom Promise (installed in some of the devDeps)', function (done) { + var func = redolent(function () { return 123 }) + var promise = func() + + test.strictEqual(Promise.___customPromise, true) + test.strictEqual(promise.___customPromise, true) + + promise.then(function (res) { + test.strictEqual(res, 123) + done() + }, done).catch(done) + }) } else { factory(function (fn, opts) { return redolent(fn, extend({}, opts)) }) - factoryNoPromise(redolent, { Promise: false }) + test('should always load native promise if >= 0.12', function (done) { + var promise = redolent(function () { + return 1 + })() + + test.strictEqual(Promise.___nativePromise, true) + test.strictEqual(promise.___nativePromise, true) + promise.then(function (num) { + test.strictEqual(num, 1) + done() + }, done).catch(done) + }) } diff --git a/yarn.lock b/yarn.lock index 2a9cd29..d2e0d0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,8 +38,8 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" ajv@^4.7.0: - version "4.11.4" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.4.tgz#ebf3a55d4b132ea60ff5847ae85d2ef069960b45" + version "4.11.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" @@ -183,8 +183,8 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: js-tokens "^3.0.0" babel-generator@^6.18.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.23.0.tgz#6b8edab956ef3116f79d8c84c5a3c05f32a74bc5" + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" @@ -366,7 +366,18 @@ circular-json@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" -clean-stacktrace@^1.0.0: +clean-stacktrace-metadata@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clean-stacktrace-metadata/-/clean-stacktrace-metadata-1.0.2.tgz#49cc35ebac153e630d42c5bb89e349653029a0ca" + dependencies: + normalize-path "^2.0.1" + parse-filepath "^1.0.1" + +clean-stacktrace-relative-paths@^1.0.1, clean-stacktrace-relative-paths@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clean-stacktrace-relative-paths/-/clean-stacktrace-relative-paths-1.0.2.tgz#4a6a4b883522e15cad02a9e82b5751d07c6e33f5" + +clean-stacktrace@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/clean-stacktrace/-/clean-stacktrace-1.1.0.tgz#8b8cdc87f640daaba9c595ab6edb897b63b0ce33" dependencies: @@ -465,9 +476,9 @@ concat-stream@^1.4.10, concat-stream@^1.4.6, concat-stream@^1.4.7: readable-stream "^2.2.2" typedarray "^0.0.6" -conventional-changelog-angular@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.3.2.tgz#495691c0822b59ada913384422651d3d968b52f6" +conventional-changelog-angular@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.3.3.tgz#e7ce807a85dd4750e1b417f766045497511e0726" dependencies: compare-func "^1.3.1" github-url-from-git "^1.4.0" @@ -485,9 +496,9 @@ conventional-changelog-codemirror@^0.1.0: dependencies: q "^1.4.1" -conventional-changelog-core@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-1.7.0.tgz#2dc506a0e9fdd2674b7c7c65afe4367207854dcd" +conventional-changelog-core@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-1.8.0.tgz#977848b416caf15fb09f20b12a62d40ef145b957" dependencies: conventional-changelog-writer "^1.1.0" conventional-commits-parser "^1.0.0" @@ -503,9 +514,9 @@ conventional-changelog-core@^1.7.0: read-pkg-up "^1.0.1" through2 "^2.0.0" -conventional-changelog-ember@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.2.4.tgz#1869fcb4b6918eb6f10dcb84ebced1d9e4500997" +conventional-changelog-ember@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.2.5.tgz#ce21d5cf83cd5ebe05d23fdf232d8844f4b56a4f" dependencies: q "^1.4.1" @@ -556,14 +567,14 @@ conventional-changelog-writer@^1.1.0: through2 "^2.0.0" conventional-changelog@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.2.tgz#8bf3afaf719cb05db74cfa11c8544181f22ac8ad" + version "1.1.3" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.3.tgz#26283078ac38c094df2af1604b0a46bbc0165c4d" dependencies: - conventional-changelog-angular "^1.3.2" + conventional-changelog-angular "^1.3.3" conventional-changelog-atom "^0.1.0" conventional-changelog-codemirror "^0.1.0" - conventional-changelog-core "^1.7.0" - conventional-changelog-ember "^0.2.4" + conventional-changelog-core "^1.8.0" + conventional-changelog-ember "^0.2.5" conventional-changelog-eslint "^0.1.0" conventional-changelog-express "^0.1.0" conventional-changelog-jquery "^0.1.0" @@ -647,7 +658,13 @@ cz-conventional-changelog@1.1.5: dependencies: word-wrap "^1.0.3" -d@^0.1.1, d@~0.1.1: +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +d@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" dependencies: @@ -675,8 +692,8 @@ debug-log@^1.0.0, debug-log@^1.0.1: resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" debug@^2.1.1, debug@^2.2.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.2.tgz#dfa96a861ee9b8c2f29349b3bcc41aa599a71e0f" + version "2.6.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" dependencies: ms "0.7.2" @@ -813,20 +830,20 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: - version "0.10.12" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.11, es5-ext@~0.10.14, es5-ext@~0.10.2: + version "0.10.14" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.14.tgz#625bc9ab9cac0f6fb9dc271525823d1800b3d360" dependencies: es6-iterator "2" es6-symbol "~3.1" -es6-iterator@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" dependencies: - d "^0.1.1" - es5-ext "^0.10.7" - es6-symbol "3" + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" es6-map@^0.1.3: version "0.1.4" @@ -840,30 +857,30 @@ es6-map@^0.1.3: event-emitter "~0.3.4" es6-set@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-symbol "3" - event-emitter "~0.3.4" + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" -es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" + d "1" + es5-ext "~0.10.14" es6-weak-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" dependencies: - d "^0.1.1" - es5-ext "^0.10.8" - es6-iterator "2" - es6-symbol "3" + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" @@ -979,12 +996,12 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -event-emitter@~0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" +event-emitter@~0.3.4, event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" dependencies: - d "~0.1.1" - es5-ext "~0.10.7" + d "1" + es5-ext "~0.10.14" event-stream@~3.3.0: version "3.3.4" @@ -1083,6 +1100,13 @@ find-cache-dir@^0.1.1: mkdirp "^0.5.1" pkg-dir "^1.0.0" +find-callsite@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-callsite/-/find-callsite-1.1.2.tgz#cbdca0803572027432affd3727a29ddd090d8273" + dependencies: + clean-stacktrace-relative-paths "^1.0.1" + extend-shallow "^2.0.1" + find-index@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" @@ -1181,8 +1205,8 @@ foreground-child@^1.3.3, foreground-child@^1.5.3: signal-exit "^3.0.0" from@~0: - version "0.1.3" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.3.tgz#ef63ac2062ac32acf7862e0d40b44b896f22f3bc" + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" fs-access@^1.0.0: version "1.0.1" @@ -1530,8 +1554,8 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" ignore@^3.0.9, ignore@^3.2.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.4.tgz#4055e03596729a8fabe45a43c100ad5ed815c4e8" + version "3.2.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" imurmurhash@^0.1.4: version "0.1.4" @@ -2264,17 +2288,16 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -mukla@^0.4.8: - version "0.4.8" - resolved "https://registry.yarnpkg.com/mukla/-/mukla-0.4.8.tgz#42f84d3e89ff4b6fa13dd4117b71615e656d4e7e" +mukla@^0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/mukla/-/mukla-0.4.9.tgz#195cf3954154597e35599fdbb4a13c2a41d733f4" dependencies: always-done "^1.1.0" - clean-stacktrace "^1.0.0" core-assert "^0.2.1" error-symbol "^0.1.0" extend-shallow "^2.0.1" get-fn-name "^1.0.0" - lazy-cache "^2.0.1" + stacktrace-metadata "^2.0.1" success-symbol "^0.1.0" multipipe@^0.1.2: @@ -2287,6 +2310,15 @@ mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +native-or-another@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/native-or-another/-/native-or-another-5.0.1.tgz#be5c182dd11958e23674a4a6d09653429cec11ab" + dependencies: + extend-shallow "^2.0.1" + native-promise "^1.0.1" + semver "^5.3.0" + try-catch-callback "^2.0.2" + native-promise@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/native-promise/-/native-promise-1.0.1.tgz#6d7e9d06c3d45f51c5306da3400b7e91a5f8890e" @@ -2661,8 +2693,8 @@ read-pkg@^1.0.0, read-pkg@^1.1.0: string_decoder "~0.10.x" readable-stream@^2.1.5, readable-stream@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" + version "2.2.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" dependencies: buffer-shims "^1.0.0" core-util-is "~1.0.0" @@ -2802,8 +2834,8 @@ rollup-plugin-buble@^0.15.0: rollup-pluginutils "^1.5.0" rollup-plugin-commonjs@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.0.0.tgz#3c908d312c23b86a690e30efb31d3c388b5af6b8" + version "8.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.0.2.tgz#98b1589bfe32a6c0f67790b60c0b499972afed89" dependencies: acorn "^4.0.1" estree-walker "^0.3.0" @@ -2834,8 +2866,8 @@ rollup-pluginutils@^2.0.1: micromatch "^2.3.11" rollup@^0.41.5: - version "0.41.5" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.5.tgz#cdfaade5cd1c2c7314351566a50ef74df6e66e3d" + version "0.41.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" dependencies: source-map-support "^0.4.0" @@ -2931,10 +2963,10 @@ slide@^1.1.5: resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" source-map-support@^0.4.0: - version "0.4.11" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + version "0.4.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.13.tgz#9782e6f7deb424d5f173327a1879eb46453bdcd4" dependencies: - source-map "^0.5.3" + source-map "^0.5.6" source-map@^0.4.4: version "0.4.4" @@ -2942,7 +2974,7 @@ source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -3008,6 +3040,16 @@ stack-utils-node-internals@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils-node-internals/-/stack-utils-node-internals-1.0.1.tgz#ab4a8a469b6cbec72b0bfb589df5e28b1d12281f" +stacktrace-metadata@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stacktrace-metadata/-/stacktrace-metadata-2.0.1.tgz#737e47d61bb800743dbd32ecc33e01ac611ebb85" + dependencies: + clean-stacktrace "^1.1.0" + clean-stacktrace-metadata "^1.0.2" + clean-stacktrace-relative-paths "^1.0.2" + extend-shallow "^2.0.1" + find-callsite "^1.1.2" + standard-engine@~5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-5.4.0.tgz#e0e86959ea0786425d3383e40c1bf70d2f985579" @@ -3210,7 +3252,7 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -try-catch-callback@^2.0.0: +try-catch-callback@^2.0.0, try-catch-callback@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/try-catch-callback/-/try-catch-callback-2.0.2.tgz#3ca71efa4242d8a45ee1c02c91bd17a150cdd534" dependencies: @@ -3241,8 +3283,8 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" uglify-js@^2.6: - version "2.8.12" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.12.tgz#8a50f5d482243650b7108f6080aa3a6afe2a6c55" + version "2.8.13" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.13.tgz#d0cdf02f3c661484fac601b7e723207b735a374c" dependencies: source-map "~0.5.1" uglify-to-browserify "~1.0.0" @@ -3387,8 +3429,8 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" yallist@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" yargs-parser@^4.0.2, yargs-parser@^4.2.0: version "4.2.1"