@bitsocial/bitsocial-cli 0.19.45 → 0.19.47
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 +57 -26
- package/dist/cli/commands/community/create.d.ts +1 -0
- package/dist/cli/commands/community/create.js +38 -2
- package/dist/cli/commands/community/edit.js +27 -22
- package/dist/cli/commands/community/start.d.ts +3 -0
- package/dist/cli/commands/community/start.js +25 -5
- package/dist/cli/commands/daemon.js +5 -5
- package/dist/cli/commands/logs.d.ts +5 -0
- package/dist/cli/commands/logs.js +96 -15
- package/dist/cli/commands/update/install.js +62 -26
- package/dist/update/fast-update.d.ts +6 -0
- package/dist/update/fast-update.js +182 -0
- package/dist/update/npm-registry.d.ts +1 -0
- package/dist/update/npm-registry.js +1 -1
- package/dist/util.d.ts +6 -1
- package/dist/util.js +44 -4
- package/oclif.manifest.json +52 -7
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -344,7 +344,7 @@ EXAMPLES
|
|
|
344
344
|
$ bitsocial challenge install ./my-local-challenge
|
|
345
345
|
```
|
|
346
346
|
|
|
347
|
-
_See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
347
|
+
_See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/challenge/install.ts)_
|
|
348
348
|
|
|
349
349
|
## `bitsocial challenge list`
|
|
350
350
|
|
|
@@ -367,7 +367,7 @@ EXAMPLES
|
|
|
367
367
|
$ bitsocial challenge list -q
|
|
368
368
|
```
|
|
369
369
|
|
|
370
|
-
_See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
370
|
+
_See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/challenge/list.ts)_
|
|
371
371
|
|
|
372
372
|
## `bitsocial challenge remove NAME`
|
|
373
373
|
|
|
@@ -392,7 +392,7 @@ EXAMPLES
|
|
|
392
392
|
$ bitsocial challenge remove @scope/my-challenge
|
|
393
393
|
```
|
|
394
394
|
|
|
395
|
-
_See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
395
|
+
_See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/challenge/remove.ts)_
|
|
396
396
|
|
|
397
397
|
## `bitsocial community create`
|
|
398
398
|
|
|
@@ -400,12 +400,13 @@ Create a community with specific properties. A newly created community will be s
|
|
|
400
400
|
|
|
401
401
|
```
|
|
402
402
|
USAGE
|
|
403
|
-
$ bitsocial community create --pkcRpcUrl <value> [--privateKeyPath <value>]
|
|
403
|
+
$ bitsocial community create --pkcRpcUrl <value> [--privateKeyPath <value>] [-f <value>]
|
|
404
404
|
|
|
405
405
|
FLAGS
|
|
406
|
-
--
|
|
407
|
-
|
|
408
|
-
|
|
406
|
+
-f, --jsonFile=<value> Path to a JSON/JSONC file containing create options (supports comments)
|
|
407
|
+
--pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] URL to PKC RPC
|
|
408
|
+
--privateKeyPath=<value> Private key (PEM) of the community signer that will be used to determine address (if
|
|
409
|
+
address is not a domain). If it's not provided then PKC will generate a private key
|
|
409
410
|
|
|
410
411
|
DESCRIPTION
|
|
411
412
|
Create a community with specific properties. A newly created community will be started after creation and be able to
|
|
@@ -415,9 +416,13 @@ EXAMPLES
|
|
|
415
416
|
Create a community with title 'Hello Plebs' and description 'Welcome'
|
|
416
417
|
|
|
417
418
|
$ bitsocial community create --title 'Hello Plebs' --description 'Welcome'
|
|
419
|
+
|
|
420
|
+
Create a community using options from a JSON/JSONC file
|
|
421
|
+
|
|
422
|
+
$ bitsocial community create --jsonFile ./create-options.json
|
|
418
423
|
```
|
|
419
424
|
|
|
420
|
-
_See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
425
|
+
_See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/create.ts)_
|
|
421
426
|
|
|
422
427
|
## `bitsocial community delete ADDRESSES`
|
|
423
428
|
|
|
@@ -442,7 +447,7 @@ EXAMPLES
|
|
|
442
447
|
$ bitsocial community delete 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
|
|
443
448
|
```
|
|
444
449
|
|
|
445
|
-
_See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
450
|
+
_See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/delete.ts)_
|
|
446
451
|
|
|
447
452
|
## `bitsocial community edit ADDRESS`
|
|
448
453
|
|
|
@@ -456,16 +461,28 @@ ARGUMENTS
|
|
|
456
461
|
ADDRESS Address of the community to edit. It could be the name domain, or a public key
|
|
457
462
|
|
|
458
463
|
FLAGS
|
|
459
|
-
-f, --jsonFile=<value> Path to a JSON file containing edit options
|
|
464
|
+
-f, --jsonFile=<value> Path to a JSON/JSONC file containing edit options (supports comments)
|
|
460
465
|
--pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] URL to PKC RPC
|
|
461
466
|
|
|
462
467
|
DESCRIPTION
|
|
463
468
|
Edit a community's properties. For a list of properties, visit https://github.com/pkcprotocol/pkc-js
|
|
464
469
|
|
|
470
|
+
Merge behavior with CLI flags:
|
|
471
|
+
- Objects are merged with the community's current state (new keys are added, existing keys are overwritten).
|
|
472
|
+
- Arrays are extended: new values are prepended to the existing array.
|
|
473
|
+
- Setting a value to null removes it (e.g. --roles['mod.bso'] null).
|
|
474
|
+
|
|
475
|
+
Merge behavior with --jsonFile:
|
|
476
|
+
- Objects are merged the same way as CLI flags.
|
|
477
|
+
- Arrays are replaced entirely (RFC 7396 JSON Merge Patch semantics).
|
|
478
|
+
- When both --jsonFile and CLI flags are provided, CLI flags take priority.
|
|
479
|
+
|
|
480
|
+
For modifying complex settings like challenges, consider using a web UI instead: https://bitsocial.net/apps
|
|
481
|
+
|
|
465
482
|
EXAMPLES
|
|
466
|
-
Change the
|
|
483
|
+
Change the name of the community
|
|
467
484
|
|
|
468
|
-
$ bitsocial community edit 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu --
|
|
485
|
+
$ bitsocial community edit 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu --name newName.bso
|
|
469
486
|
|
|
470
487
|
Add the author address 'esteban.bso' as an admin on the community
|
|
471
488
|
|
|
@@ -495,12 +512,12 @@ EXAMPLES
|
|
|
495
512
|
|
|
496
513
|
$ bitsocial community edit bitsocial.bso --settings.fetchThumbnailUrls=false
|
|
497
514
|
|
|
498
|
-
Edit a community using options from a JSON file
|
|
515
|
+
Edit a community using options from a JSON/JSONC file
|
|
499
516
|
|
|
500
517
|
$ bitsocial community edit bitsocial.bso --jsonFile ./edit-options.json
|
|
501
518
|
```
|
|
502
519
|
|
|
503
|
-
_See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
520
|
+
_See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/edit.ts)_
|
|
504
521
|
|
|
505
522
|
## `bitsocial community get [ADDRESS]`
|
|
506
523
|
|
|
@@ -531,7 +548,7 @@ EXAMPLES
|
|
|
531
548
|
$ bitsocial community get --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
|
|
532
549
|
```
|
|
533
550
|
|
|
534
|
-
_See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
551
|
+
_See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/get.ts)_
|
|
535
552
|
|
|
536
553
|
## `bitsocial community list`
|
|
537
554
|
|
|
@@ -554,7 +571,7 @@ EXAMPLES
|
|
|
554
571
|
$ bitsocial community list
|
|
555
572
|
```
|
|
556
573
|
|
|
557
|
-
_See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
574
|
+
_See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/list.ts)_
|
|
558
575
|
|
|
559
576
|
## `bitsocial community start ADDRESSES`
|
|
560
577
|
|
|
@@ -562,13 +579,14 @@ Start a community
|
|
|
562
579
|
|
|
563
580
|
```
|
|
564
581
|
USAGE
|
|
565
|
-
$ bitsocial community start ADDRESSES... --pkcRpcUrl <value>
|
|
582
|
+
$ bitsocial community start ADDRESSES... --pkcRpcUrl <value> [--concurrency <value>]
|
|
566
583
|
|
|
567
584
|
ARGUMENTS
|
|
568
585
|
ADDRESSES... Addresses of communities to start. Separated by space
|
|
569
586
|
|
|
570
587
|
FLAGS
|
|
571
|
-
--
|
|
588
|
+
--concurrency=<value> [default: 5] Number of communities to start in parallel
|
|
589
|
+
--pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] URL to PKC RPC
|
|
572
590
|
|
|
573
591
|
DESCRIPTION
|
|
574
592
|
Start a community
|
|
@@ -581,9 +599,13 @@ EXAMPLES
|
|
|
581
599
|
Start all communities in your data path
|
|
582
600
|
|
|
583
601
|
$ bitsocial community start $(bitsocial community list -q)
|
|
602
|
+
|
|
603
|
+
Start communities sequentially (no concurrency)
|
|
604
|
+
|
|
605
|
+
$ bitsocial community start $(bitsocial community list -q) --concurrency 1
|
|
584
606
|
```
|
|
585
607
|
|
|
586
|
-
_See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
608
|
+
_See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/start.ts)_
|
|
587
609
|
|
|
588
610
|
## `bitsocial community stop ADDRESSES`
|
|
589
611
|
|
|
@@ -608,7 +630,7 @@ EXAMPLES
|
|
|
608
630
|
$ bitsocial community stop Qmb99crTbSUfKXamXwZBe829Vf6w5w5TktPkb6WstC9RFW
|
|
609
631
|
```
|
|
610
632
|
|
|
611
|
-
_See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
633
|
+
_See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/community/stop.ts)_
|
|
612
634
|
|
|
613
635
|
## `bitsocial daemon`
|
|
614
636
|
|
|
@@ -649,7 +671,7 @@ EXAMPLES
|
|
|
649
671
|
$ bitsocial daemon --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY
|
|
650
672
|
```
|
|
651
673
|
|
|
652
|
-
_See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
674
|
+
_See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/daemon.ts)_
|
|
653
675
|
|
|
654
676
|
## `bitsocial help [COMMAND]`
|
|
655
677
|
|
|
@@ -677,7 +699,8 @@ View the latest BitSocial daemon log file. By default dumps the full log and exi
|
|
|
677
699
|
|
|
678
700
|
```
|
|
679
701
|
USAGE
|
|
680
|
-
$ bitsocial logs [-f] [-n <value>] [--since <value>] [--until <value>] [--logPath <value>]
|
|
702
|
+
$ bitsocial logs [-f] [-n <value>] [--since <value>] [--until <value>] [--logPath <value>] [--stdout |
|
|
703
|
+
--stderr]
|
|
681
704
|
|
|
682
705
|
FLAGS
|
|
683
706
|
-f, --follow Follow log output in real-time (like tail -f)
|
|
@@ -685,6 +708,8 @@ FLAGS
|
|
|
685
708
|
--logPath=<value> Specify the directory containing log files
|
|
686
709
|
--since=<value> Show logs since timestamp (ISO 8601, e.g. 2026-01-02T13:23:37Z) or relative time (e.g. 30s,
|
|
687
710
|
42m, 2h, 1d)
|
|
711
|
+
--stderr Show only stderr log entries (output of pkc-logger library)
|
|
712
|
+
--stdout Show only stdout log entries
|
|
688
713
|
--until=<value> Show logs before timestamp (ISO 8601, e.g. 2026-01-02T13:23:37Z) or relative time (e.g. 30s,
|
|
689
714
|
42m, 2h, 1d)
|
|
690
715
|
|
|
@@ -704,9 +729,15 @@ EXAMPLES
|
|
|
704
729
|
$ bitsocial logs --since 2026-01-02T13:23:37Z --until 2026-01-02T14:00:00Z
|
|
705
730
|
|
|
706
731
|
$ bitsocial logs --since 1h -f
|
|
732
|
+
|
|
733
|
+
$ bitsocial logs --stdout
|
|
734
|
+
|
|
735
|
+
$ bitsocial logs --stderr
|
|
736
|
+
|
|
737
|
+
$ bitsocial logs --stdout -f
|
|
707
738
|
```
|
|
708
739
|
|
|
709
|
-
_See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
740
|
+
_See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/logs.ts)_
|
|
710
741
|
|
|
711
742
|
## `bitsocial update check`
|
|
712
743
|
|
|
@@ -723,7 +754,7 @@ EXAMPLES
|
|
|
723
754
|
$ bitsocial update check
|
|
724
755
|
```
|
|
725
756
|
|
|
726
|
-
_See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
757
|
+
_See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/update/check.ts)_
|
|
727
758
|
|
|
728
759
|
## `bitsocial update install [VERSION]`
|
|
729
760
|
|
|
@@ -755,7 +786,7 @@ EXAMPLES
|
|
|
755
786
|
$ bitsocial update install --no-restart-daemons
|
|
756
787
|
```
|
|
757
788
|
|
|
758
|
-
_See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
789
|
+
_See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/update/install.ts)_
|
|
759
790
|
|
|
760
791
|
## `bitsocial update versions`
|
|
761
792
|
|
|
@@ -777,7 +808,7 @@ EXAMPLES
|
|
|
777
808
|
$ bitsocial update versions --limit 5
|
|
778
809
|
```
|
|
779
810
|
|
|
780
|
-
_See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.
|
|
811
|
+
_See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.47/src/cli/commands/update/versions.ts)_
|
|
781
812
|
<!-- commandsstop -->
|
|
782
813
|
|
|
783
814
|
## Contribution
|
|
@@ -7,6 +7,7 @@ export default class Create extends BaseCommand {
|
|
|
7
7
|
}[];
|
|
8
8
|
static flags: {
|
|
9
9
|
privateKeyPath: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
jsonFile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
12
13
|
}
|
|
@@ -3,7 +3,7 @@ import { Flags } from "@oclif/core";
|
|
|
3
3
|
import DataObjectParser from "dataobject-parser";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import { BaseCommand } from "../../base-command.js";
|
|
6
|
-
import { PKCLogger } from "../../../util.js";
|
|
6
|
+
import { PKCLogger, mergeDeep, parseJsoncFile } from "../../../util.js";
|
|
7
7
|
import * as remeda from "remeda";
|
|
8
8
|
export default class Create extends BaseCommand {
|
|
9
9
|
static description = "Create a community with specific properties. A newly created community will be started after creation and be able to receive publications. For a list of properties, visit https://github.com/pkcprotocol/pkc-js";
|
|
@@ -11,12 +11,21 @@ export default class Create extends BaseCommand {
|
|
|
11
11
|
{
|
|
12
12
|
description: "Create a community with title 'Hello Plebs' and description 'Welcome'",
|
|
13
13
|
command: "<%= config.bin %> <%= command.id %> --title 'Hello Plebs' --description 'Welcome'"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
description: "Create a community using options from a JSON/JSONC file",
|
|
17
|
+
command: "<%= config.bin %> <%= command.id %> --jsonFile ./create-options.json"
|
|
14
18
|
}
|
|
15
19
|
];
|
|
16
20
|
static flags = {
|
|
17
21
|
privateKeyPath: Flags.file({
|
|
18
22
|
exists: true,
|
|
19
23
|
description: "Private key (PEM) of the community signer that will be used to determine address (if address is not a domain). If it's not provided then PKC will generate a private key"
|
|
24
|
+
}),
|
|
25
|
+
jsonFile: Flags.file({
|
|
26
|
+
char: "f",
|
|
27
|
+
exists: true,
|
|
28
|
+
description: "Path to a JSON/JSONC file containing create options (supports comments)"
|
|
20
29
|
})
|
|
21
30
|
};
|
|
22
31
|
async run() {
|
|
@@ -24,7 +33,34 @@ export default class Create extends BaseCommand {
|
|
|
24
33
|
const log = PKCLogger("bitsocial-cli:commands:community:create");
|
|
25
34
|
log(`flags: `, flags);
|
|
26
35
|
const pkc = await this._connectToPkcRpc(flags.pkcRpcUrl.toString());
|
|
27
|
-
const
|
|
36
|
+
const cliCreateOptions = DataObjectParser.transpose(remeda.omit(flags, ["pkcRpcUrl", "privateKeyPath", "jsonFile"]))["_data"];
|
|
37
|
+
// Parse JSONC file if provided
|
|
38
|
+
let jsonFileOptions = {};
|
|
39
|
+
if (flags.jsonFile) {
|
|
40
|
+
try {
|
|
41
|
+
jsonFileOptions = await parseJsoncFile(flags.jsonFile);
|
|
42
|
+
log("JSONC file options parsed:", jsonFileOptions);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
if (e instanceof Error) {
|
|
46
|
+
await pkc.destroy();
|
|
47
|
+
this.error(e.message);
|
|
48
|
+
}
|
|
49
|
+
throw e;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Merge: JSON file options first, then CLI flags override
|
|
53
|
+
let createOptions;
|
|
54
|
+
if (flags.jsonFile && Object.keys(cliCreateOptions).length > 0) {
|
|
55
|
+
createOptions = mergeDeep(jsonFileOptions, cliCreateOptions);
|
|
56
|
+
}
|
|
57
|
+
else if (flags.jsonFile) {
|
|
58
|
+
createOptions = jsonFileOptions;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
createOptions = cliCreateOptions;
|
|
62
|
+
}
|
|
63
|
+
log("Final create options:", createOptions);
|
|
28
64
|
if (flags.privateKeyPath)
|
|
29
65
|
try {
|
|
30
66
|
//@ts-expect-error
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
//@ts-expect-error
|
|
2
2
|
import DataObjectParser from "dataobject-parser";
|
|
3
3
|
import { Args, Flags } from "@oclif/core";
|
|
4
|
-
import fs from "fs";
|
|
5
4
|
import { BaseCommand } from "../../base-command.js";
|
|
6
|
-
import { PKCLogger, mergeDeep } from "../../../util.js";
|
|
5
|
+
import { PKCLogger, mergeDeep, parseJsoncFile, replaceNullWithUndefined } from "../../../util.js";
|
|
7
6
|
import * as remeda from "remeda";
|
|
8
7
|
export default class Edit extends BaseCommand {
|
|
9
|
-
static description =
|
|
8
|
+
static description = `Edit a community's properties. For a list of properties, visit https://github.com/pkcprotocol/pkc-js
|
|
9
|
+
|
|
10
|
+
Merge behavior with CLI flags:
|
|
11
|
+
- Objects are merged with the community's current state (new keys are added, existing keys are overwritten).
|
|
12
|
+
- Arrays are extended: new values are prepended to the existing array.
|
|
13
|
+
- Setting a value to null removes it (e.g. --roles['mod.bso'] null).
|
|
14
|
+
|
|
15
|
+
Merge behavior with --jsonFile:
|
|
16
|
+
- Objects are merged the same way as CLI flags.
|
|
17
|
+
- Arrays are replaced entirely (RFC 7396 JSON Merge Patch semantics).
|
|
18
|
+
- When both --jsonFile and CLI flags are provided, CLI flags take priority.
|
|
19
|
+
|
|
20
|
+
For modifying complex settings like challenges, consider using a web UI instead: https://bitsocial.net/apps`;
|
|
10
21
|
static args = {
|
|
11
22
|
address: Args.string({
|
|
12
23
|
name: "address",
|
|
@@ -18,16 +29,13 @@ export default class Edit extends BaseCommand {
|
|
|
18
29
|
jsonFile: Flags.file({
|
|
19
30
|
char: "f",
|
|
20
31
|
exists: true,
|
|
21
|
-
description: "Path to a JSON file containing edit options"
|
|
32
|
+
description: "Path to a JSON/JSONC file containing edit options (supports comments)"
|
|
22
33
|
})
|
|
23
34
|
};
|
|
24
35
|
static examples = [
|
|
25
|
-
// TODO update this to change the name instead
|
|
26
|
-
// Also are we testing modifying name properly?
|
|
27
|
-
// in theory user should not modify address, they should modify name
|
|
28
36
|
{
|
|
29
|
-
description: "Change the
|
|
30
|
-
command: "bitsocial community edit 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu --
|
|
37
|
+
description: "Change the name of the community",
|
|
38
|
+
command: "bitsocial community edit 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu --name newName.bso"
|
|
31
39
|
},
|
|
32
40
|
{
|
|
33
41
|
description: "Add the author address 'esteban.bso' as an admin on the community",
|
|
@@ -54,7 +62,7 @@ export default class Edit extends BaseCommand {
|
|
|
54
62
|
command: "bitsocial community edit bitsocial.bso --settings.fetchThumbnailUrls=false"
|
|
55
63
|
},
|
|
56
64
|
{
|
|
57
|
-
description: "Edit a community using options from a JSON file",
|
|
65
|
+
description: "Edit a community using options from a JSON/JSONC file",
|
|
58
66
|
command: "bitsocial community edit bitsocial.bso --jsonFile ./edit-options.json"
|
|
59
67
|
}
|
|
60
68
|
];
|
|
@@ -65,21 +73,16 @@ export default class Edit extends BaseCommand {
|
|
|
65
73
|
const pkc = await this._connectToPkcRpc(flags.pkcRpcUrl.toString());
|
|
66
74
|
const cliEditOptions = DataObjectParser.transpose(remeda.omit(flags, ["pkcRpcUrl", "jsonFile"]))["_data"];
|
|
67
75
|
log("CLI edit options parsed:", cliEditOptions);
|
|
68
|
-
// Parse
|
|
76
|
+
// Parse JSONC file if provided
|
|
69
77
|
let jsonFileOptions = {};
|
|
70
78
|
if (flags.jsonFile) {
|
|
71
79
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
75
|
-
this.error("JSON file must contain a JSON object (not an array, null, string, or number)");
|
|
76
|
-
}
|
|
77
|
-
jsonFileOptions = parsed;
|
|
78
|
-
log("JSON file options parsed:", jsonFileOptions);
|
|
80
|
+
jsonFileOptions = await parseJsoncFile(flags.jsonFile);
|
|
81
|
+
log("JSONC file options parsed:", jsonFileOptions);
|
|
79
82
|
}
|
|
80
83
|
catch (e) {
|
|
81
|
-
if (e instanceof
|
|
82
|
-
this.error(
|
|
84
|
+
if (e instanceof Error) {
|
|
85
|
+
this.error(e.message);
|
|
83
86
|
}
|
|
84
87
|
throw e;
|
|
85
88
|
}
|
|
@@ -102,9 +105,11 @@ export default class Edit extends BaseCommand {
|
|
|
102
105
|
try {
|
|
103
106
|
const community = await pkc.createCommunity({ address: args.address });
|
|
104
107
|
const mergedState = remeda.pick(community, remeda.keys.strict(editOptions));
|
|
105
|
-
|
|
108
|
+
// JSON file edits use RFC 7396 JSON Merge Patch semantics (arrays replace, objects merge).
|
|
109
|
+
// CLI flag edits use concat semantics (arrays extend with new values).
|
|
110
|
+
const finalMergedState = mergeDeep(mergedState, editOptions, flags.jsonFile ? "replace" : "concat");
|
|
106
111
|
log("Internal community state after merge:", finalMergedState);
|
|
107
|
-
await community.edit(finalMergedState);
|
|
112
|
+
await community.edit(replaceNullWithUndefined(finalMergedState));
|
|
108
113
|
this.log(community.address);
|
|
109
114
|
}
|
|
110
115
|
catch (e) {
|
|
@@ -5,6 +5,9 @@ export default class Start extends BaseCommand {
|
|
|
5
5
|
static args: {
|
|
6
6
|
addresses: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
7
|
};
|
|
8
|
+
static flags: {
|
|
9
|
+
concurrency: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
8
11
|
static examples: (string | {
|
|
9
12
|
description: string;
|
|
10
13
|
command: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PKCLogger } from "../../../util.js";
|
|
2
2
|
import { BaseCommand } from "../../base-command.js";
|
|
3
|
-
import { Args } from "@oclif/core";
|
|
3
|
+
import { Args, Flags } from "@oclif/core";
|
|
4
|
+
import pLimit from "p-limit";
|
|
4
5
|
export default class Start extends BaseCommand {
|
|
5
6
|
static description = "Start a community";
|
|
6
7
|
static strict = false; // To allow for variable length arguments
|
|
@@ -11,12 +12,23 @@ export default class Start extends BaseCommand {
|
|
|
11
12
|
description: "Addresses of communities to start. Separated by space"
|
|
12
13
|
})
|
|
13
14
|
};
|
|
15
|
+
static flags = {
|
|
16
|
+
concurrency: Flags.integer({
|
|
17
|
+
description: "Number of communities to start in parallel",
|
|
18
|
+
default: 5,
|
|
19
|
+
min: 0
|
|
20
|
+
})
|
|
21
|
+
};
|
|
14
22
|
static examples = [
|
|
15
23
|
"bitsocial community start plebbit.bso",
|
|
16
24
|
"bitsocial community start 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu",
|
|
17
25
|
{
|
|
18
26
|
description: "Start all communities in your data path",
|
|
19
27
|
command: "bitsocial community start $(bitsocial community list -q)"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
description: "Start communities sequentially (no concurrency)",
|
|
31
|
+
command: "bitsocial community start $(bitsocial community list -q) --concurrency 1"
|
|
20
32
|
}
|
|
21
33
|
];
|
|
22
34
|
async run() {
|
|
@@ -25,8 +37,11 @@ export default class Start extends BaseCommand {
|
|
|
25
37
|
const log = PKCLogger("bitsocial-cli:commands:community:start");
|
|
26
38
|
log(`addresses: `, addresses);
|
|
27
39
|
log(`flags: `, flags);
|
|
40
|
+
const concurrency = Math.max(flags.concurrency, 1);
|
|
41
|
+
const limit = pLimit(concurrency);
|
|
28
42
|
const pkc = await this._connectToPkcRpc(flags.pkcRpcUrl.toString());
|
|
29
|
-
|
|
43
|
+
const errors = [];
|
|
44
|
+
const tasks = addresses.map((address) => limit(async () => {
|
|
30
45
|
try {
|
|
31
46
|
const community = await pkc.createCommunity({ address });
|
|
32
47
|
await community.start();
|
|
@@ -36,11 +51,16 @@ export default class Start extends BaseCommand {
|
|
|
36
51
|
const error = e instanceof Error ? e : new Error(typeof e === "string" ? e : JSON.stringify(e));
|
|
37
52
|
//@ts-expect-error
|
|
38
53
|
error.details = { ...error.details, address };
|
|
54
|
+
errors.push({ address, error });
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
await Promise.all(tasks);
|
|
58
|
+
await pkc.destroy();
|
|
59
|
+
if (errors.length > 0) {
|
|
60
|
+
for (const { error } of errors) {
|
|
39
61
|
console.error(error);
|
|
40
|
-
await pkc.destroy();
|
|
41
|
-
this.exit(1);
|
|
42
62
|
}
|
|
63
|
+
this.exit(1);
|
|
43
64
|
}
|
|
44
|
-
await pkc.destroy();
|
|
45
65
|
}
|
|
46
66
|
}
|
|
@@ -96,12 +96,12 @@ export default class Daemon extends Command {
|
|
|
96
96
|
const stdoutWrite = process.stdout.write.bind(process.stdout);
|
|
97
97
|
const stderrWrite = process.stderr.write.bind(process.stderr);
|
|
98
98
|
const isLogFileOverLimit = () => logFile.bytesWritten > 20000000; // 20mb
|
|
99
|
-
const writeTimestampedLine = (text) => {
|
|
99
|
+
const writeTimestampedLine = (text, stream) => {
|
|
100
100
|
if (isLogFileOverLimit())
|
|
101
101
|
return;
|
|
102
102
|
if (!text || text.trim().length === 0)
|
|
103
103
|
return;
|
|
104
|
-
const timestamp = `[${new Date().toISOString()}] `;
|
|
104
|
+
const timestamp = `[${new Date().toISOString()}] [${stream}] `;
|
|
105
105
|
const lines = text.split("\n");
|
|
106
106
|
const timestamped = lines.map((line, i) => (i === 0 ? timestamp + line : line)).join("\n");
|
|
107
107
|
logFile.write(timestamped);
|
|
@@ -115,13 +115,13 @@ export default class Daemon extends Command {
|
|
|
115
115
|
debugModule.inspectOpts.colors = true;
|
|
116
116
|
debugModule.inspectOpts.hideDate = true;
|
|
117
117
|
debugModule.log = (...args) => {
|
|
118
|
-
writeTimestampedLine(formatWithOptions({ depth: Logger.inspectOpts?.depth || 10, colors: true }, ...args).trimStart() + EOL);
|
|
118
|
+
writeTimestampedLine(formatWithOptions({ depth: Logger.inspectOpts?.depth || 10, colors: true }, ...args).trimStart() + EOL, "stderr");
|
|
119
119
|
};
|
|
120
120
|
const asString = (data) => (typeof data === "string" ? data : Buffer.from(data).toString());
|
|
121
121
|
process.stdout.write = (...args) => {
|
|
122
122
|
//@ts-expect-error
|
|
123
123
|
const res = stdoutWrite(...args);
|
|
124
|
-
writeTimestampedLine(asString(args[0]));
|
|
124
|
+
writeTimestampedLine(asString(args[0]), "stdout");
|
|
125
125
|
return res;
|
|
126
126
|
};
|
|
127
127
|
process.stderr.write = (...args) => {
|
|
@@ -129,7 +129,7 @@ export default class Daemon extends Command {
|
|
|
129
129
|
// Debug output goes to stderr; we want it in logs only.
|
|
130
130
|
// Real errors are caught by uncaughtException/unhandledRejection handlers
|
|
131
131
|
// which use console.error -> stderr.write -> this override -> log file.
|
|
132
|
-
writeTimestampedLine(asString(args[0]).trimStart());
|
|
132
|
+
writeTimestampedLine(asString(args[0]).trimStart(), "stderr");
|
|
133
133
|
return true;
|
|
134
134
|
};
|
|
135
135
|
const log = Logger("bitsocial-cli:daemon");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from "@oclif/core";
|
|
2
2
|
interface LogEntry {
|
|
3
3
|
timestamp: Date | null;
|
|
4
|
+
stream: "stdout" | "stderr" | null;
|
|
4
5
|
lines: string[];
|
|
5
6
|
}
|
|
6
7
|
export default class Logs extends Command {
|
|
@@ -11,13 +12,17 @@ export default class Logs extends Command {
|
|
|
11
12
|
since: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
until: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
logPath: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
stdout: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
stderr: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
17
|
};
|
|
15
18
|
static examples: string[];
|
|
16
19
|
private _findLatestLogFile;
|
|
17
20
|
_parseTimestamp(value: string): Date;
|
|
18
21
|
_extractTimestamp(line: string): Date | null;
|
|
22
|
+
_extractStream(line: string): "stdout" | "stderr" | null;
|
|
19
23
|
_parseLogEntries(content: string): LogEntry[];
|
|
20
24
|
_filterEntries(entries: LogEntry[], since?: Date, until?: Date): LogEntry[];
|
|
25
|
+
_filterByStream(entries: LogEntry[], stream: "stdout" | "stderr"): LogEntry[];
|
|
21
26
|
_tailEntries(entries: LogEntry[], tailValue: string): LogEntry[];
|
|
22
27
|
run(): Promise<void>;
|
|
23
28
|
}
|