register.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. "use strict"
  2. module.exports = require('./loader')(global, loadImplementation);
  3. /**
  4. * Node.js version of loadImplementation.
  5. *
  6. * Requires the given implementation and returns the registration
  7. * containing {Promise, implementation}
  8. *
  9. * If implementation is undefined or global.Promise, loads it
  10. * Otherwise uses require
  11. */
  12. function loadImplementation(implementation){
  13. var impl = null
  14. if(shouldPreferGlobalPromise(implementation)){
  15. // if no implementation or env specified use global.Promise
  16. impl = {
  17. Promise: global.Promise,
  18. implementation: 'global.Promise'
  19. }
  20. } else if(implementation){
  21. // if implementation specified, require it
  22. var lib = require(implementation)
  23. impl = {
  24. Promise: lib.Promise || lib,
  25. implementation: implementation
  26. }
  27. } else {
  28. // try to auto detect implementation. This is non-deterministic
  29. // and should prefer other branches, but this is our last chance
  30. // to load something without throwing error
  31. impl = tryAutoDetect()
  32. }
  33. if(impl === null){
  34. throw new Error('Cannot find any-promise implementation nor'+
  35. ' global.Promise. You must install polyfill or call'+
  36. ' require("any-promise/register") with your preferred'+
  37. ' implementation, e.g. require("any-promise/register/bluebird")'+
  38. ' on application load prior to any require("any-promise").')
  39. }
  40. return impl
  41. }
  42. /**
  43. * Determines if the global.Promise should be preferred if an implementation
  44. * has not been registered.
  45. */
  46. function shouldPreferGlobalPromise(implementation){
  47. if(implementation){
  48. return implementation === 'global.Promise'
  49. } else if(typeof global.Promise !== 'undefined'){
  50. // Load global promise if implementation not specified
  51. // Versions < 0.11 did not have global Promise
  52. // Do not use for version < 0.12 as version 0.11 contained buggy versions
  53. var version = (/v(\d+)\.(\d+)\.(\d+)/).exec(process.version)
  54. return !(version && +version[1] == 0 && +version[2] < 12)
  55. }
  56. // do not have global.Promise or another implementation was specified
  57. return false
  58. }
  59. /**
  60. * Look for common libs as last resort there is no guarantee that
  61. * this will return a desired implementation or even be deterministic.
  62. * The priority is also nearly arbitrary. We are only doing this
  63. * for older versions of Node.js <0.12 that do not have a reasonable
  64. * global.Promise implementation and we the user has not registered
  65. * the preference. This preserves the behavior of any-promise <= 0.1
  66. * and may be deprecated or removed in the future
  67. */
  68. function tryAutoDetect(){
  69. var libs = [
  70. "es6-promise",
  71. "promise",
  72. "native-promise-only",
  73. "bluebird",
  74. "rsvp",
  75. "when",
  76. "q",
  77. "pinkie",
  78. "lie",
  79. "vow"]
  80. var i = 0, len = libs.length
  81. for(; i < len; i++){
  82. try {
  83. return loadImplementation(libs[i])
  84. } catch(e){}
  85. }
  86. return null
  87. }