Skip to content

Commit 32b9bda

Browse files
authored
Allows passing size or custom alphabet via cli as args (#334)
* Allows passing size or custom alphabet via cli as args * Increase test coverage, make work with Node 12
1 parent 246d5f8 commit 32b9bda

File tree

5 files changed

+172
-10
lines changed

5 files changed

+172
-10
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,19 @@ npx: installed 1 in 0.63s
468468
LZfXLFzPPR4NNrgjlWDxn
469469
```
470470

471-
If you want to change alphabet or ID size, you should use [`nanoid-cli`].
471+
Size of generated ID can be specified with `--size` (or `-s`) option:
472472

473-
[`nanoid-cli`]: https://github.com/twhitbeck/nanoid-cli
473+
```sh
474+
$ npx nanoid --size 10
475+
L3til0JS4z
476+
```
477+
478+
Custom alphabet can be specified with `--alphabet` (or `-a`) option (note that in this case `--size` is required):
474479

480+
```sh
481+
$ npx nanoid --alphabet abc --size 15
482+
bccbcabaabaccab
483+
```
475484

476485
### Other Programming Languages
477486

README.ru.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,19 @@ npx: installed 1 in 0.63s
456456
LZfXLFzPPR4NNrgjlWDxn
457457
```
458458

459-
Для смены алфавита или длины ID есть отдельный проект [`nanoid-cli`].
459+
Длину генерируемых ID можно передать в аргументе `--size` (или `-s`):
460460

461-
[`nanoid-cli`]: https://github.com/twhitbeck/nanoid-cli
461+
```sh
462+
$ npx nanoid --size 10
463+
L3til0JS4z
464+
```
465+
466+
Изменить алфавит можно при помощи аргумента `--alphabet` (ли `-a`) (обратите внимание, что в этом случае `--size` обязателен):
462467

468+
```sh
469+
$ npx nanoid --alphabet abc --size 15
470+
bccbcabaabaccab
471+
```
463472

464473
### Другие языки программирования
465474

bin/nanoid.cjs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
#!/usr/bin/env node
22

3-
let { nanoid } = require('..')
3+
let { nanoid, customAlphabet } = require('..')
4+
let { parseArgs } = require('./utils')
45

5-
process.stdout.write(nanoid() + '\n')
6+
let parsedArgs = parseArgs(process.argv)
7+
8+
if (parsedArgs.help) {
9+
process.stdout.write(`
10+
Usage
11+
$ nanoid [options]
12+
13+
Options
14+
-s, --size Generated ID size
15+
-a, --alphabet Alphabet to use
16+
-h, --help Show this help
17+
18+
Examples
19+
$ nano --s=15
20+
S9sBF77U6sDB8Yg
21+
22+
$ nano --size=10 --alphabet=abc
23+
bcabababca
24+
`)
25+
process.exit()
26+
}
27+
28+
let alphabet = parsedArgs.alphabet || parsedArgs.a
29+
let size = parsedArgs.size || parsedArgs.s ? Number(parsedArgs.size || parsedArgs.s) : undefined
30+
31+
if (typeof size !== 'undefined' && (Number.isNaN(size) || size <= 0)) {
32+
process.stderr.write('Size must be positive integer\n')
33+
process.exit(1)
34+
}
35+
36+
if (alphabet) {
37+
if (typeof size === 'undefined') {
38+
process.stderr.write('You must also specify size option, when using custom alphabet\n')
39+
process.exit(1)
40+
}
41+
process.stdout.write(customAlphabet(alphabet, size)())
42+
} else {
43+
process.stdout.write(nanoid(size))
44+
}
45+
46+
process.stdout.write('\n')

bin/nanoid.test.js

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,74 @@
1-
let { test } = require('uvu')
2-
let { is, match } = require('uvu/assert')
1+
let { suite } = require('uvu')
2+
let { is, match, equal } = require('uvu/assert')
33
let { promisify } = require('util')
44
let { join } = require('path')
55
let child = require('child_process')
66

7+
let { parseArgs } = require('./utils')
8+
79
let exec = promisify(child.exec)
810

9-
test('prints unique ID', async () => {
11+
const nanoIdSuit = suite('nanoid')
12+
13+
nanoIdSuit('prints unique ID', async () => {
1014
let { stdout, stderr } = await exec('node ' + join(__dirname, 'nanoid.cjs'))
1115
is(stderr, '')
1216
match(stdout, /^[\w-]{21}\n$/)
1317
})
1418

15-
test.run()
19+
nanoIdSuit('uses size', async () => {
20+
let { stdout, stderr } = await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --size=10')
21+
is(stderr, '')
22+
match(stdout, /^[\w-]{10}\n$/)
23+
})
24+
25+
nanoIdSuit('uses alphabet', async () => {
26+
let { stdout, stderr } = await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --alphabet=abc --size=15')
27+
is(stderr, '')
28+
match(stdout, /^[abc]{15}\n$/)
29+
})
30+
31+
nanoIdSuit('show an error if size is not a number', async () => {
32+
try {
33+
await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --s abc')
34+
} catch (e) {
35+
match(e, /Size must be positive integer/)
36+
}
37+
})
38+
39+
nanoIdSuit('shows an error if size is not provided when using custom alphabet', async () => {
40+
try {
41+
await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --alphabet abc')
42+
} catch (e) {
43+
match(e, /You must also specify size option, when using custom alphabet/)
44+
}
45+
})
46+
47+
nanoIdSuit('requires error if size is a negative number', async () => {
48+
try {
49+
await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --size "-1"')
50+
} catch (e) {
51+
match(e, /Size must be positive integer/)
52+
}
53+
})
54+
55+
nanoIdSuit('displays help', async () => {
56+
let { stdout, stderr } = await exec('node ' + join(__dirname, 'nanoid.cjs') + ' --help')
57+
is(stderr, '')
58+
match(stdout, /Usage/)
59+
match(stdout, /\$ nanoid \[options]/)
60+
})
61+
62+
nanoIdSuit.run()
63+
64+
const parseArgsSuite = suite('parseArgs')
65+
66+
parseArgsSuite('parses args', () => {
67+
equal(parseArgs(['node', 'nanoid.cjs', '--help']), { help: true })
68+
equal(parseArgs(['node', 'nanoid.cjs', '--help', '--size=30']), { help: true, size: '30' })
69+
equal(parseArgs(['node', 'nanoid.cjs', '--help', '-s', '30']), { help: true, s: '30' })
70+
equal(parseArgs(['node', 'nanoid.cjs', '--help', '-size', '30']), { help: true, size: '30' })
71+
equal(parseArgs(['node', 'nanoid.cjs', '--help', '-size', '30', '-alphabet', 'abc']), { help: true, size: '30', alphabet: 'abc' })
72+
})
73+
74+
parseArgsSuite.run()

bin/utils/index.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
let cleanArgName = (arg) => arg.startsWith('--') ? arg.slice(2) : arg.slice(1)
2+
3+
let parseArgs = (argv) => {
4+
argv.splice(0, 2)
5+
6+
let parsedArgs = {}
7+
8+
let currentArg = null
9+
argv.forEach((arg) => {
10+
if (arg.includes('=')) {
11+
if (currentArg) {
12+
parsedArgs[currentArg] = true
13+
currentArg = null
14+
}
15+
let argSplit = arg.split('=')
16+
parsedArgs[cleanArgName(argSplit[0])] = argSplit[1]
17+
18+
return
19+
}
20+
21+
if (arg.startsWith('-') || arg.startsWith('--')) {
22+
if (currentArg) {
23+
parsedArgs[currentArg] = true
24+
currentArg = null
25+
}
26+
27+
currentArg = cleanArgName(arg)
28+
return
29+
}
30+
31+
if (currentArg) {
32+
parsedArgs[currentArg] = arg
33+
currentArg = null
34+
}
35+
})
36+
37+
if (currentArg) {
38+
parsedArgs[currentArg] = true
39+
}
40+
41+
return parsedArgs
42+
}
43+
44+
module.exports = { parseArgs }

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy