@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.
- package/README.md +191 -163
- package/dist/commands/account/base.d.ts +3 -4
- package/dist/commands/account/base.js +8 -6
- package/dist/commands/account/forget.js +3 -3
- package/dist/commands/account/get-sppi.js +7 -11
- package/dist/commands/account/info.d.ts +1 -13
- package/dist/commands/account/info.js +20 -40
- package/dist/commands/account/list.js +6 -6
- package/dist/commands/account/login.d.ts +6 -5
- package/dist/commands/account/login.js +96 -145
- package/dist/commands/account/switch.js +2 -2
- 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 +5 -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 +3 -8
- 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 +22 -9
- package/dist/managers/config-file-manager.js +247 -122
- 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/oclif.manifest.json +462 -212
- 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
package/dist/lib/container.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Config } from '@oclif/core';
|
|
2
|
-
import { type ProviderClient } from '@super-protocol/provider-client';
|
|
3
2
|
import { AccountManager, ConfigFileManager, ConfigManager } from '../managers/index.js';
|
|
3
|
+
import { type SwarmClient } from './swarm-client/index.js';
|
|
4
4
|
interface RuntimeConfig {
|
|
5
5
|
configFile?: string;
|
|
6
6
|
}
|
|
@@ -11,31 +11,23 @@ export declare class AppContainer {
|
|
|
11
11
|
private _accountManager?;
|
|
12
12
|
private _configFileManager?;
|
|
13
13
|
private _configManager?;
|
|
14
|
-
private
|
|
15
|
-
private providerClientOptions?;
|
|
14
|
+
private _swarmClient?;
|
|
16
15
|
private readonly initQueue;
|
|
17
16
|
private logger;
|
|
18
|
-
private providerClientInitToken;
|
|
19
17
|
private runtimeConfigFile?;
|
|
20
18
|
private constructor();
|
|
21
19
|
static initialize(currentDir: string, config: Config): AppContainer;
|
|
22
20
|
get accountManager(): AccountManager;
|
|
23
21
|
get configFileManager(): ConfigFileManager;
|
|
24
22
|
get configManager(): ConfigManager;
|
|
23
|
+
get swarmClient(): SwarmClient;
|
|
25
24
|
static get container(): AppContainer;
|
|
26
|
-
get providerClient(): ProviderClient;
|
|
27
25
|
build(): Promise<this>;
|
|
28
26
|
initAccountManager(rebuild?: boolean): this;
|
|
29
|
-
|
|
27
|
+
initSwarmClient(rebuild?: boolean): this;
|
|
30
28
|
initConfigFileManager(rebuild?: boolean): this;
|
|
31
29
|
initConfigManager(rebuild?: boolean): this;
|
|
32
|
-
initProviderClient({ enableAuth, enableCookies, rebuild, }?: {
|
|
33
|
-
enableAuth?: boolean;
|
|
34
|
-
enableCookies?: boolean;
|
|
35
|
-
rebuild?: boolean;
|
|
36
|
-
}): this;
|
|
37
30
|
setupRuntimeConfig(config: RuntimeConfig): this;
|
|
38
|
-
private getProviderClientForBootstrap;
|
|
39
31
|
private queueInit;
|
|
40
32
|
private waitFor;
|
|
41
33
|
}
|
package/dist/lib/container.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { createProviderClient, loggerMiddleware, requestIdMiddleware, } from '@super-protocol/provider-client';
|
|
3
|
-
import { BlockchainConnector } from '@super-protocol/sdk-js';
|
|
4
|
-
import { PROVIDER_URL } from '../constants.js';
|
|
5
2
|
import logger from '../logger.js';
|
|
6
3
|
import { AccountManager, ConfigFileManager, ConfigManager } from '../managers/index.js';
|
|
7
|
-
import {
|
|
8
|
-
import { createCookieMiddleware } from '../middlewares/cookies-middleware.js';
|
|
4
|
+
import { createSwarmClient } from './swarm-client/index.js';
|
|
9
5
|
export class AppContainer {
|
|
10
6
|
cwdDir;
|
|
11
7
|
oclifConfig;
|
|
@@ -13,11 +9,9 @@ export class AppContainer {
|
|
|
13
9
|
_accountManager;
|
|
14
10
|
_configFileManager;
|
|
15
11
|
_configManager;
|
|
16
|
-
|
|
17
|
-
providerClientOptions;
|
|
12
|
+
_swarmClient;
|
|
18
13
|
initQueue = new Map();
|
|
19
14
|
logger;
|
|
20
|
-
providerClientInitToken = 0;
|
|
21
15
|
runtimeConfigFile;
|
|
22
16
|
constructor(cwdDir, oclifConfig) {
|
|
23
17
|
this.cwdDir = cwdDir;
|
|
@@ -48,18 +42,18 @@ export class AppContainer {
|
|
|
48
42
|
}
|
|
49
43
|
return this._configManager;
|
|
50
44
|
}
|
|
45
|
+
get swarmClient() {
|
|
46
|
+
if (!this._swarmClient) {
|
|
47
|
+
throw new Error('Swarm client not initialized');
|
|
48
|
+
}
|
|
49
|
+
return this._swarmClient;
|
|
50
|
+
}
|
|
51
51
|
static get container() {
|
|
52
52
|
if (!AppContainer.appContainer) {
|
|
53
53
|
throw new Error('AppContainer not initialized');
|
|
54
54
|
}
|
|
55
55
|
return AppContainer.appContainer;
|
|
56
56
|
}
|
|
57
|
-
get providerClient() {
|
|
58
|
-
if (!this._providerClient) {
|
|
59
|
-
throw new Error('Provider client not initialized');
|
|
60
|
-
}
|
|
61
|
-
return this._providerClient;
|
|
62
|
-
}
|
|
63
57
|
async build() {
|
|
64
58
|
await Promise.all(this.initQueue.values());
|
|
65
59
|
return this;
|
|
@@ -80,26 +74,26 @@ export class AppContainer {
|
|
|
80
74
|
this._accountManager = accountManager;
|
|
81
75
|
}, rebuild);
|
|
82
76
|
}
|
|
83
|
-
|
|
84
|
-
this.initConfigManager();
|
|
85
|
-
return this.queueInit('
|
|
77
|
+
initSwarmClient(rebuild = false) {
|
|
78
|
+
this.initConfigManager(rebuild);
|
|
79
|
+
return this.queueInit('swarmClient', async () => {
|
|
86
80
|
await this.waitFor('configManager', { required: true });
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const client = await this.getProviderClientForBootstrap();
|
|
90
|
-
const { data, error } = await client.GET('/api/config');
|
|
91
|
-
if (error || !data) {
|
|
92
|
-
throw new Error('Could not get configuration from provider');
|
|
93
|
-
}
|
|
94
|
-
blockchainConfig = {
|
|
95
|
-
blockchainUrl: data.blockchainUrl,
|
|
96
|
-
contractAddress: data.contractAddress,
|
|
97
|
-
};
|
|
98
|
-
await this.configManager.set('blockchain', blockchainConfig);
|
|
81
|
+
if (this._swarmClient && !rebuild) {
|
|
82
|
+
return;
|
|
99
83
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
84
|
+
if (rebuild) {
|
|
85
|
+
this._swarmClient = undefined;
|
|
86
|
+
}
|
|
87
|
+
const swarmUrl = await this.configManager.get('swarmUrl');
|
|
88
|
+
const auth = await this.configManager.getCredentials();
|
|
89
|
+
const accessToken = auth?.accessKey;
|
|
90
|
+
this.logger.info('Initializing swarm client');
|
|
91
|
+
this._swarmClient = createSwarmClient({
|
|
92
|
+
accessToken,
|
|
93
|
+
baseUrl: swarmUrl,
|
|
94
|
+
logger: this.logger,
|
|
95
|
+
});
|
|
96
|
+
}, rebuild);
|
|
103
97
|
}
|
|
104
98
|
initConfigFileManager(rebuild = false) {
|
|
105
99
|
return this.queueInit('configFileManager', async () => {
|
|
@@ -136,66 +130,6 @@ export class AppContainer {
|
|
|
136
130
|
this._configManager = configManager;
|
|
137
131
|
}, rebuild);
|
|
138
132
|
}
|
|
139
|
-
initProviderClient({ enableAuth = true, enableCookies = true, rebuild = false, } = {}) {
|
|
140
|
-
this.initConfigManager();
|
|
141
|
-
const options = { enableAuth, enableCookies };
|
|
142
|
-
const optionsChanged = this.providerClientOptions &&
|
|
143
|
-
(this.providerClientOptions.enableAuth !== options.enableAuth ||
|
|
144
|
-
this.providerClientOptions.enableCookies !== options.enableCookies);
|
|
145
|
-
if (optionsChanged) {
|
|
146
|
-
rebuild = true;
|
|
147
|
-
this.logger.debug({ newOptions: options, oldOptions: this.providerClientOptions }, 'Provider client options changed, rebuilding');
|
|
148
|
-
}
|
|
149
|
-
const shouldSchedule = rebuild || !this.initQueue.has('providerClient');
|
|
150
|
-
const initToken = shouldSchedule
|
|
151
|
-
? ++this.providerClientInitToken
|
|
152
|
-
: this.providerClientInitToken;
|
|
153
|
-
return this.queueInit('providerClient', async () => {
|
|
154
|
-
if (this._providerClient && !rebuild) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (rebuild && this._providerClient) {
|
|
158
|
-
this.logger.debug('Clearing existing provider client for rebuild');
|
|
159
|
-
this._providerClient = undefined;
|
|
160
|
-
}
|
|
161
|
-
await this.waitFor('configManager', { required: true });
|
|
162
|
-
const providerUrl = (await this.configManager.get('providerUrl')) || PROVIDER_URL;
|
|
163
|
-
this.logger.info('Initializing provider client');
|
|
164
|
-
const providerClient = createProviderClient({
|
|
165
|
-
baseUrl: providerUrl,
|
|
166
|
-
logger: this.logger,
|
|
167
|
-
middlewares: [requestIdMiddleware, loggerMiddleware],
|
|
168
|
-
});
|
|
169
|
-
if (enableCookies) {
|
|
170
|
-
this.logger.info('Initializing cookie middleware');
|
|
171
|
-
const cookiesMiddleware = await createCookieMiddleware(this.configManager, this.logger, providerUrl);
|
|
172
|
-
providerClient.use(cookiesMiddleware);
|
|
173
|
-
}
|
|
174
|
-
if (enableAuth) {
|
|
175
|
-
this.logger.info('Initializing auth middleware');
|
|
176
|
-
const authMiddleware = await createAuthMiddleware(this.configManager, providerClient, this.logger);
|
|
177
|
-
providerClient.use(authMiddleware);
|
|
178
|
-
}
|
|
179
|
-
if (process.env.SP_CLI_DEBUG_REQUESTS === '1') {
|
|
180
|
-
providerClient.use({
|
|
181
|
-
onRequest: async ({ request }) => {
|
|
182
|
-
this.logger.debug({
|
|
183
|
-
hasAuthHeader: Boolean(request.headers.get('Authorization')),
|
|
184
|
-
hasBody: Boolean(request.body),
|
|
185
|
-
method: request.method,
|
|
186
|
-
url: request.url,
|
|
187
|
-
}, 'Requesting');
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
if (initToken !== this.providerClientInitToken) {
|
|
192
|
-
this.logger.debug({ initToken, providerClientInitToken: this.providerClientInitToken }, 'Skipping provider client assignment (superseded)');
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
this._providerClient = providerClient;
|
|
196
|
-
this.providerClientOptions = options;
|
|
197
|
-
}, rebuild);
|
|
198
|
-
}
|
|
199
133
|
setupRuntimeConfig(config) {
|
|
200
134
|
const previousRuntimeConfigFile = this.runtimeConfigFile;
|
|
201
135
|
if (config.configFile) {
|
|
@@ -211,11 +145,10 @@ export class AppContainer {
|
|
|
211
145
|
this.logger.debug({ previousRuntimeConfigFile, runtimeConfigFile: this.runtimeConfigFile }, 'Runtime config changed; clearing dependent services');
|
|
212
146
|
this._configManager = undefined;
|
|
213
147
|
this._accountManager = undefined;
|
|
214
|
-
this.
|
|
215
|
-
this.providerClientOptions = undefined;
|
|
148
|
+
this._swarmClient = undefined;
|
|
216
149
|
this.initQueue.delete('configManager');
|
|
217
150
|
this.initQueue.delete('accountManager');
|
|
218
|
-
this.initQueue.delete('
|
|
151
|
+
this.initQueue.delete('swarmClient');
|
|
219
152
|
this.initQueue.delete('blockchainConnector');
|
|
220
153
|
this.initQueue.delete('configFileManager');
|
|
221
154
|
}
|
|
@@ -224,24 +157,6 @@ export class AppContainer {
|
|
|
224
157
|
}
|
|
225
158
|
return this;
|
|
226
159
|
}
|
|
227
|
-
async getProviderClientForBootstrap() {
|
|
228
|
-
if (this._providerClient) {
|
|
229
|
-
return this._providerClient;
|
|
230
|
-
}
|
|
231
|
-
const queued = this.initQueue.get('providerClient');
|
|
232
|
-
if (queued) {
|
|
233
|
-
await queued;
|
|
234
|
-
return this.providerClient;
|
|
235
|
-
}
|
|
236
|
-
await this.waitFor('configManager', { required: true });
|
|
237
|
-
const providerUrl = (await this.configManager.get('providerUrl')) || PROVIDER_URL;
|
|
238
|
-
this.logger.debug({ providerUrl }, 'Creating bootstrap provider client');
|
|
239
|
-
return createProviderClient({
|
|
240
|
-
baseUrl: providerUrl,
|
|
241
|
-
logger: this.logger,
|
|
242
|
-
middlewares: [requestIdMiddleware, loggerMiddleware],
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
160
|
queueInit(name, task, force = false) {
|
|
246
161
|
if (force) {
|
|
247
162
|
this.initQueue.delete(name);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isZodType } from '@ts-rest/core';
|
|
2
|
+
import { fetchWithTimeoutClient } from './fetch-timeout.client.js';
|
|
3
|
+
export const createSwarmFetchApi = ({ fetchClient = fetch, timeout, }) => {
|
|
4
|
+
const fetchWithTimeout = fetchWithTimeoutClient(fetchClient, timeout);
|
|
5
|
+
return async ({ route, path, method, headers, body, validateResponse, fetchOptions }) => {
|
|
6
|
+
const result = await fetchWithTimeout(path, {
|
|
7
|
+
...fetchOptions,
|
|
8
|
+
method,
|
|
9
|
+
headers,
|
|
10
|
+
body,
|
|
11
|
+
});
|
|
12
|
+
const contentType = result.headers.get('content-type');
|
|
13
|
+
if (contentType?.includes('application/') && contentType.includes('json')) {
|
|
14
|
+
const response = {
|
|
15
|
+
status: result.status,
|
|
16
|
+
body: await result.json(),
|
|
17
|
+
headers: result.headers,
|
|
18
|
+
};
|
|
19
|
+
const responseSchema = route.responses[response.status];
|
|
20
|
+
if ((validateResponse ?? route.validateResponseOnClient) && isZodType(responseSchema)) {
|
|
21
|
+
return {
|
|
22
|
+
...response,
|
|
23
|
+
body: responseSchema.parse(response.body),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return response;
|
|
27
|
+
}
|
|
28
|
+
if (contentType?.includes('text/')) {
|
|
29
|
+
return {
|
|
30
|
+
status: result.status,
|
|
31
|
+
body: await result.text(),
|
|
32
|
+
headers: result.headers,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
status: result.status,
|
|
37
|
+
body: await result.blob(),
|
|
38
|
+
headers: result.headers,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fetchWithTimeoutClient: (fetchClient: typeof fetch, timeout?: number) => (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const fetchWithTimeoutClient = (fetchClient, timeout) => async (input, init) => {
|
|
2
|
+
if (!timeout || timeout <= 0) {
|
|
3
|
+
return fetchClient(input, init);
|
|
4
|
+
}
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const cleanups = [];
|
|
7
|
+
if (init?.signal) {
|
|
8
|
+
const onAbort = () => controller.abort(init.signal?.reason);
|
|
9
|
+
if (init.signal.aborted) {
|
|
10
|
+
controller.abort(init.signal.reason);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
init.signal.addEventListener('abort', onAbort, { once: true });
|
|
14
|
+
cleanups.push(() => init.signal?.removeEventListener('abort', onAbort));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const abortSignal = AbortSignal.timeout(timeout);
|
|
18
|
+
if (abortSignal.aborted) {
|
|
19
|
+
controller.abort(abortSignal.reason);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const onTimeoutAbort = () => controller.abort(abortSignal.reason);
|
|
23
|
+
abortSignal.addEventListener('abort', onTimeoutAbort, { once: true });
|
|
24
|
+
cleanups.push(() => abortSignal.removeEventListener('abort', onTimeoutAbort));
|
|
25
|
+
}
|
|
26
|
+
const promise = fetchClient(input, { ...init, signal: controller.signal });
|
|
27
|
+
return promise.finally(() => {
|
|
28
|
+
for (const cleanup of cleanups) {
|
|
29
|
+
cleanup();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { authorizationMiddleware, defaultMiddlewares, loggerMiddleware, requestIdMiddleware } from './middlewares/index.js';
|
|
2
|
+
import type { SwarmClient, SwarmClientOptions } from './types.js';
|
|
3
|
+
export declare const createSwarmClient: (options?: SwarmClientOptions) => SwarmClient;
|
|
4
|
+
export type { SwarmClientOptions, SwarmClient, SwarmMiddleware, SwarmMiddlewareContext, } from './types.js';
|
|
5
|
+
export { authorizationMiddleware, defaultMiddlewares, loggerMiddleware, requestIdMiddleware };
|
|
6
|
+
export * from '@super-protocol/swarm-contracts';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { apiContract } from '@super-protocol/swarm-contracts';
|
|
2
|
+
import { initClient } from '@ts-rest/core';
|
|
3
|
+
import { createSwarmFetchApi } from './fetch-api.js';
|
|
4
|
+
import { authorizationMiddleware, defaultMiddlewares, loggerMiddleware, requestIdMiddleware, } from './middlewares/index.js';
|
|
5
|
+
const applyMiddlewares = (api, middlewares, context) => middlewares.reduceRight((next, middleware) => middleware(next, context), api);
|
|
6
|
+
export const createSwarmClient = (options = {}) => {
|
|
7
|
+
const { accessToken = process.env.SP_ACCESS_TOKEN, baseUrl: baseUrlFromOptions = process.env.SP_SWARM_URL, middlewares = defaultMiddlewares, timeout, fetchClient, baseHeaders, jsonQuery, validateResponse, credentials, throwOnUnknownStatus, logger, api, } = options;
|
|
8
|
+
const baseUrl = baseUrlFromOptions?.trim();
|
|
9
|
+
if (!baseUrl || baseUrl === 'undefined' || baseUrl === 'null') {
|
|
10
|
+
throw new Error('Swarm client baseUrl is required. Set SP_SWARM_URL or pass baseUrl.');
|
|
11
|
+
}
|
|
12
|
+
const mergedBaseHeaders = accessToken || baseHeaders
|
|
13
|
+
? {
|
|
14
|
+
...(accessToken ? { authorization: `Bearer ${accessToken}` } : {}),
|
|
15
|
+
...baseHeaders,
|
|
16
|
+
}
|
|
17
|
+
: undefined;
|
|
18
|
+
const baseApi = api ?? createSwarmFetchApi({ fetchClient, timeout });
|
|
19
|
+
const apiWithMiddleware = applyMiddlewares(baseApi, middlewares, { accessToken, logger });
|
|
20
|
+
return initClient(apiContract, {
|
|
21
|
+
baseUrl,
|
|
22
|
+
api: apiWithMiddleware,
|
|
23
|
+
baseHeaders: mergedBaseHeaders,
|
|
24
|
+
jsonQuery,
|
|
25
|
+
validateResponse,
|
|
26
|
+
credentials,
|
|
27
|
+
throwOnUnknownStatus,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
export { authorizationMiddleware, defaultMiddlewares, loggerMiddleware, requestIdMiddleware };
|
|
31
|
+
export * from '@super-protocol/swarm-contracts';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const authorizationMiddleware = (next, { accessToken }) => async (args) => {
|
|
2
|
+
if (!accessToken || args.headers.authorization) {
|
|
3
|
+
return next(args);
|
|
4
|
+
}
|
|
5
|
+
return next({
|
|
6
|
+
...args,
|
|
7
|
+
headers: {
|
|
8
|
+
...args.headers,
|
|
9
|
+
authorization: `Bearer ${accessToken}`,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { authorizationMiddleware } from './authorization.middleware.js';
|
|
2
|
+
import { loggerMiddleware } from './logger.middleware.js';
|
|
3
|
+
import { requestIdMiddleware } from './request-id.middleware.js';
|
|
4
|
+
export type { SwarmMiddleware, SwarmMiddlewareContext } from '../types.js';
|
|
5
|
+
export { authorizationMiddleware, loggerMiddleware, requestIdMiddleware };
|
|
6
|
+
export declare const defaultMiddlewares: import("../types.js").SwarmMiddleware[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { authorizationMiddleware } from './authorization.middleware.js';
|
|
2
|
+
import { loggerMiddleware } from './logger.middleware.js';
|
|
3
|
+
import { requestIdMiddleware } from './request-id.middleware.js';
|
|
4
|
+
export { authorizationMiddleware, loggerMiddleware, requestIdMiddleware };
|
|
5
|
+
export const defaultMiddlewares = [requestIdMiddleware, loggerMiddleware, authorizationMiddleware];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const loggerMiddleware = (next, { logger }) => async (args) => {
|
|
2
|
+
if (!logger) {
|
|
3
|
+
return next(args);
|
|
4
|
+
}
|
|
5
|
+
const requestId = args.headers['request-id'];
|
|
6
|
+
logger.trace({
|
|
7
|
+
method: args.method,
|
|
8
|
+
url: args.path,
|
|
9
|
+
requestId,
|
|
10
|
+
}, 'Swarm request');
|
|
11
|
+
try {
|
|
12
|
+
const response = await next(args);
|
|
13
|
+
logger.trace({
|
|
14
|
+
method: args.method,
|
|
15
|
+
url: args.path,
|
|
16
|
+
requestId,
|
|
17
|
+
status: response.status,
|
|
18
|
+
}, 'Swarm response');
|
|
19
|
+
return response;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
logger.error({
|
|
23
|
+
err: error,
|
|
24
|
+
method: args.method,
|
|
25
|
+
url: args.path,
|
|
26
|
+
requestId,
|
|
27
|
+
}, 'Swarm request failed');
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export const requestIdMiddleware = (next) => async (args) => {
|
|
3
|
+
if (args.headers['request-id']) {
|
|
4
|
+
return next(args);
|
|
5
|
+
}
|
|
6
|
+
return next({
|
|
7
|
+
...args,
|
|
8
|
+
headers: {
|
|
9
|
+
...args.headers,
|
|
10
|
+
'request-id': randomUUID(),
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ApiContract } from '@super-protocol/swarm-contracts';
|
|
2
|
+
import type { ApiFetcher, ClientArgs, FetchOptions, InitClientArgs, InitClientReturn } from '@ts-rest/core';
|
|
3
|
+
import type pino from 'pino';
|
|
4
|
+
export type SwarmClient = InitClientReturn<ApiContract, InitClientArgs>;
|
|
5
|
+
export type SwarmMiddlewareContext = {
|
|
6
|
+
accessToken?: string;
|
|
7
|
+
logger?: pino.BaseLogger;
|
|
8
|
+
};
|
|
9
|
+
export type SwarmMiddleware = (next: ApiFetcher, context: SwarmMiddlewareContext) => ApiFetcher;
|
|
10
|
+
export interface SwarmClientOptions {
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
accessToken?: string;
|
|
13
|
+
logger?: pino.BaseLogger;
|
|
14
|
+
middlewares?: SwarmMiddleware[];
|
|
15
|
+
timeout?: number;
|
|
16
|
+
fetchClient?: typeof fetch;
|
|
17
|
+
baseHeaders?: ClientArgs['baseHeaders'];
|
|
18
|
+
jsonQuery?: boolean;
|
|
19
|
+
validateResponse?: boolean;
|
|
20
|
+
credentials?: FetchOptions['credentials'];
|
|
21
|
+
throwOnUnknownStatus?: boolean;
|
|
22
|
+
api?: ApiFetcher;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -12,26 +12,10 @@ export class AccountManager {
|
|
|
12
12
|
this.logger = logger;
|
|
13
13
|
}
|
|
14
14
|
async create() {
|
|
15
|
-
this.
|
|
16
|
-
const account = privateKeyToAccount(this.privateKey);
|
|
17
|
-
this.account = {
|
|
18
|
-
address: account.address,
|
|
19
|
-
privateKey: this.privateKey,
|
|
20
|
-
};
|
|
21
|
-
await this.save();
|
|
22
|
-
this.logger.debug('Created new account');
|
|
23
|
-
return this.account;
|
|
15
|
+
return this.setAccountFromPrivateKey(generatePrivateKey(), 'Created new account');
|
|
24
16
|
}
|
|
25
17
|
async createFromKey(privateKey) {
|
|
26
|
-
this.privateKey
|
|
27
|
-
const account = privateKeyToAccount(this.privateKey);
|
|
28
|
-
this.account = {
|
|
29
|
-
address: account.address,
|
|
30
|
-
privateKey: this.privateKey,
|
|
31
|
-
};
|
|
32
|
-
await this.save();
|
|
33
|
-
this.logger.debug('Created new account from key');
|
|
34
|
-
return this.account;
|
|
18
|
+
return this.setAccountFromPrivateKey(privateKey, 'Created new account from key');
|
|
35
19
|
}
|
|
36
20
|
async createSign(nonce) {
|
|
37
21
|
if (!this.privateKey) {
|
|
@@ -76,4 +60,15 @@ export class AccountManager {
|
|
|
76
60
|
async save() {
|
|
77
61
|
await this.configManager.set('account', this.account);
|
|
78
62
|
}
|
|
63
|
+
async setAccountFromPrivateKey(privateKey, logMessage) {
|
|
64
|
+
this.privateKey = privateKey;
|
|
65
|
+
const account = privateKeyToAccount(privateKey);
|
|
66
|
+
this.account = {
|
|
67
|
+
address: account.address,
|
|
68
|
+
privateKey,
|
|
69
|
+
};
|
|
70
|
+
await this.save();
|
|
71
|
+
this.logger.debug(logMessage);
|
|
72
|
+
return this.account;
|
|
73
|
+
}
|
|
79
74
|
}
|
|
@@ -14,30 +14,43 @@ export declare class ConfigFileManager implements IManager {
|
|
|
14
14
|
private readonly configsDir;
|
|
15
15
|
private runtimeConfigFile?;
|
|
16
16
|
constructor(configDir: string, logger: pino.BaseLogger, options?: ConfigFileManagerOptions);
|
|
17
|
-
createConfig(configFileName: string, name
|
|
18
|
-
updateConfigName(configFileName: string, name: string): Promise<
|
|
17
|
+
createConfig(configFileName: string, name?: string, url?: string, account?: Account, authUrl?: string): Promise<string>;
|
|
18
|
+
updateConfigName(configFileName: string, name: string): Promise<{
|
|
19
|
+
updated: boolean;
|
|
20
|
+
fileName: string;
|
|
21
|
+
}>;
|
|
22
|
+
updateConfigAuthUrl(configFileName: string, authUrl: string): Promise<boolean>;
|
|
19
23
|
deleteConfig(configName: string): Promise<void>;
|
|
20
24
|
deleteConfigByName(name?: string): Promise<void>;
|
|
21
|
-
getConfigData(configName: string): CliConfig | undefined
|
|
25
|
+
getConfigData(configName: string): Promise<CliConfig | undefined>;
|
|
22
26
|
getConfigDir(): string;
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
configExists(configName: string): Promise<boolean>;
|
|
28
|
+
private listConfigFiles;
|
|
29
|
+
private getConfigBaseName;
|
|
30
|
+
getConfigWithName(name: string): Promise<{
|
|
25
31
|
file: string;
|
|
26
32
|
name: string;
|
|
27
|
-
}
|
|
28
|
-
getConfigsWithNames(): Array<{
|
|
33
|
+
}>;
|
|
34
|
+
getConfigsWithNames(): Promise<Array<{
|
|
29
35
|
file: string;
|
|
30
36
|
name: string;
|
|
31
|
-
}
|
|
37
|
+
}>>;
|
|
32
38
|
getCurrentConfigFile(): string | undefined;
|
|
33
39
|
getCurrentConfigPath(): Promise<string>;
|
|
34
40
|
importConfig(sourcePath: string, targetName?: string): Promise<string>;
|
|
35
41
|
init(): Promise<void>;
|
|
36
|
-
private removeConfig;
|
|
37
42
|
setCurrentConfig(configName: string): Promise<void>;
|
|
38
43
|
setRuntimeConfigFile(runtimeConfigFile?: string): void;
|
|
39
44
|
private ensureDirectories;
|
|
45
|
+
private normalizeConfigFiles;
|
|
40
46
|
private load;
|
|
41
47
|
private save;
|
|
48
|
+
private pathExists;
|
|
49
|
+
private readJsonFileOrThrow;
|
|
50
|
+
private tryReadJsonFile;
|
|
51
|
+
private writeJsonFile;
|
|
52
|
+
private resolveConfigFileName;
|
|
53
|
+
private isNotFoundError;
|
|
54
|
+
private isAlreadyExistsError;
|
|
42
55
|
}
|
|
43
56
|
export {};
|