@super-protocol/sp-cli 0.0.8 → 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.
- package/README.md +200 -167
- package/dist/commands/account/base.d.ts +3 -4
- package/dist/commands/account/base.js +12 -9
- package/dist/commands/account/forget.d.ts +1 -1
- package/dist/commands/account/forget.js +66 -17
- package/dist/commands/account/get-sppi.js +7 -11
- package/dist/commands/account/info.d.ts +1 -13
- package/dist/commands/account/info.js +25 -45
- package/dist/commands/account/list.js +6 -6
- package/dist/commands/account/login.d.ts +10 -3
- package/dist/commands/account/login.js +143 -87
- package/dist/commands/account/switch.d.ts +3 -0
- package/dist/commands/account/switch.js +31 -11
- package/dist/commands/assets/base.d.ts +39 -0
- package/dist/commands/assets/base.js +217 -0
- package/dist/commands/assets/create.d.ts +41 -0
- package/dist/commands/assets/create.js +277 -0
- package/dist/commands/assets/delete.d.ts +14 -0
- package/dist/commands/assets/delete.js +69 -0
- package/dist/commands/assets/get.d.ts +14 -0
- package/dist/commands/assets/get.js +79 -0
- package/dist/commands/assets/list.d.ts +7 -0
- package/dist/commands/assets/list.js +33 -0
- package/dist/commands/assets/update.d.ts +44 -0
- package/dist/commands/assets/update.js +321 -0
- package/dist/commands/base.d.ts +1 -0
- package/dist/commands/base.js +6 -0
- package/dist/config/config.schema.d.ts +2 -11
- package/dist/config/config.schema.js +2 -7
- package/dist/constants.d.ts +3 -3
- package/dist/constants.js +3 -3
- package/dist/errors.d.ts +0 -2
- package/dist/errors.js +0 -2
- package/dist/hooks/prerun/auth.js +5 -9
- package/dist/interfaces/config-manager.interface.d.ts +3 -1
- package/dist/lib/container.d.ts +4 -12
- package/dist/lib/container.js +28 -113
- package/dist/lib/swarm-client/fetch-api.d.ts +7 -0
- package/dist/lib/swarm-client/fetch-api.js +41 -0
- package/dist/lib/swarm-client/fetch-timeout.client.d.ts +1 -0
- package/dist/lib/swarm-client/fetch-timeout.client.js +32 -0
- package/dist/lib/swarm-client/index.d.ts +6 -0
- package/dist/lib/swarm-client/index.js +31 -0
- package/dist/lib/swarm-client/middlewares/authorization.middleware.d.ts +2 -0
- package/dist/lib/swarm-client/middlewares/authorization.middleware.js +12 -0
- package/dist/lib/swarm-client/middlewares/index.d.ts +6 -0
- package/dist/lib/swarm-client/middlewares/index.js +5 -0
- package/dist/lib/swarm-client/middlewares/logger.middleware.d.ts +2 -0
- package/dist/lib/swarm-client/middlewares/logger.middleware.js +30 -0
- package/dist/lib/swarm-client/middlewares/request-id.middleware.d.ts +2 -0
- package/dist/lib/swarm-client/middlewares/request-id.middleware.js +13 -0
- package/dist/lib/swarm-client/types.d.ts +23 -0
- package/dist/lib/swarm-client/types.js +1 -0
- package/dist/managers/account-manager.d.ts +1 -0
- package/dist/managers/account-manager.js +13 -18
- package/dist/managers/config-file-manager.d.ts +24 -17
- package/dist/managers/config-file-manager.js +285 -161
- package/dist/managers/config-manager.d.ts +6 -6
- package/dist/managers/config-manager.js +8 -8
- package/dist/services/account.service.d.ts +42 -0
- package/dist/services/account.service.js +140 -0
- package/dist/services/asset.service.d.ts +35 -0
- package/dist/services/asset.service.js +120 -0
- package/dist/services/auth.service.d.ts +4 -6
- package/dist/services/auth.service.js +108 -118
- package/dist/utils/helper.js +2 -2
- package/dist/utils/progress.js +1 -0
- package/dist/utils/prompt.service.d.ts +8 -1
- package/dist/utils/prompt.service.js +33 -1
- package/oclif.manifest.json +479 -215
- package/package.json +7 -8
- package/dist/commands/files/download.d.ts +0 -15
- package/dist/commands/files/download.js +0 -63
- package/dist/commands/files/upload.d.ts +0 -18
- package/dist/commands/files/upload.js +0 -83
- package/dist/commands/storage/base.d.ts +0 -13
- package/dist/commands/storage/base.js +0 -125
- package/dist/commands/storage/create.d.ts +0 -11
- package/dist/commands/storage/create.js +0 -53
- package/dist/commands/storage/select.d.ts +0 -9
- package/dist/commands/storage/select.js +0 -38
- package/dist/commands/storage/show.d.ts +0 -17
- package/dist/commands/storage/show.js +0 -34
- package/dist/commands/storage/update.d.ts +0 -14
- package/dist/commands/storage/update.js +0 -204
- package/dist/commands/workflows/extend-lease.d.ts +0 -17
- package/dist/commands/workflows/extend-lease.js +0 -102
- package/dist/hooks/finally/shutdown-blockchain.d.ts +0 -3
- package/dist/hooks/finally/shutdown-blockchain.js +0 -8
- package/dist/middlewares/auth-middleware.d.ts +0 -9
- package/dist/middlewares/auth-middleware.js +0 -91
- package/dist/middlewares/cookies-middleware.d.ts +0 -8
- package/dist/middlewares/cookies-middleware.js +0 -80
- package/dist/services/storage.service.d.ts +0 -73
- package/dist/services/storage.service.js +0 -378
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
1
|
import { Flags } from '@oclif/core';
|
|
4
|
-
import { generatePrivateKey
|
|
5
|
-
import {
|
|
2
|
+
import { generatePrivateKey } from 'viem/accounts';
|
|
3
|
+
import { SWARM_URL } from '../../constants.js';
|
|
4
|
+
import { AccountService } from '../../services/account.service.js';
|
|
6
5
|
import { AuthService } from '../../services/auth.service.js';
|
|
7
|
-
import {
|
|
8
|
-
import { getConfigNameFromCredentials } from '../../utils/helper.js';
|
|
6
|
+
import { getConfigName, preparePath } from '../../utils/helper.js';
|
|
9
7
|
import { promptService } from '../../utils/prompt.service.js';
|
|
10
8
|
import { BaseAccountCommand } from './base.js';
|
|
11
9
|
export default class AccountLoginCommand extends BaseAccountCommand {
|
|
12
10
|
static aliases = ['login'];
|
|
13
11
|
static authenticate = false;
|
|
12
|
+
static summary = 'Login and account creation for SuperProtocol';
|
|
14
13
|
static description = 'Login to SuperProtocol (sign up or sign in).';
|
|
15
14
|
static examples = [
|
|
16
15
|
`<%= config.bin %> <%= command.id %>
|
|
@@ -23,8 +22,15 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
23
22
|
privateKey: Flags.string({
|
|
24
23
|
description: 'Account private key used for authentication',
|
|
25
24
|
}),
|
|
25
|
+
path: Flags.string({
|
|
26
|
+
description: 'Path to account(configuration) file to import',
|
|
27
|
+
}),
|
|
26
28
|
url: Flags.string({
|
|
27
|
-
description: '
|
|
29
|
+
description: 'Swarm Api URL',
|
|
30
|
+
hidden: true,
|
|
31
|
+
}),
|
|
32
|
+
authUrl: Flags.string({
|
|
33
|
+
description: 'Auth URL',
|
|
28
34
|
hidden: true,
|
|
29
35
|
}),
|
|
30
36
|
yes: Flags.boolean({
|
|
@@ -33,49 +39,40 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
33
39
|
description: 'Skip questions (generate keys when needed).',
|
|
34
40
|
}),
|
|
35
41
|
};
|
|
36
|
-
|
|
42
|
+
accountService;
|
|
37
43
|
shouldSkipLogin = false;
|
|
38
44
|
async inputPrompt(options) {
|
|
39
45
|
return promptService.text(options);
|
|
40
46
|
}
|
|
41
47
|
async checkStorage() {
|
|
42
|
-
|
|
43
|
-
.initProviderClient({ enableAuth: true, enableCookies: true, rebuild: true })
|
|
44
|
-
.build();
|
|
45
|
-
const { providerClient } = this.container;
|
|
46
|
-
const storageService = new StorageService(providerClient, this.logger);
|
|
47
|
-
if (!(await storageService.hasStorage())) {
|
|
48
|
-
this.logger.info('Requesting default storage');
|
|
49
|
-
const { id, isCentralized, storageType } = await storageService.getCentralizedStorage();
|
|
50
|
-
this.logger.info({ id, isCentralized, storageType }, 'Requested new storage');
|
|
51
|
-
await storageService.saveStorage(id);
|
|
52
|
-
}
|
|
48
|
+
this.logger.info('Storage initialization skipped (mock)');
|
|
53
49
|
}
|
|
54
50
|
async init() {
|
|
55
51
|
await super.init();
|
|
56
52
|
await this.container.initConfigFileManager().build();
|
|
57
|
-
this.
|
|
53
|
+
this.accountService = new AccountService(this.container.configFileManager);
|
|
58
54
|
await this.resolveConfiguration();
|
|
59
55
|
if (this.shouldSkipLogin) {
|
|
60
56
|
return;
|
|
61
57
|
}
|
|
62
58
|
await this.initAccountContext({
|
|
63
59
|
assumeYes: this.flags.yes,
|
|
64
|
-
enableAuth: false,
|
|
65
|
-
enableCookies: true,
|
|
66
60
|
});
|
|
67
61
|
}
|
|
68
62
|
async run() {
|
|
69
63
|
if (this.shouldSkipLogin) {
|
|
70
64
|
return { account: undefined, success: false };
|
|
71
65
|
}
|
|
72
|
-
const { accountManager, configManager
|
|
73
|
-
const authService = new AuthService(accountManager, configManager,
|
|
66
|
+
const { accountManager, configManager } = this.container;
|
|
67
|
+
const authService = new AuthService(accountManager, configManager, this.logger);
|
|
74
68
|
try {
|
|
75
69
|
await authService.auth({ force: true });
|
|
76
70
|
}
|
|
77
71
|
catch (error) {
|
|
78
|
-
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
this.error(error, { exit: 1 });
|
|
74
|
+
}
|
|
75
|
+
this.error(String(error), { exit: 1 });
|
|
79
76
|
}
|
|
80
77
|
try {
|
|
81
78
|
await this.checkStorage();
|
|
@@ -90,7 +87,7 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
90
87
|
}
|
|
91
88
|
async askName(fallback) {
|
|
92
89
|
const value = await this.inputPrompt({
|
|
93
|
-
message: '
|
|
90
|
+
message: 'Account name:',
|
|
94
91
|
placeholder: fallback,
|
|
95
92
|
});
|
|
96
93
|
const trimmed = value.trim();
|
|
@@ -101,40 +98,48 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
101
98
|
}
|
|
102
99
|
createAccountFromKey(privateKey) {
|
|
103
100
|
try {
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
address: account.address,
|
|
107
|
-
privateKey: privateKey,
|
|
108
|
-
};
|
|
101
|
+
return this.accountService.createAccountFromKey(privateKey);
|
|
109
102
|
}
|
|
110
103
|
catch (error) {
|
|
111
|
-
|
|
112
|
-
this.error(
|
|
104
|
+
const message = error instanceof Error && error.message ? error.message : 'Invalid private key provided.';
|
|
105
|
+
this.logger.error({ err: error }, message);
|
|
106
|
+
this.error(message);
|
|
113
107
|
}
|
|
114
108
|
}
|
|
115
|
-
async
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
return;
|
|
109
|
+
async updateConfigDisplayName(configFile, displayName) {
|
|
110
|
+
const result = await this.accountService.updateConfigDisplayName(configFile, displayName);
|
|
111
|
+
if (result.status === 'skipped') {
|
|
112
|
+
return configFile;
|
|
119
113
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const configs = this.configFileManager.getConfigsWithNames();
|
|
126
|
-
const matches = [];
|
|
127
|
-
for (const config of configs) {
|
|
128
|
-
const configData = this.configFileManager.getConfigData(config.file);
|
|
129
|
-
const storedKey = configData?.account?.privateKey?.toLowerCase();
|
|
130
|
-
const storedUrl = (configData?.providerUrl ?? PROVIDER_URL).trim();
|
|
131
|
-
const keyMatches = storedKey === normalizedKey;
|
|
132
|
-
const urlMatches = !matchProviderUrl || storedUrl === providerUrl;
|
|
133
|
-
if (keyMatches && urlMatches) {
|
|
134
|
-
matches.push(config);
|
|
135
|
-
}
|
|
114
|
+
if (result.status === 'updated') {
|
|
115
|
+
this.log(`Updated account name to "${displayName}"`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.log(`Account name: "${displayName}"`);
|
|
136
119
|
}
|
|
137
|
-
return
|
|
120
|
+
return result.configFile;
|
|
121
|
+
}
|
|
122
|
+
async setCurrentAndAuth(configFile, authUrl) {
|
|
123
|
+
await this.accountService.setCurrentConfig(configFile);
|
|
124
|
+
await this.accountService.updateConfigAuthUrl(configFile, authUrl);
|
|
125
|
+
}
|
|
126
|
+
async applySelectionWithDisplayName(configFile, displayName, authUrl) {
|
|
127
|
+
const updatedFile = await this.updateConfigDisplayName(configFile, displayName);
|
|
128
|
+
await this.setCurrentAndAuth(updatedFile, authUrl);
|
|
129
|
+
return updatedFile;
|
|
130
|
+
}
|
|
131
|
+
async selectMatchedConfig(matches) {
|
|
132
|
+
if (matches.length === 1) {
|
|
133
|
+
return matches[0].file;
|
|
134
|
+
}
|
|
135
|
+
if (this.flags.yes) {
|
|
136
|
+
this.log(`Too many matched accounts: ${matches.map((conf) => conf.name).join(',')} Selected first: ${matches[0].name}`);
|
|
137
|
+
return matches[0].file;
|
|
138
|
+
}
|
|
139
|
+
return this.selectPrompt({
|
|
140
|
+
message: 'Multiple accounts found for this private key. Select one:',
|
|
141
|
+
options: matches.map((match) => ({ label: match.name, value: match.file })),
|
|
142
|
+
});
|
|
138
143
|
}
|
|
139
144
|
async getPrivateKeyOrGenerate() {
|
|
140
145
|
const generatedKey = generatePrivateKey();
|
|
@@ -149,17 +154,17 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
149
154
|
const trimmed = value.trim();
|
|
150
155
|
return trimmed || generatedKey;
|
|
151
156
|
}
|
|
152
|
-
async resolveByName(name, privateKey,
|
|
153
|
-
const configs = this.
|
|
157
|
+
async resolveByName(name, privateKey, swarmUrl, authUrl) {
|
|
158
|
+
const configs = await this.accountService.getConfigsWithNames();
|
|
154
159
|
const normalized = name.toLowerCase();
|
|
155
160
|
const existingByName = configs.find((config) => config.name.toLowerCase() === normalized || config.file.toLowerCase() === normalized);
|
|
156
161
|
if (existingByName) {
|
|
157
|
-
await this.
|
|
162
|
+
await this.setCurrentAndAuth(existingByName.file, authUrl);
|
|
158
163
|
return;
|
|
159
164
|
}
|
|
160
165
|
let shouldCreate = true;
|
|
161
166
|
if (!this.flags.yes) {
|
|
162
|
-
shouldCreate = await this.confirmPrompt(`
|
|
167
|
+
shouldCreate = await this.confirmPrompt(`Account with "${name}" not found. Create it?`, true);
|
|
163
168
|
}
|
|
164
169
|
if (!shouldCreate) {
|
|
165
170
|
this.shouldSkipLogin = true;
|
|
@@ -167,74 +172,125 @@ export default class AccountLoginCommand extends BaseAccountCommand {
|
|
|
167
172
|
}
|
|
168
173
|
const resolvedKey = privateKey ?? (await this.getPrivateKeyOrGenerate());
|
|
169
174
|
const account = this.createAccountFromKey(resolvedKey);
|
|
170
|
-
const configFile =
|
|
171
|
-
await this.createConfigIfMissing(configFile, name,
|
|
175
|
+
const configFile = getConfigName(name);
|
|
176
|
+
const { created, configFile: createdFile } = await this.accountService.createConfigIfMissing(configFile, name, swarmUrl, account, authUrl);
|
|
177
|
+
if (created) {
|
|
178
|
+
this.log(`Created account: ${name}`);
|
|
179
|
+
}
|
|
172
180
|
let shouldSwitch = true;
|
|
173
181
|
if (!this.flags.yes) {
|
|
174
|
-
shouldSwitch = await this.confirmPrompt(`Switch to
|
|
182
|
+
shouldSwitch = await this.confirmPrompt(`Switch to account "${name}" now?`, true);
|
|
175
183
|
}
|
|
176
184
|
if (!shouldSwitch) {
|
|
177
185
|
this.shouldSkipLogin = true;
|
|
178
186
|
return;
|
|
179
187
|
}
|
|
180
|
-
await this.
|
|
188
|
+
await this.setCurrentAndAuth(createdFile, authUrl);
|
|
181
189
|
}
|
|
182
|
-
async
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
190
|
+
async loadConfigFromPath(configPath) {
|
|
191
|
+
try {
|
|
192
|
+
return await this.accountService.loadConfigFromPath(configPath);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
196
|
+
this.error(`Invalid account file: ${message}`, { exit: 1 });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async resolveByPath(rawPath, name, authUrl) {
|
|
200
|
+
const sourcePath = preparePath(rawPath);
|
|
201
|
+
const config = await this.loadConfigFromPath(sourcePath);
|
|
202
|
+
const targetFile = this.accountService.resolveConfigFileName(sourcePath, config, name);
|
|
203
|
+
const desiredName = name?.trim();
|
|
204
|
+
const privateKey = config.account.privateKey;
|
|
205
|
+
const swarmUrl = (config.swarmUrl ?? SWARM_URL).trim();
|
|
206
|
+
const matches = await this.accountService.findConfigsByPrivateKey(privateKey, swarmUrl, true);
|
|
207
|
+
if (matches.length > 0) {
|
|
208
|
+
const selectedFile = await this.selectMatchedConfig(matches);
|
|
209
|
+
this.log('Account already exists. Nothing to import.');
|
|
210
|
+
await this.applySelectionWithDisplayName(selectedFile, desiredName, authUrl);
|
|
186
211
|
return;
|
|
187
212
|
}
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
213
|
+
if (await this.accountService.configExists(targetFile)) {
|
|
214
|
+
const existingConfig = await this.accountService.getConfigData(targetFile);
|
|
215
|
+
const existingKey = existingConfig?.account?.privateKey?.trim().toLowerCase();
|
|
216
|
+
const existingUrl = (existingConfig?.swarmUrl ?? SWARM_URL).trim();
|
|
217
|
+
const importedKey = privateKey.trim().toLowerCase();
|
|
218
|
+
if (!existingKey || existingKey !== importedKey || existingUrl !== swarmUrl) {
|
|
219
|
+
this.error(`Account file "${targetFile}" already exists with different credentials. Use a different name or remove the existing file before importing.`, { exit: 1 });
|
|
193
220
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
221
|
+
this.log(`Account already exists. Switching to ${name || targetFile}`);
|
|
222
|
+
await this.setCurrentAndAuth(targetFile, authUrl);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const importedFile = await this.accountService.importConfig(sourcePath, name);
|
|
227
|
+
await this.setCurrentAndAuth(importedFile, authUrl);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
this.error(error instanceof Error ? error.message : String(error), { exit: 1 });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async resolveByPrivateKey(privateKey, swarmUrl, matchSwarmUrl, name, authUrl) {
|
|
234
|
+
const matches = await this.accountService.findConfigsByPrivateKey(privateKey, swarmUrl, matchSwarmUrl);
|
|
235
|
+
const desiredName = name?.trim();
|
|
236
|
+
if (matches.length > 0) {
|
|
237
|
+
const selectedFile = await this.selectMatchedConfig(matches);
|
|
238
|
+
await this.applySelectionWithDisplayName(selectedFile, desiredName, authUrl);
|
|
199
239
|
return;
|
|
200
240
|
}
|
|
201
241
|
let shouldCreate = true;
|
|
202
242
|
if (!this.flags.yes) {
|
|
203
|
-
shouldCreate = await this.confirmPrompt('No
|
|
243
|
+
shouldCreate = await this.confirmPrompt('No accounts found for this private key. Create a new one?', true);
|
|
204
244
|
}
|
|
205
245
|
if (!shouldCreate) {
|
|
206
246
|
this.shouldSkipLogin = true;
|
|
207
247
|
return;
|
|
208
248
|
}
|
|
209
249
|
const account = this.createAccountFromKey(privateKey);
|
|
210
|
-
const suggestedName =
|
|
250
|
+
const suggestedName = desiredName || account.address;
|
|
211
251
|
const displayName = this.flags.yes ? suggestedName : await this.askName(suggestedName);
|
|
212
|
-
const configFile =
|
|
213
|
-
await this.createConfigIfMissing(configFile, displayName,
|
|
252
|
+
const configFile = getConfigName(displayName);
|
|
253
|
+
const { created, configFile: createdFile } = await this.accountService.createConfigIfMissing(configFile, displayName, swarmUrl, account, authUrl);
|
|
254
|
+
if (created) {
|
|
255
|
+
this.log(`Created account: ${displayName}`);
|
|
256
|
+
}
|
|
214
257
|
let shouldSwitch = true;
|
|
215
258
|
if (!this.flags.yes) {
|
|
216
|
-
shouldSwitch = await this.confirmPrompt(`Switch to
|
|
259
|
+
shouldSwitch = await this.confirmPrompt(`Switch to account "${displayName}" now?`, true);
|
|
217
260
|
}
|
|
218
261
|
if (!shouldSwitch) {
|
|
219
262
|
this.shouldSkipLogin = true;
|
|
220
263
|
return;
|
|
221
264
|
}
|
|
222
|
-
await this.
|
|
265
|
+
await this.setCurrentAndAuth(createdFile, authUrl);
|
|
223
266
|
}
|
|
224
267
|
async resolveConfiguration() {
|
|
225
268
|
const name = this.flags.name?.trim();
|
|
269
|
+
const configPath = this.flags.path?.trim();
|
|
270
|
+
if (configPath !== undefined && !configPath) {
|
|
271
|
+
this.error('Account path cannot be empty.', { exit: 1 });
|
|
272
|
+
}
|
|
226
273
|
const privateKey = this.flags.privateKey?.trim();
|
|
227
274
|
const url = this.flags.url?.trim();
|
|
228
275
|
if (url !== undefined && !url) {
|
|
229
|
-
this.error('
|
|
276
|
+
this.error('Swarm URL cannot be empty.', { exit: 1 });
|
|
230
277
|
}
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
|
|
278
|
+
const authUrl = this.flags.authUrl?.trim();
|
|
279
|
+
if (authUrl !== undefined && !authUrl) {
|
|
280
|
+
this.error('Auth URL cannot be empty.', { exit: 1 });
|
|
281
|
+
}
|
|
282
|
+
const swarmUrl = (url || SWARM_URL).trim();
|
|
283
|
+
if (configPath) {
|
|
284
|
+
await this.resolveByPath(configPath, name, authUrl);
|
|
234
285
|
return;
|
|
235
286
|
}
|
|
236
287
|
if (privateKey) {
|
|
237
|
-
await this.resolveByPrivateKey(privateKey,
|
|
288
|
+
await this.resolveByPrivateKey(privateKey, swarmUrl, Boolean(url), name, authUrl);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (name) {
|
|
292
|
+
await this.resolveByName(name, privateKey, swarmUrl, authUrl);
|
|
293
|
+
return;
|
|
238
294
|
}
|
|
239
295
|
}
|
|
240
296
|
static maskPrivateKey(privateKey) {
|
|
@@ -6,6 +6,9 @@ export default class AccountSwitchCommand extends BaseAccountCommand<typeof Acco
|
|
|
6
6
|
static examples: string[];
|
|
7
7
|
protected configFileManager: ConfigFileManager;
|
|
8
8
|
protected configManager: ConfigManager;
|
|
9
|
+
static flags: {
|
|
10
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
9
12
|
init(): Promise<void>;
|
|
10
13
|
run(): Promise<void>;
|
|
11
14
|
private switchConfig;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
1
2
|
import { BaseAccountCommand } from './base.js';
|
|
2
3
|
export default class AccountSwitchCommand extends BaseAccountCommand {
|
|
3
4
|
static authenticate = false;
|
|
@@ -5,6 +6,12 @@ export default class AccountSwitchCommand extends BaseAccountCommand {
|
|
|
5
6
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
6
7
|
configFileManager;
|
|
7
8
|
configManager;
|
|
9
|
+
static flags = {
|
|
10
|
+
name: Flags.string({
|
|
11
|
+
char: 'n',
|
|
12
|
+
description: 'Account name to switch',
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
8
15
|
async init() {
|
|
9
16
|
await super.init();
|
|
10
17
|
await this.container.initConfigFileManager().build();
|
|
@@ -12,28 +19,41 @@ export default class AccountSwitchCommand extends BaseAccountCommand {
|
|
|
12
19
|
await this.container.initConfigManager().build();
|
|
13
20
|
}
|
|
14
21
|
async run() {
|
|
15
|
-
const
|
|
22
|
+
const { name } = this.flags;
|
|
23
|
+
const configs = await this.configFileManager.getConfigsWithNames();
|
|
16
24
|
const currentConfig = this.configFileManager.getCurrentConfigFile();
|
|
17
25
|
if (configs.length === 0) {
|
|
18
26
|
this.log('No accounts found');
|
|
19
|
-
this.log('Create a new account with: sp account login --privateKey "<PRIVATE_KEY>" --name "Account Name"');
|
|
27
|
+
this.log('Create a new account with: sp account login --privateKey "<PRIVATE_KEY>" --name "Account Name" or sp account login');
|
|
20
28
|
return;
|
|
21
29
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
let selected;
|
|
31
|
+
if (name) {
|
|
32
|
+
try {
|
|
33
|
+
const config = await this.configFileManager.getConfigWithName(name);
|
|
34
|
+
selected = config.file;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
this.error(`Account with name ${name} not found`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
selected = await this.selectPrompt({
|
|
42
|
+
initialValue: currentConfig,
|
|
43
|
+
message: 'Select an account:',
|
|
44
|
+
options: configs.map((config) => ({
|
|
45
|
+
label: config.name ?? config.file,
|
|
46
|
+
value: config.file,
|
|
47
|
+
})),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
30
50
|
const selectedConfig = configs.find((c) => c.file === selected);
|
|
31
51
|
await this.switchConfig(selected, selectedConfig?.name || selected);
|
|
32
52
|
}
|
|
33
53
|
async switchConfig(configFile, displayName) {
|
|
34
54
|
await this.configFileManager.setCurrentConfig(configFile);
|
|
35
55
|
this.log(`Switched to account: ${displayName || configFile}`);
|
|
36
|
-
await this.
|
|
56
|
+
await this.container.initConfigManager(true).build();
|
|
37
57
|
this.configFileManager = this.container.configFileManager;
|
|
38
58
|
this.configManager = this.container.configManager;
|
|
39
59
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Command } from '@oclif/core';
|
|
2
|
+
import { type AssetCredentials, AssetService, AssetType, SourceType } from '../../services/asset.service.js';
|
|
3
|
+
import { BaseCommand } from '../base.js';
|
|
4
|
+
export type AssetCredentialsFlags = {
|
|
5
|
+
storjBucket?: string;
|
|
6
|
+
storjPath?: string;
|
|
7
|
+
storjToken?: string;
|
|
8
|
+
s3Bucket?: string;
|
|
9
|
+
s3Path?: string;
|
|
10
|
+
s3AccessKey?: string;
|
|
11
|
+
s3SecretKey?: string;
|
|
12
|
+
s3Region?: string;
|
|
13
|
+
s3Endpoint?: string;
|
|
14
|
+
dockerImage?: string;
|
|
15
|
+
dockerRegistry?: string;
|
|
16
|
+
dockerUsername?: string;
|
|
17
|
+
dockerPassword?: string;
|
|
18
|
+
githubRepo?: string;
|
|
19
|
+
githubToken?: string;
|
|
20
|
+
githubBranch?: string;
|
|
21
|
+
gdocsDocumentId?: string;
|
|
22
|
+
gdocsApiKey?: string;
|
|
23
|
+
gdocsServiceAccountJson?: string;
|
|
24
|
+
};
|
|
25
|
+
export declare abstract class BaseAssetCommand<T extends typeof Command> extends BaseCommand<T> {
|
|
26
|
+
static summary: string;
|
|
27
|
+
protected assetService: AssetService;
|
|
28
|
+
protected currentDir: string;
|
|
29
|
+
init(): Promise<void>;
|
|
30
|
+
protected parseCredentialsInput(raw: string, fieldName: string): Record<string, unknown>;
|
|
31
|
+
protected promptCredentials<T extends SourceType>(sourceType: T): Promise<AssetCredentials>;
|
|
32
|
+
protected promptOptionalText(message: string, secret?: boolean): Promise<string | undefined>;
|
|
33
|
+
protected promptRequiredText(message: string): Promise<string>;
|
|
34
|
+
protected parseSizeInput(raw: string): number | undefined;
|
|
35
|
+
protected getAllowedSourceTypes(type: AssetType): readonly SourceType[];
|
|
36
|
+
protected assertSourceTypeAllowed(type: AssetType, sourceType: SourceType): void;
|
|
37
|
+
protected hasCredentialsFlags(flags: AssetCredentialsFlags): boolean;
|
|
38
|
+
protected buildCredentialsFromFlags(sourceType: SourceType, flags: AssetCredentialsFlags): AssetCredentials;
|
|
39
|
+
}
|