secrez 1.1.1 → 1.1.3
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/README.md +503 -444
- package/bin/secrez.js +50 -47
- package/coverage.report +91 -85
- package/package.json +10 -12
- package/src/Command.js +78 -57
- package/src/PreCommand.js +75 -70
- package/src/Welcome.js +144 -134
- package/src/cliConfig.js +14 -14
- package/src/commands/Alias.js +123 -100
- package/src/commands/Bash.js +10 -12
- package/src/commands/Cat.js +117 -107
- package/src/commands/Cd.js +39 -42
- package/src/commands/Chat.js +75 -63
- package/src/commands/Conf.js +123 -99
- package/src/commands/Contacts.js +189 -171
- package/src/commands/Copy.js +132 -113
- package/src/commands/Courier.js +123 -105
- package/src/commands/Ds.js +88 -76
- package/src/commands/Edit.js +122 -103
- package/src/commands/Export.js +201 -116
- package/src/commands/Find.js +115 -110
- package/src/commands/Help.js +20 -23
- package/src/commands/Import.js +296 -225
- package/src/commands/Lcat.js +36 -39
- package/src/commands/Lcd.js +38 -39
- package/src/commands/Lls.js +58 -55
- package/src/commands/Lpwd.js +20 -24
- package/src/commands/Ls.js +107 -97
- package/src/commands/Mkdir.js +35 -38
- package/src/commands/Mv.js +147 -114
- package/src/commands/Paste.js +68 -65
- package/src/commands/Pwd.js +18 -23
- package/src/commands/Quit.js +22 -24
- package/src/commands/Rm.js +78 -70
- package/src/commands/Shell.js +31 -32
- package/src/commands/Ssh.js +77 -63
- package/src/commands/Tag.js +133 -112
- package/src/commands/Totp.js +166 -136
- package/src/commands/Touch.js +169 -56
- package/src/commands/Use.js +44 -41
- package/src/commands/Ver.js +16 -18
- package/src/commands/Whoami.js +34 -37
- package/src/commands/chat/Contacts.js +41 -44
- package/src/commands/chat/Help.js +20 -23
- package/src/commands/chat/Join.js +59 -55
- package/src/commands/chat/Leave.js +16 -22
- package/src/commands/chat/Quit.js +19 -24
- package/src/commands/chat/Send.js +58 -57
- package/src/commands/chat/Show.js +60 -51
- package/src/commands/chat/Whoami.js +18 -22
- package/src/commands/index.js +20 -22
- package/src/index.js +3 -3
- package/src/prompts/ChatPrompt.js +87 -82
- package/src/prompts/ChatPromptMock.js +11 -17
- package/src/prompts/CommandPrompt.js +146 -138
- package/src/prompts/Completion.js +64 -69
- package/src/prompts/MainPrompt.js +84 -77
- package/src/prompts/MainPromptMock.js +19 -30
- package/src/prompts/MultiEditorPrompt.js +21 -22
- package/src/prompts/SigintManager.js +21 -24
- package/src/utils/AliasManager.js +16 -18
- package/src/utils/ContactManager.js +15 -17
- package/src/utils/Fido2Client.js +59 -49
- package/src/utils/HelpProto.js +130 -117
- package/src/utils/Logger.js +48 -50
- package/.eslintignore +0 -0
- package/.eslintrc +0 -33
- package/.jshintrc +0 -3
package/src/commands/Contacts.js
CHANGED
@@ -1,338 +1,356 @@
|
|
1
|
-
const Crypto = require(
|
2
|
-
const {utils: hubUtils} = require(
|
3
|
-
const chalk = require(
|
4
|
-
const ContactManager = require(
|
5
|
-
const superagent = require(
|
6
|
-
|
7
|
-
class Contacts extends require('../Command') {
|
1
|
+
const Crypto = require("@secrez/crypto");
|
2
|
+
const { utils: hubUtils } = require("@secrez/hub");
|
3
|
+
const chalk = require("chalk");
|
4
|
+
const ContactManager = require("../utils/ContactManager");
|
5
|
+
const superagent = require("superagent");
|
8
6
|
|
7
|
+
class Contacts extends require("../Command") {
|
9
8
|
setHelpAndCompletion() {
|
10
9
|
this.cliConfig.completion.contacts = {
|
11
|
-
_self: this
|
12
|
-
}
|
13
|
-
this.cliConfig.completion.help.contacts = true
|
10
|
+
_self: this,
|
11
|
+
};
|
12
|
+
this.cliConfig.completion.help.contacts = true;
|
14
13
|
this.optionDefinitions = [
|
15
14
|
{
|
16
|
-
name:
|
17
|
-
alias:
|
18
|
-
type: Boolean
|
15
|
+
name: "help",
|
16
|
+
alias: "h",
|
17
|
+
type: Boolean,
|
19
18
|
},
|
20
19
|
{
|
21
|
-
name:
|
22
|
-
alias:
|
20
|
+
name: "list",
|
21
|
+
alias: "l",
|
23
22
|
type: Boolean,
|
24
|
-
default: true
|
23
|
+
default: true,
|
25
24
|
},
|
26
25
|
{
|
27
|
-
name:
|
28
|
-
alias:
|
29
|
-
type: String
|
26
|
+
name: "add",
|
27
|
+
alias: "a",
|
28
|
+
type: String,
|
30
29
|
},
|
31
30
|
{
|
32
|
-
name:
|
33
|
-
alias:
|
34
|
-
type: String
|
31
|
+
name: "update",
|
32
|
+
alias: "u",
|
33
|
+
type: String,
|
35
34
|
},
|
36
35
|
{
|
37
|
-
name:
|
38
|
-
alias:
|
39
|
-
type: String
|
36
|
+
name: "delete",
|
37
|
+
alias: "d",
|
38
|
+
type: String,
|
40
39
|
},
|
41
40
|
{
|
42
|
-
name:
|
43
|
-
alias:
|
41
|
+
name: "rename",
|
42
|
+
alias: "r",
|
44
43
|
type: String,
|
45
|
-
multiple: true
|
44
|
+
multiple: true,
|
46
45
|
},
|
47
46
|
{
|
48
|
-
name:
|
49
|
-
alias:
|
50
|
-
type: String
|
51
|
-
}
|
52
|
-
]
|
47
|
+
name: "show",
|
48
|
+
alias: "s",
|
49
|
+
type: String,
|
50
|
+
},
|
51
|
+
];
|
53
52
|
}
|
54
53
|
|
55
54
|
help() {
|
56
55
|
return {
|
57
|
-
description: [
|
56
|
+
description: ["Manages your contacts"],
|
58
57
|
examples: [
|
59
|
-
[
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
[
|
64
|
-
[
|
65
|
-
|
66
|
-
|
58
|
+
[
|
59
|
+
"contacts -a pan",
|
60
|
+
"adds a new trusted contact pan, asking for his public key or hub url",
|
61
|
+
],
|
62
|
+
["contacts -u pan", "updates the hub url"],
|
63
|
+
["contacts -s pan", "returns pan's public key and url"],
|
64
|
+
["contacts -d ema", "deletes ema's data"],
|
65
|
+
["contacts -r ema joe", "renames ema"],
|
66
|
+
["contacts", "listed all trusted contacts"],
|
67
|
+
],
|
68
|
+
};
|
67
69
|
}
|
68
70
|
|
69
71
|
async getPublicKeyFromUrl(url) {
|
70
72
|
try {
|
71
|
-
url = new URL(url)
|
72
|
-
let id = hubUtils.getClientIdFromHostname(url.hostname)
|
73
|
-
let apiurl = url.protocol +
|
73
|
+
url = new URL(url);
|
74
|
+
let id = hubUtils.getClientIdFromHostname(url.hostname);
|
75
|
+
let apiurl = url.protocol + "//" + url.host.split(id + ".")[1];
|
74
76
|
let res = await superagent
|
75
|
-
|
76
|
-
|
77
|
-
return res.body.publickey
|
77
|
+
.get(`${apiurl}/api/v1/publickey/${id}`)
|
78
|
+
.set("Accept", "application/json");
|
79
|
+
return res.body.publickey;
|
78
80
|
} catch (e) {
|
79
|
-
throw new Error(
|
81
|
+
throw new Error("Inactive/wrong url");
|
80
82
|
}
|
81
83
|
}
|
82
84
|
|
83
85
|
async createContact(options) {
|
84
|
-
const {name} = options
|
86
|
+
const { name } = options;
|
85
87
|
if (options.update) {
|
86
|
-
await this.contactManager.remove(name)
|
88
|
+
await this.contactManager.remove(name);
|
87
89
|
}
|
88
90
|
await this.contactManager.create({
|
89
91
|
name,
|
90
92
|
publicKey: options.publicKey,
|
91
|
-
url: options.url
|
92
|
-
})
|
93
|
+
url: options.url,
|
94
|
+
});
|
93
95
|
}
|
94
96
|
|
95
97
|
async add(options) {
|
96
|
-
let name = options.name = options.add
|
97
|
-
let existingDataIfSo = this.contactManager.get(name)
|
98
|
+
let name = (options.name = options.add);
|
99
|
+
let existingDataIfSo = this.contactManager.get(name);
|
98
100
|
if (existingDataIfSo) {
|
99
|
-
throw new Error(`A contact named "${name}" already exists`)
|
101
|
+
throw new Error(`A contact named "${name}" already exists`);
|
100
102
|
}
|
101
|
-
let publicKey
|
102
|
-
let url
|
103
|
-
if (process.env.NODE_ENV ===
|
104
|
-
publicKey = options.publicKey
|
105
|
-
url = options.url
|
103
|
+
let publicKey;
|
104
|
+
let url;
|
105
|
+
if (process.env.NODE_ENV === "test") {
|
106
|
+
publicKey = options.publicKey;
|
107
|
+
url = options.url;
|
106
108
|
} else {
|
107
109
|
let choice = await this.useSelect({
|
108
|
-
message:
|
109
|
-
choices: [
|
110
|
-
})
|
110
|
+
message: "Chose method",
|
111
|
+
choices: ["Public key", "Url on hub"],
|
112
|
+
});
|
111
113
|
if (!choice) {
|
112
|
-
throw new Error(
|
114
|
+
throw new Error("Operation canceled");
|
113
115
|
}
|
114
|
-
if (choice ===
|
115
|
-
url = await this.useInput(
|
116
|
-
|
117
|
-
|
116
|
+
if (choice === "Url on hub") {
|
117
|
+
url = await this.useInput(
|
118
|
+
Object.assign(options, {
|
119
|
+
message: `Paste ${name}'s url on hub`,
|
120
|
+
})
|
121
|
+
);
|
118
122
|
if (!url) {
|
119
|
-
throw new Error(
|
123
|
+
throw new Error("Operation canceled");
|
120
124
|
}
|
121
125
|
try {
|
122
|
-
publicKey = await this.getPublicKeyFromUrl(url)
|
123
|
-
} catch (e) {
|
124
|
-
}
|
126
|
+
publicKey = await this.getPublicKeyFromUrl(url);
|
127
|
+
} catch (e) {}
|
125
128
|
} else {
|
126
|
-
publicKey = await this.useInput(
|
127
|
-
|
128
|
-
|
129
|
+
publicKey = await this.useInput(
|
130
|
+
Object.assign(options, {
|
131
|
+
message: `Paste ${name}'s public key`,
|
132
|
+
})
|
133
|
+
);
|
129
134
|
}
|
130
135
|
if (!publicKey) {
|
131
|
-
throw new Error(
|
136
|
+
throw new Error(
|
137
|
+
choice === "Url on hub"
|
138
|
+
? "Client not found on hub"
|
139
|
+
: "Operation canceled"
|
140
|
+
);
|
132
141
|
}
|
133
142
|
}
|
134
143
|
if (!Crypto.isValidSecrezPublicKey(publicKey)) {
|
135
|
-
throw new Error(
|
144
|
+
throw new Error("The public key is not a valid one");
|
136
145
|
}
|
137
146
|
if (url && !hubUtils.isValidUrl(url)) {
|
138
|
-
throw new Error(
|
147
|
+
throw new Error("The url does not look valid");
|
139
148
|
}
|
140
|
-
this.checkIfAlreadyExists(name, publicKey, url)
|
141
|
-
await this.createContact(Object.assign(options, {publicKey, url}))
|
142
|
-
return `The contact "${name}" has been added to your trusted contacts
|
149
|
+
this.checkIfAlreadyExists(name, publicKey, url);
|
150
|
+
await this.createContact(Object.assign(options, { publicKey, url }));
|
151
|
+
return `The contact "${name}" has been added to your trusted contacts`;
|
143
152
|
}
|
144
153
|
|
145
154
|
checkIfAlreadyExists(name, publicKey, url) {
|
146
|
-
let allContacts = this.contactManager.get()
|
155
|
+
let allContacts = this.contactManager.get();
|
147
156
|
for (let contact in allContacts) {
|
148
|
-
let content = JSON.parse(allContacts[contact].content)
|
157
|
+
let content = JSON.parse(allContacts[contact].content);
|
149
158
|
if (contact !== name) {
|
150
159
|
if (publicKey && content.publicKey === publicKey) {
|
151
|
-
throw new Error(
|
160
|
+
throw new Error(
|
161
|
+
`The contact "${contact}" is already associated to this public key`
|
162
|
+
);
|
152
163
|
} else if (url && content.url === url) {
|
153
|
-
throw new Error(
|
164
|
+
throw new Error(
|
165
|
+
`The contact "${contact}" is already associated to this url`
|
166
|
+
);
|
154
167
|
}
|
155
168
|
} else {
|
156
169
|
if (publicKey && content.publicKey !== publicKey) {
|
157
|
-
throw new Error(
|
170
|
+
throw new Error(
|
171
|
+
`"${contact}" is associated to a different public key. Verify your contact, please`
|
172
|
+
);
|
158
173
|
}
|
159
174
|
}
|
160
175
|
}
|
161
176
|
}
|
162
177
|
|
163
178
|
async update(options) {
|
164
|
-
let name = options.name = options.update
|
165
|
-
let existingDataIfSo = this.contactManager.get(name)
|
179
|
+
let name = (options.name = options.update);
|
180
|
+
let existingDataIfSo = this.contactManager.get(name);
|
166
181
|
if (!existingDataIfSo) {
|
167
|
-
throw new Error(
|
182
|
+
throw new Error("Contact not found");
|
168
183
|
}
|
169
|
-
let publicKey
|
170
|
-
let url
|
171
|
-
if (process.env.NODE_ENV ===
|
172
|
-
publicKey = options.publicKey
|
173
|
-
url = options.url
|
184
|
+
let publicKey;
|
185
|
+
let url;
|
186
|
+
if (process.env.NODE_ENV === "test") {
|
187
|
+
publicKey = options.publicKey;
|
188
|
+
url = options.url;
|
174
189
|
} else {
|
175
190
|
let choice = await this.useSelect({
|
176
|
-
message:
|
177
|
-
choices: [
|
178
|
-
})
|
179
|
-
if (choice ===
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
191
|
+
message: "Chose method",
|
192
|
+
choices: ["Public key", "Url on hub"],
|
193
|
+
});
|
194
|
+
if (choice === "Url on hub") {
|
195
|
+
url = await this.useInput(
|
196
|
+
Object.assign(options, {
|
197
|
+
message: `Paste ${name}'s url on hub`,
|
198
|
+
})
|
199
|
+
);
|
184
200
|
if (!url) {
|
185
|
-
throw new Error(
|
201
|
+
throw new Error("Operation canceled");
|
186
202
|
}
|
187
203
|
try {
|
188
|
-
publicKey = await this.getPublicKeyFromUrl(url)
|
189
|
-
} catch (e) {
|
190
|
-
}
|
204
|
+
publicKey = await this.getPublicKeyFromUrl(url);
|
205
|
+
} catch (e) {}
|
191
206
|
} else {
|
192
|
-
publicKey = await this.useInput(
|
193
|
-
|
194
|
-
|
207
|
+
publicKey = await this.useInput(
|
208
|
+
Object.assign(options, {
|
209
|
+
message: `Paste ${name}'s public key`,
|
210
|
+
})
|
211
|
+
);
|
195
212
|
}
|
196
213
|
if (!publicKey) {
|
197
|
-
throw new Error(
|
214
|
+
throw new Error(
|
215
|
+
choice === "Url on hub" ? "Url not active" : "Operation canceled"
|
216
|
+
);
|
198
217
|
}
|
199
218
|
}
|
200
219
|
if (!publicKey) {
|
201
|
-
publicKey = JSON.parse(existingDataIfSo.content).publicKey
|
220
|
+
publicKey = JSON.parse(existingDataIfSo.content).publicKey;
|
202
221
|
}
|
203
|
-
this.checkIfAlreadyExists(name, publicKey, url)
|
222
|
+
this.checkIfAlreadyExists(name, publicKey, url);
|
204
223
|
if (existingDataIfSo) {
|
205
|
-
await this.contactManager.remove(name)
|
224
|
+
await this.contactManager.remove(name);
|
206
225
|
}
|
207
|
-
await this.createContact(Object.assign(options, {publicKey, url}))
|
208
|
-
return `The contact "${name}" has been updated
|
226
|
+
await this.createContact(Object.assign(options, { publicKey, url }));
|
227
|
+
return `The contact "${name}" has been updated`;
|
209
228
|
}
|
210
229
|
|
211
230
|
async rename(options) {
|
212
|
-
let [existentName, newName] = options.rename
|
231
|
+
let [existentName, newName] = options.rename;
|
213
232
|
if (!this.contactManager.get(existentName)) {
|
214
|
-
throw new Error(`A contact named "${existentName}" does not exist`)
|
233
|
+
throw new Error(`A contact named "${existentName}" does not exist`);
|
215
234
|
}
|
216
235
|
if (this.contactManager.get(newName)) {
|
217
|
-
throw new Error(`A contact named "${newName}" already exists`)
|
236
|
+
throw new Error(`A contact named "${newName}" already exists`);
|
218
237
|
}
|
219
|
-
let error = this.contactManager.validateName(newName)
|
238
|
+
let error = this.contactManager.validateName(newName);
|
220
239
|
if (error) {
|
221
|
-
throw new Error(error)
|
240
|
+
throw new Error(error);
|
222
241
|
}
|
223
242
|
if (await this.contactManager.rename(existentName, newName)) {
|
224
|
-
return chalk.grey(
|
243
|
+
return chalk.grey(
|
244
|
+
`The contact "${existentName}" has been renamed "${newName}"`
|
245
|
+
);
|
225
246
|
} else {
|
226
|
-
throw new Error(`Could not rename "${existentName}"`)
|
247
|
+
throw new Error(`Could not rename "${existentName}"`);
|
227
248
|
}
|
228
249
|
}
|
229
250
|
|
230
251
|
async delete(options) {
|
231
|
-
let existentContact = options.delete
|
252
|
+
let existentContact = options.delete;
|
232
253
|
if (!this.contactManager.get(existentContact)) {
|
233
|
-
throw new Error(`A contact named "${existentContact}" does not exist`)
|
254
|
+
throw new Error(`A contact named "${existentContact}" does not exist`);
|
234
255
|
}
|
235
256
|
if (await this.contactManager.remove(existentContact)) {
|
236
|
-
return chalk.grey(`The contact "${existentContact}" has been deleted`)
|
257
|
+
return chalk.grey(`The contact "${existentContact}" has been deleted`);
|
237
258
|
} else {
|
238
|
-
throw new Error(`Could not delete "${existentContact}"`)
|
259
|
+
throw new Error(`Could not delete "${existentContact}"`);
|
239
260
|
}
|
240
261
|
}
|
241
262
|
|
242
263
|
async list(options) {
|
243
|
-
let list = []
|
244
|
-
let contacts = this.contactManager.get()
|
264
|
+
let list = [];
|
265
|
+
let contacts = this.contactManager.get();
|
245
266
|
for (let contact in contacts) {
|
246
|
-
let content = JSON.parse(contacts[contact].content)
|
247
|
-
list.push([contact, content])
|
267
|
+
let content = JSON.parse(contacts[contact].content);
|
268
|
+
list.push([contact, content]);
|
248
269
|
}
|
249
|
-
return list
|
270
|
+
return list;
|
250
271
|
}
|
251
272
|
|
252
273
|
formatContact(l) {
|
253
274
|
let result = [
|
254
275
|
chalk.bold(l[0]),
|
255
|
-
|
256
|
-
chalk.grey(
|
257
|
-
l[1].publicKey
|
258
|
-
]
|
276
|
+
"\n",
|
277
|
+
chalk.grey("public key: "),
|
278
|
+
l[1].publicKey,
|
279
|
+
];
|
259
280
|
if (l[1].url) {
|
260
|
-
result.push(
|
261
|
-
'\n',
|
262
|
-
chalk.grey('url: '),
|
263
|
-
l[1].url
|
264
|
-
)
|
281
|
+
result.push("\n", chalk.grey("url: "), l[1].url);
|
265
282
|
}
|
266
|
-
return result.join(
|
283
|
+
return result.join("");
|
267
284
|
}
|
268
285
|
|
269
286
|
async show(options) {
|
270
|
-
let contact = options.show
|
271
|
-
let content = ((await this.contactManager.get()[contact]) || {}).content
|
287
|
+
let contact = options.show;
|
288
|
+
let content = ((await this.contactManager.get()[contact]) || {}).content;
|
272
289
|
if (!content) {
|
273
|
-
throw new Error(
|
290
|
+
throw new Error(
|
291
|
+
`A contact named "${contact}" is not in your trusted circle`
|
292
|
+
);
|
274
293
|
}
|
275
|
-
content = JSON.parse(content)
|
276
|
-
return options.asIs
|
294
|
+
content = JSON.parse(content);
|
295
|
+
return options.asIs
|
296
|
+
? Object.assign(content, { contact })
|
297
|
+
: this.formatContact([contact, content]);
|
277
298
|
}
|
278
299
|
|
279
300
|
async contacts(options) {
|
280
301
|
if (!this.contactManager) {
|
281
|
-
this.contactManager = new ContactManager(this.secrez.cache)
|
302
|
+
this.contactManager = new ContactManager(this.secrez.cache);
|
282
303
|
}
|
283
304
|
if (options.list) {
|
284
|
-
let contacts = await this.list(options)
|
305
|
+
let contacts = await this.list(options);
|
285
306
|
if (options.asIs) {
|
286
|
-
return contacts
|
307
|
+
return contacts;
|
287
308
|
}
|
288
309
|
if (contacts.length) {
|
289
310
|
for (let i = 0; i < contacts.length; i++) {
|
290
|
-
contacts[i] = this.formatContact(contacts[i])
|
311
|
+
contacts[i] = this.formatContact(contacts[i]);
|
291
312
|
}
|
292
|
-
return contacts
|
313
|
+
return contacts;
|
293
314
|
} else {
|
294
|
-
return
|
315
|
+
return "No contacts found";
|
295
316
|
}
|
296
317
|
} else if (options.add) {
|
297
|
-
return this.add(options)
|
318
|
+
return this.add(options);
|
298
319
|
} else if (options.update) {
|
299
|
-
return this.update(options)
|
320
|
+
return this.update(options);
|
300
321
|
} else if (options.show) {
|
301
|
-
return this.show(options)
|
322
|
+
return this.show(options);
|
302
323
|
} else if (options.rename) {
|
303
|
-
return this.rename(options)
|
324
|
+
return this.rename(options);
|
304
325
|
} else if (options.delete) {
|
305
|
-
return this.delete(options)
|
326
|
+
return this.delete(options);
|
306
327
|
} else {
|
307
|
-
throw new Error('Missing parameters. Run "contacts -h" to see examples.')
|
328
|
+
throw new Error('Missing parameters. Run "contacts -h" to see examples.');
|
308
329
|
}
|
309
330
|
}
|
310
331
|
|
311
332
|
async exec(options = {}) {
|
312
333
|
if (options.help) {
|
313
|
-
return this.showHelp()
|
334
|
+
return this.showHelp();
|
314
335
|
}
|
315
336
|
try {
|
316
337
|
if (!Object.keys(options).length) {
|
317
|
-
options.list = true
|
338
|
+
options.list = true;
|
318
339
|
}
|
319
|
-
this.validate(options)
|
320
|
-
let result = await this.contacts(options)
|
340
|
+
this.validate(options);
|
341
|
+
let result = await this.contacts(options);
|
321
342
|
if (!Array.isArray(result)) {
|
322
|
-
result = [result]
|
343
|
+
result = [result];
|
323
344
|
}
|
324
345
|
for (let r of result) {
|
325
|
-
this.Logger.reset(r)
|
346
|
+
this.Logger.reset(r);
|
326
347
|
}
|
327
|
-
|
328
348
|
} catch (e) {
|
329
349
|
// console.log(e)
|
330
|
-
this.Logger.red(e.message)
|
350
|
+
this.Logger.red(e.message);
|
331
351
|
}
|
332
|
-
await this.prompt.run()
|
352
|
+
await this.prompt.run();
|
333
353
|
}
|
334
354
|
}
|
335
355
|
|
336
|
-
module.exports = Contacts
|
337
|
-
|
338
|
-
|
356
|
+
module.exports = Contacts;
|