nanoid 3.1.19 → 3.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nanoid might be problematic. Click here for more details.
- package/README.md +52 -40
- package/async/index.browser.js +1 -2
- package/async/index.cjs +71 -0
- package/async/index.d.ts +3 -3
- package/async/index.js +3 -4
- package/async/index.native.js +3 -4
- package/async/package.json +11 -0
- package/index.browser.js +3 -5
- package/index.cjs +80 -0
- package/index.d.ts +5 -5
- package/index.dev.js +104 -0
- package/index.js +5 -6
- package/index.prod.js +104 -0
- package/non-secure/index.cjs +30 -0
- package/non-secure/index.d.ts +2 -2
- package/non-secure/index.js +1 -1
- package/non-secure/package.json +6 -0
- package/package.json +42 -8
- package/url-alphabet/index.cjs +6 -0
- package/url-alphabet/index.js +1 -1
- package/url-alphabet/package.json +6 -0
- package/CHANGELOG.md +0 -238
- package/bin/nanoid.test.js +0 -11
package/README.md
CHANGED
@@ -47,7 +47,6 @@ Supports modern browsers, IE [with Babel], Node.js and React Native.
|
|
47
47
|
* [Create React App](#create-react-app)
|
48
48
|
* [React Native](#react-native)
|
49
49
|
* [Rollup](#rollup)
|
50
|
-
* [Expo](#expo)
|
51
50
|
* [PouchDB and CouchDB](#pouchdb-and-couchdb)
|
52
51
|
* [Mongoose](#mongoose)
|
53
52
|
* [ES Modules](#es-modules)
|
@@ -139,7 +138,7 @@ Test configuration: Dell XPS 2-in-1 7390, Fedora 32, Node.js 15.1.
|
|
139
138
|
Tidelift will coordinate the fix and disclosure.
|
140
139
|
|
141
140
|
[Secure random values (in Node.js)]: https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba
|
142
|
-
[better algorithm]: https://github.com/ai/nanoid/blob/
|
141
|
+
[better algorithm]: https://github.com/ai/nanoid/blob/main/index.js
|
143
142
|
|
144
143
|
|
145
144
|
## Usage
|
@@ -154,6 +153,12 @@ import { nanoid } from 'nanoid'
|
|
154
153
|
model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
|
155
154
|
```
|
156
155
|
|
156
|
+
In Node.js you can use CommonJS import:
|
157
|
+
|
158
|
+
```js
|
159
|
+
const { nanoid } = require('nanoid')
|
160
|
+
```
|
161
|
+
|
157
162
|
If you want to reduce the ID size (and increase collisions probability),
|
158
163
|
you can pass the size as an argument.
|
159
164
|
|
@@ -192,22 +197,43 @@ import { nanoid } from 'nanoid'
|
|
192
197
|
|
193
198
|
### React
|
194
199
|
|
195
|
-
|
196
|
-
among renders.
|
200
|
+
There’s currently no correct way to use nanoid for React `key` prop
|
201
|
+
since it should be consistent among renders.
|
197
202
|
|
198
|
-
|
203
|
+
```jsx
|
204
|
+
function Todos({todos}) {
|
205
|
+
return (
|
206
|
+
<ul>
|
207
|
+
{todos.map(todo => (
|
208
|
+
<li key={nanoid()}> /* DON’T DO IT */
|
209
|
+
{todo.text}
|
210
|
+
</li>
|
211
|
+
))}
|
212
|
+
</ul>
|
213
|
+
)
|
214
|
+
}
|
215
|
+
```
|
216
|
+
|
217
|
+
You should rather try to reach for stable id inside your list item.
|
199
218
|
|
200
219
|
```jsx
|
201
|
-
|
220
|
+
const todoItems = todos.map((todo) =>
|
221
|
+
<li key={todo.id}>
|
222
|
+
{todo.text}
|
223
|
+
</li>
|
224
|
+
)
|
202
225
|
```
|
203
226
|
|
204
|
-
|
227
|
+
In case you don’t have stable ids you'd rather use index as `key`
|
228
|
+
instead of `nanoid()`:
|
205
229
|
|
206
230
|
```jsx
|
207
|
-
const
|
208
|
-
|
209
|
-
|
210
|
-
}
|
231
|
+
const todoItems = todos.map((text, index) =>
|
232
|
+
<li key={index}> /* Still not recommended but preferred over nanoid().
|
233
|
+
Only do this if items have no stable IDs. */
|
234
|
+
{text}
|
235
|
+
</li>
|
236
|
+
)
|
211
237
|
```
|
212
238
|
|
213
239
|
If you want to use Nano ID in the `id` prop, you must set some string prefix
|
@@ -220,22 +246,21 @@ If you want to use Nano ID in the `id` prop, you must set some string prefix
|
|
220
246
|
|
221
247
|
### Create React App
|
222
248
|
|
223
|
-
Create React App
|
224
|
-
with ES modules packages.
|
249
|
+
Create React App < 4.0.0 had
|
250
|
+
[a problem](https://github.com/ai/nanoid/issues/205) with ES modules packages.
|
225
251
|
|
226
252
|
```
|
227
253
|
TypeError: (0 , _nanoid.nanoid) is not a function
|
228
254
|
```
|
229
255
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
Use Nano ID 2 `npm i nanoid@^2.0.0` until Create React App 4.0 release.
|
256
|
+
Use Nano ID 2 `npm i nanoid@^2.0.0` if you're using a version below
|
257
|
+
CRA 4.0.
|
234
258
|
|
235
259
|
|
236
260
|
### React Native
|
237
261
|
|
238
|
-
React Native does not have built-in random generator.
|
262
|
+
React Native does not have built-in random generator. The following polyfill
|
263
|
+
works for plain React Native and Expo starting with `39.x`.
|
239
264
|
|
240
265
|
1. Check [`react-native-get-random-values`] docs and install it.
|
241
266
|
2. Import it before Nano ID.
|
@@ -252,39 +277,25 @@ For Expo framework see the next section.
|
|
252
277
|
|
253
278
|
### Rollup
|
254
279
|
|
255
|
-
For Rollup you will need [`@rollup/plugin-
|
280
|
+
For Rollup you will need [`@rollup/plugin-node-resolve`] to bundle browser version
|
281
|
+
of this library and [`@rollup/plugin-replace`] to replace
|
256
282
|
`process.env.NODE_ENV`:
|
257
283
|
|
258
284
|
```js
|
259
285
|
plugins: [
|
286
|
+
nodeResolve({
|
287
|
+
browser: true
|
288
|
+
}),
|
260
289
|
replace({
|
261
|
-
'process.env.NODE_ENV': JSON.stringify(process.env.
|
290
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
|
262
291
|
})
|
263
292
|
]
|
264
293
|
```
|
265
294
|
|
295
|
+
[`@rollup/plugin-node-resolve`]: https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
266
296
|
[`@rollup/plugin-replace`]: https://github.com/rollup/plugins/tree/master/packages/replace
|
267
297
|
|
268
298
|
|
269
|
-
### Expo
|
270
|
-
|
271
|
-
If you use Expo in React Native, you need a different workaround.
|
272
|
-
|
273
|
-
1. Install [`expo-random`](https://www.npmjs.com/package/expo-random).
|
274
|
-
2. Use `nanoid/async` instead of `nanoid`.
|
275
|
-
3. Import `index.native.js` file directly.
|
276
|
-
|
277
|
-
```js
|
278
|
-
import { nanoid } from 'nanoid/async/index.native'
|
279
|
-
|
280
|
-
async function createUser () {
|
281
|
-
user.id = await nanoid()
|
282
|
-
}
|
283
|
-
```
|
284
|
-
|
285
|
-
[`expo-random`]: https://www.npmjs.com/package/expo-random
|
286
|
-
|
287
|
-
|
288
299
|
### PouchDB and CouchDB
|
289
300
|
|
290
301
|
In PouchDB and CouchDB, IDs can’t start with an underscore `_`.
|
@@ -375,7 +386,7 @@ the same ID generator on the client and server side.
|
|
375
386
|
* [C++](https://github.com/mcmikecreations/nanoid_cpp)
|
376
387
|
* [Clojure and ClojureScript](https://github.com/zelark/nano-id)
|
377
388
|
* [Crystal](https://github.com/mamantoha/nanoid.cr)
|
378
|
-
* [Dart](https://github.com/pd4d10/nanoid-dart)
|
389
|
+
* [Dart & Flutter](https://github.com/pd4d10/nanoid-dart)
|
379
390
|
* [Deno](https://github.com/ianfabs/nanoid)
|
380
391
|
* [Go](https://github.com/matoous/go-nanoid)
|
381
392
|
* [Elixir](https://github.com/railsmechanic/nanoid)
|
@@ -383,6 +394,7 @@ the same ID generator on the client and server side.
|
|
383
394
|
* [Janet](https://sr.ht/~statianzo/janet-nanoid/)
|
384
395
|
* [Java](https://github.com/aventrix/jnanoid)
|
385
396
|
* [Nim](https://github.com/icyphox/nanoid.nim)
|
397
|
+
* [Perl](https://github.com/tkzwtks/Nanoid-perl)
|
386
398
|
* [PHP](https://github.com/hidehalo/nanoid-php)
|
387
399
|
* [Python](https://github.com/puyuan/py-nanoid)
|
388
400
|
with [dictionaries](https://pypi.org/project/nanoid-dictionary)
|
package/async/index.browser.js
CHANGED
@@ -34,7 +34,6 @@ let customAlphabet = (alphabet, size) => {
|
|
34
34
|
while (i--) {
|
35
35
|
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
36
36
|
id += alphabet[bytes[i] & mask] || ''
|
37
|
-
// Return if id length equals size.
|
38
37
|
if (id.length === size) return Promise.resolve(id)
|
39
38
|
}
|
40
39
|
}
|
@@ -68,4 +67,4 @@ let nanoid = (size = 21) => {
|
|
68
67
|
return Promise.resolve(id)
|
69
68
|
}
|
70
69
|
|
71
|
-
|
70
|
+
export { nanoid, customAlphabet, random }
|
package/async/index.cjs
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
let crypto = require('crypto')
|
2
|
+
|
3
|
+
let { urlAlphabet } = require('../url-alphabet/index.cjs')
|
4
|
+
|
5
|
+
// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
|
6
|
+
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
|
7
|
+
let random = bytes =>
|
8
|
+
new Promise((resolve, reject) => {
|
9
|
+
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
|
10
|
+
// Memory flushing is unnecessary since the buffer allocation itself resets
|
11
|
+
// the memory with the new bytes.
|
12
|
+
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
|
13
|
+
if (err) {
|
14
|
+
reject(err)
|
15
|
+
} else {
|
16
|
+
resolve(buf)
|
17
|
+
}
|
18
|
+
})
|
19
|
+
})
|
20
|
+
|
21
|
+
let customAlphabet = (alphabet, size) => {
|
22
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
23
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
24
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
25
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
26
|
+
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
27
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
28
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
29
|
+
// the random bytes redundancy has to be satisfied.
|
30
|
+
|
31
|
+
// Note: every hardware random generator call is performance expensive,
|
32
|
+
// because the system call for entropy collection takes a lot of time.
|
33
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
34
|
+
|
35
|
+
// Next, a step determines how many random bytes to generate.
|
36
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
37
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
38
|
+
// according to benchmarks).
|
39
|
+
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
|
40
|
+
|
41
|
+
let tick = id =>
|
42
|
+
random(step).then(bytes => {
|
43
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
44
|
+
let i = step
|
45
|
+
while (i--) {
|
46
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
47
|
+
id += alphabet[bytes[i] & mask] || ''
|
48
|
+
if (id.length === size) return id
|
49
|
+
}
|
50
|
+
return tick(id)
|
51
|
+
})
|
52
|
+
|
53
|
+
return () => tick('')
|
54
|
+
}
|
55
|
+
|
56
|
+
let nanoid = (size = 21) =>
|
57
|
+
random(size).then(bytes => {
|
58
|
+
let id = ''
|
59
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
60
|
+
while (size--) {
|
61
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
62
|
+
// The following mask reduces the random byte in the 0-255 value
|
63
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
64
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
65
|
+
// the bitmask trims bytes down to the alphabet size.
|
66
|
+
id += urlAlphabet[bytes[size] & 63]
|
67
|
+
}
|
68
|
+
return id
|
69
|
+
})
|
70
|
+
|
71
|
+
module.exports = { nanoid, customAlphabet, random }
|
package/async/index.d.ts
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
* @param size Size of the ID. The default size is 21.
|
15
15
|
* @returns A promise with a random string.
|
16
16
|
*/
|
17
|
-
export function nanoid
|
17
|
+
export function nanoid(size?: number): Promise<string>
|
18
18
|
|
19
19
|
/**
|
20
20
|
* A low-level function.
|
@@ -35,7 +35,7 @@ export function nanoid (size?: number): Promise<string>
|
|
35
35
|
* })
|
36
36
|
* ```
|
37
37
|
*/
|
38
|
-
export function customAlphabet
|
38
|
+
export function customAlphabet(
|
39
39
|
alphabet: string,
|
40
40
|
size: number
|
41
41
|
): () => Promise<string>
|
@@ -53,4 +53,4 @@ export function customAlphabet (
|
|
53
53
|
* @param bytes Size of the array.
|
54
54
|
* @returns A promise with a random bytes array.
|
55
55
|
*/
|
56
|
-
export function random
|
56
|
+
export function random(bytes: number): Promise<Uint8Array>
|
package/async/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
import crypto from 'crypto'
|
2
2
|
|
3
|
-
|
3
|
+
import { urlAlphabet } from '../url-alphabet/index.js'
|
4
4
|
|
5
5
|
// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
|
6
6
|
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
|
@@ -45,7 +45,6 @@ let customAlphabet = (alphabet, size) => {
|
|
45
45
|
while (i--) {
|
46
46
|
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
47
47
|
id += alphabet[bytes[i] & mask] || ''
|
48
|
-
// Return if id length equals size.
|
49
48
|
if (id.length === size) return id
|
50
49
|
}
|
51
50
|
return tick(id)
|
@@ -69,4 +68,4 @@ let nanoid = (size = 21) =>
|
|
69
68
|
return id
|
70
69
|
})
|
71
70
|
|
72
|
-
|
71
|
+
export { nanoid, customAlphabet, random }
|
package/async/index.native.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
import { getRandomBytesAsync } from 'expo-random'
|
2
2
|
|
3
|
-
|
3
|
+
import { urlAlphabet } from '../url-alphabet/index.js'
|
4
4
|
|
5
5
|
let random = getRandomBytesAsync
|
6
6
|
|
@@ -31,7 +31,6 @@ let customAlphabet = (alphabet, size) => {
|
|
31
31
|
while (i--) {
|
32
32
|
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
33
33
|
id += alphabet[bytes[i] & mask] || ''
|
34
|
-
// Return if id length equals size.
|
35
34
|
if (id.length === size) return id
|
36
35
|
}
|
37
36
|
return tick(id)
|
@@ -55,4 +54,4 @@ let nanoid = (size = 21) =>
|
|
55
54
|
return id
|
56
55
|
})
|
57
56
|
|
58
|
-
|
57
|
+
export { nanoid, customAlphabet, random }
|
package/index.browser.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// This file replaces `index.js` in bundlers like webpack or Rollup,
|
2
2
|
// according to `browser` config in `package.json`.
|
3
3
|
|
4
|
-
|
4
|
+
import { urlAlphabet } from './url-alphabet/index.js'
|
5
5
|
|
6
6
|
if (process.env.NODE_ENV !== 'production') {
|
7
7
|
// All bundlers will remove this block in the production bundle.
|
@@ -14,8 +14,7 @@ if (process.env.NODE_ENV !== 'production') {
|
|
14
14
|
'React Native does not have a built-in secure random generator. ' +
|
15
15
|
'If you don’t need unpredictable IDs use `nanoid/non-secure`. ' +
|
16
16
|
'For secure IDs, import `react-native-get-random-values` ' +
|
17
|
-
'before Nano ID.
|
18
|
-
'and use `nanoid/async`.'
|
17
|
+
'before Nano ID.'
|
19
18
|
)
|
20
19
|
}
|
21
20
|
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') {
|
@@ -67,7 +66,6 @@ let customRandom = (alphabet, size, getRandom) => {
|
|
67
66
|
while (j--) {
|
68
67
|
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
69
68
|
id += alphabet[bytes[j] & mask] || ''
|
70
|
-
// Return if id length equals size.
|
71
69
|
if (id.length === size) return id
|
72
70
|
}
|
73
71
|
}
|
@@ -103,4 +101,4 @@ let nanoid = (size = 21) => {
|
|
103
101
|
return id
|
104
102
|
}
|
105
103
|
|
106
|
-
|
104
|
+
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
package/index.cjs
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
let crypto = require('crypto')
|
2
|
+
|
3
|
+
let { urlAlphabet } = require('./url-alphabet/index.cjs')
|
4
|
+
|
5
|
+
// It is best to make fewer, larger requests to the crypto module to
|
6
|
+
// avoid system call overhead. So, random numbers are generated in a
|
7
|
+
// pool. The pool is a Buffer that is larger than the initial random
|
8
|
+
// request size by this multiplier. The pool is enlarged if subsequent
|
9
|
+
// requests exceed the maximum buffer size.
|
10
|
+
const POOL_SIZE_MULTIPLIER = 32
|
11
|
+
let pool, poolOffset
|
12
|
+
|
13
|
+
let random = bytes => {
|
14
|
+
if (!pool || pool.length < bytes) {
|
15
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
|
16
|
+
crypto.randomFillSync(pool)
|
17
|
+
poolOffset = 0
|
18
|
+
} else if (poolOffset + bytes > pool.length) {
|
19
|
+
crypto.randomFillSync(pool)
|
20
|
+
poolOffset = 0
|
21
|
+
}
|
22
|
+
|
23
|
+
let res = pool.subarray(poolOffset, poolOffset + bytes)
|
24
|
+
poolOffset += bytes
|
25
|
+
return res
|
26
|
+
}
|
27
|
+
|
28
|
+
let customRandom = (alphabet, size, getRandom) => {
|
29
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
30
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
31
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
32
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
33
|
+
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
34
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
35
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
36
|
+
// the random bytes redundancy has to be satisfied.
|
37
|
+
|
38
|
+
// Note: every hardware random generator call is performance expensive,
|
39
|
+
// because the system call for entropy collection takes a lot of time.
|
40
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
41
|
+
|
42
|
+
// Next, a step determines how many random bytes to generate.
|
43
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
44
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
45
|
+
// according to benchmarks).
|
46
|
+
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
|
47
|
+
|
48
|
+
return () => {
|
49
|
+
let id = ''
|
50
|
+
while (true) {
|
51
|
+
let bytes = getRandom(step)
|
52
|
+
// A compact alternative for `for (let i = 0; i < step; i++)`.
|
53
|
+
let i = step
|
54
|
+
while (i--) {
|
55
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
56
|
+
id += alphabet[bytes[i] & mask] || ''
|
57
|
+
if (id.length === size) return id
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
|
64
|
+
|
65
|
+
let nanoid = (size = 21) => {
|
66
|
+
let bytes = random(size)
|
67
|
+
let id = ''
|
68
|
+
// A compact alternative for `for (let i = 0; i < size; i++)`.
|
69
|
+
while (size--) {
|
70
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
71
|
+
// The following mask reduces the random byte in the 0-255 value
|
72
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
73
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
74
|
+
// the bitmask trims bytes down to the alphabet size.
|
75
|
+
id += urlAlphabet[bytes[size] & 63]
|
76
|
+
}
|
77
|
+
return id
|
78
|
+
}
|
79
|
+
|
80
|
+
module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
package/index.d.ts
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
* @param size Size of the ID. The default size is 21.
|
13
13
|
* @returns A random string.
|
14
14
|
*/
|
15
|
-
export function nanoid
|
15
|
+
export function nanoid(size?: number): string
|
16
16
|
|
17
17
|
/**
|
18
18
|
* Generate secure unique ID with custom alphabet.
|
@@ -30,7 +30,7 @@ export function nanoid (size?: number): string
|
|
30
30
|
* nanoid() //=> "8ё56а"
|
31
31
|
* ```
|
32
32
|
*/
|
33
|
-
export function customAlphabet
|
33
|
+
export function customAlphabet(alphabet: string, size: number): () => string
|
34
34
|
|
35
35
|
/**
|
36
36
|
* Generate unique ID with custom random generator and alphabet.
|
@@ -57,7 +57,7 @@ export function customAlphabet (alphabet: string, size: number): () => string
|
|
57
57
|
* @param random A random bytes generator.
|
58
58
|
* @returns A random string generator.
|
59
59
|
*/
|
60
|
-
export function customRandom
|
60
|
+
export function customRandom(
|
61
61
|
alphabet: string,
|
62
62
|
size: number,
|
63
63
|
random: (bytes: number) => Uint8Array
|
@@ -68,7 +68,7 @@ export function customRandom (
|
|
68
68
|
*
|
69
69
|
* ```js
|
70
70
|
* import { urlAlphabet } from 'nanoid'
|
71
|
-
* const nanoid =
|
71
|
+
* const nanoid = customAlphabet(urlAlphabet, 10)
|
72
72
|
* nanoid() //=> "Uakgb_J5m9"
|
73
73
|
* ```
|
74
74
|
*/
|
@@ -85,4 +85,4 @@ export const urlAlphabet: string
|
|
85
85
|
* @param bytes Size of the array.
|
86
86
|
* @returns An array of random bytes.
|
87
87
|
*/
|
88
|
-
export function random
|
88
|
+
export function random(bytes: number): Uint8Array
|
package/index.dev.js
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
// This file replaces `index.js` in bundlers like webpack or Rollup,
|
2
|
+
// according to `browser` config in `package.json`.
|
3
|
+
|
4
|
+
import { urlAlphabet } from './url-alphabet/index.js'
|
5
|
+
|
6
|
+
if (true) {
|
7
|
+
// All bundlers will remove this block in the production bundle.
|
8
|
+
if (
|
9
|
+
typeof navigator !== 'undefined' &&
|
10
|
+
navigator.product === 'ReactNative' &&
|
11
|
+
typeof crypto === 'undefined'
|
12
|
+
) {
|
13
|
+
throw new Error(
|
14
|
+
'React Native does not have a built-in secure random generator. ' +
|
15
|
+
'If you don’t need unpredictable IDs use `nanoid/non-secure`. ' +
|
16
|
+
'For secure IDs, import `react-native-get-random-values` ' +
|
17
|
+
'before Nano ID.'
|
18
|
+
)
|
19
|
+
}
|
20
|
+
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') {
|
21
|
+
throw new Error(
|
22
|
+
'Import file with `if (!window.crypto) window.crypto = window.msCrypto`' +
|
23
|
+
' before importing Nano ID to fix IE 11 support'
|
24
|
+
)
|
25
|
+
}
|
26
|
+
if (typeof crypto === 'undefined') {
|
27
|
+
throw new Error(
|
28
|
+
'Your browser does not have secure random generator. ' +
|
29
|
+
'If you don’t need unpredictable IDs, you can use nanoid/non-secure.'
|
30
|
+
)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
35
|
+
|
36
|
+
let customRandom = (alphabet, size, getRandom) => {
|
37
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
38
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
39
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
40
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
41
|
+
// `Math.clz32` is not used, because it is not available in browsers.
|
42
|
+
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
43
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
44
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
45
|
+
// the random bytes redundancy has to be satisfied.
|
46
|
+
|
47
|
+
// Note: every hardware random generator call is performance expensive,
|
48
|
+
// because the system call for entropy collection takes a lot of time.
|
49
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
50
|
+
|
51
|
+
// Next, a step determines how many random bytes to generate.
|
52
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
53
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
54
|
+
// according to benchmarks).
|
55
|
+
|
56
|
+
// `-~f => Math.ceil(f)` if f is a float
|
57
|
+
// `-~i => i + 1` if i is an integer
|
58
|
+
let step = -~((1.6 * mask * size) / alphabet.length)
|
59
|
+
|
60
|
+
return () => {
|
61
|
+
let id = ''
|
62
|
+
while (true) {
|
63
|
+
let bytes = getRandom(step)
|
64
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
65
|
+
let j = step
|
66
|
+
while (j--) {
|
67
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
68
|
+
id += alphabet[bytes[j] & mask] || ''
|
69
|
+
if (id.length === size) return id
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
|
76
|
+
|
77
|
+
let nanoid = (size = 21) => {
|
78
|
+
let id = ''
|
79
|
+
let bytes = crypto.getRandomValues(new Uint8Array(size))
|
80
|
+
|
81
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
82
|
+
while (size--) {
|
83
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
84
|
+
// The following mask reduces the random byte in the 0-255 value
|
85
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
86
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
87
|
+
// the bitmask trims bytes down to the alphabet size.
|
88
|
+
let byte = bytes[size] & 63
|
89
|
+
if (byte < 36) {
|
90
|
+
// `0-9a-z`
|
91
|
+
id += byte.toString(36)
|
92
|
+
} else if (byte < 62) {
|
93
|
+
// `A-Z`
|
94
|
+
id += (byte - 26).toString(36).toUpperCase()
|
95
|
+
} else if (byte < 63) {
|
96
|
+
id += '_'
|
97
|
+
} else {
|
98
|
+
id += '-'
|
99
|
+
}
|
100
|
+
}
|
101
|
+
return id
|
102
|
+
}
|
103
|
+
|
104
|
+
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
package/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
import crypto from 'crypto'
|
2
2
|
|
3
|
-
|
3
|
+
import { urlAlphabet } from './url-alphabet/index.js'
|
4
4
|
|
5
5
|
// It is best to make fewer, larger requests to the crypto module to
|
6
6
|
// avoid system call overhead. So, random numbers are generated in a
|
@@ -49,12 +49,11 @@ let customRandom = (alphabet, size, getRandom) => {
|
|
49
49
|
let id = ''
|
50
50
|
while (true) {
|
51
51
|
let bytes = getRandom(step)
|
52
|
-
// A compact alternative for `for (
|
52
|
+
// A compact alternative for `for (let i = 0; i < step; i++)`.
|
53
53
|
let i = step
|
54
54
|
while (i--) {
|
55
55
|
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
56
56
|
id += alphabet[bytes[i] & mask] || ''
|
57
|
-
// Return if id length equals size.
|
58
57
|
if (id.length === size) return id
|
59
58
|
}
|
60
59
|
}
|
@@ -66,7 +65,7 @@ let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
|
|
66
65
|
let nanoid = (size = 21) => {
|
67
66
|
let bytes = random(size)
|
68
67
|
let id = ''
|
69
|
-
// A compact alternative for `for (
|
68
|
+
// A compact alternative for `for (let i = 0; i < size; i++)`.
|
70
69
|
while (size--) {
|
71
70
|
// It is incorrect to use bytes exceeding the alphabet size.
|
72
71
|
// The following mask reduces the random byte in the 0-255 value
|
@@ -78,4 +77,4 @@ let nanoid = (size = 21) => {
|
|
78
77
|
return id
|
79
78
|
}
|
80
79
|
|
81
|
-
|
80
|
+
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
package/index.prod.js
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
// This file replaces `index.js` in bundlers like webpack or Rollup,
|
2
|
+
// according to `browser` config in `package.json`.
|
3
|
+
|
4
|
+
import { urlAlphabet } from './url-alphabet/index.js'
|
5
|
+
|
6
|
+
if (false) {
|
7
|
+
// All bundlers will remove this block in the production bundle.
|
8
|
+
if (
|
9
|
+
typeof navigator !== 'undefined' &&
|
10
|
+
navigator.product === 'ReactNative' &&
|
11
|
+
typeof crypto === 'undefined'
|
12
|
+
) {
|
13
|
+
throw new Error(
|
14
|
+
'React Native does not have a built-in secure random generator. ' +
|
15
|
+
'If you don’t need unpredictable IDs use `nanoid/non-secure`. ' +
|
16
|
+
'For secure IDs, import `react-native-get-random-values` ' +
|
17
|
+
'before Nano ID.'
|
18
|
+
)
|
19
|
+
}
|
20
|
+
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') {
|
21
|
+
throw new Error(
|
22
|
+
'Import file with `if (!window.crypto) window.crypto = window.msCrypto`' +
|
23
|
+
' before importing Nano ID to fix IE 11 support'
|
24
|
+
)
|
25
|
+
}
|
26
|
+
if (typeof crypto === 'undefined') {
|
27
|
+
throw new Error(
|
28
|
+
'Your browser does not have secure random generator. ' +
|
29
|
+
'If you don’t need unpredictable IDs, you can use nanoid/non-secure.'
|
30
|
+
)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
35
|
+
|
36
|
+
let customRandom = (alphabet, size, getRandom) => {
|
37
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
38
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
39
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
40
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
41
|
+
// `Math.clz32` is not used, because it is not available in browsers.
|
42
|
+
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
43
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
44
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
45
|
+
// the random bytes redundancy has to be satisfied.
|
46
|
+
|
47
|
+
// Note: every hardware random generator call is performance expensive,
|
48
|
+
// because the system call for entropy collection takes a lot of time.
|
49
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
50
|
+
|
51
|
+
// Next, a step determines how many random bytes to generate.
|
52
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
53
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
54
|
+
// according to benchmarks).
|
55
|
+
|
56
|
+
// `-~f => Math.ceil(f)` if f is a float
|
57
|
+
// `-~i => i + 1` if i is an integer
|
58
|
+
let step = -~((1.6 * mask * size) / alphabet.length)
|
59
|
+
|
60
|
+
return () => {
|
61
|
+
let id = ''
|
62
|
+
while (true) {
|
63
|
+
let bytes = getRandom(step)
|
64
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
65
|
+
let j = step
|
66
|
+
while (j--) {
|
67
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
68
|
+
id += alphabet[bytes[j] & mask] || ''
|
69
|
+
if (id.length === size) return id
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
|
76
|
+
|
77
|
+
let nanoid = (size = 21) => {
|
78
|
+
let id = ''
|
79
|
+
let bytes = crypto.getRandomValues(new Uint8Array(size))
|
80
|
+
|
81
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
82
|
+
while (size--) {
|
83
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
84
|
+
// The following mask reduces the random byte in the 0-255 value
|
85
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
86
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
87
|
+
// the bitmask trims bytes down to the alphabet size.
|
88
|
+
let byte = bytes[size] & 63
|
89
|
+
if (byte < 36) {
|
90
|
+
// `0-9a-z`
|
91
|
+
id += byte.toString(36)
|
92
|
+
} else if (byte < 62) {
|
93
|
+
// `A-Z`
|
94
|
+
id += (byte - 26).toString(36).toUpperCase()
|
95
|
+
} else if (byte < 63) {
|
96
|
+
id += '_'
|
97
|
+
} else {
|
98
|
+
id += '-'
|
99
|
+
}
|
100
|
+
}
|
101
|
+
return id
|
102
|
+
}
|
103
|
+
|
104
|
+
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// This alphabet uses `A-Za-z0-9_-` symbols. The genetic algorithm helped
|
2
|
+
// optimize the gzip compression for this alphabet.
|
3
|
+
let urlAlphabet =
|
4
|
+
'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW'
|
5
|
+
|
6
|
+
let customAlphabet = (alphabet, size) => {
|
7
|
+
return () => {
|
8
|
+
let id = ''
|
9
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
10
|
+
let i = size
|
11
|
+
while (i--) {
|
12
|
+
// `| 0` is more compact and faster than `Math.floor()`.
|
13
|
+
id += alphabet[(Math.random() * alphabet.length) | 0]
|
14
|
+
}
|
15
|
+
return id
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
let nanoid = (size = 21) => {
|
20
|
+
let id = ''
|
21
|
+
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
22
|
+
let i = size
|
23
|
+
while (i--) {
|
24
|
+
// `| 0` is more compact and faster than `Math.floor()`.
|
25
|
+
id += urlAlphabet[(Math.random() * 64) | 0]
|
26
|
+
}
|
27
|
+
return id
|
28
|
+
}
|
29
|
+
|
30
|
+
module.exports = { nanoid, customAlphabet }
|
package/non-secure/index.d.ts
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
* @param size Size of the ID. The default size is 21.
|
11
11
|
* @returns A random string.
|
12
12
|
*/
|
13
|
-
export function nanoid
|
13
|
+
export function nanoid(size?: number): string
|
14
14
|
|
15
15
|
/**
|
16
16
|
* Generate URL-friendly unique ID based on the custom alphabet.
|
@@ -27,4 +27,4 @@ export function nanoid (size?: number): string
|
|
27
27
|
* model.id = //=> "8ё56а"
|
28
28
|
* ```
|
29
29
|
*/
|
30
|
-
export function customAlphabet
|
30
|
+
export function customAlphabet(alphabet: string, size: number): () => string
|
package/non-secure/index.js
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nanoid",
|
3
|
-
"version": "3.1.
|
3
|
+
"version": "3.1.23",
|
4
4
|
"description": "A tiny (108 bytes), secure URL-friendly unique string ID generator",
|
5
5
|
"keywords": [
|
6
6
|
"uuid",
|
@@ -15,13 +15,47 @@
|
|
15
15
|
"license": "MIT",
|
16
16
|
"repository": "ai/nanoid",
|
17
17
|
"browser": {
|
18
|
-
"./index.js": "./index.browser.js"
|
19
|
-
"./async/index.js": "./async/index.browser.js"
|
20
|
-
},
|
21
|
-
"react-native": {
|
22
|
-
"./async/index.js": "./async/index.native.js"
|
18
|
+
"./index.js": "./index.browser.js"
|
23
19
|
},
|
20
|
+
"react-native": "index.js",
|
24
21
|
"bin": "./bin/nanoid.cjs",
|
25
22
|
"sideEffects": false,
|
26
|
-
"types": "./index.d.ts"
|
27
|
-
|
23
|
+
"types": "./index.d.ts",
|
24
|
+
"type": "module",
|
25
|
+
"main": "index.cjs",
|
26
|
+
"module": "index.js",
|
27
|
+
"exports": {
|
28
|
+
".": {
|
29
|
+
"browser": {
|
30
|
+
"development": "./index.dev.js",
|
31
|
+
"production": "./index.prod.js",
|
32
|
+
"default": "./index.prod.js"
|
33
|
+
},
|
34
|
+
"require": "./index.cjs",
|
35
|
+
"import": "./index.js",
|
36
|
+
"default": "./index.js",
|
37
|
+
"types": "./index.d.ts"
|
38
|
+
},
|
39
|
+
"./package.json": "./package.json",
|
40
|
+
"./async/package.json": "./async/package.json",
|
41
|
+
"./async": {
|
42
|
+
"browser": "./async/index.browser.js",
|
43
|
+
"require": "./async/index.cjs",
|
44
|
+
"import": "./async/index.js",
|
45
|
+
"default": "./async/index.js"
|
46
|
+
},
|
47
|
+
"./non-secure/package.json": "./non-secure/package.json",
|
48
|
+
"./non-secure": {
|
49
|
+
"require": "./non-secure/index.cjs",
|
50
|
+
"import": "./non-secure/index.js",
|
51
|
+
"default": "./non-secure/index.js"
|
52
|
+
},
|
53
|
+
"./url-alphabet/package.json": "./url-alphabet/package.json",
|
54
|
+
"./url-alphabet": {
|
55
|
+
"require": "./url-alphabet/index.cjs",
|
56
|
+
"import": "./url-alphabet/index.js",
|
57
|
+
"default": "./url-alphabet/index.js"
|
58
|
+
},
|
59
|
+
"./index.d.ts": "./index.d.ts"
|
60
|
+
}
|
61
|
+
}
|
package/url-alphabet/index.js
CHANGED
package/CHANGELOG.md
DELETED
@@ -1,238 +0,0 @@
|
|
1
|
-
# Change Log
|
2
|
-
This project adheres to [Semantic Versioning](http://semver.org/).
|
3
|
-
|
4
|
-
## 3.1.19
|
5
|
-
* Reduce `customAlphabet` size (by Enrico Scherlies).
|
6
|
-
|
7
|
-
## 3.1.18
|
8
|
-
* Fixed `package.exports`.
|
9
|
-
|
10
|
-
## 3.1.17
|
11
|
-
* Added files without `process`.
|
12
|
-
|
13
|
-
## 3.1.16
|
14
|
-
* Speeded up Nano ID 4 times (by Peter Boyer).
|
15
|
-
|
16
|
-
## 3.1.15
|
17
|
-
* Fixed `package.types` path.
|
18
|
-
|
19
|
-
## 3.1.14
|
20
|
-
* Added `package.types`.
|
21
|
-
|
22
|
-
## 3.1.13
|
23
|
-
* Removed Node.js 15.0.0 with `randomFillSync` regression from `engines.node`.
|
24
|
-
|
25
|
-
## 3.1.12
|
26
|
-
* Improved IE 11 docs.
|
27
|
-
|
28
|
-
## 3.1.11
|
29
|
-
* Fixed asynchronous `customAlphabet` in browser (by @LoneRifle).
|
30
|
-
|
31
|
-
## 3.1.10
|
32
|
-
* Fix ES modules support.
|
33
|
-
|
34
|
-
## 3.1.9
|
35
|
-
* Try to fix React Native Expo support.
|
36
|
-
|
37
|
-
## 3.1.8
|
38
|
-
* Add React Native Expo support.
|
39
|
-
|
40
|
-
## 3.1.7
|
41
|
-
* Clean up code.
|
42
|
-
|
43
|
-
## 3.1.6
|
44
|
-
* Avoid `self` using.
|
45
|
-
|
46
|
-
## 3.1.5
|
47
|
-
* Improve IE docs and warning.
|
48
|
-
|
49
|
-
## 3.1.4
|
50
|
-
* Restrict old Node.js 13 by `engines.node` (by Cansin Yildiz).
|
51
|
-
|
52
|
-
## 3.1.3
|
53
|
-
* Fix ES modules issue with CLI.
|
54
|
-
|
55
|
-
## 3.1.2
|
56
|
-
* Add shebang to CLI.
|
57
|
-
|
58
|
-
## 3.1.1
|
59
|
-
* Fix CLI.
|
60
|
-
|
61
|
-
## 3.1
|
62
|
-
* Add `npx nanoid` CLI.
|
63
|
-
|
64
|
-
## 3.0.2
|
65
|
-
* Fix docs (by Dylan Irlbeck ).
|
66
|
-
|
67
|
-
## 3.0.1
|
68
|
-
* Fix React Native warning on `non-secure` import (by Jia Huang).
|
69
|
-
|
70
|
-
## 3.0
|
71
|
-
**Migration guide:** <https://github.com/ai/nanoid/releases/tag/3.0.0>
|
72
|
-
* Move to ES2016 syntax. You need to use Babel for IE 11.
|
73
|
-
* Move to named exports `import { nanoid } from 'nanoid'`.
|
74
|
-
* Move `import url from 'nanoid/url'` to `import { urlAlphabet } from 'nanoid'`.
|
75
|
-
* Replace `format()` to `customRandom()`.
|
76
|
-
* Replace `generate()` to `customAlphabet()`.
|
77
|
-
* Remove `async/format`.
|
78
|
-
* Remove React Native support for `nanoid/async`.
|
79
|
-
* Add `nanoid.js` to use directly in browser from CDN.
|
80
|
-
* Add TypeScript type definitions.
|
81
|
-
* Add ES modules support for bundlers, Node.js, and React Native.
|
82
|
-
* Fix React Native support.
|
83
|
-
* Reduce size.
|
84
|
-
* Improve docs (by Dair Aidarkhanov).
|
85
|
-
|
86
|
-
## 2.1.11
|
87
|
-
* Reduce size (by Anton Evzhakov).
|
88
|
-
|
89
|
-
## 2.1.10
|
90
|
-
* Reduce size by 10% (by Anton Khlynovskiy).
|
91
|
-
|
92
|
-
## 2.1.9
|
93
|
-
* Reduce `format` and `async/format` size (by Dair Aidarkhanov).
|
94
|
-
|
95
|
-
## 2.1.8
|
96
|
-
* Improve React docs (by Nahum Zsilva).
|
97
|
-
|
98
|
-
## 2.1.7
|
99
|
-
* Reduce `index`, `async` and `non-secure` size (by @polemius).
|
100
|
-
|
101
|
-
## 2.1.6
|
102
|
-
* Reduce size (by Stas Lashmanov).
|
103
|
-
* Return fast mask for Node.js.
|
104
|
-
|
105
|
-
## 2.1.5
|
106
|
-
* Reduce size (by Max Graey).
|
107
|
-
* Fix IE support.
|
108
|
-
|
109
|
-
## 2.1.4
|
110
|
-
* Reduce `generate` size (by Vsevolod Rodionov).
|
111
|
-
* Reduce `format` and `format` size (by Victor).
|
112
|
-
* Reduce `async`, `non-secure` and `non-secure/generate` size.
|
113
|
-
* Speed up `format` and `async/format` (by Max Graey).
|
114
|
-
* Improve development process on Windows (by Stanislav Lashmanov).
|
115
|
-
|
116
|
-
## 2.1.3
|
117
|
-
* Improve performance (by Stephen Richardson).
|
118
|
-
* Reduce size (by Stephen Richardson).
|
119
|
-
|
120
|
-
## 2.1.2
|
121
|
-
* Improve docs.
|
122
|
-
|
123
|
-
## 2.1.1
|
124
|
-
* Fix React Native support (by Shawn Hwei).
|
125
|
-
|
126
|
-
## 2.1
|
127
|
-
* Improve React Native support (by Sebastian Werner).
|
128
|
-
|
129
|
-
## 2.0.4
|
130
|
-
* Improve error text for React Native (by Sebastian Werner).
|
131
|
-
|
132
|
-
## 2.0.3
|
133
|
-
* Fix freeze on string in ID length.
|
134
|
-
|
135
|
-
## 2.0.2
|
136
|
-
* Improve docs (by Sylvanus Kateile and Mark Stosberg).
|
137
|
-
|
138
|
-
## 2.0.1
|
139
|
-
* Reduce npm package size.
|
140
|
-
* Mark package as not having side effects (by @xiaody).
|
141
|
-
|
142
|
-
## 2.0
|
143
|
-
* Use `-` instead of `~` in default alphabet to by file name safe.
|
144
|
-
* Add `nanoid/non-secure/generate`.
|
145
|
-
|
146
|
-
## 1.3.4
|
147
|
-
* Reduce `non-secure` size.
|
148
|
-
* Add `async` callback type check.
|
149
|
-
|
150
|
-
## 1.3.3
|
151
|
-
* Fix `nanoid/async` performance regression.
|
152
|
-
* Fix old Node.js `not seeded` issue in synchronous version too.
|
153
|
-
|
154
|
-
## 1.3.2
|
155
|
-
* Fix random generator `not seeded` issue of old Node.js.
|
156
|
-
|
157
|
-
## 1.3.1
|
158
|
-
* Reduce library size.
|
159
|
-
|
160
|
-
## 1.3
|
161
|
-
* Add `nanoid/async/format` and `nanoid/async/generate`.
|
162
|
-
* Improve synchronous API performance.
|
163
|
-
* Reduce `url` size (by Daniil Poroshin).
|
164
|
-
* Improve React Native docs (by joelgetaction).
|
165
|
-
|
166
|
-
## 1.2.6
|
167
|
-
* Reduce library size (by rqrqrqrq).
|
168
|
-
|
169
|
-
## 1.2.5
|
170
|
-
* Fix Node.js 6.11.1 support (by Andrey Belym).
|
171
|
-
|
172
|
-
## 1.2.4
|
173
|
-
* Speed up Node.js secure generators (by Dmitriy Tsvettsikh).
|
174
|
-
|
175
|
-
## 1.2.3
|
176
|
-
* Fix JSDoc (by Hendry Sadrak).
|
177
|
-
|
178
|
-
## 1.2.2
|
179
|
-
* Fix distribution in `nanoid/non-secure` (by Eatall).
|
180
|
-
|
181
|
-
## 1.2.1
|
182
|
-
* Fix old Node.js support.
|
183
|
-
|
184
|
-
## 1.2
|
185
|
-
* Add `nanoid/async`.
|
186
|
-
* Fix `nanoid/non-secure` JSDoc.
|
187
|
-
* Add Chinese documentation (by Wenliang Dai).
|
188
|
-
* Speed up and reduce size of `nanoid/non-secure` (by Ori Livni).
|
189
|
-
|
190
|
-
## 1.1.1
|
191
|
-
* Improve performance and reduce size of non-secure ID generator.
|
192
|
-
|
193
|
-
## 1.1
|
194
|
-
* Add non-secure ID generator.
|
195
|
-
* Suggest to use non-secure ID generator for React Native developers.
|
196
|
-
* Reduce size.
|
197
|
-
|
198
|
-
## 1.0.7
|
199
|
-
* Fix documentation.
|
200
|
-
|
201
|
-
## 1.0.6
|
202
|
-
* Fix documentation.
|
203
|
-
|
204
|
-
## 1.0.5
|
205
|
-
* Reduce `nanoid/index` size (by Anton Khlynovskiy).
|
206
|
-
|
207
|
-
## 1.0.4
|
208
|
-
* Reduce npm package size.
|
209
|
-
|
210
|
-
## 1.0.3
|
211
|
-
* Reduce npm package size.
|
212
|
-
|
213
|
-
## 1.0.2
|
214
|
-
* Fix Web Workers support (by Zachary Golba).
|
215
|
-
|
216
|
-
## 1.0.1
|
217
|
-
* Reduce `nanoid/index` size (by Anton Khlynovskiy).
|
218
|
-
|
219
|
-
## 1.0
|
220
|
-
* Use 21 symbols by default (by David Klebanoff).
|
221
|
-
|
222
|
-
## 0.2.2
|
223
|
-
* Reduce `nanoid/generate` size (by Anton Khlynovskiy).
|
224
|
-
* Speed up Node.js random generator.
|
225
|
-
|
226
|
-
## 0.2.1
|
227
|
-
* Fix documentation (by Piper Chester).
|
228
|
-
|
229
|
-
## 0.2
|
230
|
-
* Add `size` argument to `nanoid()`.
|
231
|
-
* Improve performance by 50%.
|
232
|
-
* Reduce library size by 26% (by Vsevolod Rodionov and Oleg Mokhov).
|
233
|
-
|
234
|
-
## 0.1.1
|
235
|
-
* Reduce library size by 5%.
|
236
|
-
|
237
|
-
## 0.1
|
238
|
-
* Initial release.
|
package/bin/nanoid.test.js
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
let { promisify } = require('util')
|
2
|
-
let { join } = require('path')
|
3
|
-
let child = require('child_process')
|
4
|
-
|
5
|
-
let exec = promisify(child.exec)
|
6
|
-
|
7
|
-
it('prints unique ID', async () => {
|
8
|
-
let { stdout, stderr } = await exec('node ' + join(__dirname, 'nanoid.cjs'))
|
9
|
-
expect(stderr).toEqual('')
|
10
|
-
expect(stdout).toMatch(/^[\w-]{21}\n$/)
|
11
|
-
})
|