api2key-base-sdk 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 +181 -0
- package/dist/ai/client.d.ts +18 -0
- package/dist/ai/client.js +14 -0
- package/dist/auth/client.d.ts +21 -0
- package/dist/auth/client.js +28 -0
- package/dist/core/client.d.ts +8 -0
- package/dist/core/client.js +68 -0
- package/dist/core/errors.d.ts +9 -0
- package/dist/core/errors.js +15 -0
- package/dist/core/types.d.ts +121 -0
- package/dist/core/types.js +1 -0
- package/dist/credits/client.d.ts +40 -0
- package/dist/credits/client.js +43 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +21 -0
- package/dist/payment/client.d.ts +16 -0
- package/dist/payment/client.js +24 -0
- package/dist/projects/client.d.ts +22 -0
- package/dist/projects/client.js +17 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# api2key-base-sdk
|
|
2
|
+
|
|
3
|
+
`api2key-base-sdk` 是一个面向子项目的 TypeScript SDK,用于调用 Api2Key API 对外提供的稳定 API。
|
|
4
|
+
|
|
5
|
+
它的目标不是让业务项目直接依赖平台内部源码,而是通过统一的 SDK 边界,把公共能力沉淀为可复用、可发布、可升级的标准接入层。
|
|
6
|
+
|
|
7
|
+
## 这个包解决什么问题
|
|
8
|
+
|
|
9
|
+
当你的系统采用“平台基座 + 独立业务项目”的架构时,业务项目通常都需要复用同一批公共能力,例如:
|
|
10
|
+
|
|
11
|
+
1. 用户登录、注册、身份校验
|
|
12
|
+
2. 项目商品与项目权限查询
|
|
13
|
+
3. 支付下单与订单支付状态查询
|
|
14
|
+
4. 积分余额、预扣、确认、取消、流水查询
|
|
15
|
+
5. AI 模型列表与余额能力
|
|
16
|
+
|
|
17
|
+
如果每个子项目都自己手写请求逻辑,会很快出现以下问题:
|
|
18
|
+
|
|
19
|
+
1. 接口路径、请求头、鉴权方式在多个项目里重复维护
|
|
20
|
+
2. 返回结构和错误处理不统一
|
|
21
|
+
3. 平台接口一旦升级,多个子项目要分别修改
|
|
22
|
+
4. 子项目容易误依赖平台内部实现,造成耦合失控
|
|
23
|
+
|
|
24
|
+
这个 SDK 就是为了解决这些问题而存在。
|
|
25
|
+
|
|
26
|
+
## 设计目标
|
|
27
|
+
|
|
28
|
+
1. 子项目只依赖稳定 API 协议,不依赖平台内部源码
|
|
29
|
+
2. 公共能力通过统一客户端暴露,减少重复开发
|
|
30
|
+
3. 平台服务和业务项目可以独立演进、独立部署
|
|
31
|
+
4. 接口鉴权、错误处理、请求封装保持一致
|
|
32
|
+
|
|
33
|
+
## 适用场景
|
|
34
|
+
|
|
35
|
+
这个包适合以下场景:
|
|
36
|
+
|
|
37
|
+
1. 你有一个独立部署的平台基座服务,对外暴露 `/api/v1` 稳定接口
|
|
38
|
+
2. 你有多个独立部署的业务项目,需要复用平台提供的公共能力
|
|
39
|
+
3. 你希望业务项目只关心自身业务逻辑,而不是重复实现认证、支付、积分、模型等底层接入
|
|
40
|
+
|
|
41
|
+
## 当前支持的能力
|
|
42
|
+
|
|
43
|
+
目前 SDK 已封装以下客户端:
|
|
44
|
+
|
|
45
|
+
1. `auth`:认证与身份相关接口
|
|
46
|
+
2. `projects`:项目商品、项目会员、项目权限相关接口
|
|
47
|
+
3. `payment`:支付创建与支付状态查询接口
|
|
48
|
+
4. `credits`:积分余额、流水、预扣、确认、取消、消费接口
|
|
49
|
+
5. `ai`:AI 模型列表与 AI 余额接口
|
|
50
|
+
|
|
51
|
+
## 安装方式
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install api2key-base-sdk
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 使用前提
|
|
58
|
+
|
|
59
|
+
1. Node.js 版本需要 `>=18`
|
|
60
|
+
2. 平台服务已经对外提供稳定的 `/api/v1` 路由
|
|
61
|
+
3. 你的业务项目可以拿到平台服务地址,以及所需的访问令牌或服务密钥
|
|
62
|
+
|
|
63
|
+
## 快速开始
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { createPlatformAClient } from 'api2key-base-sdk';
|
|
67
|
+
|
|
68
|
+
const platformA = createPlatformAClient({
|
|
69
|
+
baseUrl: process.env.PLATFORM_A_BASE_URL!,
|
|
70
|
+
getServiceSecret: () => process.env.PLATFORM_A_SERVICE_SECRET,
|
|
71
|
+
getProjectId: () => process.env.PLATFORM_A_PROJECT_ID,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const products = await platformA.projects.getProducts('project-b');
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
上面的示例做了三件事:
|
|
78
|
+
|
|
79
|
+
1. 指定平台基座服务地址 `baseUrl`
|
|
80
|
+
2. 提供服务间调用所需的密钥 `getServiceSecret`
|
|
81
|
+
3. 提供当前业务项目标识 `getProjectId`
|
|
82
|
+
|
|
83
|
+
然后就可以直接通过 `platformA.projects.getProducts('project-b')` 调用平台对外能力,而不需要在业务项目里重复拼接请求。
|
|
84
|
+
|
|
85
|
+
## 创建客户端时可配置的内容
|
|
86
|
+
|
|
87
|
+
创建 SDK 客户端时,常见可配置项包括:
|
|
88
|
+
|
|
89
|
+
1. `baseUrl`:平台服务地址
|
|
90
|
+
2. `fetchImpl`:自定义 `fetch` 实现
|
|
91
|
+
3. `defaultHeaders`:默认请求头
|
|
92
|
+
4. `getAccessToken`:获取用户访问令牌
|
|
93
|
+
5. `getServiceSecret`:获取服务间调用密钥
|
|
94
|
+
6. `getProjectId`:获取当前项目标识
|
|
95
|
+
|
|
96
|
+
这意味着同一个 SDK 既可以被前端服务端渲染层使用,也可以被后端业务服务使用。
|
|
97
|
+
|
|
98
|
+
## 各客户端说明
|
|
99
|
+
|
|
100
|
+
### auth
|
|
101
|
+
|
|
102
|
+
用于处理认证相关能力,例如:
|
|
103
|
+
|
|
104
|
+
1. 登录
|
|
105
|
+
2. 注册
|
|
106
|
+
3. 获取当前用户信息
|
|
107
|
+
4. 退出登录
|
|
108
|
+
|
|
109
|
+
### projects
|
|
110
|
+
|
|
111
|
+
用于处理与项目维度相关的能力,例如:
|
|
112
|
+
|
|
113
|
+
1. 查询某个项目可售商品
|
|
114
|
+
2. 查询当前用户在某个项目下的会员状态
|
|
115
|
+
3. 查询当前用户的项目权限
|
|
116
|
+
|
|
117
|
+
### payment
|
|
118
|
+
|
|
119
|
+
用于统一支付流程接入,例如:
|
|
120
|
+
|
|
121
|
+
1. 创建统一支付订单
|
|
122
|
+
2. 查询支付状态
|
|
123
|
+
|
|
124
|
+
### credits
|
|
125
|
+
|
|
126
|
+
用于积分体系接入,例如:
|
|
127
|
+
|
|
128
|
+
1. 查询余额
|
|
129
|
+
2. 查询流水
|
|
130
|
+
3. 预扣积分
|
|
131
|
+
4. 确认扣减
|
|
132
|
+
5. 取消预扣
|
|
133
|
+
6. 直接消费积分
|
|
134
|
+
|
|
135
|
+
### ai
|
|
136
|
+
|
|
137
|
+
用于 AI 能力接入,例如:
|
|
138
|
+
|
|
139
|
+
1. 获取当前可用模型列表
|
|
140
|
+
2. 查询 AI 余额
|
|
141
|
+
|
|
142
|
+
## 错误处理
|
|
143
|
+
|
|
144
|
+
SDK 内部已经区分了两类错误:
|
|
145
|
+
|
|
146
|
+
1. `PlatformApiError`:平台接口已返回响应,但返回的是业务错误或非成功状态
|
|
147
|
+
2. `PlatformTransportError`:请求过程本身失败,例如网络异常、返回非 JSON、缺少必要密钥等
|
|
148
|
+
|
|
149
|
+
建议业务项目在接入时分别处理这两类错误,以便更容易定位问题。
|
|
150
|
+
|
|
151
|
+
## 为什么推荐通过 SDK 接入,而不是直接请求 API
|
|
152
|
+
|
|
153
|
+
直接请求 API 并不是不能做,但从长期维护看,SDK 更合适:
|
|
154
|
+
|
|
155
|
+
1. 路径、请求头、鉴权规则可以统一管理
|
|
156
|
+
2. 返回结构可以统一抽象
|
|
157
|
+
3. 错误处理语义更清晰
|
|
158
|
+
4. 平台升级时只需要升级 SDK,而不是逐个修改业务项目
|
|
159
|
+
|
|
160
|
+
## 发布约定
|
|
161
|
+
|
|
162
|
+
当前包的发布约定如下:
|
|
163
|
+
|
|
164
|
+
1. 包名为 `api2key-base-sdk`
|
|
165
|
+
2. 通过 Git tag 触发自动发布
|
|
166
|
+
3. tag 格式为 `v*`
|
|
167
|
+
4. tag 里的版本号必须与 `package.json` 中的版本号一致
|
|
168
|
+
5. GitHub Actions 优先建议使用 npm trusted publishing;如果使用 `NPM_TOKEN`,则必须是启用了 `Bypass 2FA` 的 npm granular publish token
|
|
169
|
+
|
|
170
|
+
例如当版本为 `0.1.0` 时,应推送:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
git tag v0.1.0
|
|
174
|
+
git push origin v0.1.0
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
当前包元信息中的许可证仍为 `UNLICENSED`。
|
|
180
|
+
|
|
181
|
+
如果你的目标是公开开源分发,请在正式发布前明确许可证类型,并补充对应的 `LICENSE` 文件。
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PlatformHttpClient } from '../core/client';
|
|
2
|
+
import type { AiModelSummary } from '../core/types';
|
|
3
|
+
export declare class AiClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: PlatformHttpClient);
|
|
6
|
+
getModels(input: {
|
|
7
|
+
projectId?: string;
|
|
8
|
+
accessToken?: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
projectId?: string | null;
|
|
11
|
+
userTier?: string;
|
|
12
|
+
models: AiModelSummary[];
|
|
13
|
+
grouped?: Record<string, AiModelSummary[]>;
|
|
14
|
+
}>;
|
|
15
|
+
getBalance(accessToken?: string): Promise<{
|
|
16
|
+
balance: number;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export class AiClient {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
getModels(input) {
|
|
6
|
+
return this.http.request('/api/v1/ai/models', {
|
|
7
|
+
accessToken: input.accessToken,
|
|
8
|
+
query: { projectId: input.projectId },
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
getBalance(accessToken) {
|
|
12
|
+
return this.http.request('/api/v1/ai/balance', { accessToken });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PlatformHttpClient } from '../core/client';
|
|
2
|
+
import type { AuthSession, AuthUser } from '../core/types';
|
|
3
|
+
export declare class AuthClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: PlatformHttpClient);
|
|
6
|
+
login(input: {
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}): Promise<AuthSession>;
|
|
10
|
+
register(input: {
|
|
11
|
+
email: string;
|
|
12
|
+
password: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
projectId?: string;
|
|
15
|
+
}): Promise<AuthSession>;
|
|
16
|
+
me(accessToken?: string): Promise<{
|
|
17
|
+
user: AuthUser;
|
|
18
|
+
membership?: unknown;
|
|
19
|
+
}>;
|
|
20
|
+
logout(accessToken?: string): Promise<null>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export class AuthClient {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
login(input) {
|
|
6
|
+
return this.http.request('/api/v1/auth/login', {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
body: input,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
register(input) {
|
|
12
|
+
return this.http.request('/api/v1/auth/register', {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
body: input,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
me(accessToken) {
|
|
18
|
+
return this.http.request('/api/v1/auth/me', {
|
|
19
|
+
accessToken,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
logout(accessToken) {
|
|
23
|
+
return this.http.request('/api/v1/auth/logout', {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
accessToken,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PlatformClientOptions, PlatformRequestOptions } from './types';
|
|
2
|
+
export declare class PlatformHttpClient {
|
|
3
|
+
private readonly baseUrl;
|
|
4
|
+
private readonly fetchImpl;
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options: PlatformClientOptions);
|
|
7
|
+
request<T>(path: string, requestOptions?: PlatformRequestOptions): Promise<T>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { PlatformApiError, PlatformTransportError } from './errors';
|
|
2
|
+
function buildQueryString(query) {
|
|
3
|
+
if (!query)
|
|
4
|
+
return '';
|
|
5
|
+
const params = new URLSearchParams();
|
|
6
|
+
for (const [key, value] of Object.entries(query)) {
|
|
7
|
+
if (value == null)
|
|
8
|
+
continue;
|
|
9
|
+
params.set(key, String(value));
|
|
10
|
+
}
|
|
11
|
+
const serialized = params.toString();
|
|
12
|
+
return serialized ? `?${serialized}` : '';
|
|
13
|
+
}
|
|
14
|
+
export class PlatformHttpClient {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
18
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
19
|
+
}
|
|
20
|
+
async request(path, requestOptions = {}) {
|
|
21
|
+
const headers = new Headers(this.options.defaultHeaders);
|
|
22
|
+
headers.set('Content-Type', 'application/json');
|
|
23
|
+
if (requestOptions.headers) {
|
|
24
|
+
for (const [key, value] of Object.entries(requestOptions.headers)) {
|
|
25
|
+
headers.set(key, value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const accessToken = requestOptions.accessToken ?? (await this.options.getAccessToken?.());
|
|
29
|
+
if (accessToken) {
|
|
30
|
+
headers.set('Authorization', `Bearer ${accessToken}`);
|
|
31
|
+
}
|
|
32
|
+
const projectId = requestOptions.projectId ?? (await this.options.getProjectId?.());
|
|
33
|
+
if (projectId) {
|
|
34
|
+
headers.set('X-Project-Id', projectId);
|
|
35
|
+
}
|
|
36
|
+
if (requestOptions.useServiceSecret) {
|
|
37
|
+
const serviceSecret = await this.options.getServiceSecret?.();
|
|
38
|
+
if (!serviceSecret) {
|
|
39
|
+
throw new PlatformTransportError('Missing service secret for platform API call');
|
|
40
|
+
}
|
|
41
|
+
headers.set('X-Service-Secret', serviceSecret);
|
|
42
|
+
}
|
|
43
|
+
const url = `${this.baseUrl}${path}${buildQueryString(requestOptions.query)}`;
|
|
44
|
+
let response;
|
|
45
|
+
try {
|
|
46
|
+
response = await this.fetchImpl(url, {
|
|
47
|
+
method: requestOptions.method ?? 'GET',
|
|
48
|
+
headers,
|
|
49
|
+
body: requestOptions.body == null ? undefined : JSON.stringify(requestOptions.body),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
const message = error instanceof Error ? error.message : 'Unknown transport error';
|
|
54
|
+
throw new PlatformTransportError(message);
|
|
55
|
+
}
|
|
56
|
+
let payload = null;
|
|
57
|
+
try {
|
|
58
|
+
payload = (await response.json());
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new PlatformTransportError(`Platform API returned a non-JSON response for ${url}`);
|
|
62
|
+
}
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
throw new PlatformApiError(payload.message, response.status, payload.code, payload.data);
|
|
65
|
+
}
|
|
66
|
+
return payload.data;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class PlatformApiError extends Error {
|
|
2
|
+
readonly httpStatus: number;
|
|
3
|
+
readonly code: number;
|
|
4
|
+
readonly data: unknown;
|
|
5
|
+
constructor(message: string, httpStatus: number, code: number, data?: unknown);
|
|
6
|
+
}
|
|
7
|
+
export declare class PlatformTransportError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class PlatformApiError extends Error {
|
|
2
|
+
constructor(message, httpStatus, code, data = null) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'PlatformApiError';
|
|
5
|
+
this.httpStatus = httpStatus;
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.data = data;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class PlatformTransportError extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'PlatformTransportError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
2
|
+
export interface PlatformEnvelope<T> {
|
|
3
|
+
code: number;
|
|
4
|
+
message: string;
|
|
5
|
+
data: T;
|
|
6
|
+
}
|
|
7
|
+
export interface PlatformClientOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
fetchImpl?: typeof fetch;
|
|
10
|
+
defaultHeaders?: Record<string, string>;
|
|
11
|
+
getAccessToken?: () => MaybePromise<string | undefined>;
|
|
12
|
+
getServiceSecret?: () => MaybePromise<string | undefined>;
|
|
13
|
+
getProjectId?: () => MaybePromise<string | undefined>;
|
|
14
|
+
}
|
|
15
|
+
export interface PlatformRequestOptions {
|
|
16
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
17
|
+
body?: unknown;
|
|
18
|
+
query?: Record<string, string | number | boolean | undefined | null>;
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
accessToken?: string;
|
|
21
|
+
projectId?: string;
|
|
22
|
+
useServiceSecret?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface AuthUser {
|
|
25
|
+
id: string;
|
|
26
|
+
email: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
avatar?: string | null;
|
|
29
|
+
role: 'user' | 'admin' | 'super_admin';
|
|
30
|
+
creditsBalance?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface AuthSession {
|
|
33
|
+
user: AuthUser;
|
|
34
|
+
accessToken: string;
|
|
35
|
+
refreshToken?: string;
|
|
36
|
+
expiresIn?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface ProjectSummary {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
slug: string;
|
|
42
|
+
description?: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface ProductSummary {
|
|
45
|
+
id: string;
|
|
46
|
+
projectId?: string | null;
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string | null;
|
|
49
|
+
price: number;
|
|
50
|
+
discountPrice?: number | null;
|
|
51
|
+
durationDays: number;
|
|
52
|
+
credits: number;
|
|
53
|
+
tier: string;
|
|
54
|
+
features: string[];
|
|
55
|
+
sortOrder?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface MembershipView {
|
|
58
|
+
tier: string;
|
|
59
|
+
status: string;
|
|
60
|
+
start_date?: number | null;
|
|
61
|
+
end_date?: number | null;
|
|
62
|
+
source?: 'project' | 'global' | 'none';
|
|
63
|
+
credits?: number | null;
|
|
64
|
+
role?: string | null;
|
|
65
|
+
auto_renew?: number | null;
|
|
66
|
+
is_active?: boolean;
|
|
67
|
+
days_remaining?: number;
|
|
68
|
+
}
|
|
69
|
+
export interface CreditsBalance {
|
|
70
|
+
balance: number;
|
|
71
|
+
reserved?: number;
|
|
72
|
+
total_earned?: number;
|
|
73
|
+
total_spent?: number;
|
|
74
|
+
}
|
|
75
|
+
export interface CreditsLedgerItem {
|
|
76
|
+
id: string;
|
|
77
|
+
delta: number;
|
|
78
|
+
balance_after: number;
|
|
79
|
+
type: string;
|
|
80
|
+
service?: string | null;
|
|
81
|
+
model?: string | null;
|
|
82
|
+
description?: string | null;
|
|
83
|
+
created_at: number;
|
|
84
|
+
}
|
|
85
|
+
export interface PaymentCreateResponse {
|
|
86
|
+
paymentType: string;
|
|
87
|
+
orderNo: string;
|
|
88
|
+
unifiedOrderNo?: string;
|
|
89
|
+
data?: {
|
|
90
|
+
qrCode?: string;
|
|
91
|
+
payUrl?: string;
|
|
92
|
+
paypalOrderId?: string;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export interface PaymentQueryResponse {
|
|
96
|
+
localStatus: string;
|
|
97
|
+
unifiedStatus: number;
|
|
98
|
+
unifiedStatusDesc: string;
|
|
99
|
+
paid?: boolean;
|
|
100
|
+
order?: {
|
|
101
|
+
orderNo: string;
|
|
102
|
+
amount: number;
|
|
103
|
+
status: string;
|
|
104
|
+
paidAt?: number | null;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export interface AiModelSummary {
|
|
108
|
+
key: string;
|
|
109
|
+
id: string;
|
|
110
|
+
name: string;
|
|
111
|
+
modelId: string;
|
|
112
|
+
provider?: string | null;
|
|
113
|
+
modelType?: string | null;
|
|
114
|
+
minTier?: string | null;
|
|
115
|
+
creditCostPerRequest?: number | null;
|
|
116
|
+
isFeatured?: boolean | null;
|
|
117
|
+
description?: string | null;
|
|
118
|
+
inputPricing?: number;
|
|
119
|
+
outputPricing?: number;
|
|
120
|
+
locked?: boolean;
|
|
121
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PlatformHttpClient } from '../core/client';
|
|
2
|
+
import type { CreditsBalance, CreditsLedgerItem } from '../core/types';
|
|
3
|
+
export declare class CreditsClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: PlatformHttpClient);
|
|
6
|
+
getBalance(accessToken?: string): Promise<CreditsBalance>;
|
|
7
|
+
getLedger(input: {
|
|
8
|
+
accessToken?: string;
|
|
9
|
+
page?: number;
|
|
10
|
+
pageSize?: number;
|
|
11
|
+
}): Promise<{
|
|
12
|
+
list: CreditsLedgerItem[];
|
|
13
|
+
total?: number;
|
|
14
|
+
}>;
|
|
15
|
+
spend(input: {
|
|
16
|
+
userId: string;
|
|
17
|
+
amount: number;
|
|
18
|
+
service: string;
|
|
19
|
+
taskId?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
balanceAfter: number;
|
|
23
|
+
idempotent?: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
reserve(input: {
|
|
26
|
+
userId: string;
|
|
27
|
+
amount: number;
|
|
28
|
+
service: string;
|
|
29
|
+
taskId: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
reservation_id: string;
|
|
32
|
+
idempotent?: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
confirm(id: string): Promise<{
|
|
35
|
+
ok: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
cancel(id: string): Promise<{
|
|
38
|
+
ok: boolean;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class CreditsClient {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
getBalance(accessToken) {
|
|
6
|
+
return this.http.request('/api/v1/credits/balance', { accessToken });
|
|
7
|
+
}
|
|
8
|
+
getLedger(input) {
|
|
9
|
+
return this.http.request('/api/v1/credits/ledger', {
|
|
10
|
+
accessToken: input.accessToken,
|
|
11
|
+
query: {
|
|
12
|
+
page: input.page,
|
|
13
|
+
pageSize: input.pageSize,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
spend(input) {
|
|
18
|
+
return this.http.request('/api/v1/credits/spend', {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
body: input,
|
|
21
|
+
useServiceSecret: true,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
reserve(input) {
|
|
25
|
+
return this.http.request('/api/v1/credits/reserve', {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
body: input,
|
|
28
|
+
useServiceSecret: true,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
confirm(id) {
|
|
32
|
+
return this.http.request(`/api/v1/credits/confirm/${id}`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
useServiceSecret: true,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
cancel(id) {
|
|
38
|
+
return this.http.request(`/api/v1/credits/cancel/${id}`, {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
useServiceSecret: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PlatformHttpClient } from './core/client';
|
|
2
|
+
import type { PlatformClientOptions } from './core/types';
|
|
3
|
+
import { AuthClient } from './auth/client';
|
|
4
|
+
import { ProjectsClient } from './projects/client';
|
|
5
|
+
import { CreditsClient } from './credits/client';
|
|
6
|
+
import { PaymentClient } from './payment/client';
|
|
7
|
+
import { AiClient } from './ai/client';
|
|
8
|
+
export * from './core/errors';
|
|
9
|
+
export * from './core/types';
|
|
10
|
+
export declare class PlatformAClient {
|
|
11
|
+
readonly http: PlatformHttpClient;
|
|
12
|
+
readonly auth: AuthClient;
|
|
13
|
+
readonly projects: ProjectsClient;
|
|
14
|
+
readonly credits: CreditsClient;
|
|
15
|
+
readonly payment: PaymentClient;
|
|
16
|
+
readonly ai: AiClient;
|
|
17
|
+
constructor(options: PlatformClientOptions);
|
|
18
|
+
}
|
|
19
|
+
export declare function createPlatformAClient(options: PlatformClientOptions): PlatformAClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PlatformHttpClient } from './core/client';
|
|
2
|
+
import { AuthClient } from './auth/client';
|
|
3
|
+
import { ProjectsClient } from './projects/client';
|
|
4
|
+
import { CreditsClient } from './credits/client';
|
|
5
|
+
import { PaymentClient } from './payment/client';
|
|
6
|
+
import { AiClient } from './ai/client';
|
|
7
|
+
export * from './core/errors';
|
|
8
|
+
export * from './core/types';
|
|
9
|
+
export class PlatformAClient {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.http = new PlatformHttpClient(options);
|
|
12
|
+
this.auth = new AuthClient(this.http);
|
|
13
|
+
this.projects = new ProjectsClient(this.http);
|
|
14
|
+
this.credits = new CreditsClient(this.http);
|
|
15
|
+
this.payment = new PaymentClient(this.http);
|
|
16
|
+
this.ai = new AiClient(this.http);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function createPlatformAClient(options) {
|
|
20
|
+
return new PlatformAClient(options);
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PlatformHttpClient } from '../core/client';
|
|
2
|
+
import type { PaymentCreateResponse, PaymentQueryResponse } from '../core/types';
|
|
3
|
+
export declare class PaymentClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: PlatformHttpClient);
|
|
6
|
+
createUnified(input: {
|
|
7
|
+
orderId: string;
|
|
8
|
+
paymentType?: 'alipay' | 'wechat' | 'paypal';
|
|
9
|
+
accessToken?: string;
|
|
10
|
+
}): Promise<PaymentCreateResponse>;
|
|
11
|
+
queryUnified(input: {
|
|
12
|
+
orderId?: string;
|
|
13
|
+
orderNo?: string;
|
|
14
|
+
accessToken?: string;
|
|
15
|
+
}): Promise<PaymentQueryResponse>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class PaymentClient {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
createUnified(input) {
|
|
6
|
+
return this.http.request('/api/v1/payment/unified/create', {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
accessToken: input.accessToken,
|
|
9
|
+
body: {
|
|
10
|
+
orderId: input.orderId,
|
|
11
|
+
paymentType: input.paymentType ?? 'wechat',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
queryUnified(input) {
|
|
16
|
+
return this.http.request('/api/v1/payment/unified/query', {
|
|
17
|
+
accessToken: input.accessToken,
|
|
18
|
+
query: {
|
|
19
|
+
orderId: input.orderId,
|
|
20
|
+
orderNo: input.orderNo,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PlatformHttpClient } from '../core/client';
|
|
2
|
+
import type { MembershipView, ProductSummary, ProjectSummary } from '../core/types';
|
|
3
|
+
export declare class ProjectsClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: PlatformHttpClient);
|
|
6
|
+
getProducts(projectId: string): Promise<{
|
|
7
|
+
project: ProjectSummary | null;
|
|
8
|
+
products: ProductSummary[];
|
|
9
|
+
total?: number;
|
|
10
|
+
}>;
|
|
11
|
+
getMembership(projectId: string, accessToken?: string): Promise<{
|
|
12
|
+
project: ProjectSummary;
|
|
13
|
+
membership: MembershipView;
|
|
14
|
+
}>;
|
|
15
|
+
getPermissions(input: {
|
|
16
|
+
accessToken?: string;
|
|
17
|
+
projectId?: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
permission?: unknown;
|
|
20
|
+
permissions?: unknown[];
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class ProjectsClient {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
getProducts(projectId) {
|
|
6
|
+
return this.http.request(`/api/v1/projects/${projectId}/products`);
|
|
7
|
+
}
|
|
8
|
+
getMembership(projectId, accessToken) {
|
|
9
|
+
return this.http.request(`/api/v1/projects/${projectId}/membership`, { accessToken });
|
|
10
|
+
}
|
|
11
|
+
getPermissions(input) {
|
|
12
|
+
return this.http.request('/api/v1/user/project-permissions', {
|
|
13
|
+
accessToken: input.accessToken,
|
|
14
|
+
query: { projectId: input.projectId },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api2key-base-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for consuming the Api2Key API stable APIs",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"platform",
|
|
19
|
+
"foundation",
|
|
20
|
+
"sdk",
|
|
21
|
+
"typescript",
|
|
22
|
+
"api-client",
|
|
23
|
+
"billing",
|
|
24
|
+
"credits",
|
|
25
|
+
"hono",
|
|
26
|
+
"cloudflare-workers"
|
|
27
|
+
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc -p tsconfig.build.json",
|
|
39
|
+
"clean": "rm -rf dist",
|
|
40
|
+
"pack:check": "npm pack --dry-run",
|
|
41
|
+
"release:check": "npm run clean && npm run type-check && npm run build && npm run pack:check",
|
|
42
|
+
"type-check": "tsc --noEmit",
|
|
43
|
+
"prepublishOnly": "npm run clean && npm run type-check && npm run build"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^5.3.3"
|
|
47
|
+
}
|
|
48
|
+
}
|