Skip to content

Commit

Permalink
Add expo-random support to nanoid/async
Browse files Browse the repository at this point in the history
  • Loading branch information
ai committed May 12, 2020
1 parent ea3eecb commit 3ac74c1
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 22 deletions.
4 changes: 3 additions & 1 deletion async/index.browser.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
let { random } = require('./random')

let customAlphabet = (alphabet, size) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
// values closer to the alphabet size. The bitmask calculates the closest
Expand Down Expand Up @@ -65,4 +67,4 @@ let nanoid = (size = 21) => {
return Promise.resolve(id)
}

module.exports = { nanoid, customAlphabet }
module.exports = { nanoid, customAlphabet, random }
21 changes: 2 additions & 19 deletions async/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
let crypto = require('crypto')

let { urlAlphabet } = require('..')

// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
let random = bytes =>
new Promise((resolve, reject) => {
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
// Memory flushing is unnecessary since the buffer allocation itself resets
// the memory with the new bytes.
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
if (err) {
reject(err)
} else {
resolve(buf)
}
})
})
let { random } = require('./random')

let customAlphabet = (alphabet, size) => {
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
Expand Down Expand Up @@ -69,4 +52,4 @@ let nanoid = (size = 21) =>
return id
})

module.exports = { nanoid, customAlphabet }
module.exports = { nanoid, customAlphabet, random }
4 changes: 4 additions & 0 deletions async/random/index.browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let random = bytes =>
Promise.resolve(crypto.getRandomValues(new Uint8Array(bytes)))

module.exports = { random }
12 changes: 12 additions & 0 deletions async/random/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generate an array of random bytes collected from hardware noise.
*
* ```js
* import { customRandom, random } from 'nanoid'
* const nanoid = customRandom("abcdef", 5, random)
* ```
*
* @param bytes Size of the array.
* @returns An array of random bytes.
*/
export function random (bytes: number): Promise<Uint8Array>
19 changes: 19 additions & 0 deletions async/random/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
let crypto = require('crypto')

// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
let random = bytes =>
new Promise((resolve, reject) => {
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
// Memory flushing is unnecessary since the buffer allocation itself resets
// the memory with the new bytes.
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
if (err) {
reject(err)
} else {
resolve(buf)
}
})
})

module.exports = { random }
5 changes: 5 additions & 0 deletions async/random/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let { getRandomBytesAsync } = require('expo-random')

let random = getRandomBytesAsync

module.exports = { random }
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"./index.js": "./index.browser.js",
"./async/index.js": "./async/index.browser.js"
},
"react-native": {
"./async/random/index.js": "./async/random/index.native.js",
"./async/index.js": "./async/index.js"
},
"bin": "./bin/nanoid.cjs",
"sideEffects": false,
"devDependencies": {
Expand Down Expand Up @@ -119,7 +123,7 @@
},
"overrides": [
{
"files": "*.rn.js",
"files": "*.native.js",
"rules": {
"node/no-missing-require": "off",
"global-require": "off"
Expand Down
21 changes: 20 additions & 1 deletion test/async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function times (size, callback) {

for (let type of ['node', 'browser']) {
describe(`${type}`, () => {
let { nanoid, customAlphabet } = type === 'node' ? node : browser
let { nanoid, customAlphabet, random } = type === 'node' ? node : browser

describe('nanoid', () => {
function mock (callback) {
Expand Down Expand Up @@ -107,6 +107,25 @@ for (let type of ['node', 'browser']) {
}
})

describe('random', () => {
it('generates small random buffers', async () => {
expect(await random(10)).toHaveLength(10)
})

it('generates random buffers', async () => {
let numbers = {}
let bytes = await random(10000)
expect(bytes).toHaveLength(10000)
for (let byte of bytes) {
if (!numbers[byte]) numbers[byte] = 0
numbers[byte] += 1
expect(typeof byte).toEqual('number')
expect(byte).toBeLessThanOrEqual(255)
expect(byte).toBeGreaterThanOrEqual(0)
}
})
})

describe('customAlphabet', () => {
it('has options', async () => {
let nanoidA = customAlphabet('a', 5)
Expand Down

0 comments on commit 3ac74c1

Please sign in to comment.