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