@super-protocol/sp-cli 0.0.1-alpha.35 → 0.0.2
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 +260 -65
- package/bin/dev.cmd +1 -1
- package/bin/dev.js +5 -3
- package/bin/run.js +3 -2
- package/dist/commands/auth/login.d.ts +3 -2
- package/dist/commands/auth/login.js +52 -24
- package/dist/commands/auth/me.d.ts +3 -2
- package/dist/commands/auth/me.js +9 -4
- package/dist/commands/base.d.ts +18 -0
- package/dist/commands/base.js +45 -0
- package/dist/commands/config/add.d.ts +13 -0
- package/dist/commands/config/add.js +84 -0
- package/dist/commands/config/base.d.ts +14 -0
- package/dist/commands/config/base.js +62 -0
- package/dist/commands/config/create.d.ts +11 -0
- package/dist/commands/config/create.js +51 -0
- package/dist/commands/config/delete.d.ts +10 -0
- package/dist/commands/config/delete.js +25 -0
- package/dist/commands/config/index.d.ts +6 -0
- package/dist/commands/config/index.js +22 -0
- package/dist/commands/config/list.d.ts +6 -0
- package/dist/commands/config/list.js +39 -0
- package/dist/commands/config/show.d.ts +6 -0
- package/dist/commands/config/show.js +10 -0
- package/dist/commands/config/use.d.ts +6 -0
- package/dist/commands/config/use.js +25 -0
- package/dist/config/config-file.schema.d.ts +6 -0
- package/dist/config/config-file.schema.js +5 -0
- package/dist/config/config.schema.d.ts +2 -0
- package/dist/config/config.schema.js +12 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +5 -0
- package/dist/hooks/init/init-container.d.ts +3 -0
- package/dist/hooks/init/init-container.js +6 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +23 -1
- package/dist/interfaces/index.d.ts +0 -1
- package/dist/interfaces/index.js +0 -1
- package/dist/interfaces/manager.interface.d.ts +1 -1
- package/dist/lib/container.d.ts +40 -0
- package/dist/lib/container.js +177 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +62 -0
- package/dist/managers/account-manager.d.ts +2 -2
- package/dist/managers/account-manager.js +18 -9
- package/dist/managers/config-file-manager.d.ts +50 -0
- package/dist/managers/config-file-manager.js +278 -0
- package/dist/managers/config-manager.d.ts +12 -6
- package/dist/managers/config-manager.js +38 -14
- package/dist/managers/index.d.ts +1 -2
- package/dist/managers/index.js +1 -2
- package/dist/middlewares/auth-middleware.d.ts +9 -0
- package/dist/middlewares/auth-middleware.js +87 -0
- package/dist/middlewares/cookies-middleware.d.ts +8 -0
- package/dist/middlewares/cookies-middleware.js +80 -0
- package/dist/utils/helper.d.ts +1 -0
- package/dist/utils/helper.js +1 -0
- package/oclif.manifest.json +545 -7
- package/package.json +32 -14
- package/dist/commands/refresh.d.ts +0 -4
- package/dist/commands/refresh.js +0 -7
- package/dist/config/constants.d.ts +0 -1
- package/dist/config/constants.js +0 -2
- package/dist/interfaces/abstract.command.d.ts +0 -16
- package/dist/interfaces/abstract.command.js +0 -59
- package/dist/managers/auth-manager.d.ts +0 -19
- package/dist/managers/auth-manager.js +0 -101
- package/dist/managers/cookies-manager.d.ts +0 -15
- package/dist/managers/cookies-manager.js +0 -92
package/dist/commands/refresh.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const PROVIDER_BASE_URL: string;
|
package/dist/config/constants.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
import { ProviderClient } from '@super-protocol/provider-client';
|
|
3
|
-
import pino from 'pino';
|
|
4
|
-
import { AuthManager, CookiesManager } from '../managers/index.js';
|
|
5
|
-
import { IAccountManager } from './account-manager.interface.js';
|
|
6
|
-
import { IConfigManager } from './config-manager.interface.js';
|
|
7
|
-
export declare abstract class SpCommand extends Command {
|
|
8
|
-
protected accountManager: IAccountManager;
|
|
9
|
-
protected authManager: AuthManager;
|
|
10
|
-
protected configManager: IConfigManager;
|
|
11
|
-
protected cookiesManager: CookiesManager;
|
|
12
|
-
protected logger: pino.BaseLogger;
|
|
13
|
-
protected providerClient: ProviderClient;
|
|
14
|
-
getConfigManager(): IConfigManager;
|
|
15
|
-
init(): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
import { createProviderClient, loggerMiddleware, requestIdMiddleware, } from '@super-protocol/provider-client';
|
|
3
|
-
import pino from 'pino';
|
|
4
|
-
import { PROVIDER_BASE_URL } from '../config/constants.js';
|
|
5
|
-
import { AccountManager, AuthManager, ConfigManager, CookiesManager, } from '../managers/index.js';
|
|
6
|
-
export class SpCommand extends Command {
|
|
7
|
-
accountManager;
|
|
8
|
-
authManager;
|
|
9
|
-
configManager;
|
|
10
|
-
cookiesManager;
|
|
11
|
-
logger;
|
|
12
|
-
providerClient;
|
|
13
|
-
getConfigManager() {
|
|
14
|
-
return this.configManager;
|
|
15
|
-
}
|
|
16
|
-
async init() {
|
|
17
|
-
this.logger = pino({
|
|
18
|
-
level: process.env.SP_LOG_LEVEL || 'silent',
|
|
19
|
-
transport: {
|
|
20
|
-
options: {
|
|
21
|
-
colorize: true,
|
|
22
|
-
},
|
|
23
|
-
target: 'pino-pretty',
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
await super.init();
|
|
27
|
-
this.logger.info('Initializing config manager');
|
|
28
|
-
this.configManager = new ConfigManager(this.config, this.logger);
|
|
29
|
-
await this.configManager.init(this.id);
|
|
30
|
-
this.logger.info('Initializing account manager');
|
|
31
|
-
this.accountManager = new AccountManager(this.configManager, this.logger);
|
|
32
|
-
await this.accountManager.init(this.id);
|
|
33
|
-
this.logger.info('Initializing provider client');
|
|
34
|
-
this.providerClient = createProviderClient({
|
|
35
|
-
baseUrl: PROVIDER_BASE_URL,
|
|
36
|
-
logger: this.logger,
|
|
37
|
-
middlewares: [requestIdMiddleware, loggerMiddleware],
|
|
38
|
-
});
|
|
39
|
-
this.providerClient.use({
|
|
40
|
-
onRequest: async ({ request }) => {
|
|
41
|
-
const req = request.clone();
|
|
42
|
-
const readBody = await req.body?.getReader().read();
|
|
43
|
-
let body;
|
|
44
|
-
if (readBody && readBody.value)
|
|
45
|
-
body = Buffer.from(readBody.value).toString('utf8');
|
|
46
|
-
this.logger.debug({
|
|
47
|
-
body,
|
|
48
|
-
url: req.url,
|
|
49
|
-
}, 'Requesting');
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
this.logger.info('Initializing cookies manager');
|
|
53
|
-
this.cookiesManager = new CookiesManager(this.configManager, this.providerClient, this.logger, PROVIDER_BASE_URL);
|
|
54
|
-
await this.cookiesManager.init(this.id);
|
|
55
|
-
this.logger.info('Initializing authorization manager');
|
|
56
|
-
this.authManager = new AuthManager(this.configManager, this.providerClient, this.logger);
|
|
57
|
-
await this.authManager.init(this.id);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ProviderClient } from '@super-protocol/provider-client';
|
|
2
|
-
import pino from 'pino';
|
|
3
|
-
import { Auth } from '../config/config.schema.js';
|
|
4
|
-
import { IConfigManager, IManager } from '../interfaces/index.js';
|
|
5
|
-
export declare class AuthManager implements IManager {
|
|
6
|
-
private readonly configManager;
|
|
7
|
-
private readonly providerClient;
|
|
8
|
-
private readonly logger;
|
|
9
|
-
private auth?;
|
|
10
|
-
private refreshPromise?;
|
|
11
|
-
private readonly skipCommands;
|
|
12
|
-
constructor(configManager: IConfigManager, providerClient: ProviderClient, logger: pino.BaseLogger);
|
|
13
|
-
ensureAccessKey(forceRefresh?: boolean): Promise<string | undefined>;
|
|
14
|
-
init(command?: string): Promise<void>;
|
|
15
|
-
setCredentials(auth: Auth): Promise<void>;
|
|
16
|
-
private isAccessKeyExpired;
|
|
17
|
-
private performRefresh;
|
|
18
|
-
private refreshAccessKey;
|
|
19
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { decode } from 'jsonwebtoken';
|
|
2
|
-
import { AuthorizationRequiredError } from '../errors.js';
|
|
3
|
-
export class AuthManager {
|
|
4
|
-
configManager;
|
|
5
|
-
providerClient;
|
|
6
|
-
logger;
|
|
7
|
-
auth;
|
|
8
|
-
refreshPromise;
|
|
9
|
-
skipCommands = ['init', 'help', 'version', 'auth:login'];
|
|
10
|
-
constructor(configManager, providerClient, logger) {
|
|
11
|
-
this.configManager = configManager;
|
|
12
|
-
this.providerClient = providerClient;
|
|
13
|
-
this.logger = logger;
|
|
14
|
-
}
|
|
15
|
-
async ensureAccessKey(forceRefresh = false) {
|
|
16
|
-
if (!this.auth) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
const { accessKey } = this.auth;
|
|
20
|
-
if (!forceRefresh && accessKey && !this.isAccessKeyExpired(accessKey)) {
|
|
21
|
-
return accessKey;
|
|
22
|
-
}
|
|
23
|
-
return this.refreshAccessKey();
|
|
24
|
-
}
|
|
25
|
-
async init(command) {
|
|
26
|
-
if (command && this.skipCommands.includes(command)) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
this.auth = await this.configManager.get('auth');
|
|
30
|
-
if (!this.auth) {
|
|
31
|
-
throw new AuthorizationRequiredError('Authorization not found please login first');
|
|
32
|
-
}
|
|
33
|
-
this.logger.info('Setup authorization middleware');
|
|
34
|
-
this.providerClient.use({
|
|
35
|
-
onRequest: async ({ request }) => {
|
|
36
|
-
const accessToken = await this.ensureAccessKey();
|
|
37
|
-
if (accessToken) {
|
|
38
|
-
request.headers.set('Authorization', `Bearer ${accessToken}`);
|
|
39
|
-
}
|
|
40
|
-
return request;
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
async setCredentials(auth) {
|
|
45
|
-
this.auth = auth;
|
|
46
|
-
await this.configManager.set('auth', auth);
|
|
47
|
-
}
|
|
48
|
-
isAccessKeyExpired(accessKey) {
|
|
49
|
-
try {
|
|
50
|
-
const payload = decode(accessKey);
|
|
51
|
-
if (!payload || typeof payload.exp !== 'number') {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
const now = Math.floor(Date.now() / 1000);
|
|
55
|
-
return now >= payload.exp;
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async performRefresh() {
|
|
62
|
-
if (!this.auth) {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
this.logger.info('Performed refresh token');
|
|
66
|
-
let refreshResult;
|
|
67
|
-
try {
|
|
68
|
-
refreshResult = await this.providerClient.POST('/api/auth/refresh-access');
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
this.logger.error({ err: error }, 'failure refresh token');
|
|
72
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
73
|
-
throw new AuthorizationRequiredError(`Unable to reach provider API: ${message}`);
|
|
74
|
-
}
|
|
75
|
-
const { data, error: refreshError } = refreshResult;
|
|
76
|
-
if (refreshError) {
|
|
77
|
-
this.logger.error({ refreshError }, 'Faulire refresh response');
|
|
78
|
-
throw new AuthorizationRequiredError(`Unable to refresh access key: ${JSON.stringify(refreshError)}`);
|
|
79
|
-
}
|
|
80
|
-
if (!data || !data.accessToken) {
|
|
81
|
-
this.logger.error({ response: data }, 'Server returned incorrect response');
|
|
82
|
-
throw new AuthorizationRequiredError('Provider returned an unexpected refresh response.');
|
|
83
|
-
}
|
|
84
|
-
const updatedAuth = {
|
|
85
|
-
accessKey: data.accessToken,
|
|
86
|
-
};
|
|
87
|
-
this.setCredentials(updatedAuth);
|
|
88
|
-
return updatedAuth.accessKey;
|
|
89
|
-
}
|
|
90
|
-
async refreshAccessKey() {
|
|
91
|
-
if (!this.auth) {
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
if (!this.refreshPromise) {
|
|
95
|
-
this.refreshPromise = this.performRefresh().finally(() => {
|
|
96
|
-
this.refreshPromise = undefined;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
return this.refreshPromise;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { ProviderClient } from '@super-protocol/provider-client';
|
|
2
|
-
import type pino from 'pino';
|
|
3
|
-
import type { IConfigManager, IManager } from '../interfaces/index.js';
|
|
4
|
-
export declare class CookiesManager implements IManager {
|
|
5
|
-
private readonly configManager;
|
|
6
|
-
private readonly providerClient;
|
|
7
|
-
private readonly logger;
|
|
8
|
-
private readonly baseUrl;
|
|
9
|
-
private cookieJar;
|
|
10
|
-
constructor(configManager: IConfigManager, providerClient: ProviderClient, logger: pino.BaseLogger, baseUrl: string);
|
|
11
|
-
init(_command?: string): Promise<void>;
|
|
12
|
-
private extractSetCookieHeaders;
|
|
13
|
-
private loadCookieJar;
|
|
14
|
-
private persistCookieJar;
|
|
15
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { CookieJar } from 'tough-cookie';
|
|
2
|
-
export class CookiesManager {
|
|
3
|
-
configManager;
|
|
4
|
-
providerClient;
|
|
5
|
-
logger;
|
|
6
|
-
baseUrl;
|
|
7
|
-
cookieJar = new CookieJar();
|
|
8
|
-
constructor(configManager, providerClient, logger, baseUrl) {
|
|
9
|
-
this.configManager = configManager;
|
|
10
|
-
this.providerClient = providerClient;
|
|
11
|
-
this.logger = logger;
|
|
12
|
-
this.baseUrl = baseUrl;
|
|
13
|
-
}
|
|
14
|
-
async init(_command) {
|
|
15
|
-
await this.loadCookieJar();
|
|
16
|
-
this.providerClient.use({
|
|
17
|
-
onRequest: async ({ request }) => {
|
|
18
|
-
const requestUrl = request.url ?? this.baseUrl;
|
|
19
|
-
try {
|
|
20
|
-
const cookieHeader = await this.cookieJar.getCookieString(requestUrl);
|
|
21
|
-
if (cookieHeader) {
|
|
22
|
-
request.headers.set('Cookie', cookieHeader);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
this.logger.warn({ err: error, requestUrl }, 'Failed to attach cookies to request');
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
onResponse: async ({ response }) => {
|
|
30
|
-
const rawCookies = this.extractSetCookieHeaders(response);
|
|
31
|
-
if (rawCookies.length === 0) {
|
|
32
|
-
return response;
|
|
33
|
-
}
|
|
34
|
-
const targetUrl = response.url || this.baseUrl;
|
|
35
|
-
const updates = await Promise.all(rawCookies.map(async (rawCookie) => {
|
|
36
|
-
try {
|
|
37
|
-
const storedCookie = await this.cookieJar.setCookie(rawCookie, targetUrl);
|
|
38
|
-
if (storedCookie) {
|
|
39
|
-
this.logger.debug({ cookie: storedCookie.key }, 'Updated cookie from response');
|
|
40
|
-
}
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
this.logger.warn({ err: error, rawCookie }, 'Failed to store cookie from response');
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}));
|
|
48
|
-
if (updates.some(Boolean)) {
|
|
49
|
-
await this.persistCookieJar();
|
|
50
|
-
}
|
|
51
|
-
return response;
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
extractSetCookieHeaders(response) {
|
|
56
|
-
const cookiesFromGetter = response.headers.getSetCookie?.();
|
|
57
|
-
if (cookiesFromGetter && cookiesFromGetter.length > 0) {
|
|
58
|
-
return cookiesFromGetter;
|
|
59
|
-
}
|
|
60
|
-
// For capability to nodejs < 20
|
|
61
|
-
const headersWithRaw = response.headers;
|
|
62
|
-
const raw = headersWithRaw.raw?.();
|
|
63
|
-
const headerList = raw?.['set-cookie'];
|
|
64
|
-
if (headerList && headerList.length > 0) {
|
|
65
|
-
return headerList;
|
|
66
|
-
}
|
|
67
|
-
const headerValue = response.headers.get('set-cookie');
|
|
68
|
-
return headerValue ? [headerValue] : [];
|
|
69
|
-
}
|
|
70
|
-
async loadCookieJar() {
|
|
71
|
-
try {
|
|
72
|
-
const stored = await this.configManager.get('cookies');
|
|
73
|
-
if (stored && typeof stored === 'object') {
|
|
74
|
-
this.cookieJar = CookieJar.fromJSON(stored);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
this.logger.warn({ err: error }, 'Failed to load cookies from config');
|
|
80
|
-
}
|
|
81
|
-
this.cookieJar = new CookieJar();
|
|
82
|
-
}
|
|
83
|
-
async persistCookieJar() {
|
|
84
|
-
try {
|
|
85
|
-
const serialized = this.cookieJar.toJSON();
|
|
86
|
-
await this.configManager.set('cookies', serialized);
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
this.logger.warn({ err: error }, 'Failed to persist cookies');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|