index.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*!
  2. * uid-safe
  3. * Copyright(c) 2014 Jonathan Ong
  4. * Copyright(c) 2015-2017 Douglas Christopher Wilson
  5. * MIT Licensed
  6. */
  7. 'use strict'
  8. /**
  9. * Module dependencies.
  10. * @private
  11. */
  12. var randomBytes = require('random-bytes')
  13. /**
  14. * Module variables.
  15. * @private
  16. */
  17. var EQUAL_END_REGEXP = /=+$/
  18. var PLUS_GLOBAL_REGEXP = /\+/g
  19. var SLASH_GLOBAL_REGEXP = /\//g
  20. /**
  21. * Module exports.
  22. * @public
  23. */
  24. module.exports = uid
  25. module.exports.sync = uidSync
  26. /**
  27. * Create a unique ID.
  28. *
  29. * @param {number} length
  30. * @param {function} [callback]
  31. * @return {Promise}
  32. * @public
  33. */
  34. function uid (length, callback) {
  35. // validate callback is a function, if provided
  36. if (callback !== undefined && typeof callback !== 'function') {
  37. throw new TypeError('argument callback must be a function')
  38. }
  39. // require the callback without promises
  40. if (!callback && !global.Promise) {
  41. throw new TypeError('argument callback is required')
  42. }
  43. if (callback) {
  44. // classic callback style
  45. return generateUid(length, callback)
  46. }
  47. return new Promise(function executor (resolve, reject) {
  48. generateUid(length, function onUid (err, str) {
  49. if (err) return reject(err)
  50. resolve(str)
  51. })
  52. })
  53. }
  54. /**
  55. * Create a unique ID sync.
  56. *
  57. * @param {number} length
  58. * @return {string}
  59. * @public
  60. */
  61. function uidSync (length) {
  62. return toString(randomBytes.sync(length))
  63. }
  64. /**
  65. * Generate a unique ID string.
  66. *
  67. * @param {number} length
  68. * @param {function} callback
  69. * @private
  70. */
  71. function generateUid (length, callback) {
  72. randomBytes(length, function (err, buf) {
  73. if (err) return callback(err)
  74. callback(null, toString(buf))
  75. })
  76. }
  77. /**
  78. * Change a Buffer into a string.
  79. *
  80. * @param {Buffer} buf
  81. * @return {string}
  82. * @private
  83. */
  84. function toString (buf) {
  85. return buf.toString('base64')
  86. .replace(EQUAL_END_REGEXP, '')
  87. .replace(PLUS_GLOBAL_REGEXP, '-')
  88. .replace(SLASH_GLOBAL_REGEXP, '_')
  89. }