apipay 0.1.0
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 +141 -0
- package/bin/dev.js +5 -0
- package/bin/run.js +4 -0
- package/dist/commands/banks/add.d.ts +7 -0
- package/dist/commands/banks/add.d.ts.map +1 -0
- package/dist/commands/banks/add.js +84 -0
- package/dist/commands/banks/add.js.map +1 -0
- package/dist/commands/banks/list.d.ts +7 -0
- package/dist/commands/banks/list.d.ts.map +1 -0
- package/dist/commands/banks/list.js +37 -0
- package/dist/commands/banks/list.js.map +1 -0
- package/dist/commands/banks/remove.d.ts +10 -0
- package/dist/commands/banks/remove.d.ts.map +1 -0
- package/dist/commands/banks/remove.js +47 -0
- package/dist/commands/banks/remove.js.map +1 -0
- package/dist/commands/banks/toggle.d.ts +10 -0
- package/dist/commands/banks/toggle.d.ts.map +1 -0
- package/dist/commands/banks/toggle.js +29 -0
- package/dist/commands/banks/toggle.js.map +1 -0
- package/dist/commands/config/get.d.ts +10 -0
- package/dist/commands/config/get.d.ts.map +1 -0
- package/dist/commands/config/get.js +50 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/reset.d.ts +7 -0
- package/dist/commands/config/reset.d.ts.map +1 -0
- package/dist/commands/config/reset.js +21 -0
- package/dist/commands/config/reset.js.map +1 -0
- package/dist/commands/config/set.d.ts +11 -0
- package/dist/commands/config/set.d.ts.map +1 -0
- package/dist/commands/config/set.js +25 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/init.d.ts +18 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +109 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/keys/create.d.ts +7 -0
- package/dist/commands/keys/create.d.ts.map +1 -0
- package/dist/commands/keys/create.js +68 -0
- package/dist/commands/keys/create.js.map +1 -0
- package/dist/commands/keys/list.d.ts +7 -0
- package/dist/commands/keys/list.d.ts.map +1 -0
- package/dist/commands/keys/list.js +36 -0
- package/dist/commands/keys/list.js.map +1 -0
- package/dist/commands/keys/revoke.d.ts +10 -0
- package/dist/commands/keys/revoke.d.ts.map +1 -0
- package/dist/commands/keys/revoke.js +66 -0
- package/dist/commands/keys/revoke.js.map +1 -0
- package/dist/commands/login.d.ts +17 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +171 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +32 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/metrics/summary.d.ts +7 -0
- package/dist/commands/metrics/summary.d.ts.map +1 -0
- package/dist/commands/metrics/summary.js +38 -0
- package/dist/commands/metrics/summary.js.map +1 -0
- package/dist/commands/metrics/transactions.d.ts +13 -0
- package/dist/commands/metrics/transactions.d.ts.map +1 -0
- package/dist/commands/metrics/transactions.js +51 -0
- package/dist/commands/metrics/transactions.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +98 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/webhooks/add.d.ts +7 -0
- package/dist/commands/webhooks/add.d.ts.map +1 -0
- package/dist/commands/webhooks/add.js +66 -0
- package/dist/commands/webhooks/add.js.map +1 -0
- package/dist/commands/webhooks/history.d.ts +10 -0
- package/dist/commands/webhooks/history.d.ts.map +1 -0
- package/dist/commands/webhooks/history.js +42 -0
- package/dist/commands/webhooks/history.js.map +1 -0
- package/dist/commands/webhooks/list.d.ts +7 -0
- package/dist/commands/webhooks/list.d.ts.map +1 -0
- package/dist/commands/webhooks/list.js +37 -0
- package/dist/commands/webhooks/list.js.map +1 -0
- package/dist/commands/webhooks/remove.d.ts +10 -0
- package/dist/commands/webhooks/remove.d.ts.map +1 -0
- package/dist/commands/webhooks/remove.js +34 -0
- package/dist/commands/webhooks/remove.js.map +1 -0
- package/dist/commands/webhooks/resend.d.ts +10 -0
- package/dist/commands/webhooks/resend.d.ts.map +1 -0
- package/dist/commands/webhooks/resend.js +28 -0
- package/dist/commands/webhooks/resend.js.map +1 -0
- package/dist/commands/webhooks/toggle.d.ts +10 -0
- package/dist/commands/webhooks/toggle.d.ts.map +1 -0
- package/dist/commands/webhooks/toggle.js +29 -0
- package/dist/commands/webhooks/toggle.js.map +1 -0
- package/dist/commands/webhooks/update.d.ts +10 -0
- package/dist/commands/webhooks/update.d.ts.map +1 -0
- package/dist/commands/webhooks/update.js +42 -0
- package/dist/commands/webhooks/update.js.map +1 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +33 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +44 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +177 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/base-command.d.ts +42 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +81 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/lib/config.d.ts +50 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +106 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +44 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +33 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/formatters.d.ts +26 -0
- package/dist/lib/formatters.d.ts.map +1 -0
- package/dist/lib/formatters.js +96 -0
- package/dist/lib/formatters.js.map +1 -0
- package/dist/lib/prompts.d.ts +21 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +92 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/validators.d.ts +12 -0
- package/dist/lib/validators.d.ts.map +1 -0
- package/dist/lib/validators.js +91 -0
- package/dist/lib/validators.js.map +1 -0
- package/oclif.manifest.json +1002 -0
- package/package.json +84 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { ApiKeyCommand } from '../../lib/base-command.js';
|
|
4
|
+
import { success, kvLine } from '../../lib/formatters.js';
|
|
5
|
+
import { promptWebhookUrl, promptWebhookType } from '../../lib/prompts.js';
|
|
6
|
+
export default class WebhooksUpdate extends ApiKeyCommand {
|
|
7
|
+
static description = 'Update a webhook URL or transaction type';
|
|
8
|
+
static args = {
|
|
9
|
+
id: Args.string({ description: 'Webhook ID', required: true }),
|
|
10
|
+
};
|
|
11
|
+
static examples = ['<%= config.bin %> webhooks:update <webhook-id>'];
|
|
12
|
+
async run() {
|
|
13
|
+
const { args } = await this.parse(WebhooksUpdate);
|
|
14
|
+
console.log(`\n Updating webhook ${chalk.cyan(args.id.slice(0, 8))}...\n`);
|
|
15
|
+
console.log(' Leave blank to keep the current value.\n');
|
|
16
|
+
const webhookUrl = await promptWebhookUrl();
|
|
17
|
+
const type = await promptWebhookType();
|
|
18
|
+
this.spinner.start('Updating webhook...');
|
|
19
|
+
try {
|
|
20
|
+
const body = {};
|
|
21
|
+
if (webhookUrl)
|
|
22
|
+
body.webhookUrl = webhookUrl;
|
|
23
|
+
if (type)
|
|
24
|
+
body.type = type;
|
|
25
|
+
const data = await this.api.patch(`/client/webhooks/${args.id}`, body, 'apikey');
|
|
26
|
+
const webhook = data?.data ?? data;
|
|
27
|
+
this.spinner.succeed('Webhook updated!');
|
|
28
|
+
kvLine('URL', webhook?.webhookUrl ?? webhookUrl);
|
|
29
|
+
kvLine('Type', webhook?.type ?? type);
|
|
30
|
+
console.log('');
|
|
31
|
+
success('Webhook configuration updated.');
|
|
32
|
+
if (this.jsonOutput) {
|
|
33
|
+
this.outputJson(webhook);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.spinner.fail('Failed to update webhook');
|
|
38
|
+
this.handleError(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/webhooks/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,aAAa;IACvD,MAAM,CAAU,WAAW,GAAG,0CAA0C,CAAC;IAEzE,MAAM,CAAU,IAAI,GAAG;QACrB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KAC/D,CAAC;IAEF,MAAM,CAAU,QAAQ,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAE9E,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAElD,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAE1D,MAAM,UAAU,GAAG,MAAM,gBAAgB,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAEvC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,IAAI,GAA2B,EAAE,CAAC;YACxC,IAAI,UAAU;gBAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7C,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YAE3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACjF,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YAEnC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,IAAI,UAAU,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC9C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAI9D,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,oBAAoB;IACtD,OAAgB,WAAW,SAA8C;IAEzE,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2B3B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { AuthenticatedCommand } from '../lib/base-command.js';
|
|
3
|
+
import { getAuth } from '../lib/config.js';
|
|
4
|
+
import { kvLine } from '../lib/formatters.js';
|
|
5
|
+
export default class Whoami extends AuthenticatedCommand {
|
|
6
|
+
static description = 'Display the currently authenticated user';
|
|
7
|
+
static examples = ['<%= config.bin %> whoami'];
|
|
8
|
+
async run() {
|
|
9
|
+
this.spinner.start('Fetching profile...');
|
|
10
|
+
try {
|
|
11
|
+
const data = await this.api.post('/auth/me', undefined, 'jwt');
|
|
12
|
+
const user = data?.data ?? data;
|
|
13
|
+
this.spinner.stop();
|
|
14
|
+
console.log('');
|
|
15
|
+
console.log(chalk.bold(' Current User'));
|
|
16
|
+
console.log(chalk.gray(' ────────────'));
|
|
17
|
+
kvLine('Email', user?.email ?? getAuth()?.email ?? 'unknown');
|
|
18
|
+
kvLine('Name', user?.name ?? '—');
|
|
19
|
+
kvLine('Role', user?.role ?? 'USER');
|
|
20
|
+
kvLine('Active', user?.isActive ? chalk.green('Yes') : chalk.red('No'));
|
|
21
|
+
kvLine('User ID', user?.id ?? '');
|
|
22
|
+
console.log('');
|
|
23
|
+
if (this.jsonOutput) {
|
|
24
|
+
this.outputJson(user);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
this.spinner.fail('Failed to fetch profile');
|
|
29
|
+
this.handleError(error);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,oBAAoB;IACtD,MAAM,CAAU,WAAW,GAAG,0CAA0C,CAAC;IAEzE,MAAM,CAAU,QAAQ,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExD,KAAK,CAAC,GAAG;QACP,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC/D,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YAEhC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAEpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,OAAO,EAAE,EAAE,KAAK,IAAI,SAAS,CAAC,CAAC;YAC9D,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACxE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YAC7C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API error structure
|
|
3
|
+
*/
|
|
4
|
+
export declare class ApiError extends Error {
|
|
5
|
+
statusCode: number;
|
|
6
|
+
body: any;
|
|
7
|
+
constructor(statusCode: number, body: any);
|
|
8
|
+
}
|
|
9
|
+
type AuthMode = 'jwt' | 'apikey' | 'none';
|
|
10
|
+
/**
|
|
11
|
+
* API Client
|
|
12
|
+
* Wraps fetch with auth, retry, and token refresh logic.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ApiClient {
|
|
15
|
+
private baseUrl;
|
|
16
|
+
constructor(baseUrl?: string);
|
|
17
|
+
private getHeaders;
|
|
18
|
+
/**
|
|
19
|
+
* Try to refresh the JWT access token using the stored refresh token.
|
|
20
|
+
*/
|
|
21
|
+
private refreshToken;
|
|
22
|
+
/**
|
|
23
|
+
* Core request method with retry and auto-refresh.
|
|
24
|
+
*/
|
|
25
|
+
request<T = any>(method: string, path: string, options?: {
|
|
26
|
+
body?: any;
|
|
27
|
+
authMode?: AuthMode;
|
|
28
|
+
retries?: number;
|
|
29
|
+
}): Promise<T>;
|
|
30
|
+
get<T = any>(path: string, authMode?: AuthMode): Promise<T>;
|
|
31
|
+
post<T = any>(path: string, body?: any, authMode?: AuthMode): Promise<T>;
|
|
32
|
+
patch<T = any>(path: string, body?: any, authMode?: AuthMode): Promise<T>;
|
|
33
|
+
delete<T = any>(path: string, authMode?: AuthMode): Promise<T>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get singleton API client
|
|
37
|
+
*/
|
|
38
|
+
export declare function getApiClient(): ApiClient;
|
|
39
|
+
/**
|
|
40
|
+
* Format API error for display
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatApiError(error: unknown): string;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAExB,UAAU,EAAE,MAAM;IAClB,IAAI,EAAE,GAAG;gBADT,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG;CAWnB;AAED,KAAK,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE1C;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B,OAAO,CAAC,UAAU;IAqBlB;;OAEG;YACW,YAAY;IAmC1B;;OAEG;IACG,OAAO,CAAC,CAAC,GAAG,GAAG,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,OAAO,CAAC,CAAC,CAAC;IAkDb,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB;IAItD,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAE,QAAiB;IAInE,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAE,QAAiB;IAIpE,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB;CAG1D;AAID;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAKxC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAuBrD"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getApiBaseUrl, getApiKey, getAuth, setAuth } from './config.js';
|
|
3
|
+
import { MAX_RETRIES, RETRY_DELAY_MS } from './constants.js';
|
|
4
|
+
/**
|
|
5
|
+
* API error structure
|
|
6
|
+
*/
|
|
7
|
+
export class ApiError extends Error {
|
|
8
|
+
statusCode;
|
|
9
|
+
body;
|
|
10
|
+
constructor(statusCode, body) {
|
|
11
|
+
const msg = typeof body?.message === 'string'
|
|
12
|
+
? body.message
|
|
13
|
+
: typeof body?.data?.message === 'string'
|
|
14
|
+
? body.data.message
|
|
15
|
+
: `API request failed with status ${statusCode}`;
|
|
16
|
+
super(msg);
|
|
17
|
+
this.statusCode = statusCode;
|
|
18
|
+
this.body = body;
|
|
19
|
+
this.name = 'ApiError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* API Client
|
|
24
|
+
* Wraps fetch with auth, retry, and token refresh logic.
|
|
25
|
+
*/
|
|
26
|
+
export class ApiClient {
|
|
27
|
+
baseUrl;
|
|
28
|
+
constructor(baseUrl) {
|
|
29
|
+
this.baseUrl = baseUrl ?? getApiBaseUrl();
|
|
30
|
+
}
|
|
31
|
+
getHeaders(authMode) {
|
|
32
|
+
const headers = {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
Accept: 'application/json',
|
|
35
|
+
};
|
|
36
|
+
if (authMode === 'jwt') {
|
|
37
|
+
const auth = getAuth();
|
|
38
|
+
if (auth?.accessToken) {
|
|
39
|
+
headers['Authorization'] = `Bearer ${auth.accessToken}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (authMode === 'apikey') {
|
|
43
|
+
const key = getApiKey();
|
|
44
|
+
if (key?.accessKey && key?.secretKey) {
|
|
45
|
+
headers['Authorization'] = `Bearer ${key.accessKey}:${key.secretKey}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return headers;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Try to refresh the JWT access token using the stored refresh token.
|
|
52
|
+
*/
|
|
53
|
+
async refreshToken() {
|
|
54
|
+
const auth = getAuth();
|
|
55
|
+
if (!auth?.refreshToken)
|
|
56
|
+
return false;
|
|
57
|
+
try {
|
|
58
|
+
const res = await fetch(`${this.baseUrl}/auth/refresh`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: {
|
|
61
|
+
'Content-Type': 'application/json',
|
|
62
|
+
Authorization: `Bearer ${auth.accessToken}`,
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({ refreshToken: auth.refreshToken }),
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok)
|
|
67
|
+
return false;
|
|
68
|
+
const json = (await res.json());
|
|
69
|
+
const tokens = json.data?.data ?? json.data;
|
|
70
|
+
if (tokens?.accessToken) {
|
|
71
|
+
setAuth({
|
|
72
|
+
...auth,
|
|
73
|
+
accessToken: tokens.accessToken,
|
|
74
|
+
refreshToken: tokens.refreshToken ?? auth.refreshToken,
|
|
75
|
+
expiresAt: Date.now() + (tokens.expiresIn ?? 900) * 1000,
|
|
76
|
+
});
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// refresh failed silently
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Core request method with retry and auto-refresh.
|
|
87
|
+
*/
|
|
88
|
+
async request(method, path, options = {}) {
|
|
89
|
+
const { body, authMode = 'none', retries = MAX_RETRIES } = options;
|
|
90
|
+
const url = `${this.baseUrl}${path}`;
|
|
91
|
+
let lastError = null;
|
|
92
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
93
|
+
try {
|
|
94
|
+
const res = await fetch(url, {
|
|
95
|
+
method,
|
|
96
|
+
headers: this.getHeaders(authMode),
|
|
97
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
98
|
+
});
|
|
99
|
+
// Auto-refresh on 401 for JWT
|
|
100
|
+
if (res.status === 401 && authMode === 'jwt' && attempt === 0) {
|
|
101
|
+
const refreshed = await this.refreshToken();
|
|
102
|
+
if (refreshed)
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const json = (await res.json());
|
|
106
|
+
if (!res.ok) {
|
|
107
|
+
throw new ApiError(res.status, json);
|
|
108
|
+
}
|
|
109
|
+
// Unwrap the backend envelope: { data: { ... }, statusCode, timestamp }
|
|
110
|
+
return (json?.data ?? json);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
lastError = error;
|
|
114
|
+
if (error instanceof ApiError) {
|
|
115
|
+
// Don't retry client errors (4xx) except 429
|
|
116
|
+
if (error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (attempt < retries) {
|
|
121
|
+
const delay = RETRY_DELAY_MS * Math.pow(2, attempt);
|
|
122
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
throw lastError ?? new Error('Request failed');
|
|
127
|
+
}
|
|
128
|
+
/* ===== Convenience methods ===== */
|
|
129
|
+
get(path, authMode = 'none') {
|
|
130
|
+
return this.request('GET', path, { authMode });
|
|
131
|
+
}
|
|
132
|
+
post(path, body, authMode = 'none') {
|
|
133
|
+
return this.request('POST', path, { body, authMode });
|
|
134
|
+
}
|
|
135
|
+
patch(path, body, authMode = 'none') {
|
|
136
|
+
return this.request('PATCH', path, { body, authMode });
|
|
137
|
+
}
|
|
138
|
+
delete(path, authMode = 'none') {
|
|
139
|
+
return this.request('DELETE', path, { authMode });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
let _client = null;
|
|
143
|
+
/**
|
|
144
|
+
* Get singleton API client
|
|
145
|
+
*/
|
|
146
|
+
export function getApiClient() {
|
|
147
|
+
if (!_client) {
|
|
148
|
+
_client = new ApiClient();
|
|
149
|
+
}
|
|
150
|
+
return _client;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Format API error for display
|
|
154
|
+
*/
|
|
155
|
+
export function formatApiError(error) {
|
|
156
|
+
if (error instanceof ApiError) {
|
|
157
|
+
switch (error.statusCode) {
|
|
158
|
+
case 401:
|
|
159
|
+
return `${chalk.red('Authentication failed.')} Run ${chalk.cyan('apipay login')} to sign in.`;
|
|
160
|
+
case 403:
|
|
161
|
+
return `${chalk.red('Permission denied.')} You don't have access to this resource.`;
|
|
162
|
+
case 404:
|
|
163
|
+
return chalk.red('Resource not found.');
|
|
164
|
+
case 409:
|
|
165
|
+
return chalk.red(error.message);
|
|
166
|
+
case 429:
|
|
167
|
+
return chalk.yellow('Rate limit exceeded. Please wait and try again.');
|
|
168
|
+
default:
|
|
169
|
+
return chalk.red(error.message);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (error instanceof TypeError && error.cause?.code === 'ECONNREFUSED') {
|
|
173
|
+
return `${chalk.red('Cannot reach the API server.')} Check your connection or run ${chalk.cyan('apipay config:set apiBaseUrl <url>')} to update the endpoint.`;
|
|
174
|
+
}
|
|
175
|
+
return chalk.red(String(error));
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAW7D;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IAExB;IACA;IAFT,YACS,UAAkB,EAClB,IAAS;QAEhB,MAAM,GAAG,GACP,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ;YAC/B,CAAC,CAAC,IAAI,CAAC,OAAO;YACd,CAAC,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,OAAO,KAAK,QAAQ;gBACvC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO;gBACnB,CAAC,CAAC,kCAAkC,UAAU,EAAE,CAAC;QACvD,KAAK,CAAC,GAAG,CAAC,CAAC;QATJ,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAK;QAShB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAID;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAExB,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,aAAa,EAAE,CAAC;IAC5C,CAAC;IAEO,UAAU,CAAC,QAAkB;QACnC,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC3B,CAAC;QAEF,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;YACvB,IAAI,IAAI,EAAE,WAAW,EAAE,CAAC;gBACtB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1D,CAAC;QACH,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;YACxB,IAAI,GAAG,EAAE,SAAS,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;gBACrC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YACxE,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,YAAY;YAAE,OAAO,KAAK,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;gBACtD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,WAAW,EAAE;iBAC5C;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;aAC1D,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,KAAK,CAAC;YAE1B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgB,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;YAE5C,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;gBACxB,OAAO,CAAC;oBACN,GAAG,IAAI;oBACP,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY;oBACtD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI;iBACzD,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CACX,MAAc,EACd,IAAY,EACZ,UAII,EAAE;QAEN,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;QACnE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QAErC,IAAI,SAAS,GAAiB,IAAI,CAAC;QAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAC3B,MAAM;oBACN,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAClC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;iBAC9C,CAAC,CAAC;gBAEH,8BAA8B;gBAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;oBAC9D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC5C,IAAI,SAAS;wBAAE,SAAS;gBAC1B,CAAC;gBAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;gBAEvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACvC,CAAC;gBAED,wEAAwE;gBACxE,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAM,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAc,CAAC;gBAE3B,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;oBAC9B,6CAA6C;oBAC7C,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;wBAClF,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;oBACtB,MAAM,KAAK,GAAG,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;oBACpD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACjD,CAAC;IAED,qCAAqC;IAErC,GAAG,CAAU,IAAY,EAAE,WAAqB,MAAM;QACpD,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,CAAU,IAAY,EAAE,IAAU,EAAE,WAAqB,MAAM;QACjE,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAU,IAAY,EAAE,IAAU,EAAE,WAAqB,MAAM;QAClE,OAAO,IAAI,CAAC,OAAO,CAAI,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,CAAU,IAAY,EAAE,WAAqB,MAAM;QACvD,OAAO,IAAI,CAAC,OAAO,CAAI,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;CACF;AAED,IAAI,OAAO,GAAqB,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,QAAQ,KAAK,CAAC,UAAU,EAAE,CAAC;YACzB,KAAK,GAAG;gBACN,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;YAChG,KAAK,GAAG;gBACN,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,0CAA0C,CAAC;YACtF,KAAK,GAAG;gBACN,OAAO,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAC1C,KAAK,GAAG;gBACN,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAClC,KAAK,GAAG;gBACN,OAAO,KAAK,CAAC,MAAM,CAAC,iDAAiD,CAAC,CAAC;YACzE;gBACE,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,IAAI,KAAK,YAAY,SAAS,IAAK,KAAa,CAAC,KAAK,EAAE,IAAI,KAAK,cAAc,EAAE,CAAC;QAChF,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,iCAAiC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,0BAA0B,CAAC;IACjK,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { type Ora } from 'ora';
|
|
3
|
+
import { ApiClient } from './api-client.js';
|
|
4
|
+
/**
|
|
5
|
+
* BaseCommand
|
|
6
|
+
* Shared base for all apipay CLI commands.
|
|
7
|
+
* Provides spinner, api client, auth checks, and --json/--quiet flags.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class BaseCommand extends Command {
|
|
10
|
+
static baseFlags: {
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
protected api: ApiClient;
|
|
15
|
+
protected spinner: Ora;
|
|
16
|
+
protected jsonOutput: boolean;
|
|
17
|
+
protected quietOutput: boolean;
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
/** Require JWT auth — exits with error if not logged in */
|
|
20
|
+
protected requireAuth(): void;
|
|
21
|
+
/** Require API key — exits with error if not configured */
|
|
22
|
+
protected requireApiKey(): void;
|
|
23
|
+
/** Output JSON data or formatted text */
|
|
24
|
+
protected outputJson(data: any): void;
|
|
25
|
+
/** Handle API errors with user-friendly messages */
|
|
26
|
+
protected handleError(error: unknown): never;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* AuthenticatedCommand
|
|
30
|
+
* Base for commands that require JWT authentication.
|
|
31
|
+
*/
|
|
32
|
+
export declare abstract class AuthenticatedCommand extends BaseCommand {
|
|
33
|
+
init(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* ApiKeyCommand
|
|
37
|
+
* Base for commands that require API key authentication (banks, webhooks, metrics).
|
|
38
|
+
*/
|
|
39
|
+
export declare abstract class ApiKeyCommand extends BaseCommand {
|
|
40
|
+
init(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=base-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.d.ts","sourceRoot":"","sources":["../../src/lib/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAE7C,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,SAAS,EAAgC,MAAM,iBAAiB,CAAC;AAG1E;;;;GAIG;AACH,8BAAsB,WAAY,SAAQ,OAAO;IAC/C,MAAM,CAAC,SAAS;;;MAUd;IAEF,SAAS,CAAC,GAAG,EAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,OAAO,EAAG,GAAG,CAAC;IACxB,SAAS,CAAC,UAAU,UAAS;IAC7B,SAAS,CAAC,WAAW,UAAS;IAExB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,2DAA2D;IAC3D,SAAS,CAAC,WAAW,IAAI,IAAI;IAS7B,2DAA2D;IAC3D,SAAS,CAAC,aAAa,IAAI,IAAI;IAU/B,yCAAyC;IACzC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAMrC,oDAAoD;IACpD,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK;CAI7C;AAED;;;GAGG;AACH,8BAAsB,oBAAqB,SAAQ,WAAW;IACtD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B;AAED;;;GAGG;AACH,8BAAsB,aAAc,SAAQ,WAAW;IAC/C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { formatApiError, getApiClient } from './api-client.js';
|
|
5
|
+
import { isLoggedIn, getApiKey } from './config.js';
|
|
6
|
+
/**
|
|
7
|
+
* BaseCommand
|
|
8
|
+
* Shared base for all apipay CLI commands.
|
|
9
|
+
* Provides spinner, api client, auth checks, and --json/--quiet flags.
|
|
10
|
+
*/
|
|
11
|
+
export class BaseCommand extends Command {
|
|
12
|
+
static baseFlags = {
|
|
13
|
+
json: Flags.boolean({
|
|
14
|
+
description: 'Output raw JSON (for scripting/CI)',
|
|
15
|
+
default: false,
|
|
16
|
+
}),
|
|
17
|
+
quiet: Flags.boolean({
|
|
18
|
+
char: 'q',
|
|
19
|
+
description: 'Suppress interactive output',
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
api;
|
|
24
|
+
spinner;
|
|
25
|
+
jsonOutput = false;
|
|
26
|
+
quietOutput = false;
|
|
27
|
+
async init() {
|
|
28
|
+
await super.init();
|
|
29
|
+
const { flags } = await this.parse(this.constructor);
|
|
30
|
+
this.jsonOutput = flags.json ?? false;
|
|
31
|
+
this.quietOutput = flags.quiet ?? false;
|
|
32
|
+
this.api = getApiClient();
|
|
33
|
+
this.spinner = ora({ isSilent: this.quietOutput || this.jsonOutput });
|
|
34
|
+
}
|
|
35
|
+
/** Require JWT auth — exits with error if not logged in */
|
|
36
|
+
requireAuth() {
|
|
37
|
+
if (!isLoggedIn()) {
|
|
38
|
+
this.error(`${chalk.red('Not logged in.')} Run ${chalk.cyan('apipay login')} first.`, { exit: 1 });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Require API key — exits with error if not configured */
|
|
42
|
+
requireApiKey() {
|
|
43
|
+
const key = getApiKey();
|
|
44
|
+
if (!key?.accessKey || !key?.secretKey) {
|
|
45
|
+
this.error(`${chalk.red('No API key configured.')} Run ${chalk.cyan('apipay keys:create')} first.`, { exit: 1 });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Output JSON data or formatted text */
|
|
49
|
+
outputJson(data) {
|
|
50
|
+
if (this.jsonOutput) {
|
|
51
|
+
console.log(JSON.stringify(data, null, 2));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Handle API errors with user-friendly messages */
|
|
55
|
+
handleError(error) {
|
|
56
|
+
const msg = formatApiError(error);
|
|
57
|
+
this.error(msg, { exit: 2 });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* AuthenticatedCommand
|
|
62
|
+
* Base for commands that require JWT authentication.
|
|
63
|
+
*/
|
|
64
|
+
export class AuthenticatedCommand extends BaseCommand {
|
|
65
|
+
async init() {
|
|
66
|
+
await super.init();
|
|
67
|
+
this.requireAuth();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* ApiKeyCommand
|
|
72
|
+
* Base for commands that require API key authentication (banks, webhooks, metrics).
|
|
73
|
+
*/
|
|
74
|
+
export class ApiKeyCommand extends BaseCommand {
|
|
75
|
+
async init() {
|
|
76
|
+
await super.init();
|
|
77
|
+
this.requireAuth();
|
|
78
|
+
this.requireApiKey();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=base-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../src/lib/base-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import { type SetupStep } from './constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Auth state stored in config
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthConfig {
|
|
7
|
+
accessToken: string;
|
|
8
|
+
refreshToken: string;
|
|
9
|
+
expiresAt: number;
|
|
10
|
+
email: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* API key state stored in config
|
|
15
|
+
*/
|
|
16
|
+
export interface ApiKeyConfig {
|
|
17
|
+
id: string;
|
|
18
|
+
accessKey: string;
|
|
19
|
+
secretKey: string;
|
|
20
|
+
name: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Full config schema
|
|
24
|
+
*/
|
|
25
|
+
export interface CliConfig {
|
|
26
|
+
apiBaseUrl: string;
|
|
27
|
+
auth?: AuthConfig;
|
|
28
|
+
apiKey?: ApiKeyConfig;
|
|
29
|
+
setup: {
|
|
30
|
+
completedSteps: SetupStep[];
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the singleton config store.
|
|
35
|
+
* Persists to ~/.config/apipay/config.json (XDG compliant)
|
|
36
|
+
*/
|
|
37
|
+
export declare function getStore(): Conf<CliConfig>;
|
|
38
|
+
export declare function getAuth(): AuthConfig | undefined;
|
|
39
|
+
export declare function setAuth(auth: AuthConfig): void;
|
|
40
|
+
export declare function clearAuth(): void;
|
|
41
|
+
export declare function isLoggedIn(): boolean;
|
|
42
|
+
export declare function getApiKey(): ApiKeyConfig | undefined;
|
|
43
|
+
export declare function setApiKey(key: ApiKeyConfig): void;
|
|
44
|
+
export declare function clearApiKey(): void;
|
|
45
|
+
export declare function getCompletedSteps(): SetupStep[];
|
|
46
|
+
export declare function markStepComplete(step: SetupStep): void;
|
|
47
|
+
export declare function getNextIncompleteStep(): SetupStep | null;
|
|
48
|
+
export declare function getApiBaseUrl(): string;
|
|
49
|
+
export declare function resetAll(): void;
|
|
50
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE;QACL,cAAc,EAAE,SAAS,EAAE,CAAC;KAC7B,CAAC;CACH;AAyCD;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAQ1C;AAID,wBAAgB,OAAO,IAAI,UAAU,GAAG,SAAS,CAEhD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAG9C;AAED,wBAAgB,SAAS,IAAI,IAAI,CAIhC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAID,wBAAgB,SAAS,IAAI,YAAY,GAAG,SAAS,CAEpD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAGjD;AAED,wBAAgB,WAAW,IAAI,IAAI,CAIlC;AAID,wBAAgB,iBAAiB,IAAI,SAAS,EAAE,CAG/C;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAMtD;AAED,wBAAgB,qBAAqB,IAAI,SAAS,GAAG,IAAI,CAIxD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAE/B"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import { API_BASE_URL } from './constants.js';
|
|
3
|
+
const schema = {
|
|
4
|
+
apiBaseUrl: {
|
|
5
|
+
type: 'string',
|
|
6
|
+
default: API_BASE_URL,
|
|
7
|
+
},
|
|
8
|
+
auth: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
accessToken: { type: 'string' },
|
|
12
|
+
refreshToken: { type: 'string' },
|
|
13
|
+
expiresAt: { type: 'number' },
|
|
14
|
+
email: { type: 'string' },
|
|
15
|
+
userId: { type: 'string' },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
apiKey: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
id: { type: 'string' },
|
|
22
|
+
accessKey: { type: 'string' },
|
|
23
|
+
secretKey: { type: 'string' },
|
|
24
|
+
name: { type: 'string' },
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
setup: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
default: { completedSteps: [] },
|
|
30
|
+
properties: {
|
|
31
|
+
completedSteps: {
|
|
32
|
+
type: 'array',
|
|
33
|
+
items: { type: 'string' },
|
|
34
|
+
default: [],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
let _store = null;
|
|
40
|
+
/**
|
|
41
|
+
* Get the singleton config store.
|
|
42
|
+
* Persists to ~/.config/apipay/config.json (XDG compliant)
|
|
43
|
+
*/
|
|
44
|
+
export function getStore() {
|
|
45
|
+
if (!_store) {
|
|
46
|
+
_store = new Conf({
|
|
47
|
+
projectName: 'apipay',
|
|
48
|
+
schema,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return _store;
|
|
52
|
+
}
|
|
53
|
+
/* ===== Auth helpers ===== */
|
|
54
|
+
export function getAuth() {
|
|
55
|
+
return getStore().get('auth');
|
|
56
|
+
}
|
|
57
|
+
export function setAuth(auth) {
|
|
58
|
+
getStore().set('auth', auth);
|
|
59
|
+
markStepComplete('login');
|
|
60
|
+
}
|
|
61
|
+
export function clearAuth() {
|
|
62
|
+
getStore().delete('auth');
|
|
63
|
+
const steps = getCompletedSteps().filter((s) => s !== 'login');
|
|
64
|
+
getStore().set('setup.completedSteps', steps);
|
|
65
|
+
}
|
|
66
|
+
export function isLoggedIn() {
|
|
67
|
+
const auth = getAuth();
|
|
68
|
+
return !!auth?.accessToken;
|
|
69
|
+
}
|
|
70
|
+
/* ===== API Key helpers ===== */
|
|
71
|
+
export function getApiKey() {
|
|
72
|
+
return getStore().get('apiKey');
|
|
73
|
+
}
|
|
74
|
+
export function setApiKey(key) {
|
|
75
|
+
getStore().set('apiKey', key);
|
|
76
|
+
markStepComplete('api-key');
|
|
77
|
+
}
|
|
78
|
+
export function clearApiKey() {
|
|
79
|
+
getStore().delete('apiKey');
|
|
80
|
+
const steps = getCompletedSteps().filter((s) => s !== 'api-key');
|
|
81
|
+
getStore().set('setup.completedSteps', steps);
|
|
82
|
+
}
|
|
83
|
+
/* ===== Setup tracking ===== */
|
|
84
|
+
export function getCompletedSteps() {
|
|
85
|
+
const setup = getStore().get('setup');
|
|
86
|
+
return setup?.completedSteps ?? [];
|
|
87
|
+
}
|
|
88
|
+
export function markStepComplete(step) {
|
|
89
|
+
const steps = getCompletedSteps();
|
|
90
|
+
if (!steps.includes(step)) {
|
|
91
|
+
steps.push(step);
|
|
92
|
+
getStore().set('setup.completedSteps', steps);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function getNextIncompleteStep() {
|
|
96
|
+
const completed = getCompletedSteps();
|
|
97
|
+
const allSteps = ['login', 'api-key', 'bank', 'webhook'];
|
|
98
|
+
return allSteps.find((s) => !completed.includes(s)) ?? null;
|
|
99
|
+
}
|
|
100
|
+
export function getApiBaseUrl() {
|
|
101
|
+
return getStore().get('apiBaseUrl') || API_BASE_URL;
|
|
102
|
+
}
|
|
103
|
+
export function resetAll() {
|
|
104
|
+
getStore().clear();
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|