Skip to content

Commit 16a6364

Browse files
committed
Move the length argument to the options-object
1 parent 51402ba commit 16a6364

File tree

5 files changed

+109
-99
lines changed

5 files changed

+109
-99
lines changed

index.d.ts

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,70 @@
11
import {MergeExclusive} from 'type-fest';
22

3+
interface BaseOptions {
4+
/**
5+
Length of the returned string.
6+
*/
7+
length: number;
8+
}
9+
10+
interface TypeOption {
11+
/**
12+
Use only characters from a predefined set of allowed characters.
13+
14+
Cannot be set at the same time as the `characters` option.
15+
16+
@default 'hex'
17+
18+
@example
19+
```
20+
cryptoRandomString({length: 10});
21+
//=> '87fc70e2b9'
22+
23+
cryptoRandomString({length: 10, type:'base64'});
24+
//=> 'mhsX7xmIv/'
25+
26+
cryptoRandomString({length: 10, type:'url-safe'});
27+
//=> 'VEjfNW3Yej'
28+
```
29+
*/
30+
type?: 'hex' | 'base64' | 'url-safe';
31+
}
32+
33+
interface CharactersOption {
34+
/**
35+
Use only characters from a custom set of allowed characters.
36+
37+
Cannot be set at the same time as the `type` option.
38+
39+
Minimum length: `1`
40+
Maximum length: `65536`
41+
42+
@example
43+
```
44+
cryptoRandomString({length: 10, characters:'0123456789'});
45+
//=> '8796225811'
46+
```
47+
*/
48+
characters?: string;
49+
}
50+
351
declare namespace cryptoRandomString {
4-
interface TypeOptions {
5-
/**
6-
Use only characters from a predefined set of allowed characters.
7-
8-
Cannot be set at the same time as the `characters` option.
9-
10-
@default 'hex'
11-
12-
@example
13-
```
14-
cryptoRandomString(10, {type:'hex'});
15-
//=> '87fc70e2b9'
16-
17-
cryptoRandomString(10, {type:'base64'});
18-
//=> 'mhsX7xmIv/'
19-
20-
cryptoRandomString(10, {type:'url-safe'});
21-
//=> 'VEjfNW3Yej'
22-
```
23-
*/
24-
type?: 'hex' | 'base64' | 'url-safe';
25-
}
26-
27-
interface CharactersOptions {
28-
/**
29-
Use only characters from a custom set of allowed characters.
30-
31-
Cannot be set at the same time as the `type` option.
32-
33-
Minimum length: `1`
34-
Maximum length: `65536`
35-
36-
@example
37-
```
38-
cryptoRandomString(10, {characters:'0123456789'});
39-
//=> '8796225811'
40-
```
41-
*/
42-
characters: string;
43-
}
44-
type Options = MergeExclusive<TypeOptions, CharactersOptions>;
52+
type Options = BaseOptions & MergeExclusive<TypeOption, CharactersOption>;
4553
}
4654

4755
/**
4856
Generate a [cryptographically strong](https://en.wikipedia.org/wiki/Strong_cryptography) random string.
4957
50-
@param length - Length of the returned string.
51-
@returns Returns a randomized string.
58+
@returns A randomized string.
5259
5360
@example
5461
```
5562
import cryptoRandomString = require('crypto-random-string');
5663
57-
cryptoRandomString(10);
64+
cryptoRandomString({length: 10});
5865
//=> '2cf05d94db'
5966
```
6067
*/
61-
declare function cryptoRandomString(length: number, options?: cryptoRandomString.Options): string;
68+
declare function cryptoRandomString(options?: cryptoRandomString.Options): string;
6269

6370
export = cryptoRandomString;

index.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use strict';
22
const crypto = require('crypto');
33

4-
const urlSafeChars = 'abcdefjhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split('');
4+
const urlSafeCharacters = 'abcdefjhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split('');
55

6-
const generateForCustomCharacters = (length, chars) => {
6+
const generateForCustomCharacters = (length, characters) => {
77
// Generating entropy is faster than complex math operations, so we use the simplest way
8-
const characterCount = chars.length;
8+
const characterCount = characters.length;
99
const maxValidSelector = (Math.floor(0x10000 / characterCount) * characterCount) - 1; // Using values above this will ruin distribution when using modular division
1010
const entropyLength = 2 * Math.ceil(1.1 * length); // Generating a bit more than required so chances we need more than one pass will be really low
1111
let string = '';
@@ -22,24 +22,26 @@ const generateForCustomCharacters = (length, chars) => {
2222
continue;
2323
}
2424

25-
string += chars[entropyValue % characterCount];
25+
string += characters[entropyValue % characterCount];
2626
stringLength++;
2727
}
2828
}
2929

