@peerbit/server 2.0.0 → 4.0.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/lib/esm/aws.browser.d.ts +0 -0
- package/lib/esm/aws.browser.js +3 -0
- package/lib/esm/aws.browser.js.map +1 -0
- package/lib/esm/aws.d.ts +19 -0
- package/lib/esm/aws.js +185 -1
- package/lib/esm/aws.js.map +1 -1
- package/lib/esm/cli.js +614 -299
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/client.d.ts +13 -1
- package/lib/esm/client.js +101 -31
- package/lib/esm/client.js.map +1 -1
- package/lib/esm/config.d.ts +3 -3
- package/lib/esm/config.js +18 -16
- package/lib/esm/config.js.map +1 -1
- package/lib/esm/docker.browser.d.ts +0 -0
- package/lib/esm/docker.browser.js +3 -0
- package/lib/esm/docker.browser.js.map +1 -0
- package/lib/esm/domain.js +1 -1
- package/lib/esm/domain.js.map +1 -1
- package/lib/esm/peerbit.d.ts +2 -0
- package/lib/esm/peerbit.js +1 -0
- package/lib/esm/peerbit.js.map +1 -1
- package/lib/esm/remotes.d.ts +15 -3
- package/lib/esm/remotes.js +8 -9
- package/lib/esm/remotes.js.map +1 -1
- package/lib/esm/routes.d.ts +4 -2
- package/lib/esm/routes.js +6 -4
- package/lib/esm/routes.js.map +1 -1
- package/lib/esm/server.d.ts +5 -7
- package/lib/esm/server.js +183 -185
- package/lib/esm/server.js.map +1 -1
- package/lib/esm/signes-request.d.ts +5 -0
- package/lib/esm/signes-request.js +54 -0
- package/lib/esm/signes-request.js.map +1 -0
- package/lib/esm/trust.browser.d.ts +0 -0
- package/lib/esm/trust.browser.js +3 -0
- package/lib/esm/trust.browser.js.map +1 -0
- package/lib/esm/trust.d.ts +9 -0
- package/lib/esm/trust.js +36 -0
- package/lib/esm/trust.js.map +1 -0
- package/lib/ui/assets/aws.browser-4ed993c7.js +1 -0
- package/lib/ui/assets/index-5ed0229d.js +77 -0
- package/lib/ui/index.html +1 -1
- package/package.json +13 -7
- package/src/aws.browser.ts +1 -0
- package/src/aws.ts +250 -1
- package/src/cli.ts +726 -348
- package/src/client.ts +145 -38
- package/src/config.ts +21 -23
- package/src/docker.browser.ts +1 -0
- package/src/domain.ts +1 -1
- package/src/peerbit.ts +3 -0
- package/src/remotes.ts +24 -12
- package/src/routes.ts +6 -5
- package/src/server.ts +238 -254
- package/src/signes-request.ts +84 -0
- package/src/trust.browser.ts +1 -0
- package/src/trust.ts +39 -0
- package/lib/ui/assets/index-73eaa3bc.js +0 -53
package/src/cli.ts
CHANGED
|
@@ -5,10 +5,20 @@ import {
|
|
|
5
5
|
startCertbot,
|
|
6
6
|
} from "./domain.js";
|
|
7
7
|
import { startServerWithNode } from "./server.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
AWS_LINUX_ARM_AMIs,
|
|
10
|
+
createRecord,
|
|
11
|
+
launchNodes,
|
|
12
|
+
terminateNode,
|
|
13
|
+
} from "./aws.js";
|
|
14
|
+
import {
|
|
15
|
+
getHomeConfigDir,
|
|
16
|
+
getKeypair,
|
|
17
|
+
getPackageName,
|
|
18
|
+
getRemotesPath,
|
|
19
|
+
} from "./config.js";
|
|
10
20
|
import chalk from "chalk";
|
|
11
|
-
import {
|
|
21
|
+
import { createClient, waitForDomain } from "./client.js";
|
|
12
22
|
import { InstallDependency, StartProgram } from "./types.js";
|
|
13
23
|
import { exit } from "process";
|
|
14
24
|
import yargs from "yargs";
|
|
@@ -16,14 +26,88 @@ import readline from "readline";
|
|
|
16
26
|
import fs from "fs";
|
|
17
27
|
import path from "path";
|
|
18
28
|
import { toBase64 } from "@peerbit/crypto";
|
|
19
|
-
import { Remotes } from "./remotes.js";
|
|
29
|
+
import { DEFAULT_REMOTE_GROUP, RemoteObject, Remotes } from "./remotes.js";
|
|
30
|
+
import { peerIdFromString } from "@libp2p/peer-id";
|
|
31
|
+
import { LOCAL_API_PORT } from "./routes.js";
|
|
32
|
+
import { type PeerId } from "@libp2p/interface/peer-id";
|
|
20
33
|
|
|
21
|
-
const
|
|
34
|
+
const colors = [
|
|
35
|
+
"#00FF00",
|
|
36
|
+
"#0000FF",
|
|
37
|
+
"#FF0000",
|
|
38
|
+
"#01FFFE",
|
|
39
|
+
"#FFA6FE",
|
|
40
|
+
"#FFDB66",
|
|
41
|
+
"#006401",
|
|
42
|
+
"#010067",
|
|
43
|
+
"#95003A",
|
|
44
|
+
"#007DB5",
|
|
45
|
+
"#FF00F6",
|
|
46
|
+
"#FFEEE8",
|
|
47
|
+
"#774D00",
|
|
48
|
+
"#90FB92",
|
|
49
|
+
"#0076FF",
|
|
50
|
+
"#D5FF00",
|
|
51
|
+
"#FF937E",
|
|
52
|
+
"#6A826C",
|
|
53
|
+
"#FF029D",
|
|
54
|
+
"#FE8900",
|
|
55
|
+
"#7A4782",
|
|
56
|
+
"#7E2DD2",
|
|
57
|
+
"#85A900",
|
|
58
|
+
"#FF0056",
|
|
59
|
+
"#A42400",
|
|
60
|
+
"#00AE7E",
|
|
61
|
+
"#683D3B",
|
|
62
|
+
"#BDC6FF",
|
|
63
|
+
"#263400",
|
|
64
|
+
"#BDD393",
|
|
65
|
+
"#00B917",
|
|
66
|
+
"#9E008E",
|
|
67
|
+
"#001544",
|
|
68
|
+
"#C28C9F",
|
|
69
|
+
"#FF74A3",
|
|
70
|
+
"#01D0FF",
|
|
71
|
+
"#004754",
|
|
72
|
+
"#E56FFE",
|
|
73
|
+
"#788231",
|
|
74
|
+
"#0E4CA1",
|
|
75
|
+
"#91D0CB",
|
|
76
|
+
"#BE9970",
|
|
77
|
+
"#968AE8",
|
|
78
|
+
"#BB8800",
|
|
79
|
+
"#43002C",
|
|
80
|
+
"#DEFF74",
|
|
81
|
+
"#00FFC6",
|
|
82
|
+
"#FFE502",
|
|
83
|
+
"#620E00",
|
|
84
|
+
"#008F9C",
|
|
85
|
+
"#98FF52",
|
|
86
|
+
"#7544B1",
|
|
87
|
+
"#B500FF",
|
|
88
|
+
"#00FF78",
|
|
89
|
+
"#FF6E41",
|
|
90
|
+
"#005F39",
|
|
91
|
+
"#6B6882",
|
|
92
|
+
"#5FAD4E",
|
|
93
|
+
"#A75740",
|
|
94
|
+
"#A5FFD2",
|
|
95
|
+
"#FFB167",
|
|
96
|
+
"#009BFF",
|
|
97
|
+
"#E85EBE",
|
|
98
|
+
];
|
|
99
|
+
const padString = function (
|
|
100
|
+
string: string,
|
|
101
|
+
padding: number,
|
|
102
|
+
padChar = " ",
|
|
103
|
+
stringLength = string.valueOf().length
|
|
104
|
+
) {
|
|
22
105
|
const val = string.valueOf();
|
|
23
|
-
if (Math.abs(padding) <=
|
|
106
|
+
if (Math.abs(padding) <= stringLength) {
|
|
24
107
|
return val;
|
|
25
108
|
}
|
|
26
|
-
|
|
109
|
+
|
|
110
|
+
const m = Math.max(Math.abs(padding) - stringLength || 0, 0);
|
|
27
111
|
const pad = Array(m + 1).join(String(padChar).charAt(0));
|
|
28
112
|
// var pad = String(c || ' ').charAt(0).repeat(Math.abs(n) - this.length);
|
|
29
113
|
return padding < 0 ? pad + val : val + pad;
|
|
@@ -57,6 +141,14 @@ export const cli = async (args?: string[]) => {
|
|
|
57
141
|
type: "boolean",
|
|
58
142
|
default: false,
|
|
59
143
|
})
|
|
144
|
+
.option("grant-access", {
|
|
145
|
+
describe: "Grant access to public keys on start",
|
|
146
|
+
defaultDescription:
|
|
147
|
+
"The publickey of this device located in 'directory'",
|
|
148
|
+
type: "string",
|
|
149
|
+
array: true,
|
|
150
|
+
alias: "ga",
|
|
151
|
+
})
|
|
60
152
|
.option("reset", {
|
|
61
153
|
describe:
|
|
62
154
|
"If true, then programs opened during last session will not be opened",
|
|
@@ -64,14 +156,6 @@ export const cli = async (args?: string[]) => {
|
|
|
64
156
|
default: false,
|
|
65
157
|
alias: "r",
|
|
66
158
|
})
|
|
67
|
-
.option("password", {
|
|
68
|
-
describe:
|
|
69
|
-
"Setup password so you can interact with the node remotely",
|
|
70
|
-
type: "string",
|
|
71
|
-
defaultDescription:
|
|
72
|
-
"The password from the last session will be used or a password will be generated",
|
|
73
|
-
default: undefined,
|
|
74
|
-
})
|
|
75
159
|
.option("port-api", {
|
|
76
160
|
describe:
|
|
77
161
|
"Set API server port. Only modify this when testing locally, since NGINX config depends on the default value",
|
|
@@ -94,12 +178,29 @@ export const cli = async (args?: string[]) => {
|
|
|
94
178
|
),
|
|
95
179
|
ports: { api: args["port-api"], node: args["port-node"] },
|
|
96
180
|
bootstrap: args.bootstrap,
|
|
97
|
-
password: args.password,
|
|
98
181
|
newSession: args.reset,
|
|
182
|
+
grantAccess: args["grant-access"],
|
|
99
183
|
});
|
|
100
184
|
},
|
|
101
185
|
})
|
|
102
|
-
|
|
186
|
+
.command({
|
|
187
|
+
command: "id",
|
|
188
|
+
describe: "Get peer id",
|
|
189
|
+
builder: (yargs: yargs.Argv) => {
|
|
190
|
+
yargs.option("directory", {
|
|
191
|
+
describe: "Peerbit directory",
|
|
192
|
+
defaultDescription: "~.peerbit",
|
|
193
|
+
type: "string",
|
|
194
|
+
alias: "d",
|
|
195
|
+
default: getHomeConfigDir(),
|
|
196
|
+
});
|
|
197
|
+
return yargs;
|
|
198
|
+
},
|
|
199
|
+
handler: async (args) => {
|
|
200
|
+
const kp = await getKeypair(args.directory);
|
|
201
|
+
console.log((await kp.toPeerId()).toString());
|
|
202
|
+
},
|
|
203
|
+
})
|
|
103
204
|
.command(
|
|
104
205
|
"domain",
|
|
105
206
|
"Setup a domain and certificate for this node",
|
|
@@ -217,6 +318,167 @@ export const cli = async (args?: string[]) => {
|
|
|
217
318
|
)
|
|
218
319
|
.command("remote", "Handle remote nodes", (innerYargs) => {
|
|
219
320
|
innerYargs
|
|
321
|
+
.command("spawn", "Spawn remote nodes", (spawnYargs) => {
|
|
322
|
+
spawnYargs
|
|
323
|
+
.command({
|
|
324
|
+
command: "aws",
|
|
325
|
+
describe: "Spawn remote nodes on AWS",
|
|
326
|
+
builder: (awsArgs: yargs.Argv) => {
|
|
327
|
+
awsArgs.option("count", {
|
|
328
|
+
describe: "Amount of nodes to spawn",
|
|
329
|
+
defaultDescription: "One node",
|
|
330
|
+
type: "number",
|
|
331
|
+
alias: "c",
|
|
332
|
+
default: 1,
|
|
333
|
+
});
|
|
334
|
+
awsArgs.option("region", {
|
|
335
|
+
describe: "Region",
|
|
336
|
+
type: "string",
|
|
337
|
+
defaultDescription: "Region defined in ~.aws/config",
|
|
338
|
+
choices: Object.keys(AWS_LINUX_ARM_AMIs),
|
|
339
|
+
});
|
|
340
|
+
awsArgs.option("group", {
|
|
341
|
+
describe: "Remote group to launch nodes in",
|
|
342
|
+
type: "string",
|
|
343
|
+
alias: "g",
|
|
344
|
+
default: DEFAULT_REMOTE_GROUP,
|
|
345
|
+
});
|
|
346
|
+
awsArgs.option("size", {
|
|
347
|
+
describe: "Instance size",
|
|
348
|
+
type: "string",
|
|
349
|
+
alias: "s",
|
|
350
|
+
choices: [
|
|
351
|
+
"micro",
|
|
352
|
+
"small",
|
|
353
|
+
"medium",
|
|
354
|
+
"large",
|
|
355
|
+
"xlarge",
|
|
356
|
+
"2xlarge",
|
|
357
|
+
],
|
|
358
|
+
default: "micro",
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
awsArgs.option("name", {
|
|
362
|
+
describe: "Name prefix for spawned nodes",
|
|
363
|
+
type: "string",
|
|
364
|
+
alias: "n",
|
|
365
|
+
default: "peerbit-node",
|
|
366
|
+
});
|
|
367
|
+
awsArgs.option("grant-access", {
|
|
368
|
+
describe: "Grant access to public keys on start",
|
|
369
|
+
defaultDescription:
|
|
370
|
+
"The publickey of this device located in 'directory'",
|
|
371
|
+
type: "string",
|
|
372
|
+
array: true,
|
|
373
|
+
alias: "ga",
|
|
374
|
+
});
|
|
375
|
+
awsArgs.option("directory", {
|
|
376
|
+
describe: "Peerbit directory",
|
|
377
|
+
defaultDescription: "~.peerbit",
|
|
378
|
+
type: "string",
|
|
379
|
+
alias: "d",
|
|
380
|
+
default: getHomeConfigDir(),
|
|
381
|
+
});
|
|
382
|
+
return awsArgs;
|
|
383
|
+
},
|
|
384
|
+
handler: async (args) => {
|
|
385
|
+
const accessGrant: PeerId[] =
|
|
386
|
+
args.access?.length > 0
|
|
387
|
+
? args.access.map((x) => peerIdFromString(x))
|
|
388
|
+
: [
|
|
389
|
+
await (
|
|
390
|
+
await getKeypair(args.directory)
|
|
391
|
+
).publicKey.toPeerId(),
|
|
392
|
+
];
|
|
393
|
+
const nodes = await launchNodes({
|
|
394
|
+
email: "marcus@dao.xyz",
|
|
395
|
+
count: args.number,
|
|
396
|
+
namePrefix: args.name,
|
|
397
|
+
region: args.region,
|
|
398
|
+
grantAccess: accessGrant,
|
|
399
|
+
size: args.size,
|
|
400
|
+
});
|
|
401
|
+
console.log(
|
|
402
|
+
`Waiting for ${args.count} ${
|
|
403
|
+
args.count > 1 ? "nodes" : "node"
|
|
404
|
+
} to spawn. This might take a few minutes. You can watch the progress in your AWS console.`
|
|
405
|
+
);
|
|
406
|
+
const twirlTimer = (function () {
|
|
407
|
+
const P = ["\\", "|", "/", "-"];
|
|
408
|
+
let x = 0;
|
|
409
|
+
return setInterval(function () {
|
|
410
|
+
process.stdout.write(
|
|
411
|
+
"\r" + "Loading: " + chalk.hex(colors[x])(P[x++])
|
|
412
|
+
);
|
|
413
|
+
x &= 3;
|
|
414
|
+
}, 250);
|
|
415
|
+
})();
|
|
416
|
+
try {
|
|
417
|
+
for (const node of nodes) {
|
|
418
|
+
const domain = await waitForDomain(node.publicIp);
|
|
419
|
+
const remotes = new Remotes(getRemotesPath(args.directory));
|
|
420
|
+
remotes.add({
|
|
421
|
+
name: node.name,
|
|
422
|
+
address: domain,
|
|
423
|
+
group: args.group,
|
|
424
|
+
origin: {
|
|
425
|
+
type: "aws",
|
|
426
|
+
instanceId: node.instanceId,
|
|
427
|
+
region: node.region,
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
} catch (error: any) {
|
|
432
|
+
console.error(
|
|
433
|
+
"Error waiting for domains to be available: " +
|
|
434
|
+
error?.toString()
|
|
435
|
+
);
|
|
436
|
+
} finally {
|
|
437
|
+
clearInterval(twirlTimer);
|
|
438
|
+
process.stdout.write("\r");
|
|
439
|
+
}
|
|
440
|
+
console.log(`New nodes available ${nodes.length}:`);
|
|
441
|
+
for (const node of nodes) {
|
|
442
|
+
console.log(chalk.green(node.name));
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
})
|
|
446
|
+
.strict()
|
|
447
|
+
.demandCommand();
|
|
448
|
+
})
|
|
449
|
+
.command({
|
|
450
|
+
command: "terminate [name...]",
|
|
451
|
+
describe: "Terminate remote instances that was previously spawned",
|
|
452
|
+
builder: (killArgs: yargs.Argv) => {
|
|
453
|
+
killArgs.option("all", {
|
|
454
|
+
describe: "Kill all nodes",
|
|
455
|
+
type: "boolean",
|
|
456
|
+
default: false,
|
|
457
|
+
});
|
|
458
|
+
killArgs.positional("name", {
|
|
459
|
+
type: "string",
|
|
460
|
+
describe: "Remote name",
|
|
461
|
+
default: "localhost",
|
|
462
|
+
demandOption: false,
|
|
463
|
+
array: true,
|
|
464
|
+
});
|
|
465
|
+
return killArgs;
|
|
466
|
+
},
|
|
467
|
+
handler: async (args) => {
|
|
468
|
+
const remotes = new Remotes(getRemotesPath(args.directory));
|
|
469
|
+
const allRemotes = await remotes.all();
|
|
470
|
+
for (const remote of allRemotes) {
|
|
471
|
+
if (args.all || args.name.includes(remote.name)) {
|
|
472
|
+
if (remote.origin?.type === "aws") {
|
|
473
|
+
await terminateNode({
|
|
474
|
+
instanceId: remote.origin.instanceId,
|
|
475
|
+
region: remote.origin.region,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
})
|
|
220
482
|
.command({
|
|
221
483
|
command: "list",
|
|
222
484
|
aliases: "ls",
|
|
@@ -240,11 +502,19 @@ export const cli = async (args?: string[]) => {
|
|
|
240
502
|
.reduce((prev, c, i) => {
|
|
241
503
|
return Math.max(prev, c);
|
|
242
504
|
}, 0);
|
|
505
|
+
|
|
243
506
|
const all = await remotes.all();
|
|
244
507
|
if (all.length > 0) {
|
|
508
|
+
console.log(
|
|
509
|
+
padString("Name", maxNameLength + 10),
|
|
510
|
+
padString("Group" || "", 10),
|
|
511
|
+
"Address"
|
|
512
|
+
);
|
|
513
|
+
|
|
245
514
|
for (const remote of all) {
|
|
246
515
|
console.log(
|
|
247
516
|
padString(remote.name, maxNameLength + 10),
|
|
517
|
+
padString(remote.group || "", 10),
|
|
248
518
|
remote.address
|
|
249
519
|
);
|
|
250
520
|
}
|
|
@@ -254,25 +524,26 @@ export const cli = async (args?: string[]) => {
|
|
|
254
524
|
},
|
|
255
525
|
})
|
|
256
526
|
.command({
|
|
257
|
-
command: "add <name> <address>
|
|
527
|
+
command: "add <name> <address>",
|
|
258
528
|
describe: "Add remote",
|
|
259
529
|
builder: (yargs: yargs.Argv) => {
|
|
260
530
|
yargs
|
|
261
|
-
.positional("address", {
|
|
262
|
-
type: "string",
|
|
263
|
-
describe: "Remote name",
|
|
264
|
-
demandOption: true,
|
|
265
|
-
})
|
|
266
531
|
.positional("name", {
|
|
267
532
|
type: "string",
|
|
268
533
|
describe: "Remote address",
|
|
269
534
|
demandOption: true,
|
|
270
535
|
})
|
|
271
|
-
.positional("
|
|
536
|
+
.positional("address", {
|
|
272
537
|
type: "string",
|
|
273
|
-
describe: "
|
|
538
|
+
describe: "Remote name",
|
|
274
539
|
demandOption: true,
|
|
275
540
|
})
|
|
541
|
+
.option("group", {
|
|
542
|
+
describe: "Group name",
|
|
543
|
+
type: "string",
|
|
544
|
+
alias: "g",
|
|
545
|
+
default: DEFAULT_REMOTE_GROUP,
|
|
546
|
+
})
|
|
276
547
|
.option("directory", {
|
|
277
548
|
describe: "Peerbit directory",
|
|
278
549
|
defaultDescription: "~.peerbit",
|
|
@@ -287,7 +558,9 @@ export const cli = async (args?: string[]) => {
|
|
|
287
558
|
if (args.name === "localhost") {
|
|
288
559
|
throw new Error("Remote can not be named 'localhost'");
|
|
289
560
|
}
|
|
290
|
-
const api = await
|
|
561
|
+
const api = await createClient(await getKeypair(args.directory), {
|
|
562
|
+
address: args.address,
|
|
563
|
+
});
|
|
291
564
|
try {
|
|
292
565
|
await api.program.list();
|
|
293
566
|
} catch (error) {
|
|
@@ -297,7 +570,11 @@ export const cli = async (args?: string[]) => {
|
|
|
297
570
|
fs.mkdirSync(args.directory, { recursive: true });
|
|
298
571
|
}
|
|
299
572
|
const remotes = new Remotes(getRemotesPath(args.directory));
|
|
300
|
-
remotes.add(
|
|
573
|
+
remotes.add({
|
|
574
|
+
name: args.name,
|
|
575
|
+
address: args.address,
|
|
576
|
+
group: args.group,
|
|
577
|
+
});
|
|
301
578
|
},
|
|
302
579
|
})
|
|
303
580
|
.command({
|
|
@@ -346,6 +623,18 @@ export const cli = async (args?: string[]) => {
|
|
|
346
623
|
demandOption: false,
|
|
347
624
|
array: true,
|
|
348
625
|
})
|
|
626
|
+
.option("all", {
|
|
627
|
+
type: "boolean",
|
|
628
|
+
describe: "Connect to all nodes",
|
|
629
|
+
default: false,
|
|
630
|
+
})
|
|
631
|
+
.option("group", {
|
|
632
|
+
type: "string",
|
|
633
|
+
describe: "Remote group name",
|
|
634
|
+
alias: "g",
|
|
635
|
+
default: [],
|
|
636
|
+
array: true,
|
|
637
|
+
})
|
|
349
638
|
.option("directory", {
|
|
350
639
|
describe: "Peerbit directory",
|
|
351
640
|
defaultDescription: "~.peerbit",
|
|
@@ -356,368 +645,457 @@ export const cli = async (args?: string[]) => {
|
|
|
356
645
|
return yargs;
|
|
357
646
|
},
|
|
358
647
|
handler: async (connectArgs) => {
|
|
359
|
-
const
|
|
648
|
+
const remotes = new Remotes(getRemotesPath(connectArgs.directory));
|
|
649
|
+
let names: string[] = connectArgs.name;
|
|
650
|
+
if (
|
|
651
|
+
names.length === 0 ||
|
|
652
|
+
connectArgs.all ||
|
|
653
|
+
connectArgs.group.length > 0
|
|
654
|
+
) {
|
|
655
|
+
names = (await remotes.all()).map((x) => x.name);
|
|
656
|
+
}
|
|
657
|
+
|
|
360
658
|
const apis: {
|
|
361
659
|
log: (string: string) => void;
|
|
362
660
|
name: string;
|
|
363
|
-
api: Awaited<ReturnType<typeof
|
|
661
|
+
api: Awaited<ReturnType<typeof createClient>>;
|
|
364
662
|
}[] = [];
|
|
365
|
-
|
|
663
|
+
|
|
664
|
+
const config = await import("./config.js");
|
|
665
|
+
const keypair = await config.getKeypair(connectArgs.directory);
|
|
666
|
+
|
|
667
|
+
const selectedRemotes: RemoteObject[] = [];
|
|
366
668
|
if (names.length > 0) {
|
|
367
|
-
const
|
|
368
|
-
getRemotesPath(connectArgs.directory)
|
|
369
|
-
);
|
|
370
|
-
for (const name of names) {
|
|
669
|
+
for (const [ix, name] of names.entries()) {
|
|
371
670
|
if (name === "localhost") {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
config.getServerConfigPath(connectArgs.directory)
|
|
375
|
-
);
|
|
376
|
-
apis.push({
|
|
377
|
-
log: (string) => console.log("localhost: " + string),
|
|
671
|
+
selectedRemotes.push({
|
|
672
|
+
address: "http://localhost:" + LOCAL_API_PORT,
|
|
378
673
|
name: "localhost",
|
|
379
|
-
|
|
674
|
+
group: DEFAULT_REMOTE_GROUP,
|
|
380
675
|
});
|
|
381
676
|
} else {
|
|
382
677
|
const remote = remotes.getByName(name);
|
|
678
|
+
|
|
383
679
|
if (!remote) {
|
|
384
680
|
throw new Error("Missing remote with name: " + name);
|
|
385
681
|
}
|
|
386
|
-
|
|
387
|
-
if (
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
682
|
+
|
|
683
|
+
if (
|
|
684
|
+
connectArgs.group.length > 0 &&
|
|
685
|
+
!connectArgs.group.includes(remote.group)
|
|
686
|
+
) {
|
|
687
|
+
continue;
|
|
391
688
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
name,
|
|
395
|
-
api: await client(remote.password, remote.address),
|
|
396
|
-
});
|
|
689
|
+
|
|
690
|
+
selectedRemotes.push(remote);
|
|
397
691
|
}
|
|
398
692
|
}
|
|
399
693
|
}
|
|
400
694
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
695
|
+
const maxNameLength = selectedRemotes
|
|
696
|
+
.map((x) => x.name.length)
|
|
697
|
+
.reduce((prev, c, i) => {
|
|
698
|
+
return Math.max(prev, c);
|
|
699
|
+
}, 0);
|
|
700
|
+
|
|
701
|
+
if (selectedRemotes.length === 0) {
|
|
702
|
+
console.log(
|
|
703
|
+
chalk.red("No remotes matched your connection condition")
|
|
704
|
+
);
|
|
705
|
+
} else {
|
|
706
|
+
console.log(`Connected to (${selectedRemotes.length}):`);
|
|
707
|
+
|
|
708
|
+
for (const [ix, remote] of selectedRemotes.entries()) {
|
|
709
|
+
const chalkBg = chalk.bgHex(colors[ix]);
|
|
710
|
+
console.log(chalkBg(remote.name));
|
|
711
|
+
const logFn: (name: string) => void = (string) =>
|
|
712
|
+
console.log(
|
|
713
|
+
padString(
|
|
714
|
+
chalkBg(remote.name),
|
|
715
|
+
maxNameLength,
|
|
716
|
+
" ",
|
|
717
|
+
remote.name.length
|
|
718
|
+
) +
|
|
719
|
+
": " +
|
|
720
|
+
string
|
|
721
|
+
);
|
|
722
|
+
|
|
723
|
+
apis.push({
|
|
724
|
+
log: logFn,
|
|
725
|
+
name: remote.name,
|
|
726
|
+
api: await createClient(keypair, remote),
|
|
727
|
+
});
|
|
409
728
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
729
|
+
|
|
730
|
+
// try if authenticated
|
|
731
|
+
for (const api of apis) {
|
|
732
|
+
try {
|
|
733
|
+
await api.api.program.list();
|
|
734
|
+
} catch (error) {
|
|
735
|
+
throw new Error(
|
|
736
|
+
`Failed to connect to '${api.name}': ${error?.toString()}`
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
const rl = readline.createInterface({
|
|
742
|
+
input: process.stdin,
|
|
743
|
+
output: process.stdout,
|
|
744
|
+
terminal: true,
|
|
745
|
+
historySize: 100,
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
console.log("Write 'help' to show commands.\n");
|
|
749
|
+
rl.prompt(false);
|
|
750
|
+
const capi = () =>
|
|
751
|
+
yargs
|
|
752
|
+
.default()
|
|
753
|
+
.command("peer", "Peer info", (yargs) => {
|
|
754
|
+
yargs
|
|
755
|
+
.command({
|
|
756
|
+
command: "id",
|
|
757
|
+
describe: "Get peer id",
|
|
758
|
+
handler: async (args) => {
|
|
759
|
+
for (const api of apis) {
|
|
760
|
+
api.log((await api.api.peer.id.get()).toString());
|
|
761
|
+
}
|
|
762
|
+
},
|
|
763
|
+
})
|
|
764
|
+
.command({
|
|
765
|
+
command: "address",
|
|
766
|
+
describe: "Get addresses",
|
|
767
|
+
handler: async (args) => {
|
|
768
|
+
for (const api of apis) {
|
|
769
|
+
(await api.api.peer.addresses.get()).forEach((x) =>
|
|
770
|
+
api.log(x.toString())
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
},
|
|
774
|
+
})
|
|
775
|
+
.strict()
|
|
776
|
+
.demandCommand();
|
|
777
|
+
return yargs;
|
|
778
|
+
})
|
|
779
|
+
.command(
|
|
780
|
+
"access",
|
|
781
|
+
"Modify access control for this node",
|
|
782
|
+
(yargs) => {
|
|
783
|
+
yargs
|
|
784
|
+
.command({
|
|
785
|
+
command: "grant <peer-id>",
|
|
786
|
+
describe: "Give a peer-id admin capabilities",
|
|
787
|
+
builder: (yargs: yargs.Argv) => {
|
|
788
|
+
yargs.positional("peer-id", {
|
|
789
|
+
describe: "Peer id",
|
|
790
|
+
type: "string",
|
|
791
|
+
demandOption: true,
|
|
792
|
+
});
|
|
793
|
+
return yargs;
|
|
794
|
+
},
|
|
795
|
+
handler: async (args) => {
|
|
796
|
+
const peerId: PeerId = peerIdFromString(
|
|
797
|
+
args["peer-id"]
|
|
798
|
+
);
|
|
799
|
+
for (const api of apis) {
|
|
800
|
+
await api.api.access.allow(peerId);
|
|
801
|
+
}
|
|
802
|
+
},
|
|
803
|
+
})
|
|
804
|
+
.command({
|
|
805
|
+
command: "deny <peer-id>",
|
|
806
|
+
describe: "Remove admin capabilities from peer-id",
|
|
807
|
+
builder: (yargs: yargs.Argv) => {
|
|
808
|
+
yargs.positional("peer-id", {
|
|
809
|
+
describe: "Peer id",
|
|
810
|
+
demandOption: true,
|
|
811
|
+
});
|
|
812
|
+
return yargs;
|
|
813
|
+
},
|
|
814
|
+
handler: async (args) => {
|
|
815
|
+
const peerId = peerIdFromString(args["peer-id"]);
|
|
816
|
+
for (const api of apis) {
|
|
817
|
+
await api.api.access.deny(peerId);
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
})
|
|
821
|
+
.strict()
|
|
822
|
+
.demandCommand();
|
|
823
|
+
}
|
|
824
|
+
)
|
|
825
|
+
.command("network", "Manage network", (yargs) => {
|
|
826
|
+
yargs
|
|
827
|
+
.command({
|
|
828
|
+
command: "bootstrap",
|
|
829
|
+
describe: "Connect to bootstrap nodes",
|
|
830
|
+
handler: async () => {
|
|
831
|
+
for (const api of apis) {
|
|
832
|
+
await api.api.network.bootstrap();
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
})
|
|
836
|
+
.strict()
|
|
837
|
+
.demandCommand();
|
|
838
|
+
})
|
|
839
|
+
|
|
840
|
+
.command(
|
|
841
|
+
"topic",
|
|
842
|
+
"Manage topics the node is listening to",
|
|
843
|
+
(yargs) => {
|
|
844
|
+
yargs
|
|
845
|
+
.command({
|
|
846
|
+
command: "list",
|
|
847
|
+
aliases: "ls",
|
|
848
|
+
describe: "List all topics",
|
|
849
|
+
builder: (yargs: any) => {
|
|
850
|
+
yargs.option("replicate", {
|
|
851
|
+
type: "boolean",
|
|
852
|
+
describe: "Replicate data on this topic",
|
|
853
|
+
aliases: "r",
|
|
854
|
+
default: false,
|
|
855
|
+
});
|
|
856
|
+
return yargs;
|
|
857
|
+
},
|
|
858
|
+
handler: async (args) => {
|
|
859
|
+
/* const c = await client();
|
|
860
|
+
const topics = await c.topics.get(args.replicate);
|
|
861
|
+
if (topics?.length > 0) {
|
|
862
|
+
console.log("Topic (" + topics.length + "):");
|
|
863
|
+
for (const t of topics) {
|
|
864
|
+
console.log(t);
|
|
448
865
|
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
866
|
+
} else {
|
|
867
|
+
console.log("Not subscribed to any topics");
|
|
868
|
+
} */
|
|
869
|
+
console.error("Not implemented");
|
|
870
|
+
},
|
|
871
|
+
})
|
|
872
|
+
.strict()
|
|
873
|
+
.demandCommand();
|
|
874
|
+
return yargs;
|
|
875
|
+
}
|
|
876
|
+
)
|
|
877
|
+
.command("program", "Manage programs", (yargs) => {
|
|
459
878
|
yargs
|
|
879
|
+
.command({
|
|
880
|
+
command: "status <address>",
|
|
881
|
+
describe: "Is a program open",
|
|
882
|
+
builder: (yargs: any) => {
|
|
883
|
+
yargs.positional("address", {
|
|
884
|
+
type: "string",
|
|
885
|
+
describe: "Program address",
|
|
886
|
+
demandOption: true,
|
|
887
|
+
});
|
|
888
|
+
return yargs;
|
|
889
|
+
},
|
|
890
|
+
|
|
891
|
+
handler: async (args) => {
|
|
892
|
+
for (const api of apis) {
|
|
893
|
+
const program = await api.api.program.has(
|
|
894
|
+
args.address
|
|
895
|
+
);
|
|
896
|
+
if (!program) {
|
|
897
|
+
api.log(chalk.red("Closed"));
|
|
898
|
+
} else {
|
|
899
|
+
api.log(chalk.green("Open"));
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
},
|
|
903
|
+
})
|
|
904
|
+
.command({
|
|
905
|
+
command: "drop <address>",
|
|
906
|
+
describe: "Drop a program",
|
|
907
|
+
builder: (yargs: any) => {
|
|
908
|
+
yargs.positional("address", {
|
|
909
|
+
type: "string",
|
|
910
|
+
describe: "Program address",
|
|
911
|
+
demandOption: true,
|
|
912
|
+
});
|
|
913
|
+
return yargs;
|
|
914
|
+
},
|
|
915
|
+
|
|
916
|
+
handler: async (args) => {
|
|
917
|
+
for (const api of apis) {
|
|
918
|
+
try {
|
|
919
|
+
await api.api.program.drop(args.address);
|
|
920
|
+
} catch (error: any) {
|
|
921
|
+
api.log(
|
|
922
|
+
chalk.red(
|
|
923
|
+
`Failed to drop ${
|
|
924
|
+
args.address
|
|
925
|
+
}: ${error.toString()}`
|
|
926
|
+
)
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
})
|
|
932
|
+
.command({
|
|
933
|
+
command: "close <address>",
|
|
934
|
+
describe: "Close a program",
|
|
935
|
+
builder: (yargs: any) => {
|
|
936
|
+
yargs.positional("address", {
|
|
937
|
+
type: "string",
|
|
938
|
+
describe: "Program address",
|
|
939
|
+
demandOption: true,
|
|
940
|
+
});
|
|
941
|
+
return yargs;
|
|
942
|
+
},
|
|
943
|
+
|
|
944
|
+
handler: async (args) => {
|
|
945
|
+
for (const api of apis) {
|
|
946
|
+
await api.api.program.close(args.address);
|
|
947
|
+
}
|
|
948
|
+
},
|
|
949
|
+
})
|
|
460
950
|
.command({
|
|
461
951
|
command: "list",
|
|
952
|
+
describe: "List all running programs",
|
|
462
953
|
aliases: "ls",
|
|
463
|
-
|
|
954
|
+
handler: async (args) => {
|
|
955
|
+
for (const api of apis) {
|
|
956
|
+
const list = await api.api.program.list();
|
|
957
|
+
api.log(`Running programs (${list.length}):`);
|
|
958
|
+
list.forEach((p) => {
|
|
959
|
+
api.log(chalk.green(p));
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
},
|
|
963
|
+
})
|
|
964
|
+
|
|
965
|
+
.command({
|
|
966
|
+
command: "open [program]",
|
|
967
|
+
describe: "Open program",
|
|
464
968
|
builder: (yargs: any) => {
|
|
465
|
-
yargs.
|
|
466
|
-
type: "
|
|
467
|
-
describe: "
|
|
468
|
-
|
|
469
|
-
|
|
969
|
+
yargs.positional("program", {
|
|
970
|
+
type: "string",
|
|
971
|
+
describe: "Identifier",
|
|
972
|
+
demandOption: true,
|
|
973
|
+
});
|
|
974
|
+
yargs.option("base64", {
|
|
975
|
+
type: "string",
|
|
976
|
+
describe: "Base64 encoded serialized",
|
|
977
|
+
aliases: "b",
|
|
978
|
+
});
|
|
979
|
+
yargs.option("variant", {
|
|
980
|
+
type: "string",
|
|
981
|
+
describe: "Variant name",
|
|
982
|
+
aliases: "v",
|
|
470
983
|
});
|
|
471
984
|
return yargs;
|
|
472
985
|
},
|
|
473
986
|
handler: async (args) => {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
987
|
+
if (!args.base64 && !args.variant) {
|
|
988
|
+
throw new Error(
|
|
989
|
+
"Either base64 or variant argument needs to be provided"
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
let startArg: StartProgram;
|
|
993
|
+
if (args.base64) {
|
|
994
|
+
startArg = {
|
|
995
|
+
base64: args.base64,
|
|
996
|
+
};
|
|
997
|
+
} else {
|
|
998
|
+
startArg = {
|
|
999
|
+
variant: args.variant,
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
for (const api of apis) {
|
|
1003
|
+
const address = await api.api.program.open(
|
|
1004
|
+
startArg
|
|
1005
|
+
);
|
|
1006
|
+
api.log("Started program with address: ");
|
|
1007
|
+
api.log(chalk.green(address.toString()));
|
|
1008
|
+
}
|
|
485
1009
|
},
|
|
486
1010
|
})
|
|
487
1011
|
.strict()
|
|
488
1012
|
.demandCommand();
|
|
489
1013
|
return yargs;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
demandOption: true,
|
|
502
|
-
});
|
|
503
|
-
return yargs;
|
|
504
|
-
},
|
|
1014
|
+
})
|
|
1015
|
+
.command({
|
|
1016
|
+
command: "install <package-spec>",
|
|
1017
|
+
describe: "install and import a dependency",
|
|
1018
|
+
builder: (yargs: any) => {
|
|
1019
|
+
yargs.positional("package-spec", {
|
|
1020
|
+
type: "string",
|
|
1021
|
+
describe:
|
|
1022
|
+
"Installed dependency will be loaded with js import(...)",
|
|
1023
|
+
demandOption: true,
|
|
1024
|
+
});
|
|
505
1025
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
);
|
|
511
|
-
if (!program) {
|
|
512
|
-
api.log(chalk.red("Closed"));
|
|
513
|
-
} else {
|
|
514
|
-
api.log(chalk.green("Open"));
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
},
|
|
518
|
-
})
|
|
519
|
-
.command({
|
|
520
|
-
command: "drop <address>",
|
|
521
|
-
describe: "Drop a program",
|
|
522
|
-
builder: (yargs: any) => {
|
|
523
|
-
yargs.positional("address", {
|
|
524
|
-
type: "string",
|
|
525
|
-
describe: "Program address",
|
|
526
|
-
demandOption: true,
|
|
527
|
-
});
|
|
528
|
-
return yargs;
|
|
529
|
-
},
|
|
1026
|
+
return yargs;
|
|
1027
|
+
},
|
|
1028
|
+
handler: async (args) => {
|
|
1029
|
+
// if ends with .tgz assume it is a file
|
|
530
1030
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
chalk.red(
|
|
538
|
-
`Failed to drop ${
|
|
539
|
-
args.address
|
|
540
|
-
}: ${error.toString()}`
|
|
541
|
-
)
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
},
|
|
546
|
-
})
|
|
547
|
-
.command({
|
|
548
|
-
command: "close <address>",
|
|
549
|
-
describe: "Close a program",
|
|
550
|
-
builder: (yargs: any) => {
|
|
551
|
-
yargs.positional("address", {
|
|
552
|
-
type: "string",
|
|
553
|
-
describe: "Program address",
|
|
554
|
-
demandOption: true,
|
|
555
|
-
});
|
|
556
|
-
return yargs;
|
|
557
|
-
},
|
|
1031
|
+
let installCommand: InstallDependency;
|
|
1032
|
+
const packageName: string = args["package-spec"];
|
|
1033
|
+
if (packageName.endsWith(".tgz")) {
|
|
1034
|
+
const packagePath = path.isAbsolute(packageName)
|
|
1035
|
+
? packageName
|
|
1036
|
+
: path.join(process.cwd(), packageName);
|
|
558
1037
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
handler: async (args) => {
|
|
570
|
-
for (const api of apis) {
|
|
571
|
-
const list = await api.api.program.list();
|
|
572
|
-
api.log(`Running programs (${list.length}):`);
|
|
573
|
-
list.forEach((p) => {
|
|
574
|
-
api.log(chalk.green(p));
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
},
|
|
578
|
-
})
|
|
579
|
-
|
|
580
|
-
.command({
|
|
581
|
-
command: "open [program]",
|
|
582
|
-
describe: "Open program",
|
|
583
|
-
builder: (yargs: any) => {
|
|
584
|
-
yargs.positional("program", {
|
|
585
|
-
type: "string",
|
|
586
|
-
describe: "Identifier",
|
|
587
|
-
demandOption: true,
|
|
588
|
-
});
|
|
589
|
-
yargs.option("base64", {
|
|
590
|
-
type: "string",
|
|
591
|
-
describe: "Base64 encoded serialized",
|
|
592
|
-
aliases: "b",
|
|
593
|
-
});
|
|
594
|
-
yargs.option("variant", {
|
|
595
|
-
type: "string",
|
|
596
|
-
describe: "Variant name",
|
|
597
|
-
aliases: "v",
|
|
598
|
-
});
|
|
599
|
-
return yargs;
|
|
600
|
-
},
|
|
601
|
-
handler: async (args) => {
|
|
602
|
-
if (!args.base64 && !args.variant) {
|
|
603
|
-
throw new Error(
|
|
604
|
-
"Either base64 or variant argument needs to be provided"
|
|
605
|
-
);
|
|
606
|
-
}
|
|
607
|
-
let startArg: StartProgram;
|
|
608
|
-
if (args.base64) {
|
|
609
|
-
startArg = {
|
|
610
|
-
base64: args.base64,
|
|
611
|
-
};
|
|
612
|
-
} else {
|
|
613
|
-
startArg = {
|
|
614
|
-
variant: args.variant,
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
for (const api of apis) {
|
|
618
|
-
const address = await api.api.program.open(startArg);
|
|
619
|
-
api.log("Started program with address: ");
|
|
620
|
-
api.log(chalk.green(address.toString()));
|
|
621
|
-
}
|
|
622
|
-
},
|
|
623
|
-
})
|
|
624
|
-
.strict()
|
|
625
|
-
.demandCommand();
|
|
626
|
-
return yargs;
|
|
627
|
-
})
|
|
628
|
-
.command({
|
|
629
|
-
command: "install <package-spec>",
|
|
630
|
-
describe: "install and import a dependency",
|
|
631
|
-
builder: (yargs: any) => {
|
|
632
|
-
yargs.positional("package-spec", {
|
|
633
|
-
type: "string",
|
|
634
|
-
describe:
|
|
635
|
-
"Installed dependency will be loaded with js import(...)",
|
|
636
|
-
demandOption: true,
|
|
637
|
-
});
|
|
1038
|
+
const buffer = fs.readFileSync(packagePath);
|
|
1039
|
+
const base64 = toBase64(buffer);
|
|
1040
|
+
installCommand = {
|
|
1041
|
+
type: "tgz",
|
|
1042
|
+
name: await getPackageName(packageName),
|
|
1043
|
+
base64,
|
|
1044
|
+
};
|
|
1045
|
+
} else {
|
|
1046
|
+
installCommand = { type: "npm", name: packageName };
|
|
1047
|
+
}
|
|
638
1048
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
1049
|
+
for (const api of apis) {
|
|
1050
|
+
const newPrograms = await api.api.dependency.install(
|
|
1051
|
+
installCommand
|
|
1052
|
+
);
|
|
1053
|
+
api.log(
|
|
1054
|
+
`New programs available (${newPrograms.length}):`
|
|
1055
|
+
);
|
|
1056
|
+
newPrograms.forEach((p) => {
|
|
1057
|
+
api.log(chalk.green(p));
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
})
|
|
1062
|
+
.command({
|
|
1063
|
+
command: "restart",
|
|
1064
|
+
describe: "Restart the server",
|
|
1065
|
+
handler: async () => {
|
|
1066
|
+
for (const api of apis) {
|
|
1067
|
+
await api.api.restart();
|
|
1068
|
+
}
|
|
1069
|
+
},
|
|
1070
|
+
})
|
|
1071
|
+
.command({
|
|
1072
|
+
command: "stop",
|
|
1073
|
+
describe: "Stop the server",
|
|
1074
|
+
handler: async () => {
|
|
1075
|
+
for (const api of apis) {
|
|
1076
|
+
await api.api.stop();
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
})
|
|
1080
|
+
.help()
|
|
1081
|
+
.strict()
|
|
1082
|
+
.scriptName("")
|
|
1083
|
+
.demandCommand()
|
|
1084
|
+
.showHelpOnFail(true)
|
|
1085
|
+
.exitProcess(false);
|
|
661
1086
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
})
|
|
675
|
-
.command({
|
|
676
|
-
command: "restart",
|
|
677
|
-
describe: "Restart the server",
|
|
678
|
-
handler: async () => {
|
|
679
|
-
for (const api of apis) {
|
|
680
|
-
await api.api.restart();
|
|
681
|
-
}
|
|
682
|
-
},
|
|
683
|
-
})
|
|
684
|
-
.command({
|
|
685
|
-
command: "terminate",
|
|
686
|
-
describe: "Terminate the server",
|
|
687
|
-
handler: async () => {
|
|
688
|
-
for (const api of apis) {
|
|
689
|
-
await api.api.terminate();
|
|
690
|
-
}
|
|
691
|
-
},
|
|
692
|
-
})
|
|
693
|
-
.help()
|
|
694
|
-
.strict()
|
|
695
|
-
.scriptName("")
|
|
696
|
-
.demandCommand()
|
|
697
|
-
.showHelpOnFail(true)
|
|
698
|
-
.exitProcess(false);
|
|
699
|
-
const rl = readline.createInterface({
|
|
700
|
-
input: process.stdin,
|
|
701
|
-
output: process.stdout,
|
|
702
|
-
terminal: true,
|
|
703
|
-
historySize: 100,
|
|
704
|
-
});
|
|
705
|
-
console.log(chalk.green("Connected"));
|
|
706
|
-
console.log("Write 'help' to show commands.\n");
|
|
707
|
-
const first = true;
|
|
708
|
-
rl.prompt(false);
|
|
709
|
-
rl.on("line", async (cargs) => {
|
|
710
|
-
const cmds = capi();
|
|
711
|
-
try {
|
|
712
|
-
await cmds.parse(cargs);
|
|
713
|
-
} catch (error: any) {
|
|
714
|
-
/* console.log(chalk.red("Error parsing command: " + cargs))*/
|
|
715
|
-
}
|
|
716
|
-
rl.prompt(true);
|
|
717
|
-
});
|
|
1087
|
+
rl.on("line", async (cargs) => {
|
|
1088
|
+
const cmds = capi();
|
|
1089
|
+
try {
|
|
1090
|
+
await cmds.parse(cargs);
|
|
1091
|
+
} catch (error: any) {
|
|
1092
|
+
/* console.log(chalk.red("Error parsing command: " + cargs))*/
|
|
1093
|
+
}
|
|
1094
|
+
rl.prompt(true);
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
718
1097
|
},
|
|
719
1098
|
})
|
|
720
|
-
|
|
721
1099
|
.help()
|
|
722
1100
|
.strict()
|
|
723
1101
|
.demandCommand();
|