@typinghare/trick 2.0.0 → 2.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/LICENSE +22 -0
- package/README.md +175 -41
- package/dist/app.js +157 -65
- package/dist/color.d.ts +2 -0
- package/dist/color.js +7 -0
- package/dist/config.d.ts +45 -26
- package/dist/config.js +70 -29
- package/dist/console.d.ts +3 -0
- package/dist/console.js +9 -0
- package/dist/encrypt.d.ts +24 -32
- package/dist/encrypt.js +31 -38
- package/dist/error.d.ts +25 -6
- package/dist/error.js +36 -17
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/passphrase.d.ts +11 -3
- package/dist/passphrase.js +17 -11
- package/env.sh +1 -0
- package/package.json +12 -12
- package/src/app.ts +232 -155
- package/src/color.ts +9 -0
- package/src/config.ts +112 -69
- package/src/console.ts +11 -0
- package/src/encrypt.ts +104 -127
- package/src/error.ts +70 -57
- package/src/index.ts +3 -0
- package/src/passphrase.ts +21 -23
- package/test/resources/task_info.yml +4 -0
- package/test/resources/user_info.json +5 -0
- package/test/trick.config.json +16 -11
- package/test/resources/really.json +0 -4
- package/test/resources/task.yml +0 -3
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/passphrase.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Config } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the passphrase directory from the configuration.
|
|
4
|
+
*
|
|
5
|
+
* This function replaces any tilde (`~`) in the directory path with the user's home directory.
|
|
6
|
+
*
|
|
7
|
+
* @param config The configuration to use.
|
|
8
|
+
* @return The resolved passphrase directory path.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPassphraseDirectory(config: Config): string;
|
|
2
11
|
/**
|
|
3
12
|
* Retrieves the passphrase from the passphrase file.
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* with the given target name.
|
|
14
|
+
* The passphrase file is located in the directory specified by `config.passphraseDirectory`
|
|
15
|
+
* and is named after the `targetName`.
|
|
8
16
|
*
|
|
9
17
|
* @param config The configuration to use.
|
|
10
18
|
* @param targetName The name of the target.
|
package/dist/passphrase.js
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
import fsExtra from 'fs-extra';
|
|
2
|
-
import { PassphraseFileNotFoundError
|
|
2
|
+
import { PassphraseFileNotFoundError } from './error.js';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
/**
|
|
6
|
+
* Gets the passphrase directory from the configuration.
|
|
7
|
+
*
|
|
8
|
+
* This function replaces any tilde (`~`) in the directory path with the user's home directory.
|
|
9
|
+
*
|
|
10
|
+
* @param config The configuration to use.
|
|
11
|
+
* @return The resolved passphrase directory path.
|
|
12
|
+
*/
|
|
13
|
+
export function getPassphraseDirectory(config) {
|
|
14
|
+
return config.passphraseDirectory.replaceAll(/~/g, os.homedir());
|
|
15
|
+
}
|
|
4
16
|
/**
|
|
5
17
|
* Retrieves the passphrase from the passphrase file.
|
|
6
18
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* with the given target name.
|
|
19
|
+
* The passphrase file is located in the directory specified by `config.passphraseDirectory`
|
|
20
|
+
* and is named after the `targetName`.
|
|
10
21
|
*
|
|
11
22
|
* @param config The configuration to use.
|
|
12
23
|
* @param targetName The name of the target.
|
|
13
24
|
* @return The passphrase associated with the target name.
|
|
14
25
|
*/
|
|
15
26
|
export function getPassphrase(config, targetName) {
|
|
16
|
-
const passphraseFilePath =
|
|
27
|
+
const passphraseFilePath = path.join(getPassphraseDirectory(config), targetName);
|
|
17
28
|
if (!fsExtra.existsSync(passphraseFilePath)) {
|
|
18
29
|
throw new PassphraseFileNotFoundError(passphraseFilePath);
|
|
19
30
|
}
|
|
20
|
-
|
|
21
|
-
const passphrase = passphraseObject[targetName] || null;
|
|
22
|
-
if (passphrase === null) {
|
|
23
|
-
throw new PassphraseNotFoundError(passphraseFilePath, targetName);
|
|
24
|
-
}
|
|
25
|
-
return passphrase;
|
|
31
|
+
return fsExtra.readFileSync(passphraseFilePath, 'utf-8').trim();
|
|
26
32
|
}
|
package/env.sh
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PATH="$PWD/bin:$PATH"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typinghare/trick",
|
|
3
3
|
"description": "Save credential files to remote safely and easily.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -15,26 +15,26 @@
|
|
|
15
15
|
"homepage": "https://github.com/typinghare/trick",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"chalk": "^5.
|
|
19
|
-
"commander": "^14.0.
|
|
20
|
-
"execa": "^9.
|
|
21
|
-
"fs-extra": "^11.3.
|
|
18
|
+
"chalk": "^5.6.2",
|
|
19
|
+
"commander": "^14.0.2",
|
|
20
|
+
"execa": "^9.6.1",
|
|
21
|
+
"fs-extra": "^11.3.3"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/fs-extra": "^11.0.4",
|
|
25
|
-
"eslint": "^9.
|
|
26
|
-
"eslint-plugin-jsonc": "^2.
|
|
27
|
-
"jsonc-eslint-parser": "^2.4.
|
|
28
|
-
"prettier": "^3.
|
|
29
|
-
"typescript": "^5.
|
|
25
|
+
"eslint": "^9.39.2",
|
|
26
|
+
"eslint-plugin-jsonc": "^2.21.0",
|
|
27
|
+
"jsonc-eslint-parser": "^2.4.2",
|
|
28
|
+
"prettier": "^3.7.4",
|
|
29
|
+
"typescript": "^5.9.3"
|
|
30
30
|
},
|
|
31
31
|
"prettier": {
|
|
32
32
|
"trailingComma": "es5",
|
|
33
|
-
"tabWidth":
|
|
33
|
+
"tabWidth": 2,
|
|
34
34
|
"semi": false,
|
|
35
35
|
"singleQuote": true,
|
|
36
36
|
"endOfLine": "lf",
|
|
37
|
-
"printWidth":
|
|
37
|
+
"printWidth": 100
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node_modules/typescript/bin/tsc"
|
package/src/app.ts
CHANGED
|
@@ -1,188 +1,265 @@
|
|
|
1
1
|
import { Command } from 'commander'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CONFIG_FILE_NAME,
|
|
4
|
+
getRootDirectory,
|
|
5
|
+
getTargetFromConfig,
|
|
6
|
+
Target,
|
|
7
|
+
updateConfig,
|
|
8
|
+
} from './config.js'
|
|
3
9
|
import { decryptFiles, encryptFiles } from './encrypt.js'
|
|
4
10
|
import fsExtra from 'fs-extra'
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
11
|
+
import { getPassphrase, getPassphraseDirectory } from './passphrase.js'
|
|
12
|
+
import { resolveError } from './error.js'
|
|
13
|
+
import path from 'path'
|
|
14
|
+
import { colorFilePath, colorTargetName } from './color.js'
|
|
15
|
+
import { success, warning } from './console.js'
|
|
8
16
|
|
|
9
17
|
const program = new Command()
|
|
10
|
-
program.version('2.
|
|
18
|
+
program.version('2.1.0')
|
|
11
19
|
program.description('Save credential files to remote safely and easily.')
|
|
12
20
|
|
|
13
21
|
program
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
await updateConfig((config) => {
|
|
20
|
-
try {
|
|
21
|
-
const target = getTargetFromConfig(config, targetName)
|
|
22
|
-
target.files.push(...files)
|
|
23
|
-
} catch (err) {
|
|
24
|
-
config.default_target_name = targetName
|
|
25
|
-
config.targets[targetName] = { files }
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return true
|
|
29
|
-
})
|
|
22
|
+
.command('config')
|
|
23
|
+
.description('Display the current configuration.')
|
|
24
|
+
.action(function (): void {
|
|
25
|
+
updateConfig((config) => {
|
|
26
|
+
console.log(JSON.stringify(config, null, 2))
|
|
30
27
|
})
|
|
28
|
+
})
|
|
31
29
|
|
|
32
30
|
program
|
|
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
|
-
target.files = remainingFiles
|
|
72
|
-
const notFoundFiles = files.filter(
|
|
73
|
-
(it) => !removedFiles.includes(it)
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
for (const notFoundFile of notFoundFiles) {
|
|
77
|
-
console.log(
|
|
78
|
-
`[WARNING] File not found in the target: ${notFoundFile}`
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return true
|
|
83
|
-
})
|
|
31
|
+
.command('init')
|
|
32
|
+
.description('Initialize the configuration file.')
|
|
33
|
+
.option('-r, --root', 'Create the configuration file in the root directory.', false)
|
|
34
|
+
.action(function (options: { root: boolean }): void {
|
|
35
|
+
const configFilePath = options.root
|
|
36
|
+
? path.join(getRootDirectory(), CONFIG_FILE_NAME)
|
|
37
|
+
: path.join(process.cwd(), CONFIG_FILE_NAME)
|
|
38
|
+
|
|
39
|
+
if (fsExtra.existsSync(configFilePath)) {
|
|
40
|
+
console.log(warning(`Configuration file already exists: ${configFilePath}`))
|
|
41
|
+
return
|
|
42
|
+
} else {
|
|
43
|
+
updateConfig(() => true, options.root)
|
|
44
|
+
console.log(success(`Initialized configuration file: ${configFilePath}`))
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
program
|
|
49
|
+
.command('add')
|
|
50
|
+
.description('Add files to a target.')
|
|
51
|
+
.argument('<target>', 'The name of the target to add to')
|
|
52
|
+
.argument('[files...]', 'Files that are added to the target')
|
|
53
|
+
.action(function (targetName: string, files: string[]): void {
|
|
54
|
+
updateConfig((config) => {
|
|
55
|
+
const target = config.targets[targetName]
|
|
56
|
+
if (!target) {
|
|
57
|
+
config.targets[targetName] = { files }
|
|
58
|
+
console.log(success(`Added files to target: ${targetName}`))
|
|
59
|
+
} else {
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
if (target.files.includes(file)) {
|
|
62
|
+
console.log(warning(`File already exists in the target: ${file}`))
|
|
63
|
+
} else {
|
|
64
|
+
target.files.push(file)
|
|
65
|
+
console.log(success(`Added file to target: ${file}`))
|
|
66
|
+
}
|
|
84
67
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return true
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.command('remove')
|
|
76
|
+
.description('Remove files from a target.')
|
|
77
|
+
.argument('<target>', 'The name of the target to remove from')
|
|
78
|
+
.argument('[files...]', 'Files to remove from the target')
|
|
79
|
+
.option('-t, --target', 'Remove the target instead.')
|
|
80
|
+
.action(function (
|
|
81
|
+
targetName: string,
|
|
82
|
+
files: string[],
|
|
83
|
+
options: {
|
|
84
|
+
target: boolean
|
|
98
85
|
}
|
|
86
|
+
): void {
|
|
87
|
+
if (options.target) {
|
|
88
|
+
// Remove the target
|
|
89
|
+
return updateConfig((config) => {
|
|
90
|
+
getTargetFromConfig(config, targetName)
|
|
91
|
+
delete config.targets[targetName]
|
|
92
|
+
console.log(`[SUCCESS] Removed target: ${targetName}`)
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
}
|
|
94
|
+
return true
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Remove files from the target
|
|
99
|
+
updateConfig((config) => {
|
|
100
|
+
const target = getTargetFromConfig(config, targetName)
|
|
101
|
+
const removedFiles: string[] = []
|
|
102
|
+
const remainingFiles: string[] = []
|
|
103
|
+
for (const file of target.files) {
|
|
104
|
+
if (files.includes(file)) {
|
|
105
|
+
removedFiles.push(file)
|
|
106
|
+
console.log(success(`Removed file: ${file}`))
|
|
107
|
+
} else {
|
|
108
|
+
remainingFiles.push(file)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
target.files = remainingFiles
|
|
113
|
+
const notFoundFiles = files.filter((it) => !removedFiles.includes(it))
|
|
114
|
+
|
|
115
|
+
for (const notFoundFile of notFoundFiles) {
|
|
116
|
+
console.log(warning(`File not found in the target: ${notFoundFile}`))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return true
|
|
120
|
+
})
|
|
121
|
+
})
|
|
102
122
|
|
|
103
123
|
program
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
.command('encrypt')
|
|
125
|
+
.description('Encrypt the credential files.')
|
|
126
|
+
.argument('[targetNames...]', 'The names of targets')
|
|
127
|
+
.action(function (targetNames: string[]): void {
|
|
128
|
+
updateConfig((config) => {
|
|
129
|
+
if (targetNames.length === 0) {
|
|
130
|
+
targetNames.push(...config.defaultTargetNames)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (targetNames.length === 0) {
|
|
134
|
+
console.log(warning('No target names specified and no default targets set.'))
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const rootDirectory = getRootDirectory()
|
|
139
|
+
const trickRootDirectory = path.resolve(rootDirectory, config.trickRootDirectory)
|
|
140
|
+
for (const targetName of targetNames) {
|
|
141
|
+
const target: Target = getTargetFromConfig(config, targetName)
|
|
142
|
+
const passphrase: string = getPassphrase(config, targetName)
|
|
143
|
+
const srcFilePaths: string[] = target.files
|
|
144
|
+
|
|
145
|
+
fsExtra.ensureDir(trickRootDirectory)
|
|
146
|
+
encryptFiles(srcFilePaths, trickRootDirectory, passphrase, config.encryption.iterationCount)
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
program
|
|
152
|
+
.command('decrypt')
|
|
153
|
+
.description('Decrypt the credential files.')
|
|
154
|
+
.argument('[targetNames...]', 'The names of the targets')
|
|
155
|
+
.action(function (targetNames: string[]): void {
|
|
156
|
+
updateConfig((config) => {
|
|
157
|
+
if (targetNames.length === 0) {
|
|
158
|
+
targetNames.push(...config.defaultTargetNames)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (targetNames.length === 0) {
|
|
162
|
+
console.log(warning('No target names specified and no default targets set.'))
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const rootDirectory = getRootDirectory()
|
|
167
|
+
const trickRootDirectory = path.resolve(rootDirectory, config.trickRootDirectory)
|
|
168
|
+
for (const targetName of targetNames) {
|
|
169
|
+
const target: Target = getTargetFromConfig(config, targetName)
|
|
170
|
+
const passphrase: string = getPassphrase(config, targetName)
|
|
171
|
+
const srcFilePaths: string[] = target.files
|
|
172
|
+
|
|
173
|
+
fsExtra.ensureDir(trickRootDirectory)
|
|
174
|
+
decryptFiles(srcFilePaths, trickRootDirectory, passphrase, config.encryption.iterationCount)
|
|
175
|
+
}
|
|
124
176
|
})
|
|
177
|
+
})
|
|
125
178
|
|
|
126
179
|
program
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
180
|
+
.command('add-default')
|
|
181
|
+
.description('Add default target names.')
|
|
182
|
+
.argument('[targetNames...]', 'The names of targets to add')
|
|
183
|
+
.action(function (targetNames: string[]): void {
|
|
184
|
+
updateConfig((config) => {
|
|
185
|
+
let addedAny = false
|
|
186
|
+
for (const targetName of targetNames) {
|
|
187
|
+
if (!config.targets[targetName]) {
|
|
188
|
+
console.log(warning(`Target not found: ${targetName}`))
|
|
189
|
+
continue
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (config.defaultTargetNames.includes(targetName)) {
|
|
193
|
+
console.log(warning(`Target name already in default list: ${targetName}`))
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
config.defaultTargetNames.push(targetName)
|
|
198
|
+
console.log(success(`Added default target name: ${targetName}`))
|
|
199
|
+
addedAny = true
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return addedAny
|
|
147
203
|
})
|
|
204
|
+
})
|
|
148
205
|
|
|
149
206
|
program
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
})
|
|
207
|
+
.command('list-defaults')
|
|
208
|
+
.description('Display the default target name.')
|
|
209
|
+
.action(function (): void {
|
|
210
|
+
updateConfig((config) => {
|
|
211
|
+
for (const targetName of config.defaultTargetNames) {
|
|
212
|
+
console.log(colorTargetName(targetName))
|
|
213
|
+
}
|
|
158
214
|
})
|
|
215
|
+
})
|
|
159
216
|
|
|
160
217
|
program
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
218
|
+
.command('list')
|
|
219
|
+
.description('Display a list of targets.')
|
|
220
|
+
.action(function (): void {
|
|
221
|
+
updateConfig((config) => {
|
|
222
|
+
for (const [targetName, target] of Object.entries(config.targets)) {
|
|
223
|
+
console.log(colorTargetName(targetName))
|
|
224
|
+
for (const file of target.files) {
|
|
225
|
+
console.log(' ' + colorFilePath(file))
|
|
226
|
+
}
|
|
227
|
+
}
|
|
167
228
|
})
|
|
229
|
+
})
|
|
168
230
|
|
|
169
231
|
program
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
232
|
+
.command('set-passphrase')
|
|
233
|
+
.description('Set passphrase for a target.')
|
|
234
|
+
.argument('<target>', 'The name of the target to set passphrase for')
|
|
235
|
+
.action(function (targetName: string): void {
|
|
236
|
+
updateConfig((config) => {
|
|
237
|
+
const passphraseDirectory = getPassphraseDirectory(config)
|
|
238
|
+
if (!fsExtra.existsSync(passphraseDirectory)) {
|
|
239
|
+
fsExtra.ensureDirSync(passphraseDirectory)
|
|
240
|
+
console.log(success(`Created passphrase directory: ${passphraseDirectory}`))
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const passphraseFile = path.join(passphraseDirectory, targetName)
|
|
244
|
+
if (!fsExtra.existsSync(passphraseFile)) {
|
|
245
|
+
fsExtra.createFileSync(passphraseFile)
|
|
246
|
+
fsExtra.chmodSync(passphraseFile, 0o600)
|
|
247
|
+
console.log(success(`Created passphrase file: ${passphraseFile}`))
|
|
248
|
+
console.log(success(`You have to edit the file to set the passphrase.`))
|
|
249
|
+
} else {
|
|
250
|
+
console.log(warning(`Passphrase file already exists: ${passphraseFile}`))
|
|
251
|
+
}
|
|
181
252
|
})
|
|
253
|
+
})
|
|
182
254
|
|
|
183
|
-
|
|
255
|
+
try {
|
|
256
|
+
program.parse()
|
|
257
|
+
} catch (err) {
|
|
258
|
+
resolveError(err)
|
|
259
|
+
process.exit(1)
|
|
260
|
+
}
|
|
184
261
|
|
|
185
262
|
process.on('uncaughtException', (err) => {
|
|
186
|
-
|
|
187
|
-
|
|
263
|
+
resolveError(err)
|
|
264
|
+
process.exit(1)
|
|
188
265
|
})
|