@super-protocol/sp-cli 0.0.6 → 0.0.7
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 +97 -229
- package/dist/commands/account/base.d.ts +20 -0
- package/dist/commands/account/base.js +49 -0
- package/dist/commands/{config/delete.d.ts → account/forget.d.ts} +5 -2
- package/dist/commands/{config/delete.js → account/forget.js} +12 -5
- package/dist/commands/account/get-sppi.d.ts +2 -2
- package/dist/commands/account/get-sppi.js +8 -13
- package/dist/commands/account/info.d.ts +5 -2
- package/dist/commands/account/info.js +53 -3
- package/dist/commands/account/list.d.ts +9 -0
- package/dist/commands/{config → account}/list.js +16 -9
- package/dist/commands/account/login.d.ts +35 -0
- package/dist/commands/account/login.js +254 -0
- package/dist/commands/account/switch.d.ts +12 -0
- package/dist/commands/account/switch.js +40 -0
- package/dist/commands/base.d.ts +4 -3
- package/dist/commands/base.js +3 -1
- package/dist/commands/files/download.js +13 -5
- package/dist/commands/files/upload.js +11 -7
- package/dist/commands/storage/base.d.ts +2 -2
- package/dist/commands/storage/create.js +1 -1
- package/dist/commands/storage/select.js +3 -5
- package/dist/commands/storage/show.js +2 -4
- package/dist/commands/storage/update.js +31 -14
- package/dist/commands/workflows/extend-lease.d.ts +1 -1
- package/dist/commands/workflows/extend-lease.js +19 -10
- package/dist/config/config-file.schema.d.ts +1 -2
- package/dist/config/config-file.schema.js +0 -1
- package/dist/config/config.schema.d.ts +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +2 -0
- package/dist/hooks/finally/shutdown-blockchain.d.ts +1 -1
- package/dist/hooks/finally/shutdown-blockchain.js +1 -1
- package/dist/hooks/finally/unlock-config.d.ts +3 -0
- package/dist/hooks/finally/unlock-config.js +5 -0
- package/dist/hooks/init/init-container.d.ts +1 -1
- package/dist/hooks/init/init-container.js +2 -3
- package/dist/hooks/init/lock-config.d.ts +3 -0
- package/dist/hooks/init/lock-config.js +19 -0
- package/dist/hooks/prerun/auth.d.ts +3 -0
- package/dist/hooks/prerun/auth.js +70 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/interfaces/account-manager.interface.d.ts +1 -1
- package/dist/interfaces/config-manager.interface.d.ts +2 -2
- package/dist/lib/cli-instance-lock.d.ts +2 -0
- package/dist/lib/cli-instance-lock.js +37 -0
- package/dist/lib/container.d.ts +6 -4
- package/dist/lib/container.js +108 -38
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +4 -1
- package/dist/managers/account-manager.d.ts +7 -8
- package/dist/managers/account-manager.js +20 -45
- package/dist/managers/config-file-manager.d.ts +6 -7
- package/dist/managers/config-file-manager.js +35 -32
- package/dist/managers/config-manager.d.ts +5 -5
- package/dist/managers/config-manager.js +5 -2
- package/dist/middlewares/auth-middleware.d.ts +1 -1
- package/dist/services/auth.service.d.ts +10 -15
- package/dist/services/auth.service.js +71 -5
- package/dist/services/storage.service.d.ts +3 -3
- package/dist/services/storage.service.js +46 -19
- package/dist/utils/helper.d.ts +1 -0
- package/dist/utils/helper.js +15 -1
- package/oclif.manifest.json +258 -399
- package/package.json +17 -24
- package/dist/commands/auth/login.d.ts +0 -12
- package/dist/commands/auth/login.js +0 -50
- package/dist/commands/auth/me.d.ts +0 -5
- package/dist/commands/auth/me.js +0 -16
- package/dist/commands/config/add.d.ts +0 -13
- package/dist/commands/config/add.js +0 -73
- package/dist/commands/config/base.d.ts +0 -16
- package/dist/commands/config/base.js +0 -78
- package/dist/commands/config/create.d.ts +0 -11
- package/dist/commands/config/create.js +0 -41
- package/dist/commands/config/index.d.ts +0 -6
- package/dist/commands/config/index.js +0 -22
- package/dist/commands/config/list.d.ts +0 -6
- package/dist/commands/config/show.d.ts +0 -6
- package/dist/commands/config/show.js +0 -10
- package/dist/commands/config/use.d.ts +0 -6
- package/dist/commands/config/use.js +0 -27
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ProviderClient } from '@super-protocol/provider-client';
|
|
2
|
-
import pino from 'pino';
|
|
3
|
-
import { AccountManager } from '../managers/account-manager.js';
|
|
4
|
-
import { ConfigManager } from '../managers/config-manager.js';
|
|
1
|
+
import type { ProviderClient } from '@super-protocol/provider-client';
|
|
2
|
+
import type pino from 'pino';
|
|
3
|
+
import type { AccountManager } from '../managers/account-manager.js';
|
|
4
|
+
import type { ConfigManager } from '../managers/config-manager.js';
|
|
5
5
|
export declare class AuthError extends Error {
|
|
6
6
|
}
|
|
7
7
|
export declare class AuthService {
|
|
@@ -10,15 +10,10 @@ export declare class AuthService {
|
|
|
10
10
|
private readonly providerClient;
|
|
11
11
|
private readonly logger;
|
|
12
12
|
constructor(accountManager: AccountManager, configManager: ConfigManager, providerClient: ProviderClient, logger: pino.BaseLogger);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} | undefined;
|
|
20
|
-
user: {
|
|
21
|
-
nonce?: string;
|
|
22
|
-
} | undefined;
|
|
23
|
-
}>;
|
|
13
|
+
private hasValidRefreshCookie;
|
|
14
|
+
auth(options?: {
|
|
15
|
+
force?: boolean;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
private getTokens;
|
|
18
|
+
private getUserNonce;
|
|
24
19
|
}
|
|
@@ -1,5 +1,31 @@
|
|
|
1
|
+
import { decode } from 'jsonwebtoken';
|
|
2
|
+
import { CookieJar } from 'tough-cookie';
|
|
3
|
+
import { PROVIDER_URL } from '../constants.js';
|
|
1
4
|
export class AuthError extends Error {
|
|
2
5
|
}
|
|
6
|
+
function isAccessKeyExpired(accessKey) {
|
|
7
|
+
try {
|
|
8
|
+
const payload = decode(accessKey);
|
|
9
|
+
if (!payload || typeof payload.exp !== 'number') {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
const now = Math.floor(Date.now() / 1000);
|
|
13
|
+
return now >= payload.exp;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function isCookieExpired(cookie) {
|
|
20
|
+
if (!cookie.expires || cookie.expires === 'Infinity') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const expiresAt = cookie.expires.getTime();
|
|
24
|
+
if (!Number.isFinite(expiresAt)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return Date.now() >= expiresAt;
|
|
28
|
+
}
|
|
3
29
|
export class AuthService {
|
|
4
30
|
accountManager;
|
|
5
31
|
configManager;
|
|
@@ -11,7 +37,45 @@ export class AuthService {
|
|
|
11
37
|
this.providerClient = providerClient;
|
|
12
38
|
this.logger = logger;
|
|
13
39
|
}
|
|
14
|
-
async
|
|
40
|
+
async hasValidRefreshCookie(baseUrl) {
|
|
41
|
+
let stored;
|
|
42
|
+
try {
|
|
43
|
+
stored = await this.configManager.getCookies();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.logger.warn({ err: error }, 'Failed to read cookies from config');
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (!stored || typeof stored !== 'object') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const jar = CookieJar.fromJSON(stored);
|
|
54
|
+
const cookies = await jar.getCookies(baseUrl, { expire: false });
|
|
55
|
+
return cookies.some((cookie) => cookie.key.toLowerCase().includes('refresh') && cookie.value && !isCookieExpired(cookie));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.logger.warn({ err: error }, 'Failed to parse cookies');
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async auth(options = {}) {
|
|
63
|
+
if (!options.force) {
|
|
64
|
+
const credentials = await this.configManager.getCredentials();
|
|
65
|
+
const accessKey = credentials?.accessKey;
|
|
66
|
+
if (accessKey && !isAccessKeyExpired(accessKey)) {
|
|
67
|
+
this.logger.debug('Access key is not expired, skipping authorization');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (accessKey) {
|
|
71
|
+
const providerUrl = (await this.configManager.get('providerUrl')) || PROVIDER_URL;
|
|
72
|
+
const hasRefreshCookie = await this.hasValidRefreshCookie(providerUrl);
|
|
73
|
+
if (hasRefreshCookie) {
|
|
74
|
+
this.logger.debug('Access key expired but refresh cookie exists, skipping authorization');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
15
79
|
const address = this.accountManager.getAddress();
|
|
16
80
|
const { error: nonceError, user } = await this.getUserNonce(address);
|
|
17
81
|
if (nonceError && nonceError.statusCode === 404) {
|
|
@@ -25,7 +89,7 @@ export class AuthService {
|
|
|
25
89
|
this.logger.debug({ signUpError }, 'Error signing up');
|
|
26
90
|
const { error: nonceError, user } = await this.getUserNonce(address);
|
|
27
91
|
this.logger.debug({ nonceError, user }, 'Requesting nonce again');
|
|
28
|
-
if (user
|
|
92
|
+
if (user?.nonce) {
|
|
29
93
|
await this.getTokens(user.nonce);
|
|
30
94
|
}
|
|
31
95
|
else {
|
|
@@ -45,7 +109,7 @@ export class AuthService {
|
|
|
45
109
|
await this.getTokens(nonce);
|
|
46
110
|
}
|
|
47
111
|
}
|
|
48
|
-
else if (user
|
|
112
|
+
else if (user?.nonce) {
|
|
49
113
|
this.logger.debug({ user }, 'Requesting for existed user');
|
|
50
114
|
await this.getTokens(user.nonce);
|
|
51
115
|
}
|
|
@@ -55,7 +119,7 @@ export class AuthService {
|
|
|
55
119
|
}
|
|
56
120
|
async getTokens(nonce) {
|
|
57
121
|
const signature = await this.accountManager.createSign(nonce);
|
|
58
|
-
const { data: tokenResponse, error
|
|
122
|
+
const { data: tokenResponse, error } = await this.providerClient.POST('/api/auth/token', {
|
|
59
123
|
body: {
|
|
60
124
|
address: this.accountManager.getAddress(),
|
|
61
125
|
provider: 'sp-cli',
|
|
@@ -71,7 +135,9 @@ export class AuthService {
|
|
|
71
135
|
this.logger.error({ response: tokenResponse }, 'Unexpected token response');
|
|
72
136
|
throw new AuthError('Provider returned an unexpected token response.');
|
|
73
137
|
}
|
|
74
|
-
await this.configManager.setCredentials({
|
|
138
|
+
await this.configManager.setCredentials({
|
|
139
|
+
accessKey: accessToken,
|
|
140
|
+
});
|
|
75
141
|
}
|
|
76
142
|
async getUserNonce(address) {
|
|
77
143
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EncryptionWithIV, Resource, RuntimeInputInfo } from '@super-protocol/dto-js';
|
|
2
|
-
import { AddStorageDto, ProviderClient, StorageResponseDto, UpdateStorageDto } from '@super-protocol/provider-client';
|
|
3
|
-
import pino from 'pino';
|
|
1
|
+
import { type EncryptionWithIV, type Resource, type RuntimeInputInfo } from '@super-protocol/dto-js';
|
|
2
|
+
import { type AddStorageDto, type ProviderClient, type StorageResponseDto, type UpdateStorageDto } from '@super-protocol/provider-client';
|
|
3
|
+
import type pino from 'pino';
|
|
4
4
|
export declare class StorageError extends Error {
|
|
5
5
|
}
|
|
6
6
|
export declare class StoragesUndefinedError extends StorageError {
|
|
@@ -4,11 +4,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import { basename, dirname } from 'node:path';
|
|
7
9
|
import { StorageResourceSchema, StorageType, } from '@super-protocol/dto-js';
|
|
8
10
|
import { ResourceType, } from '@super-protocol/provider-client';
|
|
9
11
|
import { download, upload } from '@super-protocol/sp-files-addon';
|
|
10
|
-
import * as fs from 'node:fs/promises';
|
|
11
|
-
import { basename, dirname } from 'node:path';
|
|
12
12
|
import { Value } from 'typebox/value';
|
|
13
13
|
import { Retryable } from 'typescript-retry-decorator';
|
|
14
14
|
import { S3_ENDPOINT } from '../constants.js';
|
|
@@ -24,7 +24,9 @@ export class StorageUpdateError extends StorageError {
|
|
|
24
24
|
}
|
|
25
25
|
export class StorageGetError extends StorageError {
|
|
26
26
|
}
|
|
27
|
-
export const generateExternalId = () => Array.from({ length: 16 })
|
|
27
|
+
export const generateExternalId = () => Array.from({ length: 16 })
|
|
28
|
+
.map(() => Math.floor(Math.random() * 16).toString(16))
|
|
29
|
+
.join('');
|
|
28
30
|
export class StorageService {
|
|
29
31
|
providerClient;
|
|
30
32
|
logger;
|
|
@@ -38,7 +40,7 @@ export class StorageService {
|
|
|
38
40
|
const { data, error } = await this.providerClient.POST('/api/storages', {
|
|
39
41
|
body: storage,
|
|
40
42
|
});
|
|
41
|
-
if (error
|
|
43
|
+
if (error?.message) {
|
|
42
44
|
this.logger.error({ err: error }, 'Failed to create storage');
|
|
43
45
|
throw new StorageCreateError(error.message);
|
|
44
46
|
}
|
|
@@ -51,12 +53,16 @@ export class StorageService {
|
|
|
51
53
|
}
|
|
52
54
|
catch (error) {
|
|
53
55
|
this.logger.error({ err: error }, 'Storage creation failed');
|
|
54
|
-
const error_ = error instanceof StorageError
|
|
56
|
+
const error_ = error instanceof StorageError
|
|
57
|
+
? error
|
|
58
|
+
: new ProviderClientError('Request failed please try again later');
|
|
55
59
|
throw error_;
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
async download(params, progressCb) {
|
|
59
|
-
const resourceFile = await readJsonFile({
|
|
63
|
+
const resourceFile = await readJsonFile({
|
|
64
|
+
path: params.resourcePath,
|
|
65
|
+
});
|
|
60
66
|
if (!Value.Check(StorageResourceSchema, resourceFile)) {
|
|
61
67
|
throw new StorageError('Invalid resource file format, please verify resource.json against the schema.');
|
|
62
68
|
}
|
|
@@ -90,7 +96,7 @@ export class StorageService {
|
|
|
90
96
|
async getCentralizedStorage() {
|
|
91
97
|
try {
|
|
92
98
|
const storages = await this.requestStorages();
|
|
93
|
-
const centralized = storages.find(storage => storage.isCentralized);
|
|
99
|
+
const centralized = storages.find((storage) => storage.isCentralized);
|
|
94
100
|
if (!centralized) {
|
|
95
101
|
const storage = await this.initCentralizedStorage();
|
|
96
102
|
return storage;
|
|
@@ -114,7 +120,7 @@ export class StorageService {
|
|
|
114
120
|
}
|
|
115
121
|
const { activeStorageId } = data || {};
|
|
116
122
|
const storages = await this.requestStorages();
|
|
117
|
-
const storage = storages.find(storage => storage.id === activeStorageId);
|
|
123
|
+
const storage = storages.find((storage) => storage.id === activeStorageId);
|
|
118
124
|
if (!storage) {
|
|
119
125
|
throw new StorageError('Selected storage not found please select storage first');
|
|
120
126
|
}
|
|
@@ -122,7 +128,9 @@ export class StorageService {
|
|
|
122
128
|
}
|
|
123
129
|
catch (error) {
|
|
124
130
|
this.logger.error({ err: error }, 'Failed to get current storage');
|
|
125
|
-
const error_ = error instanceof StorageError
|
|
131
|
+
const error_ = error instanceof StorageError
|
|
132
|
+
? error
|
|
133
|
+
: new ProviderClientError('Request failed please try again later');
|
|
126
134
|
throw error_;
|
|
127
135
|
}
|
|
128
136
|
}
|
|
@@ -146,7 +154,9 @@ export class StorageService {
|
|
|
146
154
|
}
|
|
147
155
|
catch (error) {
|
|
148
156
|
this.logger.error({ err: error }, 'Storage initialization failed');
|
|
149
|
-
const error_ = error instanceof StorageError
|
|
157
|
+
const error_ = error instanceof StorageError
|
|
158
|
+
? error
|
|
159
|
+
: new ProviderClientError('Request failed please try again later');
|
|
150
160
|
throw error_;
|
|
151
161
|
}
|
|
152
162
|
}
|
|
@@ -167,7 +177,9 @@ export class StorageService {
|
|
|
167
177
|
}
|
|
168
178
|
catch (error) {
|
|
169
179
|
this.logger.error({ err: error }, 'Storage initialization failed');
|
|
170
|
-
const error_ = error instanceof StorageError
|
|
180
|
+
const error_ = error instanceof StorageError
|
|
181
|
+
? error
|
|
182
|
+
: new ProviderClientError('Request failed please try again later');
|
|
171
183
|
throw error_;
|
|
172
184
|
}
|
|
173
185
|
}
|
|
@@ -190,7 +202,9 @@ export class StorageService {
|
|
|
190
202
|
}
|
|
191
203
|
catch (error) {
|
|
192
204
|
this.logger.error({ err: error }, 'Failed to request storages');
|
|
193
|
-
const error_ = error instanceof StorageError
|
|
205
|
+
const error_ = error instanceof StorageError
|
|
206
|
+
? error
|
|
207
|
+
: new ProviderClientError('Request failed please try again later');
|
|
194
208
|
throw error_;
|
|
195
209
|
}
|
|
196
210
|
}
|
|
@@ -219,7 +233,9 @@ export class StorageService {
|
|
|
219
233
|
}
|
|
220
234
|
catch (error) {
|
|
221
235
|
this.logger.error({ err: error }, 'Failed to save selected storage');
|
|
222
|
-
const error_ = error instanceof StorageError
|
|
236
|
+
const error_ = error instanceof StorageError
|
|
237
|
+
? error
|
|
238
|
+
: new ProviderClientError('Request failed please try again later');
|
|
223
239
|
throw error_;
|
|
224
240
|
}
|
|
225
241
|
}
|
|
@@ -243,13 +259,17 @@ export class StorageService {
|
|
|
243
259
|
}
|
|
244
260
|
catch (error) {
|
|
245
261
|
this.logger.error({ err: error, storageId: id }, 'Failed to update storage');
|
|
246
|
-
const error_ = error instanceof StorageError
|
|
262
|
+
const error_ = error instanceof StorageError
|
|
263
|
+
? error
|
|
264
|
+
: new ProviderClientError('Request failed please try again later');
|
|
247
265
|
throw error_;
|
|
248
266
|
}
|
|
249
267
|
}
|
|
250
268
|
async upload(params, progressCb) {
|
|
251
269
|
const storage = await this.getCurrentStorage();
|
|
252
|
-
const remotePath = params.remotePath
|
|
270
|
+
const remotePath = params.remotePath
|
|
271
|
+
? params.remotePath.replaceAll('..', '').replace(/^\/+/, '')
|
|
272
|
+
: generateExternalId();
|
|
253
273
|
const resourceFilePath = preparePath(params.outputPath ?? 'resource.json');
|
|
254
274
|
try {
|
|
255
275
|
await fs.stat(resourceFilePath);
|
|
@@ -262,7 +282,9 @@ export class StorageService {
|
|
|
262
282
|
}
|
|
263
283
|
let metadata = {};
|
|
264
284
|
if (params.metadataPath) {
|
|
265
|
-
metadata = await readJsonFile({
|
|
285
|
+
metadata = await readJsonFile({
|
|
286
|
+
path: preparePath(params.metadataPath),
|
|
287
|
+
});
|
|
266
288
|
}
|
|
267
289
|
const { readCredentials, writeCredentials } = this.getStorageCredentials(storage, remotePath);
|
|
268
290
|
const info = await fs.stat(params.localPath);
|
|
@@ -315,7 +337,8 @@ export class StorageService {
|
|
|
315
337
|
bucket: storage.bucket,
|
|
316
338
|
prefix: joinPaths(storage.prefix, remotePath),
|
|
317
339
|
token: readAccessToken,
|
|
318
|
-
},
|
|
340
|
+
},
|
|
341
|
+
writeCredentials: {
|
|
319
342
|
bucket: storage.bucket,
|
|
320
343
|
prefix: joinPaths(storage.prefix, remotePath),
|
|
321
344
|
token: writeAccessToken,
|
|
@@ -334,7 +357,8 @@ export class StorageService {
|
|
|
334
357
|
endpoint: S3_ENDPOINT,
|
|
335
358
|
prefix: joinPaths(storage.prefix, remotePath),
|
|
336
359
|
secretKey: readSecretAccessKey,
|
|
337
|
-
},
|
|
360
|
+
},
|
|
361
|
+
writeCredentials: {
|
|
338
362
|
accessKeyId: writeAccessKeyId,
|
|
339
363
|
bucket: storage.bucket,
|
|
340
364
|
endpoint: S3_ENDPOINT,
|
|
@@ -347,5 +371,8 @@ export class StorageService {
|
|
|
347
371
|
}
|
|
348
372
|
}
|
|
349
373
|
__decorate([
|
|
350
|
-
Retryable({
|
|
374
|
+
Retryable({
|
|
375
|
+
maxAttempts: 3,
|
|
376
|
+
value: [StoragesUndefinedError, StorageCreateError, ProviderClientError],
|
|
377
|
+
})
|
|
351
378
|
], StorageService.prototype, "getCentralizedStorage", null);
|
package/dist/utils/helper.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const getConfigName: (name: string) => string;
|
|
2
|
+
export declare const getConfigNameFromCredentials: (privateKey: string, url: string) => string;
|
|
2
3
|
export declare const preparePath: (rawPath: string) => string;
|
|
3
4
|
export declare const joinPaths: (...args: string[]) => string;
|
|
4
5
|
export type ReadJsonFileParams = {
|
package/dist/utils/helper.js
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { existsSync } from 'node:fs';
|
|
2
3
|
import * as fs from 'node:fs/promises';
|
|
3
4
|
import path from 'node:path';
|
|
4
|
-
export const getConfigName = (name) => name.toLowerCase().replaceAll(/[^a-z0-9]+/g, '-')
|
|
5
|
+
export const getConfigName = (name) => `${name.toLowerCase().replaceAll(/[^a-z0-9]+/g, '-')}.config.json`;
|
|
6
|
+
export const getConfigNameFromCredentials = (privateKey, url) => {
|
|
7
|
+
const normalizedKey = privateKey.trim();
|
|
8
|
+
const normalizedUrl = url.trim();
|
|
9
|
+
if (!normalizedKey || !normalizedUrl) {
|
|
10
|
+
throw new Error('Private key and URL must not be empty');
|
|
11
|
+
}
|
|
12
|
+
const hashBuilder = createHash('sha256');
|
|
13
|
+
hashBuilder.update(normalizedKey);
|
|
14
|
+
hashBuilder.update('|');
|
|
15
|
+
hashBuilder.update(normalizedUrl);
|
|
16
|
+
const hash = hashBuilder.digest('hex');
|
|
17
|
+
return `${hash}.config.json`;
|
|
18
|
+
};
|
|
5
19
|
export const preparePath = (rawPath) => {
|
|
6
20
|
if (path.isAbsolute(rawPath))
|
|
7
21
|
return rawPath;
|