Passed
Push — master ( 728693...c302c5 )
by Raúl
01:10
created

cli.ts ➔ printUsageAndExit   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 10
rs 9.9
c 0
b 0
f 0
cc 2
1
#!/usr/bin/env node
2
// TODO: Allow setting the default seed for future use. Use this: https://www.npmjs.com/package/preferences
3
import * as chalk from 'chalk';
4
import * as arrispwgen from '@borfast/arrispwgen';
5
6
function printUsageAndExit(exitCode?: number) {
7
    console.log(`\nUsage: ${process.argv0} start_date [end_date] [--seed=custom_seed]\n`);
8
    console.log('If you only want the password for one specific date, specify only "start_date".');
9
    console.log('If "end_date" is also passed, a password for each day between "start_date" and "end_date" will be generated.');
10
    console.log('The --seed parameter allows you to use a custom seed for the password generator. A seed must be 8 to 10 characters long.');
11
    console.log('The dates should be specified in ISO 8601 format, i.e. "YYYY-MM-DD". Example for Christmas day 2016: "2016-12-25".');
12
13
    if (exitCode) {
14
        process.exit(exitCode);
15
    }
16
}
17
18
const args = process.argv.slice(2);
19
20
if (args.indexOf('--help') > -1 || args.indexOf('-h') > -1) {
21
    printUsageAndExit(0);
22
}
23
if (args.length > 3) {
24
    console.log('Too many arguments.\n');
25
    printUsageAndExit(1);
26
}
27
28
const dates: Date[] = [];
29
let seed = arrispwgen.DEFAULT_SEED;
30
const dateRegex = /\d{4}-\d{2}-\d{2}/;
31
args.forEach((arg: string) => {
32
    if (arg.match(dateRegex)) {
33
        dates.push(new Date(arg));
34
    } else if (arg.indexOf('--seed=') == 0) {
35
        const s = arg.split('=')[1];
36
        if (s.length >= 8 && s.length <= 10) {
37
            seed = arg.split('=')[1];
38
        } else {
39
            const problem = s.length < 8 ? 'short' : s.length > 10 ? 'long' : ' unrecognized';
40
            console.log(`Seed is too ${problem}: ${s}.\nIt's ${s.length} characters but it must be between 8 and 10.`);
41
            printUsageAndExit(1);
42
        }
43
    } else {
44
        console.log(`Unrecognized argument: ${arg}.`);
45
        printUsageAndExit(1);
46
    }
47
});
48
49
50
const date_format_options = { weekday: 'short', year: 'numeric', month: 'long', day: '2-digit' };
51
const date_formatter = new Intl.DateTimeFormat('default', date_format_options);
52
53
let data = [];
54
55
// If no date is given, default to outputting the password for the current date.
56
if (dates.length === 0) {
57
    dates.push(new Date());
58
}
59
60
if (dates.length === 1) {
61
    const long_date = date_formatter.format(dates[0]);
62
    const potd = arrispwgen.generate(dates[0], seed);
63
    data.push({
64
        date: long_date,
65
        password: potd
66
    });
67
} else {
68
    const start_date = dates[0];
69
    const end_date = dates[1];
70
    try {
71
        const potd = arrispwgen.generate_multi(start_date, end_date, seed);
72
73
        for (const p of potd) {
74
            data.push({
75
                date: date_formatter.format(p['date']),
76
                password: p['password']
77
            });
78
        }
79
    } catch (e) {
80
        if (e instanceof arrispwgen.InvalidDateRangeError) {
81
            console.log(chalk.red('The given dates are out of order. Your start date is after the end date.'));
82
            printUsageAndExit();
83
        } else {
84
            console.log(`Unknown error occurred: ${e.message}`)
85
        }
86
    }
87
}
88
89
console.log();
90
console.table(data, ['date', 'password']);
91