@super-protocol/sp-cli 0.0.9 → 0.0.10-beta

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.
Files changed (90) hide show
  1. package/README.md +191 -163
  2. package/dist/commands/account/base.d.ts +3 -4
  3. package/dist/commands/account/base.js +8 -6
  4. package/dist/commands/account/forget.js +3 -3
  5. package/dist/commands/account/get-sppi.js +7 -11
  6. package/dist/commands/account/info.d.ts +1 -13
  7. package/dist/commands/account/info.js +20 -40
  8. package/dist/commands/account/list.js +6 -6
  9. package/dist/commands/account/login.d.ts +6 -5
  10. package/dist/commands/account/login.js +96 -145
  11. package/dist/commands/account/switch.js +2 -2
  12. package/dist/commands/assets/base.d.ts +39 -0
  13. package/dist/commands/assets/base.js +217 -0
  14. package/dist/commands/assets/create.d.ts +41 -0
  15. package/dist/commands/assets/create.js +277 -0
  16. package/dist/commands/assets/delete.d.ts +14 -0
  17. package/dist/commands/assets/delete.js +69 -0
  18. package/dist/commands/assets/get.d.ts +14 -0
  19. package/dist/commands/assets/get.js +79 -0
  20. package/dist/commands/assets/list.d.ts +7 -0
  21. package/dist/commands/assets/list.js +33 -0
  22. package/dist/commands/assets/update.d.ts +44 -0
  23. package/dist/commands/assets/update.js +321 -0
  24. package/dist/commands/base.d.ts +1 -0
  25. package/dist/commands/base.js +5 -0
  26. package/dist/config/config.schema.d.ts +2 -11
  27. package/dist/config/config.schema.js +2 -7
  28. package/dist/constants.d.ts +3 -3
  29. package/dist/constants.js +3 -3
  30. package/dist/errors.d.ts +0 -2
  31. package/dist/errors.js +0 -2
  32. package/dist/hooks/prerun/auth.js +3 -8
  33. package/dist/interfaces/config-manager.interface.d.ts +3 -1
  34. package/dist/lib/container.d.ts +4 -12
  35. package/dist/lib/container.js +28 -113
  36. package/dist/lib/swarm-client/fetch-api.d.ts +7 -0
  37. package/dist/lib/swarm-client/fetch-api.js +41 -0
  38. package/dist/lib/swarm-client/fetch-timeout.client.d.ts +1 -0
  39. package/dist/lib/swarm-client/fetch-timeout.client.js +32 -0
  40. package/dist/lib/swarm-client/index.d.ts +6 -0
  41. package/dist/lib/swarm-client/index.js +31 -0
  42. package/dist/lib/swarm-client/middlewares/authorization.middleware.d.ts +2 -0
  43. package/dist/lib/swarm-client/middlewares/authorization.middleware.js +12 -0
  44. package/dist/lib/swarm-client/middlewares/index.d.ts +6 -0
  45. package/dist/lib/swarm-client/middlewares/index.js +5 -0
  46. package/dist/lib/swarm-client/middlewares/logger.middleware.d.ts +2 -0
  47. package/dist/lib/swarm-client/middlewares/logger.middleware.js +30 -0
  48. package/dist/lib/swarm-client/middlewares/request-id.middleware.d.ts +2 -0
  49. package/dist/lib/swarm-client/middlewares/request-id.middleware.js +13 -0
  50. package/dist/lib/swarm-client/types.d.ts +23 -0
  51. package/dist/lib/swarm-client/types.js +1 -0
  52. package/dist/managers/account-manager.d.ts +1 -0
  53. package/dist/managers/account-manager.js +13 -18
  54. package/dist/managers/config-file-manager.d.ts +22 -9
  55. package/dist/managers/config-file-manager.js +247 -122
  56. package/dist/managers/config-manager.d.ts +6 -6
  57. package/dist/managers/config-manager.js +8 -8
  58. package/dist/services/account.service.d.ts +42 -0
  59. package/dist/services/account.service.js +140 -0
  60. package/dist/services/asset.service.d.ts +35 -0
  61. package/dist/services/asset.service.js +120 -0
  62. package/dist/services/auth.service.d.ts +4 -6
  63. package/dist/services/auth.service.js +108 -118
  64. package/dist/utils/helper.js +2 -2
  65. package/oclif.manifest.json +462 -212
  66. package/package.json +7 -8
  67. package/dist/commands/files/download.d.ts +0 -15
  68. package/dist/commands/files/download.js +0 -63
  69. package/dist/commands/files/upload.d.ts +0 -18
  70. package/dist/commands/files/upload.js +0 -83
  71. package/dist/commands/storage/base.d.ts +0 -13
  72. package/dist/commands/storage/base.js +0 -125
  73. package/dist/commands/storage/create.d.ts +0 -11
  74. package/dist/commands/storage/create.js +0 -53
  75. package/dist/commands/storage/select.d.ts +0 -9
  76. package/dist/commands/storage/select.js +0 -38
  77. package/dist/commands/storage/show.d.ts +0 -17
  78. package/dist/commands/storage/show.js +0 -34
  79. package/dist/commands/storage/update.d.ts +0 -14
  80. package/dist/commands/storage/update.js +0 -204
  81. package/dist/commands/workflows/extend-lease.d.ts +0 -17
  82. package/dist/commands/workflows/extend-lease.js +0 -102
  83. package/dist/hooks/finally/shutdown-blockchain.d.ts +0 -3
  84. package/dist/hooks/finally/shutdown-blockchain.js +0 -8
  85. package/dist/middlewares/auth-middleware.d.ts +0 -9
  86. package/dist/middlewares/auth-middleware.js +0 -91
  87. package/dist/middlewares/cookies-middleware.d.ts +0 -8
  88. package/dist/middlewares/cookies-middleware.js +0 -80
  89. package/dist/services/storage.service.d.ts +0 -73
  90. package/dist/services/storage.service.js +0 -378
