@mytmpvpn/mytmpvpn-cli 1.1.0
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.
- package/#package-lock.json# +6527 -0
- package/.gitlab-ci.yml +16 -0
- package/README.md +63 -0
- package/build-all-dependencies +11 -0
- package/dist/mytmpvpn.js +335 -0
- package/package.json +40 -0
- package/src/mytmpvpn.ts +349 -0
- package/tsconfig.json +115 -0
package/src/mytmpvpn.ts
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/usr/bin/env -S NODE_NO_WARNINGS=1 node
|
|
2
|
+
// Use NODE_NO_WARNINGS=1 to get rid of the fetch node deprecated API
|
|
3
|
+
// https://github.com/netlify/cli/issues/4608 -- but it hangs the process: https://github.com/nodejs/node/issues/21960
|
|
4
|
+
import * as fs from 'fs'
|
|
5
|
+
import * as path from 'path'
|
|
6
|
+
import { Argument, Command, Option } from 'commander'
|
|
7
|
+
import * as log from 'loglevel'
|
|
8
|
+
log.setDefaultLevel("info")
|
|
9
|
+
|
|
10
|
+
import * as vpnlib from '@mytmpvpn/mytmpvpn-common/models/vpn'
|
|
11
|
+
import * as peanuts from '@mytmpvpn/mytmpvpn-common/models/peanuts'
|
|
12
|
+
import { getDefaultAppConfigFile, loadAppConfig } from '@mytmpvpn/mytmpvpn-client/appconfig'
|
|
13
|
+
import { getDefaultUserConfigFile, getDefaultUserProfile, getDefaultUserConfigDir, loadUserConfig, UserConfig } from '@mytmpvpn/mytmpvpn-client/userconfig'
|
|
14
|
+
import * as auth from '@mytmpvpn/mytmpvpn-client/auth'
|
|
15
|
+
import { MyTmpVpnClient } from '@mytmpvpn/mytmpvpn-client/mytmpvpn-client'
|
|
16
|
+
|
|
17
|
+
const program = new Command()
|
|
18
|
+
|
|
19
|
+
function handleError(error: any, verbose: boolean = false) {
|
|
20
|
+
if (error.response) {
|
|
21
|
+
// The request was made and the server responded with a status code
|
|
22
|
+
// that falls out of the range of 2xx
|
|
23
|
+
try {
|
|
24
|
+
log.error(`[${error.response.status}] - ${JSON.stringify(error.response.data)}`)
|
|
25
|
+
} catch (Error) {
|
|
26
|
+
log.error(`[${error.response.status}] - ${JSON.stringify(error.message)}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
log.debug(error.response.headers)
|
|
30
|
+
} else if (error.request) {
|
|
31
|
+
// The request was made but no response was received
|
|
32
|
+
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
33
|
+
// http.ClientRequest in node.js
|
|
34
|
+
log.error(`No reponse received. Check your profile and your appConfig`)
|
|
35
|
+
} else {
|
|
36
|
+
// Something happened in setting up the request that triggered an Error
|
|
37
|
+
log.error(`Error while setting up the request ${JSON.stringify(error)}`)
|
|
38
|
+
}
|
|
39
|
+
log.trace(`Stack trace: ${error}`)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
program
|
|
43
|
+
.name('mytmpvpn-cli')
|
|
44
|
+
.description('MyTmpVpn CLI')
|
|
45
|
+
.version('0.0.1')
|
|
46
|
+
.option('--verbose', 'Produce more logs')
|
|
47
|
+
.option('--appConfig <file>', 'Path to the application config file', getDefaultAppConfigFile())
|
|
48
|
+
.option('--userConfig <file>', 'Path to the user config file', getDefaultUserConfigFile())
|
|
49
|
+
.option('--profile <name>', 'Name of the profile in the user config file to use', getDefaultUserProfile())
|
|
50
|
+
program.on('option:verbose', function () {
|
|
51
|
+
log.setDefaultLevel("trace")
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
program.command('list-peanuts-packs')
|
|
55
|
+
.description(`Returns the list of peanuts packs you can purchase. A peanuts pack contains a given number of peanuts. You need a minimum of ${peanuts.PEANUTS_CONFIG.min} peanuts to create a vpn`)
|
|
56
|
+
.action((_, command) => {
|
|
57
|
+
const options = command.optsWithGlobals()
|
|
58
|
+
const appConfig = loadAppConfig(options.appConfig)
|
|
59
|
+
// We don't need authenticated user to call this API
|
|
60
|
+
const client = new MyTmpVpnClient(appConfig.apiUrl)
|
|
61
|
+
client.listPeanutsPacks()
|
|
62
|
+
.then(((packs: peanuts.PeanutsPack[]) => {
|
|
63
|
+
log.info(JSON.stringify(packs, null, 2))
|
|
64
|
+
}))
|
|
65
|
+
.catch((err) => handleError(err))
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
program.command('get-peanuts-balance')
|
|
69
|
+
.description('Get the current peanuts balance')
|
|
70
|
+
.action((_, command) => {
|
|
71
|
+
const options = command.optsWithGlobals()
|
|
72
|
+
log.debug(`Get peanuts balance`)
|
|
73
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
74
|
+
if (err) {
|
|
75
|
+
handleError(err, options.verbose)
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
client.getPeanutsBalance().then(balance => {
|
|
79
|
+
log.info(balance)
|
|
80
|
+
}).catch(err => {
|
|
81
|
+
handleError(err)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
program.command('list-regions')
|
|
87
|
+
.description('Returns the list of all regions where vpn can be created')
|
|
88
|
+
.action((_, command) => {
|
|
89
|
+
const options = command.optsWithGlobals()
|
|
90
|
+
const appConfig = loadAppConfig(options.appConfig)
|
|
91
|
+
// We don't need authenticated user to call this API
|
|
92
|
+
const client = new MyTmpVpnClient(appConfig.apiUrl)
|
|
93
|
+
client.listRegions()
|
|
94
|
+
.then(((regions: any) => {
|
|
95
|
+
log.info(JSON.stringify(regions, null, 2))
|
|
96
|
+
}))
|
|
97
|
+
.catch((err) => handleError(err))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
program.command('create')
|
|
102
|
+
.description('Create a new vpn')
|
|
103
|
+
.argument('<region>', 'region where the vpn should be created, as returned by list-regions')
|
|
104
|
+
.option('--sync', 'wait for vpn creation completion')
|
|
105
|
+
.addOption(new Option('--type <type>', 'Type of VPN')
|
|
106
|
+
.choices(vpnlib.getVpnConfigTypes())
|
|
107
|
+
.default(vpnlib.VpnType.WireGuard))
|
|
108
|
+
.option('--peanuts <nb>', 'Max number of peanuts to use (specify -1 for maximum)', '-1')
|
|
109
|
+
.action((region: string, _, command) => {
|
|
110
|
+
const options = command.optsWithGlobals()
|
|
111
|
+
const syncStr = options.sync ? "synchronously" : "asynchronously"
|
|
112
|
+
log.debug(`Creating new ${options.type} vpn into ${region} ${syncStr}`)
|
|
113
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
114
|
+
if (err) {
|
|
115
|
+
handleError(err, options.verbose)
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
client.createVpn(region, { type: options.type, maxPeanuts: options.peanuts }).then(vpn => {
|
|
119
|
+
if (!options.sync) {
|
|
120
|
+
log.info(vpn)
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
client.waitUntilVpnStateIs(vpn.vpnId, vpnlib.VpnState.Running).then(updatedVpn => {
|
|
124
|
+
log.info(updatedVpn)
|
|
125
|
+
}).catch(err => {
|
|
126
|
+
handleError(err)
|
|
127
|
+
})
|
|
128
|
+
}).catch(err => {
|
|
129
|
+
handleError(err)
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
program.command('delete')
|
|
136
|
+
.description('Delete a vpn')
|
|
137
|
+
.argument('<vpnId>', 'vpnId to delete')
|
|
138
|
+
.option('--sync', 'wait for vpn deletion completion')
|
|
139
|
+
.action((vpnId, _, command) => {
|
|
140
|
+
const options = command.optsWithGlobals()
|
|
141
|
+
const syncStr = options.sync ? "synchronously" : "asynchronously"
|
|
142
|
+
log.debug(`Deleting vpn ${vpnId} ${syncStr}`)
|
|
143
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
144
|
+
if (err) {
|
|
145
|
+
handleError(err.message || JSON.stringify(err))
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
client.deleteVpn(vpnId).then(vpn => {
|
|
149
|
+
if (!options.sync) {
|
|
150
|
+
log.info(JSON.stringify(vpn))
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
client.waitUntilVpnStateIs(vpnId, vpnlib.VpnState.Deleted).then(updatedVpn => {
|
|
154
|
+
log.info(updatedVpn)
|
|
155
|
+
return
|
|
156
|
+
}).catch(err => {
|
|
157
|
+
handleError(err.response?.data || JSON.stringify(err))
|
|
158
|
+
})
|
|
159
|
+
}).catch(err => {
|
|
160
|
+
handleError(err.response?.data || JSON.stringify(err))
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
program.command('get')
|
|
166
|
+
.description('Get information on a vpn')
|
|
167
|
+
.argument('<vpnId>', 'vpnId to get information from')
|
|
168
|
+
.action((vpnId, _, command) => {
|
|
169
|
+
const options = command.optsWithGlobals()
|
|
170
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
171
|
+
if (err) {
|
|
172
|
+
handleError(err)
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
client.getVpn(vpnId)
|
|
176
|
+
.then(result => log.info(result))
|
|
177
|
+
.catch(err => handleError(err))
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
program.command('download-config')
|
|
182
|
+
.description('Download configuration of the given vpn to the given file')
|
|
183
|
+
.argument('<vpnId>', 'vpnId to get config file from')
|
|
184
|
+
.option('--file <file>', 'file where the config should be downloaded to. Default is <vpnId>.tar.gz')
|
|
185
|
+
.option('--path <path>', 'path where the config file should be written to', getDefaultUserConfigDir())
|
|
186
|
+
.action((vpnId, _, command) => {
|
|
187
|
+
const options = command.optsWithGlobals()
|
|
188
|
+
const file = options.file ? options.file : `${vpnId}.tar.gz`
|
|
189
|
+
const fullpath = path.join(options.path, file)
|
|
190
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
191
|
+
if (err) {
|
|
192
|
+
handleError(err)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
client.getVpnConfig(vpnId, fs.createWriteStream(fullpath))
|
|
196
|
+
.then(() => log.info(fullpath))
|
|
197
|
+
.catch(err => handleError(err))
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
program.command('list')
|
|
202
|
+
.description('List all vpns')
|
|
203
|
+
.option('--region <region>', 'region to list vpns from')
|
|
204
|
+
.option('--exclude-state <state>', 'state to exclude from the list', 'DELETED')
|
|
205
|
+
.action((_, command) => {
|
|
206
|
+
const options = command.optsWithGlobals()
|
|
207
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
208
|
+
if (err) {
|
|
209
|
+
handleError(err)
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
client.listVpns(options.state)
|
|
213
|
+
.then(vpns => {
|
|
214
|
+
log.info(JSON.stringify(vpns, null, 2))
|
|
215
|
+
})
|
|
216
|
+
.catch(err => handleError(err))
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
program.command('wait')
|
|
221
|
+
.description('Wait for vpn operation completion')
|
|
222
|
+
.argument('<vpnId>', 'the vpnId to wait a status change for')
|
|
223
|
+
.argument('<state>', 'the state to wait for')
|
|
224
|
+
.action((vpnId, state: keyof typeof vpnlib.VpnState, _, command) => {
|
|
225
|
+
const options = command.optsWithGlobals()
|
|
226
|
+
const actualState = vpnlib.VpnState[state]
|
|
227
|
+
if (!actualState) {
|
|
228
|
+
handleError(`Unknown state: ${state}. Valid states: ${Object.values(vpnlib.VpnState)}`)
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
log.debug(`Waiting for ${vpnId} state to be (at least) ${state}`)
|
|
232
|
+
auth.getLoggedInClientFromFiles({ appConfigFile: options.appConfig, userConfigFile: options.userConfig, profileName: options.profile }, (err, client) => {
|
|
233
|
+
if (err) {
|
|
234
|
+
handleError(err)
|
|
235
|
+
return
|
|
236
|
+
}
|
|
237
|
+
client.waitUntilVpnStateIs(vpnId, actualState)
|
|
238
|
+
.then(vpn => {
|
|
239
|
+
log.info(vpn)
|
|
240
|
+
})
|
|
241
|
+
.catch(err => handleError(err))
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
program.command('register')
|
|
246
|
+
.description('Register a new user to the MyTmpVpn application')
|
|
247
|
+
.argument('<username>', 'the email/phone that will identify your account')
|
|
248
|
+
.argument('<password>', 'a password')
|
|
249
|
+
.action((username, password, _, command) => {
|
|
250
|
+
const options = command.optsWithGlobals()
|
|
251
|
+
var userConfig: UserConfig
|
|
252
|
+
if (fs.existsSync(options.userConfig)) {
|
|
253
|
+
userConfig = loadUserConfig(options.userConfig)
|
|
254
|
+
if (userConfig.profiles[options.profile]) {
|
|
255
|
+
handleError(`Profile ${options.profile} already exists in ${options.userConfig}, specify another profile name using --profile`)
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
userConfig.profiles[options.profile] = {
|
|
259
|
+
username: username,
|
|
260
|
+
password: password
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
userConfig = {
|
|
264
|
+
version: 1,
|
|
265
|
+
profiles: {
|
|
266
|
+
default: {
|
|
267
|
+
username: username,
|
|
268
|
+
password: password
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
auth.registerUserFromFiles(options.appConfig, username, password, (err, result) => {
|
|
274
|
+
if (err) {
|
|
275
|
+
handleError(err)
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
log.info(`Please confirm your identity with the code sent to ${username}`)
|
|
279
|
+
fs.mkdir(path.dirname(options.userConfig), { recursive: true }, (err, path?) => {
|
|
280
|
+
if (err) {
|
|
281
|
+
handleError(err)
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
log.debug(`Directory: ${path} created`)
|
|
285
|
+
fs.writeFile(options.userConfig, JSON.stringify(userConfig, null, 2), (err) => {
|
|
286
|
+
if (err) {
|
|
287
|
+
handleError(err)
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
log.info(`A new profile has been created for ${options.profile} in ${options.userConfig}`)
|
|
292
|
+
})
|
|
293
|
+
})
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
program.command('confirm-registration')
|
|
297
|
+
.description('Confirm registration to the MyTmpVpn application using the code that was sent to email/phone')
|
|
298
|
+
.argument('<username>', 'the email/phone that identify your account')
|
|
299
|
+
.argument('<code>', 'the code received')
|
|
300
|
+
.action((username, code, _, command) => {
|
|
301
|
+
const options = command.optsWithGlobals()
|
|
302
|
+
auth.confirmUserFromFiles(options.appConfig, username, code, (err, result) => {
|
|
303
|
+
if (err) {
|
|
304
|
+
handleError(err)
|
|
305
|
+
return
|
|
306
|
+
}
|
|
307
|
+
log.debug(result)
|
|
308
|
+
log.info(`User ${username} confirmed!`)
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
program.addHelpText('after', `
|
|
313
|
+
|
|
314
|
+
Examples:
|
|
315
|
+
|
|
316
|
+
# Before doing anything, you need to register to the MyTmpVpn service:
|
|
317
|
+
|
|
318
|
+
$ mytmpvpn register 'your@email.com' 'StrongPassword' # Min: 8 characters with digit, lower, upper and symbols
|
|
319
|
+
$ mytmpvpn confirm-registration 'code' # The code you've received by email
|
|
320
|
+
|
|
321
|
+
# You then need to buy some peanuts, the list of peanuts packs can be fetched using:
|
|
322
|
+
|
|
323
|
+
$ mytmpvpn list-peanuts-packs
|
|
324
|
+
|
|
325
|
+
# Visit one of those URLs returned, and complete the purchase.
|
|
326
|
+
# There is no CLI for purchasing peanuts-packs.
|
|
327
|
+
# Once you have purchased some peanuts, your peanuts balance should show it:
|
|
328
|
+
|
|
329
|
+
$ mytmpvpn get-peanuts-balance
|
|
330
|
+
|
|
331
|
+
# Then you can use the following command at will:
|
|
332
|
+
|
|
333
|
+
# List available regions:
|
|
334
|
+
$ mytmpvpn list-regions
|
|
335
|
+
|
|
336
|
+
# Create a new vpn in Paris:
|
|
337
|
+
$ mytmpvpn --sync create 'paris' # This takes several minutes, please be patient or remove --sync
|
|
338
|
+
|
|
339
|
+
# List all my vpns:
|
|
340
|
+
$ mytmpvpn list
|
|
341
|
+
|
|
342
|
+
# Fetch the configuration of a given vpn
|
|
343
|
+
$ mytmpvpn download-config 'vpn-id' # The vpn-id is provided by the list command
|
|
344
|
+
|
|
345
|
+
# Delete a given vpn
|
|
346
|
+
$ mytmpvpn delete 'vpn-id' # The vpn-id is provided by the list command
|
|
347
|
+
`)
|
|
348
|
+
|
|
349
|
+
program.parse()
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
// this project builds all of the following:
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
5
|
+
"outDir": "dist", /* Specify an output folder for all emitted files. */
|
|
6
|
+
|
|
7
|
+
// we want subprojects to inherit these options:
|
|
8
|
+
"baseUrl": ".", /* Specify the base directory to resolve non-relative module names. */
|
|
9
|
+
"paths": { /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
10
|
+
"mytmpvpn-cli/*": [
|
|
11
|
+
"dist/*"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
/* Projects */
|
|
16
|
+
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
|
17
|
+
"composite": false, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
18
|
+
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
|
19
|
+
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
20
|
+
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
21
|
+
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
22
|
+
|
|
23
|
+
/* Language and Environment */
|
|
24
|
+
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
25
|
+
"lib": ["ES2020"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
26
|
+
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
27
|
+
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
|
28
|
+
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
29
|
+
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
|
30
|
+
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
31
|
+
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
|
32
|
+
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
|
33
|
+
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
34
|
+
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
35
|
+
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
36
|
+
|
|
37
|
+
/* Modules */
|
|
38
|
+
"module": "commonjs", /* Specify what module code is generated. */
|
|
39
|
+
// "rootDir": "./src", /* Specify the root folder within your source files. */
|
|
40
|
+
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
41
|
+
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
42
|
+
//"typeRoots": ["./node_modules/@types"], /* Specify multiple folders that act like './node_modules/@types'. */
|
|
43
|
+
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
44
|
+
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
45
|
+
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
|
46
|
+
// "resolveJsonModule": true, /* Enable importing .json files. */
|
|
47
|
+
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
|
48
|
+
|
|
49
|
+
/* JavaScript Support */
|
|
50
|
+
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
51
|
+
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
|
52
|
+
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
53
|
+
|
|
54
|
+
/* Emit */
|
|
55
|
+
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
56
|
+
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
57
|
+
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
58
|
+
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
59
|
+
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
60
|
+
|
|
61
|
+
// "removeComments": true, /* Disable emitting comments. */
|
|
62
|
+
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
63
|
+
// "importHelpers": false, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
64
|
+
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
|
65
|
+
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
|
66
|
+
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
|
67
|
+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
68
|
+
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
69
|
+
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
|
70
|
+
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
|
71
|
+
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
|
72
|
+
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
|
73
|
+
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
|
74
|
+
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
|
75
|
+
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
|
76
|
+
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
77
|
+
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
78
|
+
|
|
79
|
+
/* Interop Constraints */
|
|
80
|
+
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
|
81
|
+
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
|
82
|
+
// "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
|
83
|
+
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
84
|
+
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
|
85
|
+
|
|
86
|
+
/* Type Checking */
|
|
87
|
+
"strict": true, /* Enable all strict type-checking options. */
|
|
88
|
+
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
|
89
|
+
"strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
|
90
|
+
"strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
|
91
|
+
"strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
|
92
|
+
"strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
|
93
|
+
"noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
|
94
|
+
"useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
|
95
|
+
"alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
|
96
|
+
"noUnusedLocals": false, /* Enable error reporting when local variables aren't read. */
|
|
97
|
+
"noUnusedParameters": false, /* Raise an error when a function parameter isn't read. */
|
|
98
|
+
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
|
99
|
+
"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
|
100
|
+
"noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
|
101
|
+
"noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
|
102
|
+
"noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
|
103
|
+
"noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
|
104
|
+
"allowUnusedLabels": false, /* Disable error reporting for unused labels. */
|
|
105
|
+
"allowUnreachableCode": false, /* Disable error reporting for unreachable code. */
|
|
106
|
+
|
|
107
|
+
/* Completeness */
|
|
108
|
+
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
109
|
+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
110
|
+
},
|
|
111
|
+
"include": [
|
|
112
|
+
"src/**/*",
|
|
113
|
+
"test/**/*",
|
|
114
|
+
],
|
|
115
|
+
}
|