-
Notifications
You must be signed in to change notification settings - Fork 1
/
cli.ts
executable file
·137 lines (124 loc) · 4.01 KB
/
cli.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env node
import * as program from 'commander';
import { readFile } from 'fs/promises';
import * as path from 'path';
import { Log } from './models/Log';
import { SimulatorConfig, run } from './index';
function validateAppTypeJSONInput(input: any) {
if (typeof input.state !== 'object') {
new Log(false).error(
'appType custom shadow is missing object value for "state" key',
);
return false;
}
if (typeof input.state.reported !== 'object') {
new Log(false).error(
'appType custom shadow "state" object is missing object value for "reported" key',
);
return false;
}
return true;
}
const handleAppType = async (input: any, _: unknown) => {
if (input === 'mss' || input === 'atv2') {
return input;
}
if (input[0] !== '[' && input[0] !== '{' && !input.includes('.json')) {
new Log(false).error(
'Input for appType may only be "mss", "atv2", JSON-encoded object, or path to a json file.',
);
process.exit();
}
if (input.includes('.json')) {
//Adding an additional '../' to the input since it's being called from dist and not src
const file = path.join(__dirname, '../' + input);
try {
input = await readFile(file, 'utf8');
} catch (err) {
new Log(false).error(`Error opening file: ${err}`);
process.exit();
}
}
try {
input = JSON.parse(input);
if (!validateAppTypeJSONInput(input)) {
new Log(false).info(
`Expected input: '{"state":{"reported":{...}, "desired":{...}}}', "desired" is optional.`,
);
process.exit();
}
} catch (err) {
new Log(false).error('Error parsing JSON:' + (err as any).message);
process.exit();
}
return input;
};
const getConfig = (env: any, args: string[]): SimulatorConfig =>
program
.requiredOption(
'-k, --api-key <apiKey>',
'API key for nRF Cloud',
env.API_KEY,
)
.option(
'-c, --certs-response <certsResponse>',
'JSON returned by call to the Device API endpoint: POST /devices/{deviceid}/certificates',
env.CERTS_RESPONSE,
)
.option(
'-e, --endpoint <endpoint>',
'AWS IoT MQTT endpoint',
env.MQTT_ENDPOINT,
)
.option('-d, --device-id <deviceId>', 'ID of the device', env.DEVICE_ID)
.option(
'-o, --device-ownership-code <deviceOwnershipCode>',
'PIN/ownership code of the device',
env.DEVICE_OWNERSHIP_CODE || '123456',
)
.option(
'-m, --mqtt-messages-prefix <mqttMessagesPrefix>',
'The prefix for the MQTT unique to this tenant for sending and receiving device messages',
env.MQTT_MESSAGES_PREFIX,
)
.option(
'-s, --services <services>',
'Comma-delimited list of services to enable. Any of: [gps,acc,temp,device,rsrp,location,log,alert]',
)
.option(
'-f, --app-fw-version <appFwVersion>',
'Version of the app firmware',
'1',
)
.option(
'-h, --api-host <apiHost>',
'API host for nRF Cloud',
env.API_HOST ? env.API_HOST : 'https://api.nrfcloud.com',
)
.option(
'-a, --associate',
'automatically associate device to account',
false,
)
.option('-v, --verbose', 'output debug info', false)
.option(
'-t, --app-type <appType>',
'Specifies the shadow to use. For custom shadow, pass a JSON-encoded shadow object or relative path to json file. Otherwise, pass "mss" or "atv2" to automatically generate a conformal shadow',
handleAppType,
)
.parse(args)
.opts() as SimulatorConfig;
let verbose: boolean;
(async (): Promise<void> => {
const config = getConfig(process.env, process.argv);
verbose = !!config.verbose;
const hostSplit = config.apiHost!.split('.');
let stage = hostSplit.length === 3 ? 'prod' : hostSplit[1];
// dev is default stage for sub accounts (ie https://api.coha.nrfcloud.com)
if (['dev', 'beta', 'prod'].includes(stage) === false) {
stage = 'dev';
}
config.stage = stage;
config.appType = await config.appType;
return run(config);
})().catch((err) => new Log(verbose).error(err));