@@ -0,0 +1,79 @@
1
+ import { select } from '@clack/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { BaseAssetCommand } from './base.js';
4
+ export default class AssetGet extends BaseAssetCommand {
5
+ static authenticate = false;
6
+ static description = 'Get information about an asset.';
7
+ static examples = [
8
+ '<%= config.bin %> assets get --id 11111111-1111-1111-1111-111111111111',
9
+ '<%= config.bin %> assets get --name "dataset-v1"',
10
+ ];
11
+ static flags = {
12
+ id: Flags.string({
13
+ char: 'i',
14
+ description: 'Asset ID to fetch',
15
+ }),
16
+ name: Flags.string({
17
+ char: 'n',
18
+ description: 'Asset name to fetch',
19
+ }),
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(AssetGet);
23
+ const asset = await this.resolveAsset(flags.id, flags.name);
24
+ this.assertDefined(asset, 'Asset not found');
25
+ this.printAssetInfo(asset);
26
+ return asset;
27
+ }
28
+ async resolveAsset(id, name) {
29
+ if (id) {
30
+ return this.assetService.findAssetById(id);
31
+ }
32
+ if (name) {
33
+ return this.assetService.findAssetByName(name);
34
+ }
35
+ const assets = await this.assetService.listAssets();
36
+ if (assets.length === 0) {
37
+ this.error('No assets available');
38
+ }
39
+ const selection = this.ensurePromptValue(await select({
40
+ message: 'Select asset',
41
+ options: assets.map((asset) => ({
42
+ label: `${asset.name} (${asset.id})`,
43
+ value: asset.id,
44
+ })),
45
+ }));
46
+ return assets.find((asset) => asset.id === selection);
47
+ }
48
+ printAssetInfo(asset) {
49
+ const formatValue = (value) => {
50
+ if (value === undefined || value === null || value === '') {
51
+ return 'N/A';
52
+ }
53
+ if (value instanceof Date) {
54
+ return value.toISOString();
55
+ }
56
+ return String(value);
57
+ };
58
+ this.log(`ID: ${formatValue(asset.id)}`);
59
+ this.log(`Name: ${formatValue(asset.name)}`);
60
+ this.log(`Type: ${formatValue(asset.type)}`);
61
+ this.log(`Source: ${formatValue(asset.sourceType)}`);
62
+ this.log(`Tag: ${formatValue(asset.tag)}`);
63
+ this.log(`Hash: ${formatValue(asset.hash)}`);
64
+ this.log(`Size: ${formatValue(asset.size)}`);
65
+ this.log(`User: ${formatValue(asset.userId)}`);
66
+ this.log(`Created: ${formatValue(asset.createdAt)}`);
67
+ this.log(`Updated: ${formatValue(asset.updatedAt)}`);
68
+ const hardware = asset.hardwareRequirements;
69
+ if (hardware.length > 0) {
70
+ this.log('Hardware requirements:');
71
+ for (const requirement of hardware) {
72
+ this.log(` ${JSON.stringify(requirement)}`);
73
+ }
74
+ }
75
+ else {
76
+ this.log('Hardware requirements: N/A');
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,7 @@
1
+ import { BaseAssetCommand } from './base.js';
2
+ export default class AssetList extends BaseAssetCommand<typeof AssetList> {
3
+ static authenticate: boolean;
4
+ static description: string;
5
+ static examples: string[];
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,33 @@
1
+ import { printTable } from 'console-table-printer';
2
+ import { BaseAssetCommand } from './base.js';
3
+ export default class AssetList extends BaseAssetCommand {
4
+ static authenticate = false;
5
+ static description = 'List assets for the current user.';
6
+ static examples = ['<%= config.bin %> assets list'];
7
+ async run() {
8
+ const assets = await this.assetService.listAssets();
9
+ if (assets.length === 0) {
10
+ this.log('No assets found');
11
+ return;
12
+ }
13
+ const rows = assets.map((asset) => ({
14
+ id: asset.id,
15
+ name: asset.name,
16
+ size: asset.size ?? '',
17
+ sourceType: asset.sourceType,
18
+ tags: asset.tag ?? '',
19
+ type: asset.type,
20
+ }));
21
+ printTable(rows, {
22
+ columns: [
23
+ { name: 'name', title: 'Name' },
24
+ { name: 'id', title: 'ID' },
25
+ { name: 'type', title: 'Type' },
26
+ { name: 'sourceType', title: 'Source' },
27
+ { name: 'tags', title: 'Tags' },
28
+ { name: 'size', title: 'Size' },
29
+ ],
30
+ title: 'Assets',
31
+ });
32
+ }
33
+ }
@@ -0,0 +1,44 @@
1
+ import { type Asset, AssetType, SourceType } from '../../services/asset.service.js';
2
+ import { BaseAssetCommand } from './base.js';
3
+ export default class AssetUpdate extends BaseAssetCommand<typeof AssetUpdate> {
4
+ static authenticate: boolean;
5
+ static description: string;
6
+ static examples: string[];
7
+ static flags: {
8
+ fromFile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ newName: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ type: import("@oclif/core/interfaces").OptionFlag<AssetType | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ sourceType: import("@oclif/core/interfaces").OptionFlag<SourceType | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ hash: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ size: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ storjBucket: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ storjPath: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ storjToken: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
20
+ s3Bucket: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ s3Path: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ s3AccessKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
23
+ s3SecretKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
24
+ s3Region: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ s3Endpoint: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
26
+ dockerImage: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
27
+ dockerRegistry: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
28
+ dockerUsername: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
29
+ dockerPassword: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
30
+ githubRepo: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
31
+ githubToken: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
32
+ githubBranch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
33
+ gdocsDocumentId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
34
+ gdocsApiKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
35
+ gdocsServiceAccountJson: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
36
+ };
37
+ run(): Promise<Asset>;
38
+ private loadAssetFromFile;
39
+ private promptAssetUpdate;
40
+ private resolveAsset;
41
+ private hasUpdateFlags;
42
+ private buildPayloadFromFlags;
43
+ private parseEnumValue;
44
+ }
@@ -0,0 +1,321 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { confirm, select, text } from '@clack/prompts';
4
+ import { Flags } from '@oclif/core';
5
+ import { AssetType, SourceType, } from '../../services/asset.service.js';
6
+ import { promptService } from '../../utils/prompt.service.js';
7
+ import { BaseAssetCommand } from './base.js';
8
+ const assetTypeOptions = Object.values(AssetType);
9
+ const sourceTypeOptions = Object.values(SourceType);
10
+ export default class AssetUpdate extends BaseAssetCommand {
11
+ static authenticate = false;
12
+ static description = 'Update an existing asset.';
13
+ static examples = [
14
+ '<%= config.bin %> assets update --id 11111111-1111-1111-1111-111111111111 --fromFile ./asset-update.json',
15
+ '<%= config.bin %> assets update --name "dataset-v1"',
16
+ '<%= config.bin %> assets update --id 11111111-1111-1111-1111-111111111111 --newName "dataset-v2"',
17
+ '<%= config.bin %> assets update --id 11111111-1111-1111-1111-111111111111 --sourceType s3 --s3Bucket b --s3Path p --s3AccessKey a --s3SecretKey s --s3Region us-east-1',
18
+ ];
19
+ static flags = {
20
+ fromFile: Flags.string({
21
+ char: 'f',
22
+ description: 'Path to a JSON file that contains asset update definition.',
23
+ }),
24
+ id: Flags.string({
25
+ char: 'i',
26
+ description: 'Asset ID to update',
27
+ }),
28
+ name: Flags.string({
29
+ char: 'n',
30
+ description: 'Asset name to update',
31
+ }),
32
+ newName: Flags.string({
33
+ description: 'New asset name',
34
+ }),
35
+ type: Flags.option({
36
+ char: 't',
37
+ description: 'New asset type',
38
+ options: assetTypeOptions,
39
+ })(),
40
+ sourceType: Flags.option({
41
+ char: 's',
42
+ description: 'New source type',
43
+ options: sourceTypeOptions,
44
+ })(),
45
+ tag: Flags.string({
46
+ description: 'New asset tag',
47
+ }),
48
+ hash: Flags.string({
49
+ description: 'New asset hash',
50
+ }),
51
+ size: Flags.string({
52
+ description: 'New asset size in bytes',
53
+ }),
54
+ storjBucket: Flags.string({
55
+ description: 'Storj bucket',
56
+ }),
57
+ storjPath: Flags.string({
58
+ description: 'Storj path',
59
+ }),
60
+ storjToken: Flags.string({
61
+ description: 'Storj access token',
62
+ }),
63
+ s3Bucket: Flags.string({
64
+ description: 'S3 bucket',
65
+ }),
66
+ s3Path: Flags.string({
67
+ description: 'S3 path',
68
+ }),
69
+ s3AccessKey: Flags.string({
70
+ description: 'S3 access key',
71
+ }),
72
+ s3SecretKey: Flags.string({
73
+ description: 'S3 secret key',
74
+ }),
75
+ s3Region: Flags.string({
76
+ description: 'S3 region',
77
+ }),
78
+ s3Endpoint: Flags.string({
79
+ description: 'S3 endpoint',
80
+ }),
81
+ dockerImage: Flags.string({
82
+ description: 'Docker image',
83
+ }),
84
+ dockerRegistry: Flags.string({
85
+ description: 'Docker registry',
86
+ }),
87
+ dockerUsername: Flags.string({
88
+ description: 'Docker username',
89
+ }),
90
+ dockerPassword: Flags.string({
91
+ description: 'Docker password',
92
+ }),
93
+ githubRepo: Flags.string({
94
+ description: 'GitHub repo (org/repo)',
95
+ }),
96
+ githubToken: Flags.string({
97
+ description: 'GitHub token',
98
+ }),
99
+ githubBranch: Flags.string({
100
+ description: 'GitHub branch',
101
+ }),
102
+ gdocsDocumentId: Flags.string({
103
+ description: 'Google Docs document ID',
104
+ }),
105
+ gdocsApiKey: Flags.string({
106
+ description: 'Google Docs API key',
107
+ }),
108
+ gdocsServiceAccountJson: Flags.string({
109
+ description: 'Google Docs service account JSON',
110
+ }),
111
+ };
112
+ async run() {
113
+ const { flags } = await this.parse(AssetUpdate);
114
+ if (!promptService.isInteractive && !flags.id && !flags.name) {
115
+ this.error('Provide --id or --name when running with --no-tty.');
116
+ }
117
+ const asset = await this.resolveAsset(flags.id, flags.name);
118
+ this.assertDefined(asset, 'Asset not found');
119
+ const hasUpdateFlags = this.hasUpdateFlags(flags);
120
+ if (!flags.fromFile && !hasUpdateFlags && !promptService.isInteractive) {
121
+ this.error('Provide --fromFile or update flags when running with --no-tty.');
122
+ }
123
+ let payload = flags.fromFile ? await this.loadAssetFromFile(flags.fromFile) : undefined;
124
+ if (hasUpdateFlags) {
125
+ const flagPayload = this.buildPayloadFromFlags(flags, asset);
126
+ payload = this.assetService.validateUpdatePayload(payload ? { ...payload, ...flagPayload } : flagPayload);
127
+ }
128
+ if (!payload) {
129
+ payload = await this.promptAssetUpdate(asset);
130
+ }
131
+ const effectiveType = payload.type ?? asset.type;
132
+ const effectiveSourceType = payload.sourceType ?? asset.sourceType;
133
+ this.assertSourceTypeAllowed(effectiveType, effectiveSourceType);
134
+ try {
135
+ const updated = await this.assetService.updateAsset(asset.id, payload);
136
+ this.log(`Asset updated: ${updated.id}`);
137
+ return updated;
138
+ }
139
+ catch (error) {
140
+ this.error(error instanceof Error ? error.message : String(error));
141
+ }
142
+ }
143
+ async loadAssetFromFile(filePath) {
144
+ const absolutePath = path.isAbsolute(filePath)
145
+ ? filePath
146
+ : path.join(this.currentDir, filePath);
147
+ try {
148
+ const fileContent = await fs.readFile(absolutePath, 'utf8');
149
+ const parsed = JSON.parse(fileContent);
150
+ return this.assetService.validateUpdatePayload(parsed);
151
+ }
152
+ catch (error) {
153
+ this.error(`Failed to load asset update definition: ${error instanceof Error ? error.message : String(error)}`);
154
+ }
155
+ }
156
+ async promptAssetUpdate(existing) {
157
+ const payload = {};
158
+ const name = this.ensurePromptValue(await text({
159
+ defaultValue: existing.name,
160
+ message: 'Asset name (leave empty to keep current)',
161
+ })).trim();
162
+ if (name && name !== existing.name) {
163
+ payload.name = name;
164
+ }
165
+ const changeType = this.ensurePromptValue(await confirm({
166
+ initialValue: false,
167
+ message: `Change asset type? (current: ${existing.type})`,
168
+ }));
169
+ if (changeType) {
170
+ payload.type = this.ensurePromptValue(await select({
171
+ message: 'Select asset type',
172
+ options: [
173
+ { label: 'Data', value: AssetType.DATA },
174
+ { label: 'Image', value: AssetType.IMAGE },
175
+ { label: 'Output', value: AssetType.OUTPUT },
176
+ ],
177
+ }));
178
+ }
179
+ const changeSource = this.ensurePromptValue(await confirm({
180
+ initialValue: false,
181
+ message: `Change source type? (current: ${existing.sourceType})`,
182
+ }));
183
+ if (changeSource) {
184
+ const effectiveType = payload.type ?? existing.type;
185
+ const allowedSourceTypes = this.getAllowedSourceTypes(effectiveType);
186
+ const sourceTypeOptions = [
187
+ { label: 'StorJ', value: SourceType.STORJ },
188
+ { label: 'S3', value: SourceType.S3 },
189
+ { label: 'DockerHub', value: SourceType.DOCKERHUB },
190
+ { label: 'GitHub', value: SourceType.GITHUB },
191
+ { label: 'Google Docs', value: SourceType.GOOGLE_DOCS },
192
+ ].filter((option) => allowedSourceTypes.includes(option.value));
193
+ payload.sourceType = this.ensurePromptValue(await select({
194
+ message: 'Select source type',
195
+ options: sourceTypeOptions,
196
+ }));
197
+ }
198
+ const updateCredentials = this.ensurePromptValue(await confirm({
199
+ initialValue: false,
200
+ message: 'Update credentials?',
201
+ }));
202
+ if (updateCredentials) {
203
+ const effectiveSourceType = payload.sourceType ?? existing.sourceType;
204
+ payload.credentials = await this.promptCredentials(effectiveSourceType);
205
+ payload.sourceType = effectiveSourceType;
206
+ }
207
+ const tagRaw = this.ensurePromptValue(await text({
208
+ defaultValue: existing.tag ?? '',
209
+ message: 'Tag (leave empty to keep current)',
210
+ })).trim();
211
+ if (tagRaw && tagRaw !== (existing.tag ?? '')) {
212
+ payload.tag = tagRaw;
213
+ }
214
+ const hashRaw = this.ensurePromptValue(await text({
215
+ defaultValue: existing.hash ?? '',
216
+ message: 'Hash (leave empty to keep current)',
217
+ })).trim();
218
+ if (hashRaw && hashRaw !== existing.hash) {
219
+ payload.hash = hashRaw;
220
+ }
221
+ const sizeRaw = this.ensurePromptValue(await text({
222
+ defaultValue: existing.size !== undefined ? String(existing.size) : '',
223
+ message: 'Size in bytes (leave empty to keep current)',
224
+ validate(value) {
225
+ if (!value?.trim()) {
226
+ return undefined;
227
+ }
228
+ const size = Number(value);
229
+ if (!Number.isFinite(size) || size < 0) {
230
+ return 'Size must be a positive number';
231
+ }
232
+ return undefined;
233
+ },
234
+ }));
235
+ const size = this.parseSizeInput(sizeRaw);
236
+ if (size !== undefined && size !== existing.size) {
237
+ payload.size = size;
238
+ }
239
+ if (Object.keys(payload).length === 0) {
240
+ this.error('No changes provided');
241
+ }
242
+ return payload;
243
+ }
244
+ async resolveAsset(id, name) {
245
+ if (id) {
246
+ return this.assetService.findAssetById(id);
247
+ }
248
+ if (name) {
249
+ return this.assetService.findAssetByName(name);
250
+ }
251
+ const assets = await this.assetService.listAssets();
252
+ if (assets.length === 0) {
253
+ this.error('No assets available');
254
+ }
255
+ const selection = this.ensurePromptValue(await select({
256
+ message: 'Select asset to update',
257
+ options: assets.map((asset) => ({
258
+ label: `${asset.name} (${asset.id})`,
259
+ value: asset.id,
260
+ })),
261
+ }));
262
+ return assets.find((asset) => asset.id === selection);
263
+ }
264
+ hasUpdateFlags(flags) {
265
+ return Boolean(flags.newName ||
266
+ flags.type ||
267
+ flags.sourceType ||
268
+ flags.tag ||
269
+ flags.hash ||
270
+ flags.size ||
271
+ this.hasCredentialsFlags(flags));
272
+ }
273
+ buildPayloadFromFlags(flags, existing) {
274
+ const payload = {};
275
+ const newName = flags.newName?.trim();
276
+ if (newName) {
277
+ payload.name = newName;
278
+ }
279
+ const rawType = flags.type?.trim();
280
+ if (rawType) {
281
+ payload.type = this.parseEnumValue(rawType, assetTypeOptions, 'type');
282
+ }
283
+ const rawSourceType = flags.sourceType?.trim();
284
+ if (rawSourceType) {
285
+ payload.sourceType = this.parseEnumValue(rawSourceType, sourceTypeOptions, 'sourceType');
286
+ }
287
+ const hasCredentialFlags = this.hasCredentialsFlags(flags);
288
+ if (hasCredentialFlags) {
289
+ const effectiveSourceType = payload.sourceType ?? existing.sourceType;
290
+ payload.credentials = this.buildCredentialsFromFlags(effectiveSourceType, flags);
291
+ payload.sourceType = effectiveSourceType;
292
+ }
293
+ else if (rawSourceType) {
294
+ this.error(`Provide credentials flags for sourceType "${rawSourceType}".`);
295
+ }
296
+ const tag = flags.tag?.trim();
297
+ if (tag) {
298
+ payload.tag = tag;
299
+ }
300
+ const hash = flags.hash?.trim();
301
+ if (hash) {
302
+ payload.hash = hash;
303
+ }
304
+ if (flags.size !== undefined) {
305
+ const size = this.parseSizeInput(flags.size);
306
+ if (size !== undefined) {
307
+ payload.size = size;
308
+ }
309
+ }
310
+ if (Object.keys(payload).length === 0) {
311
+ this.error('No updates provided via flags');
312
+ }
313
+ return payload;
314
+ }
315
+ parseEnumValue(value, allowed, field) {
316
+ const normalized = value.trim().toLowerCase();
317
+ const match = allowed.find((candidate) => candidate.toLowerCase() === normalized);
318
+ this.assertDefined(match, `Invalid ${field}: ${value}. Allowed: ${allowed.join(', ')}`);
319
+ return match;
320
+ }
321
+ }
@@ -13,5 +13,6 @@ export declare abstract class BaseCommand<T extends typeof Command> extends Comm
13
13
  protected logger: pino.BaseLogger;
14
14
  constructor(argv: string[], config: Config);
15
15
  protected ensurePromptValue<T>(value: symbol | T, errorMessage?: string): T;
16
+ protected assertDefined<T>(value: T | null | undefined, message: string): asserts value is T;
16
17
  init(): Promise<void>;
17
18
  }
@@ -49,6 +49,11 @@ export class BaseCommand extends Command {
49
49
  this.error(error instanceof Error ? error.message : String(error));
50
50
  }
51
51
  }
52
+ assertDefined(value, message) {
53
+ if (value === undefined || value === null) {
54
+ this.error(message);
55
+ }
56
+ }
52
57
  async init() {
53
58
  await super.init();
54
59
  const allFlags = { ...this.ctor.flags, ...super.ctor.baseFlags };
@@ -6,10 +6,6 @@ export declare const accountSchema: Type.TObject<{
6
6
  export declare const authSchema: Type.TObject<{
7
7
  accessKey: Type.TString;
8
8
  }>;
9
- export declare const blockchainSchema: Type.TObject<{
10
- blockchainUrl: Type.TOptional<Type.TString>;
11
- contractAddress: Type.TString;
12
- }>;
13
9
  export declare const cliConfigSchema: Type.TObject<{
14
10
  account: Type.TOptional<Type.TObject<{
15
11
  address: Type.TString;
@@ -18,16 +14,11 @@ export declare const cliConfigSchema: Type.TObject<{
18
14
  auth: Type.TOptional<Type.TObject<{
19
15
  accessKey: Type.TString;
20
16
  }>>;
21
- blockchain: Type.TOptional<Type.TObject<{
22
- blockchainUrl: Type.TOptional<Type.TString>;
23
- contractAddress: Type.TString;
24
- }>>;
25
- cookies: Type.TOptional<Type.TUnknown>;
17
+ authUrl: Type.TOptional<Type.TString>;
26
18
  name: Type.TOptional<Type.TString>;
27
- providerUrl: Type.TOptional<Type.TString>;
19
+ swarmUrl: Type.TOptional<Type.TString>;
28
20
  selectedStorage: Type.TOptional<Type.TString>;
29
21
  }>;
30
22
  export type CliConfig = Static<typeof cliConfigSchema>;
31
23
  export type Account = Static<typeof accountSchema>;
32
24
  export type Auth = Static<typeof authSchema>;
33
- export type Blockchain = Static<typeof blockchainSchema>;
@@ -6,16 +6,11 @@ export const accountSchema = Type.Object({
6
6
  export const authSchema = Type.Object({
7
7
  accessKey: Type.String(),
8
8
  });
9
- export const blockchainSchema = Type.Object({
10
- blockchainUrl: Type.Optional(Type.String({ format: 'url' })),
11
- contractAddress: Type.String({ pattern: '^0x[a-fA-F0-9]{40}$' }),
12
- });
13
9
  export const cliConfigSchema = Type.Object({
14
10
  account: Type.Optional(accountSchema),
15
11
  auth: Type.Optional(authSchema),
16
- blockchain: Type.Optional(blockchainSchema),
17
- cookies: Type.Optional(Type.Unknown()),
12
+ authUrl: Type.Optional(Type.String({ format: 'url' })),
18
13
  name: Type.Optional(Type.String()),
19
- providerUrl: Type.Optional(Type.String({ format: 'url' })),
14
+ swarmUrl: Type.Optional(Type.String({ format: 'url' })),
20
15
  selectedStorage: Type.Optional(Type.String({ maxLength: 36, minLength: 36 })),
21
16
  });
@@ -1,8 +1,8 @@
1
1
  export declare const FILE_ACCESS_PERMS = 384;
2
2
  export declare const DIR_ACCESS_PERMS = 448;
3
- export declare const PROVIDER_URL = "https://api.dp.superprotocol.com";
4
- export declare const REFRESH_TOKEN_URI = "/api/auth/refresh-access";
3
+ export declare const SWARM_URL = "https://api.swarm.superprotocol.com";
4
+ export declare const AUTH_PATH = "/api/auth";
5
5
  export declare const S3_ENDPOINT = "https://gateway.storjshare.io";
6
6
  export declare const S3_REGION = "us-east-1";
7
- export declare const DEFAULT_USER_CONFIG_FILE = "default.config.json";
7
+ export declare const DEFAULT_USER_CONFIG_FILE = "default.json";
8
8
  export declare const DEFAULT_USER_CONFIG_NAME = "Default";
package/dist/constants.js CHANGED
@@ -2,9 +2,9 @@
2
2
  export const FILE_ACCESS_PERMS = 0o600;
3
3
  // Directory permissions. 'drwx------'
4
4
  export const DIR_ACCESS_PERMS = 0o700;
5
- export const PROVIDER_URL = 'https://api.dp.superprotocol.com';
6
- export const REFRESH_TOKEN_URI = '/api/auth/refresh-access';
5
+ export const SWARM_URL = 'https://api.swarm.superprotocol.com';
6
+ export const AUTH_PATH = '/api/auth';
7
7
  export const S3_ENDPOINT = 'https://gateway.storjshare.io';
8
8
  export const S3_REGION = 'us-east-1';
9
- export const DEFAULT_USER_CONFIG_FILE = 'default.config.json';
9
+ export const DEFAULT_USER_CONFIG_FILE = 'default.json';
10
10
  export const DEFAULT_USER_CONFIG_NAME = 'Default';
package/dist/errors.d.ts CHANGED
@@ -8,5 +8,3 @@ export declare class InvalidPrivateKeyError extends Error {
8
8
  }
9
9
  export declare class AuthorizationRequiredError extends Error {
10
10
  }
11
- export declare class ProviderClientError extends Error {
12
- }
package/dist/errors.js CHANGED
@@ -8,5 +8,3 @@ export class InvalidPrivateKeyError extends Error {
8
8
  }
9
9
  export class AuthorizationRequiredError extends Error {
10
10
  }
11
- export class ProviderClientError extends Error {
12
- }
@@ -39,13 +39,8 @@ const hook = async (opts) => {
39
39
  const container = configFile
40
40
  ? AppContainer.container.setupRuntimeConfig({ configFile })
41
41
  : AppContainer.container;
42
- await container
43
- .initConfigFileManager()
44
- .initConfigManager()
45
- .initAccountManager()
46
- .initProviderClient({ enableAuth: false, enableCookies: true })
47
- .build();
48
- const { configManager, accountManager, providerClient } = container;
42
+ await container.initConfigFileManager().initConfigManager().initAccountManager().build();
43
+ const { configManager, accountManager } = container;
49
44
  const credentials = await configManager.get('auth');
50
45
  if (!credentials?.accessKey) {
51
46
  if (!isInteractiveMode()) {
@@ -55,7 +50,7 @@ const hook = async (opts) => {
55
50
  pinoLogger.info({ commandId }, 'Authorization not found, redirecting to account:login');
56
51
  await config.runCommand('account:login', args);
57
52
  }
58
- const authService = new AuthService(accountManager, configManager, providerClient, pinoLogger);
53
+ const authService = new AuthService(accountManager, configManager, pinoLogger);
59
54
  await authService.auth();
60
55
  pinoLogger.debug({ commandId }, 'Authentication successful');
61
56
  }
@@ -1,7 +1,9 @@
1
1
  import type { CliConfig } from '../config/config.schema.js';
2
2
  import type { IManager } from './manager.interface.js';
3
3
  export interface IConfigManager extends IManager {
4
- get<K extends keyof CliConfig, V extends CliConfig[K]>(key: K): Promise<undefined | V>;
4
+ get<K extends keyof CliConfig, V extends CliConfig[K]>(key: K): undefined | V;
5
+ getAuthUrl(): string | undefined;
6
+ getSwarmUrl(): string;
5
7
  load(): Promise<CliConfig>;
6
8
  save(): Promise<void>;
7
9
  set<K extends keyof CliConfig, V extends CliConfig[K]>(key: K, value: V): Promise<void>;