3030
return string;
3131
};
3232

33-
const allowedTypes = [undefined, 'hex', 'base64', 'url-safe'];
33+
const allowedTypes = [
34+
undefined,
35+
'hex',
36+
'base64',
37+
'url-safe'
38+
];
3439

35-
module.exports = (length, opts) => {
40+
module.exports = ({length, type, characters}) => {
3641
if (!Number.isFinite(length)) {
3742
throw new TypeError('Expected a finite number');
3843
}
3944

40-
let type = opts === undefined ? undefined : opts.type;
41-
const characters = opts === undefined ? undefined : opts.characters;
42-
4345
if (type !== undefined && characters !== undefined) {
4446
throw new TypeError('Expected either type or characters');
4547
}
@@ -65,7 +67,7 @@ module.exports = (length, opts) => {
6567
}
6668

6769
if (type === 'url-safe') {
68-
return generateForCustomCharacters(length, urlSafeChars);
70+
return generateForCustomCharacters(length, urlSafeCharacters);
6971
}
7072

7173
if (characters.length === 0) {

index.test-d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import {expectType} from 'tsd';
1+
import {expectType, expectError} from 'tsd';
22
import cryptoRandomString = require('.');
33

4-
expectType<string>(cryptoRandomString(10));
5-
expectType<string>(cryptoRandomString(10, {type: 'url-safe'}));
6-
expectType<string>(cryptoRandomString(10, {characters: '1234'}));
4+
expectType<string>(cryptoRandomString({length: 10}));
5+
expectType<string>(cryptoRandomString({length: 10, type: 'url-safe'}));
6+
expectType<string>(cryptoRandomString({length: 10, characters: '1234'}));
7+
8+
expectError(cryptoRandomString({type: 'url-safe'}));
9+
expectError(cryptoRandomString({length: 10, type: 'url-safe', characters: '1234'}));

readme.md

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# crypto-random-string [![Build Status](https://travis-ci.org/sindresorhus/crypto-random-string.svg?branch=master)](https://travis-ci.org/sindresorhus/crypto-random-string)
22

3-
> Generate a [cryptographically strong](https://en.m.wikipedia.org/wiki/Strong_cryptography) random string
3+
> Generate a [cryptographically strong](https://en.wikipedia.org/wiki/Strong_cryptography) random string
44
55
Can be useful for creating an identifier, slug, salt, fixture, etc.
66

@@ -17,44 +17,42 @@ $ npm install crypto-random-string
1717
```js
1818
const cryptoRandomString = require('crypto-random-string');
1919

20-
cryptoRandomString(10);
20+
cryptoRandomString({length: 10});
2121
//=> '2cf05d94db'
2222

23-
cryptoRandomString(10, {type: 'hex'});
24-
//=> 'c00f094c79'
25-
26-
cryptoRandomString(10, {type: 'base64'});
23+
cryptoRandomString({length: 10, type: 'base64'});
2724
//=> 'YMiMbaQl6I'
2825

29-
cryptoRandomString(10, {type: 'url-safe'});
26+
cryptoRandomString({length: 10, type: 'url-safe'});
3027
//=> 'YN-tqc8pOw'
3128

32-
cryptoRandomString(10, {characters: '1234567890'});
29+
cryptoRandomString({length: 10, characters: '1234567890'});
3330
//=> '1791935639'
3431
```
3532

3633

3734
## API
3835

39-
### cryptoRandomString(length, [options])
36+
### cryptoRandomString(options)
4037

4138
Returns a randomized string. [Hex](https://en.wikipedia.org/wiki/Hexadecimal) by default.
4239

43-
#### length
40+
#### options
4441

45-
Type: `number`
42+
Type: `object`
4643

47-
Length of the returned string.
44+
##### length
4845

49-
#### options
46+
*Required*<br>
47+
Type: `number`
5048

51-
Type: `object`
49+
Length of the returned string.
5250

5351
##### type
5452

5553
Type: `string`<br>
56-
Default: `hex`<br>
57-
Values: `hex` `base64` `url-safe`
54+
Default: `'hex'`<br>
55+
Values: `'hex'` `'base64'` `'url-safe'`
5856

5957
Use only characters from a predefined set of allowed characters.
6058

test.js

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,54 @@ import test from 'ava';
22
import cryptoRandomString from '.';
33

44
test('main', t => {
5-
t.is(cryptoRandomString(0).length, 0);
6-
t.is(cryptoRandomString(10).length, 10);
7-
t.is(cryptoRandomString(100).length, 100);
8-
t.regex(cryptoRandomString(100), /^[a-f\d]*$/); // Sanity check, probabilistic
5+
t.is(cryptoRandomString({length: 0}).length, 0);
6+
t.is(cryptoRandomString({length: 10}).length, 10);
7+
t.is(cryptoRandomString({length: 100}).length, 100);
8+
t.regex(cryptoRandomString({length: 100}), /^[a-f\d]*$/); // Sanity check, probabilistic
99
});
1010

1111
test('hex', t => {
12-
t.is(cryptoRandomString(0, {type: 'hex'}).length, 0);
13-
t.is(cryptoRandomString(10, {type: 'hex'}).length, 10);
14-
t.is(cryptoRandomString(100, {type: 'hex'}).length, 100);
15-
t.regex(cryptoRandomString(100, {type: 'hex'}), /^[a-f\d]*$/); // Sanity check, probabilistic
12+
t.is(cryptoRandomString({length: 0, type: 'hex'}).length, 0);
13+
t.is(cryptoRandomString({length: 10, type: 'hex'}).length, 10);
14+
t.is(cryptoRandomString({length: 100, type: 'hex'}).length, 100);
15+
t.regex(cryptoRandomString({length: 100, type: 'hex'}), /^[a-f\d]*$/); // Sanity check, probabilistic
1616
});
1717

1818
test('base64', t => {
19-
t.is(cryptoRandomString(0, {type: 'base64'}).length, 0);
20-
t.is(cryptoRandomString(10, {type: 'base64'}).length, 10);
21-
t.is(cryptoRandomString(100, {type: 'base64'}).length, 100);
22-
t.regex(cryptoRandomString(100, {type: 'base64'}), /^[a-zA-Z\d/+]*$/); // Sanity check, probabilistic
19+
t.is(cryptoRandomString({length: 0, type: 'base64'}).length, 0);
20+
t.is(cryptoRandomString({length: 10, type: 'base64'}).length, 10);
21+
t.is(cryptoRandomString({length: 100, type: 'base64'}).length, 100);
22+
t.regex(cryptoRandomString({length: 100, type: 'base64'}), /^[a-zA-Z\d/+]*$/); // Sanity check, probabilistic
2323
});
2424

2525
test('url-safe', t => {
26-
t.is(cryptoRandomString(0, {type: 'url-safe'}).length, 0);
27-
t.is(cryptoRandomString(10, {type: 'url-safe'}).length, 10);
28-
t.is(cryptoRandomString(100, {type: 'url-safe'}).length, 100);
29-
t.regex(cryptoRandomString(100, {type: 'url-safe'}), /^[a-zA-Z\d._~-]*$/); // Sanity check, probabilistic
26+
t.is(cryptoRandomString({length: 0, type: 'url-safe'}).length, 0);
27+
t.is(cryptoRandomString({length: 10, type: 'url-safe'}).length, 10);
28+
t.is(cryptoRandomString({length: 100, type: 'url-safe'}).length, 100);
29+
t.regex(cryptoRandomString({length: 100, type: 'url-safe'}), /^[a-zA-Z\d._~-]*$/); // Sanity check, probabilistic
3030
});
3131

3232
test('characters', t => {
33-
t.is(cryptoRandomString(0, {characters: '1234'}).length, 0);
34-
t.is(cryptoRandomString(10, {characters: '1234'}).length, 10);
35-
t.is(cryptoRandomString(100, {characters: '1234'}).length, 100);
36-
t.regex(cryptoRandomString(100, {characters: '1234'}), /^[1-4]*$/); // Sanity check, probabilistic
33+
t.is(cryptoRandomString({length: 0, characters: '1234'}).length, 0);
34+
t.is(cryptoRandomString({length: 10, characters: '1234'}).length, 10);
35+
t.is(cryptoRandomString({length: 100, characters: '1234'}).length, 100);
36+
t.regex(cryptoRandomString({length: 100, characters: '1234'}), /^[1-4]*$/); // Sanity check, probabilistic
3737
});
3838

3939
test('argument errors', t => {
4040
t.throws(() => {
41-
cryptoRandomString(Infinity);
41+
cryptoRandomString({length: Infinity});
4242
});
4343

4444
t.throws(() => {
45-
cryptoRandomString(0, {type: 'hex', characters: '1234'});
45+
cryptoRandomString({length: 0, type: 'hex', characters: '1234'});
4646
});
4747

4848
t.throws(() => {
49-
cryptoRandomString(0, {characters: 42});
49+
cryptoRandomString({length: 0, characters: 42});
5050
});
5151

5252
t.throws(() => {
53-
cryptoRandomString(0, {type: 'unknown'});
53+
cryptoRandomString({length: 0, type: 'unknown'});
5454
});
5555
});

0 commit comments

Comments
 (0)