@super-protocol/sp-cli 0.0.2-alpha.1 → 0.0.2-beta.1

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 CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @super-protocol/sp-cli
21
21
  $ sp COMMAND
22
22
  running command...
23
23
  $ sp (--version)
24
- @super-protocol/sp-cli/0.0.2-alpha.1 linux-x64 node-v22.21.1
24
+ @super-protocol/sp-cli/0.0.2-beta.1 linux-x64 node-v22.21.1
25
25
  $ sp --help [COMMAND]
26
26
  USAGE
27
27
  $ sp COMMAND
@@ -52,6 +52,10 @@ USAGE
52
52
  * [`sp plugins uninstall [PLUGIN]`](#sp-plugins-uninstall-plugin)
53
53
  * [`sp plugins unlink [PLUGIN]`](#sp-plugins-unlink-plugin)
54
54
  * [`sp plugins update`](#sp-plugins-update)
55
+ * [`sp storage base`](#sp-storage-base)
56
+ * [`sp storage create`](#sp-storage-create)
57
+ * [`sp storage select`](#sp-storage-select)
58
+ * [`sp storage update`](#sp-storage-update)
55
59
 
56
60
  ## `sp auth login`
57
61
 
@@ -73,7 +77,7 @@ EXAMPLES
73
77
  $ sp auth login
74
78
  ```
75
79
 
76
- _See code: [src/commands/auth/login.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/auth/login.ts)_
80
+ _See code: [src/commands/auth/login.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/auth/login.ts)_
77
81
 
78
82
  ## `sp auth me`
79
83
 
@@ -87,7 +91,7 @@ GLOBAL FLAGS
87
91
  --url=<value> Specify provider base URL.
88
92
  ```
89
93
 
90
- _See code: [src/commands/auth/me.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/auth/me.ts)_
94
+ _See code: [src/commands/auth/me.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/auth/me.ts)_
91
95
 
92
96
  ## `sp base`
93
97
 
@@ -101,7 +105,7 @@ GLOBAL FLAGS
101
105
  --url=<value> Specify provider base URL.
102
106
  ```
103
107
 
104
- _See code: [src/commands/base.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/base.ts)_
108
+ _See code: [src/commands/base.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/base.ts)_
105
109
 
106
110
  ## `sp config`
107
111
 
@@ -133,7 +137,7 @@ EXAMPLES
133
137
  $ sp config delete - Delete a configuration
134
138
  ```
135
139
 
136
- _See code: [src/commands/config/index.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/index.ts)_
140
+ _See code: [src/commands/config/index.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/index.ts)_
137
141
 
138
142
  ## `sp config add [FILE]`
139
143
 
@@ -174,7 +178,7 @@ EXAMPLES
174
178
  }
175
179
  ```
176
180
 
177
- _See code: [src/commands/config/add.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/add.ts)_
181
+ _See code: [src/commands/config/add.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/add.ts)_
178
182
 
179
183
  ## `sp config base`
180
184
 
@@ -188,7 +192,7 @@ GLOBAL FLAGS
188
192
  --url=<value> Specify provider base URL.
189
193
  ```
190
194
 
191
- _See code: [src/commands/config/base.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/base.ts)_
195
+ _See code: [src/commands/config/base.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/base.ts)_
192
196
 
193
197
  ## `sp config create`
194
198
 
@@ -216,7 +220,7 @@ EXAMPLES
216
220
  $ sp config create --name "Production" --url "https://api.dp.superprotocol.com"
217
221
  ```
218
222
 
219
- _See code: [src/commands/config/create.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/create.ts)_
223
+ _See code: [src/commands/config/create.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/create.ts)_
220
224
 
221
225
  ## `sp config delete`
222
226
 
@@ -246,7 +250,7 @@ EXAMPLES
246
250
  $ sp config delete --name "My Config" --force
247
251
  ```
248
252
 
249
- _See code: [src/commands/config/delete.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/delete.ts)_
253
+ _See code: [src/commands/config/delete.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/delete.ts)_
250
254
 
251
255
  ## `sp config list`
252
256
 
@@ -268,7 +272,7 @@ EXAMPLES
268
272
  $ sp config list
269
273
  ```
270
274
 
271
- _See code: [src/commands/config/list.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/list.ts)_
275
+ _See code: [src/commands/config/list.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/list.ts)_
272
276
 
273
277
  ## `sp config show`
274
278
 
@@ -290,7 +294,7 @@ EXAMPLES
290
294
  $ sp config show
291
295
  ```
292
296
 
293
- _See code: [src/commands/config/show.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/show.ts)_
297
+ _See code: [src/commands/config/show.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/show.ts)_
294
298
 
295
299
  ## `sp config use`
296
300
 
@@ -312,7 +316,7 @@ EXAMPLES
312
316
  $ sp config use
313
317
  ```
314
318
 
315
- _See code: [src/commands/config/use.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-alpha.1/src/commands/config/use.ts)_
319
+ _See code: [src/commands/config/use.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/config/use.ts)_
316
320
 
317
321
  ## `sp help [COMMAND]`
318
322
 
@@ -623,4 +627,103 @@ DESCRIPTION
623
627
  ```
624
628
 
625
629
  _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.50/src/commands/plugins/update.ts)_
630
+
631
+ ## `sp storage base`
632
+
633
+ ```
634
+ USAGE
635
+ $ sp storage base [--json] [--config <value>] [--url <value>]
636
+
637
+ GLOBAL FLAGS
638
+ --config=<value> Specify config file.
639
+ --json Format output as json.
640
+ --url=<value> Specify provider base URL.
641
+ ```
642
+
643
+ _See code: [src/commands/storage/base.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/storage/base.ts)_
644
+
645
+ ## `sp storage create`
646
+
647
+ Create a new storage entry from file or interactive prompts.
648
+
649
+ ```
650
+ USAGE
651
+ $ sp storage create [--json] [--config <value>] [--url <value>] [-f <value>] [--notDefault]
652
+
653
+ FLAGS
654
+ -f, --fromFile=<value> Path to a JSON file that contains AddStorageDto payload.
655
+ --notDefault Skip setting the created storage as default.
656
+
657
+ GLOBAL FLAGS
658
+ --config=<value> Specify config file.
659
+ --json Format output as json.
660
+ --url=<value> Specify provider base URL.
661
+
662
+ DESCRIPTION
663
+ Create a new storage entry from file or interactive prompts.
664
+
665
+ EXAMPLES
666
+ $ sp storage create
667
+
668
+ $ sp storage create --fromFile ./storage.json
669
+
670
+ $ sp storage create --not-default
671
+ ```
672
+
673
+ _See code: [src/commands/storage/create.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/storage/create.ts)_
674
+
675
+ ## `sp storage select`
676
+
677
+ Select a storage that will be used by subsequent commands.
678
+
679
+ ```
680
+ USAGE
681
+ $ sp storage select [--json] [--config <value>] [--url <value>] [-i <value>]
682
+
683
+ FLAGS
684
+ -i, --id=<value> Storage ID to select
685
+
686
+ GLOBAL FLAGS
687
+ --config=<value> Specify config file.
688
+ --json Format output as json.
689
+ --url=<value> Specify provider base URL.
690
+
691
+ DESCRIPTION
692
+ Select a storage that will be used by subsequent commands.
693
+
694
+ EXAMPLES
695
+ $ sp storage select
696
+
697
+ $ sp storage select --id=2de3e3a4-0000-1111-2222-333344445555
698
+ ```
699
+
700
+ _See code: [src/commands/storage/select.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/storage/select.ts)_
701
+
702
+ ## `sp storage update`
703
+
704
+ Update the configuration of an existing storage.
705
+
706
+ ```
707
+ USAGE
708
+ $ sp storage update [--json] [--config <value>] [--url <value>] [-f <value>] [-i <value>]
709
+
710
+ FLAGS
711
+ -f, --fromFile=<value> Path to a JSON file that contains UpdateStorageDto payload.
712
+ -i, --id=<value> Storage ID to update
713
+
714
+ GLOBAL FLAGS
715
+ --config=<value> Specify config file.
716
+ --json Format output as json.
717
+ --url=<value> Specify provider base URL.
718
+
719
+ DESCRIPTION
720
+ Update the configuration of an existing storage.
721
+
722
+ EXAMPLES
723
+ $ sp storage update --id=2de3e3a4-0000-1111-2222-333344445555 --fromFile ./storage-update.json
724
+
725
+ $ sp storage update --id=2de3e3a4-0000-1111-2222-333344445555
726
+ ```
727
+
728
+ _See code: [src/commands/storage/update.ts](https://github.com/Super-Protocol/sp-cli/blob/v0.0.2-beta.1/src/commands/storage/update.ts)_
626
729
  <!-- commandsstop -->
@@ -2,6 +2,7 @@ import { BaseCommand } from '../base.js';
2
2
  export default class SpLogin extends BaseCommand<typeof SpLogin> {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ checkStorage(): Promise<void>;
5
6
  getTokens(nonce: string): Promise<void>;
6
7
  getUserNonce(address: string): Promise<{
7
8
  error: {
@@ -1,4 +1,5 @@
1
1
  import { ux } from '@oclif/core';
2
+ import { StorageService } from '../../services/storage.service.js';
2
3
  import { BaseCommand } from '../base.js';
3
4
  export default class SpLogin extends BaseCommand {
4
5
  static description = 'Authorization';
@@ -6,6 +7,17 @@ export default class SpLogin extends BaseCommand {
6
7
  `<%= config.bin %> <%= command.id %>
7
8
  `,
8
9
  ];
10
+ async checkStorage() {
11
+ await this.container.initProviderClient({ enableAuth: true, enableCookies: true, rebuild: true }).build();
12
+ const { configManager, providerClient } = this.container;
13
+ const storageService = new StorageService(configManager, providerClient, this.logger);
14
+ if (!await storageService.hasStorage()) {
15
+ this.logger.info('Requesting default storage');
16
+ const storage = await storageService.initStorage();
17
+ this.logger.info({ storage }, 'Requested new storage');
18
+ await storageService.saveStorage(storage.id);
19
+ }
20
+ }
9
21
  async getTokens(nonce) {
10
22
  const { accountManager, configManager, providerClient } = this.container;
11
23
  const signature = await accountManager.createSign(nonce);
@@ -94,5 +106,12 @@ export default class SpLogin extends BaseCommand {
94
106
  else {
95
107
  ux.error('Unable to retrieve authentication nonce. Please try again later or contact support if the issue persists.');
96
108
  }
109
+ try {
110
+ await this.checkStorage();
111
+ }
112
+ catch (error) {
113
+ this.logger.error({ err: error }, 'Storage initialization failed');
114
+ this.warn('Storage initialization failed. You can set up storage later using "sp storage create" or "sp storage select".');
115
+ }
97
116
  }
98
117
  }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ import { BaseCommand } from '../../commands/base.js';
3
+ import { StorageService } from '../../services/storage.service.js';
4
+ export declare abstract class BaseStorageCommand<T extends typeof Command> extends BaseCommand<T> {
5
+ protected currentDir: string;
6
+ protected storageService: StorageService;
7
+ init(): Promise<void>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../commands/base.js';
2
+ import { StorageService } from '../../services/storage.service.js';
3
+ export class BaseStorageCommand extends BaseCommand {
4
+ currentDir = process.cwd();
5
+ storageService;
6
+ async init() {
7
+ await super.init();
8
+ await this.container.initConfigManager().initProviderClient().build();
9
+ const { configManager, providerClient } = this.container;
10
+ this.storageService = new StorageService(configManager, providerClient, this.logger);
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ import { BaseStorageCommand } from './base.js';
2
+ export default class StorageCreate extends BaseStorageCommand<typeof StorageCreate> {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ fromFile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ notDefault: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ private loadStorageFromFile;
11
+ private promptS3Credentials;
12
+ private promptStoragePayload;
13
+ private promptStorJCredentials;
14
+ private validateStoragePayload;
15
+ }
@@ -0,0 +1,169 @@
1
+ import { input, password, select } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { StorageType } from '@super-protocol/provider-client';
4
+ import fs from 'node:fs/promises';
5
+ import path from 'node:path';
6
+ import { BaseStorageCommand } from './base.js';
7
+ export default class StorageCreate extends BaseStorageCommand {
8
+ static description = 'Create a new storage entry from file or interactive prompts.';
9
+ static examples = [
10
+ '<%= config.bin %> storage create',
11
+ '<%= config.bin %> storage create --fromFile ./storage.json',
12
+ '<%= config.bin %> storage create --not-default',
13
+ ];
14
+ static flags = {
15
+ fromFile: Flags.string({
16
+ aliases: ['fromFile'],
17
+ char: 'f',
18
+ description: 'Path to a JSON file that contains AddStorageDto payload.',
19
+ }),
20
+ notDefault: Flags.boolean({
21
+ description: 'Skip setting the created storage as default.',
22
+ }),
23
+ };
24
+ async run() {
25
+ const { flags } = await this.parse(StorageCreate);
26
+ const payload = flags.fromFile
27
+ ? await this.loadStorageFromFile(flags.fromFile)
28
+ : await this.promptStoragePayload();
29
+ try {
30
+ const storage = await this.storageService.createStorage(payload);
31
+ this.log(`Storage created: ${storage.id}`);
32
+ if (!flags.notDefault) {
33
+ await this.storageService.saveStorage(storage.id);
34
+ this.log('Storage set as default');
35
+ }
36
+ }
37
+ catch (error) {
38
+ this.error(error instanceof Error ? error.message : String(error));
39
+ }
40
+ }
41
+ async loadStorageFromFile(filePath) {
42
+ const absolutePath = path.isAbsolute(filePath)
43
+ ? filePath
44
+ : path.join(this.currentDir, filePath);
45
+ try {
46
+ const fileContent = await fs.readFile(absolutePath, 'utf8');
47
+ const parsed = JSON.parse(fileContent);
48
+ this.validateStoragePayload(parsed);
49
+ return parsed;
50
+ }
51
+ catch (error) {
52
+ this.error(`Failed to load storage definition: ${error instanceof Error ? error.message : String(error)}`);
53
+ }
54
+ }
55
+ async promptS3Credentials() {
56
+ const region = await input({
57
+ message: 'AWS region',
58
+ validate(value) {
59
+ return value ? true : 'Region is required';
60
+ },
61
+ }).then(value => value.trim());
62
+ const readAccessKeyId = await input({
63
+ message: 'Read access key ID',
64
+ validate(value) {
65
+ return value ? true : 'Read access key ID is required';
66
+ },
67
+ }).then(value => value.trim());
68
+ const readSecretAccessKey = await password({
69
+ message: 'Read secret access key',
70
+ validate(value) {
71
+ return value ? true : 'Read secret access key is required';
72
+ },
73
+ }).then(value => value.trim());
74
+ const writeAccessKeyId = await input({
75
+ message: 'Write access key ID',
76
+ validate(value) {
77
+ return value ? true : 'Write access key ID is required';
78
+ },
79
+ }).then(value => value.trim());
80
+ const writeSecretAccessKey = await password({
81
+ message: 'Write secret access key',
82
+ validate(value) {
83
+ return value ? true : 'Write secret access key is required';
84
+ },
85
+ }).then(value => value.trim());
86
+ return {
87
+ readAccessKeyId,
88
+ readSecretAccessKey,
89
+ region,
90
+ writeAccessKeyId,
91
+ writeSecretAccessKey,
92
+ };
93
+ }
94
+ async promptStoragePayload() {
95
+ const storageType = await select({
96
+ choices: [
97
+ { name: 'Amazon S3', value: StorageType.S3 },
98
+ { name: 'StorJ', value: StorageType.StorJ },
99
+ ],
100
+ message: 'Select storage type',
101
+ });
102
+ const bucket = await input({
103
+ message: 'Bucket name',
104
+ validate(value) {
105
+ return value ? true : 'Bucket is required';
106
+ },
107
+ }).then(value => value.trim());
108
+ const prefix = await input({
109
+ default: '/',
110
+ message: 'Prefix',
111
+ validate(value) {
112
+ return value ? true : 'Prefix is required';
113
+ },
114
+ }).then(value => value.trim());
115
+ const storage = {
116
+ bucket,
117
+ prefix,
118
+ storageType,
119
+ };
120
+ if (storageType === StorageType.S3) {
121
+ storage.s3Credentials = await this.promptS3Credentials();
122
+ }
123
+ if (storageType === StorageType.StorJ) {
124
+ storage.storjCredentials = await this.promptStorJCredentials();
125
+ }
126
+ return storage;
127
+ }
128
+ async promptStorJCredentials() {
129
+ const readAccessToken = await password({
130
+ message: 'Read access token',
131
+ validate(value) {
132
+ return value ? true : 'Read access token is required';
133
+ },
134
+ }).then(value => value.trim());
135
+ const writeAccessToken = await password({
136
+ message: 'Write access token',
137
+ validate(value) {
138
+ return value ? true : 'Write access token is required';
139
+ },
140
+ }).then(value => value.trim());
141
+ return {
142
+ readAccessToken,
143
+ writeAccessToken,
144
+ };
145
+ }
146
+ validateStoragePayload(payload) {
147
+ if (!payload || typeof payload !== 'object') {
148
+ this.error('Storage definition must be an object');
149
+ }
150
+ if (!payload.bucket) {
151
+ this.error('Storage definition missing "bucket"');
152
+ }
153
+ if (!payload.prefix) {
154
+ this.error('Storage definition missing "prefix"');
155
+ }
156
+ if (!payload.storageType) {
157
+ this.error('Storage definition missing "storageType"');
158
+ }
159
+ if (!Object.values(StorageType).includes(payload.storageType)) {
160
+ this.error(`Unsupported storage type: ${payload.storageType}`);
161
+ }
162
+ if (payload.storageType === StorageType.S3 && !payload.s3Credentials) {
163
+ this.error('S3 storage requires "s3Credentials"');
164
+ }
165
+ if (payload.storageType === StorageType.StorJ && !payload.storjCredentials) {
166
+ this.error('StorJ storage requires "storjCredentials"');
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,9 @@
1
+ import { BaseStorageCommand } from './base.js';
2
+ export default class StorageSelect extends BaseStorageCommand<typeof StorageSelect> {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,44 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { StoragesEmptyError } from '../../services/storage.service.js';
4
+ import { BaseStorageCommand } from './base.js';
5
+ export default class StorageSelect extends BaseStorageCommand {
6
+ static description = 'Select a storage that will be used by subsequent commands.';
7
+ static examples = [
8
+ '<%= config.bin %> storage select',
9
+ '<%= config.bin %> storage select --id=2de3e3a4-0000-1111-2222-333344445555',
10
+ ];
11
+ static flags = {
12
+ id: Flags.string({
13
+ char: 'i',
14
+ description: 'Storage ID to select',
15
+ }),
16
+ };
17
+ async run() {
18
+ const { flags } = await this.parse(StorageSelect);
19
+ try {
20
+ let storageId = flags.id;
21
+ if (!storageId) {
22
+ const storages = await this.storageService.requestStorage();
23
+ storageId = await select({
24
+ choices: storages.map(storage => ({
25
+ name: `${storage.id} (${storage.storageType}) ${storage.bucket}/${storage.prefix} `,
26
+ value: storage.id,
27
+ })),
28
+ message: 'Select storage',
29
+ });
30
+ }
31
+ if (!storageId) {
32
+ this.error('Storage ID is required');
33
+ }
34
+ await this.storageService.saveStorage(storageId);
35
+ this.log(`Selected storage: ${storageId}`);
36
+ }
37
+ catch (error) {
38
+ if (error instanceof StoragesEmptyError) {
39
+ this.error('No storages available. Run "sp storage create" first.');
40
+ }
41
+ this.error(error instanceof Error ? error.message : String(error));
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,16 @@
1
+ import { BaseStorageCommand } from './base.js';
2
+ export default class StorageUpdate extends BaseStorageCommand<typeof StorageUpdate> {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ fromFile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ private ensureNonEmptyString;
11
+ private ensureUpdatePayload;
12
+ private loadStorageFromFile;
13
+ private promptS3Credentials;
14
+ private promptStorageUpdate;
15
+ private promptStorJCredentials;
16
+ }