api2key-base-sdk 0.1.0 → 0.1.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 CHANGED
@@ -1,181 +1,136 @@
1
1
  # api2key-base-sdk
2
2
 
3
- `api2key-base-sdk` 是一个面向子项目的 TypeScript SDK,用于调用 Api2Key API 对外提供的稳定 API。
3
+ `api2key-base-sdk` 现在只承载稳定的基础平台能力,不再包含项目业务 API 或后台管理 API。
4
4
 
5
- 它的目标不是让业务项目直接依赖平台内部源码,而是通过统一的 SDK 边界,把公共能力沉淀为可复用、可发布、可升级的标准接入层。
5
+ 适合放进所有新项目作为默认基础依赖。
6
6
 
7
- ## 这个包解决什么问题
7
+ ## 当前边界
8
8
 
9
- 当你的系统采用“平台基座 + 独立业务项目”的架构时,业务项目通常都需要复用同一批公共能力,例如:
9
+ 基础能力仅包括:
10
10
 
11
- 1. 用户登录、注册、身份校验
12
- 2. 项目商品与项目权限查询
13
- 3. 支付下单与订单支付状态查询
14
- 4. 积分余额、预扣、确认、取消、流水查询
15
- 5. AI 模型列表与余额能力
11
+ 1. `auth`
12
+ 2. `credits`
13
+ 3. `apiKeys`
14
+ 4. `settings`
16
15
 
17
- 如果每个子项目都自己手写请求逻辑,会很快出现以下问题:
16
+ 不再包含:
18
17
 
19
- 1. 接口路径、请求头、鉴权方式在多个项目里重复维护
20
- 2. 返回结构和错误处理不统一
21
- 3. 平台接口一旦升级,多个子项目要分别修改
22
- 4. 子项目容易误依赖平台内部实现,造成耦合失控
18
+ 1. 项目商品与项目会员接口
19
+ 2. 订单与支付接口
20
+ 3. AI 业务接口
21
+ 4. 管理后台接口
23
22
 
24
- 这个 SDK 就是为了解决这些问题而存在。
23
+ 这些能力已拆分为独立包:
25
24
 
26
- ## 设计目标
25
+ 1. `api2key-project-sdk`
26
+ 2. `api2key-admin-sdk`
27
27
 
28
- 1. 子项目只依赖稳定 API 协议,不依赖平台内部源码
29
- 2. 公共能力通过统一客户端暴露,减少重复开发
30
- 3. 平台服务和业务项目可以独立演进、独立部署
31
- 4. 接口鉴权、错误处理、请求封装保持一致
28
+ 安装原则:
32
29
 
33
- ## 适用场景
30
+ 1. 所有新项目默认只安装 `api2key-base-sdk`
31
+ 2. 只有需要业务扩展能力时才安装 `api2key-project-sdk`
32
+ 3. 只有需要开发管理后台时才安装 `api2key-admin-sdk`
34
33
 
35
- 这个包适合以下场景:
34
+ ## 暴露的客户端
36
35
 
37
- 1. 你有一个独立部署的平台基座服务,对外暴露 `/api/v1` 稳定接口
38
- 2. 你有多个独立部署的业务项目,需要复用平台提供的公共能力
39
- 3. 你希望业务项目只关心自身业务逻辑,而不是重复实现认证、支付、积分、模型等底层接入
36
+ 当前 `api2key-base-sdk` 只暴露以下客户端:
40
37
 
41
- ## 当前支持的能力
38
+ 1. `auth`
39
+ 2. `credits`
40
+ 3. `apiKeys`
41
+ 4. `settings`
42
42
 
43
- 目前 SDK 已封装以下客户端:
43
+ ### 1. `auth`
44
44
 
45
- 1. `auth`:认证与身份相关接口
46
- 2. `projects`:项目商品、项目会员、项目权限相关接口
47
- 3. `payment`:支付创建与支付状态查询接口
48
- 4. `credits`:积分余额、流水、预扣、确认、取消、消费接口
49
- 5. `ai`:AI 模型列表与 AI 余额接口
45
+ 负责稳定的用户认证能力。
50
46
 
51
- ## 安装方式
47
+ 当前主要方法:
52
48
 
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')` 调用平台对外能力,而不需要在业务项目里重复拼接请求。
49
+ 1. `login(input)`
50
+ 2. `register(input)`
51
+ 3. `me(accessToken?)`
52
+ 4. `logout(accessToken?)`
84
53
 
85
- ## 创建客户端时可配置的内容
54
+ ### 2. `credits`
86
55
 
87
- 创建 SDK 客户端时,常见可配置项包括:
56
+ 负责稳定的积分账户与流水能力。
88
57
 
89
- 1. `baseUrl`:平台服务地址
90
- 2. `fetchImpl`:自定义 `fetch` 实现
91
- 3. `defaultHeaders`:默认请求头
92
- 4. `getAccessToken`:获取用户访问令牌
93
- 5. `getServiceSecret`:获取服务间调用密钥
94
- 6. `getProjectId`:获取当前项目标识
58
+ 当前主要方法包括:
95
59
 
96
- 这意味着同一个 SDK 既可以被前端服务端渲染层使用,也可以被后端业务服务使用。
60
+ 1. `getBalance(accessToken?)`
61
+ 2. `getLedger(input)`
62
+ 3. `spend(input)`
63
+ 4. `reserve(input)`
64
+ 5. `confirm(id)`
65
+ 6. `cancel(id)`
97
66
 
98
- ## 各客户端说明
67
+ ### 3. `apiKeys`
99
68
 
100
- ### auth
69
+ 负责用户 API Key 生命周期管理。
101
70
 
102
- 用于处理认证相关能力,例如:
71
+ ### 4. `settings`
103
72
 
104
- 1. 登录
105
- 2. 注册
106
- 3. 获取当前用户信息
107
- 4. 退出登录
73
+ 负责用户级设置的读取与更新。
108
74
 
109
- ### projects
75
+ ## 适合哪些项目
110
76
 
111
- 用于处理与项目维度相关的能力,例如:
77
+ 适合:
112
78
 
113
- 1. 查询某个项目可售商品
114
- 2. 查询当前用户在某个项目下的会员状态
115
- 3. 查询当前用户的项目权限
79
+ 1. 所有新项目
80
+ 2. 只需要登录、积分、用户设置、API Key 的项目
81
+ 3. 需要一个长期稳定基础依赖的项目
116
82
 
117
- ### payment
83
+ 不适合单独承载:
118
84
 
119
- 用于统一支付流程接入,例如:
85
+ 1. 商品目录
86
+ 2. 会员业务
87
+ 3. 订单与支付业务
88
+ 4. AI 业务策略
89
+ 5. 管理后台接口
120
90
 
121
- 1. 创建统一支付订单
122
- 2. 查询支付状态
91
+ ## 安装
123
92
 
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
- ## 错误处理
93
+ ```bash
94
+ npm install api2key-base-sdk
95
+ ```
143
96
 
144
- SDK 内部已经区分了两类错误:
97
+ ## 使用示例
145
98
 
146
- 1. `PlatformApiError`:平台接口已返回响应,但返回的是业务错误或非成功状态
147
- 2. `PlatformTransportError`:请求过程本身失败,例如网络异常、返回非 JSON、缺少必要密钥等
99
+ ```ts
100
+ import { createBasePlatformClient } from 'api2key-base-sdk';
148
101
 
149
- 建议业务项目在接入时分别处理这两类错误,以便更容易定位问题。
102
+ const baseClient = createBasePlatformClient({
103
+ baseUrl: process.env.API2KEY_BASE_URL!,
104
+ getAccessToken: () => process.env.ACCESS_TOKEN,
105
+ getServiceSecret: () => process.env.SERVICE_SECRET,
106
+ });
150
107
 
151
- ## 为什么推荐通过 SDK 接入,而不是直接请求 API
108
+ const me = await baseClient.auth.me();
109
+ const credits = await baseClient.credits.getBalance();
110
+ const settings = await baseClient.settings.get();
111
+ ```
152
112
 
153
- 直接请求 API 并不是不能做,但从长期维护看,SDK 更合适:
113
+ ## 设计原则
154
114
 
155
- 1. 路径、请求头、鉴权规则可以统一管理
156
- 2. 返回结构可以统一抽象
157
- 3. 错误处理语义更清晰
158
- 4. 平台升级时只需要升级 SDK,而不是逐个修改业务项目
115
+ 1. 新项目默认只依赖这个包
116
+ 2. 业务扩展能力按需安装独立 SDK
117
+ 3. `api2key-base-api` 可以稳定演进而不被业务模块拖住
159
118
 
160
- ## 发布约定
119
+ ## Agent 约定
161
120
 
162
- 当前包的发布约定如下:
121
+ 后续 agent 在处理需求时,默认把这个包视为“稳定基础层”。
163
122
 
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
123
+ 规则:
169
124
 
170
- 例如当版本为 `0.1.0` 时,应推送:
125
+ 1. 如果需求属于认证、积分、用户设置、API Key,优先在这里找
126
+ 2. 不要把商品、会员、订单、支付、AI、后台管理方法加回这个包
127
+ 3. 如果新需求明显带有项目业务语义,应优先落到 `api2key-project-sdk`
128
+ 4. 如果新需求明显带有后台控制面语义,应优先落到 `api2key-admin-sdk`
171
129
 
172
- ```bash
173
- git tag v0.1.0
174
- git push origin v0.1.0
175
- ```
130
+ ## 兼容说明
176
131
 
177
- ## License
132
+ 当前仍保留 `createPlatformAClient` 作为过渡别名,但它现在只返回基础能力客户端。
178
133
 
179
- 当前包元信息中的许可证仍为 `UNLICENSED`。
134
+ 建议新代码统一使用:
180
135
 
181
- 如果你的目标是公开开源分发,请在正式发布前明确许可证类型,并补充对应的 `LICENSE` 文件。
136
+ - `createBasePlatformClient`
@@ -0,0 +1,115 @@
1
+ import type { PlatformHttpClient } from '../core/client';
2
+ import type { AdminConfigItem, AdminMembershipFilters, AdminMembershipRecord, AdminOrderFilters, AdminOrderRecord, AdminProduct, AdminProject, AdminProjectExportFormat, AdminUserRecord } from '../core/types';
3
+ export declare class AdminClient {
4
+ private readonly http;
5
+ constructor(http: PlatformHttpClient);
6
+ listProjects(accessToken?: string): Promise<{
7
+ projects: AdminProject[];
8
+ }>;
9
+ createProject(input: {
10
+ name: string;
11
+ slug: string;
12
+ description?: string;
13
+ logoUrl?: string;
14
+ settings?: Record<string, unknown>;
15
+ }, accessToken?: string): Promise<{
16
+ project: AdminProject;
17
+ }>;
18
+ updateProject(input: {
19
+ id: string;
20
+ name?: string;
21
+ description?: string;
22
+ logoUrl?: string;
23
+ status?: 'active' | 'inactive';
24
+ settings?: Record<string, unknown>;
25
+ }, accessToken?: string): Promise<null>;
26
+ deleteProject(id: string, accessToken?: string): Promise<null>;
27
+ exportProject(id: string, format?: AdminProjectExportFormat, accessToken?: string): Promise<unknown>;
28
+ listProducts(projectId?: string, accessToken?: string): Promise<AdminProduct[]>;
29
+ createProduct(input: Omit<AdminProduct, 'id'>, accessToken?: string): Promise<AdminProduct>;
30
+ updateProduct(input: AdminProduct, accessToken?: string): Promise<AdminProduct>;
31
+ deleteProduct(id: string, accessToken?: string): Promise<null>;
32
+ listMemberships(filters?: AdminMembershipFilters, accessToken?: string): Promise<{
33
+ memberships: AdminMembershipRecord[];
34
+ unboundUsers: Array<{
35
+ id: string;
36
+ email: string;
37
+ name: string | null;
38
+ role: string;
39
+ status: string;
40
+ currentProject: {
41
+ id: string;
42
+ name: string;
43
+ slug: string;
44
+ } | null;
45
+ membershipCount: number;
46
+ }>;
47
+ }>;
48
+ createMembership(input: {
49
+ scopeType: 'project' | 'global';
50
+ userId?: string;
51
+ email?: string;
52
+ projectId?: string;
53
+ role?: string;
54
+ tier: string;
55
+ status?: 'active' | 'expired' | 'cancelled';
56
+ credits?: number;
57
+ startDate?: number | null;
58
+ endDate?: number | null;
59
+ autoRenew?: boolean;
60
+ }, accessToken?: string): Promise<{
61
+ membershipId: string;
62
+ scopeType: 'project' | 'global';
63
+ }>;
64
+ updateMembership(input: {
65
+ id: string;
66
+ scopeType: 'project' | 'global';
67
+ projectId?: string;
68
+ role?: string;
69
+ tier?: string;
70
+ status?: 'active' | 'expired' | 'cancelled';
71
+ credits?: number;
72
+ startDate?: number | null;
73
+ endDate?: number | null;
74
+ autoRenew?: boolean;
75
+ }, accessToken?: string): Promise<{
76
+ id: string;
77
+ }>;
78
+ deleteMembership(id: string, scopeType: 'project' | 'global', accessToken?: string): Promise<null>;
79
+ listUsers(filters?: {
80
+ search?: string;
81
+ projectId?: string;
82
+ status?: 'active' | 'disabled' | 'banned';
83
+ limit?: number;
84
+ }, accessToken?: string): Promise<{
85
+ users: AdminUserRecord[];
86
+ }>;
87
+ updateUserProject(input: {
88
+ userId: string;
89
+ projectId?: string | null;
90
+ }, accessToken?: string): Promise<{
91
+ userId: string;
92
+ projectId: string | null;
93
+ }>;
94
+ deleteUsers(userIds: string[], accessToken?: string): Promise<{
95
+ deleted: Array<{
96
+ id: string;
97
+ email: string;
98
+ }>;
99
+ skipped: Array<{
100
+ id: string;
101
+ email?: string | null;
102
+ reason: string;
103
+ }>;
104
+ }>;
105
+ listOrders(filters?: AdminOrderFilters, accessToken?: string): Promise<{
106
+ orders: AdminOrderRecord[];
107
+ }>;
108
+ getConfig(accessToken?: string): Promise<{
109
+ configs: AdminConfigItem[];
110
+ }>;
111
+ updateConfig(input: {
112
+ key: string;
113
+ value: string;
114
+ }, accessToken?: string): Promise<AdminConfigItem>;
115
+ }
@@ -0,0 +1,146 @@
1
+ export class AdminClient {
2
+ constructor(http) {
3
+ this.http = http;
4
+ }
5
+ listProjects(accessToken) {
6
+ return this.http.request('/api/v1/admin/projects', { accessToken });
7
+ }
8
+ createProject(input, accessToken) {
9
+ return this.http.request('/api/v1/admin/projects', {
10
+ method: 'POST',
11
+ body: input,
12
+ accessToken,
13
+ });
14
+ }
15
+ updateProject(input, accessToken) {
16
+ return this.http.request('/api/v1/admin/projects', {
17
+ method: 'PUT',
18
+ body: input,
19
+ accessToken,
20
+ });
21
+ }
22
+ deleteProject(id, accessToken) {
23
+ return this.http.request('/api/v1/admin/projects', {
24
+ method: 'DELETE',
25
+ query: { id },
26
+ accessToken,
27
+ });
28
+ }
29
+ async exportProject(id, format = 'openapi', accessToken) {
30
+ const response = await this.http.requestRaw(`/api/v1/admin/projects/${id}/export`, {
31
+ query: { format },
32
+ accessToken,
33
+ });
34
+ if (!response.ok) {
35
+ const payload = await response.json().catch(() => null);
36
+ throw new Error(payload?.message ?? `Export failed with HTTP ${response.status}`);
37
+ }
38
+ const contentType = response.headers.get('Content-Type') ?? '';
39
+ if (contentType.includes('application/json')) {
40
+ return response.json();
41
+ }
42
+ return response.text();
43
+ }
44
+ listProducts(projectId, accessToken) {
45
+ return this.http.request('/api/v1/admin/products', {
46
+ query: { projectId },
47
+ accessToken,
48
+ });
49
+ }
50
+ createProduct(input, accessToken) {
51
+ return this.http.request('/api/v1/admin/products', {
52
+ method: 'POST',
53
+ body: input,
54
+ accessToken,
55
+ });
56
+ }
57
+ updateProduct(input, accessToken) {
58
+ return this.http.request('/api/v1/admin/products', {
59
+ method: 'PUT',
60
+ body: input,
61
+ accessToken,
62
+ });
63
+ }
64
+ deleteProduct(id, accessToken) {
65
+ return this.http.request('/api/v1/admin/products', {
66
+ method: 'DELETE',
67
+ query: { id },
68
+ accessToken,
69
+ });
70
+ }
71
+ listMemberships(filters = {}, accessToken) {
72
+ return this.http.request('/api/v1/admin/memberships', {
73
+ query: {
74
+ scope: filters.scope,
75
+ projectId: filters.projectId,
76
+ status: filters.status,
77
+ tier: filters.tier,
78
+ search: filters.search,
79
+ },
80
+ accessToken,
81
+ });
82
+ }
83
+ createMembership(input, accessToken) {
84
+ return this.http.request('/api/v1/admin/memberships', {
85
+ method: 'POST',
86
+ body: input,
87
+ accessToken,
88
+ });
89
+ }
90
+ updateMembership(input, accessToken) {
91
+ return this.http.request('/api/v1/admin/memberships', {
92
+ method: 'PUT',
93
+ body: input,
94
+ accessToken,
95
+ });
96
+ }
97
+ deleteMembership(id, scopeType, accessToken) {
98
+ return this.http.request('/api/v1/admin/memberships', {
99
+ method: 'DELETE',
100
+ query: { id, scopeType },
101
+ accessToken,
102
+ });
103
+ }
104
+ listUsers(filters = {}, accessToken) {
105
+ return this.http.request('/api/v1/admin/users', {
106
+ query: filters,
107
+ accessToken,
108
+ });
109
+ }
110
+ updateUserProject(input, accessToken) {
111
+ return this.http.request('/api/v1/admin/users', {
112
+ method: 'PUT',
113
+ body: input,
114
+ accessToken,
115
+ });
116
+ }
117
+ deleteUsers(userIds, accessToken) {
118
+ return this.http.request('/api/v1/admin/users', {
119
+ method: 'DELETE',
120
+ body: { userIds },
121
+ accessToken,
122
+ });
123
+ }
124
+ listOrders(filters = {}, accessToken) {
125
+ return this.http.request('/api/v1/admin/orders', {
126
+ query: {
127
+ search: filters.search,
128
+ status: filters.status,
129
+ projectId: filters.projectId,
130
+ userId: filters.userId,
131
+ limit: filters.limit,
132
+ },
133
+ accessToken,
134
+ });
135
+ }
136
+ getConfig(accessToken) {
137
+ return this.http.request('/api/v1/admin/config', { accessToken });
138
+ }
139
+ updateConfig(input, accessToken) {
140
+ return this.http.request('/api/v1/admin/config', {
141
+ method: 'PUT',
142
+ body: input,
143
+ accessToken,
144
+ });
145
+ }
146
+ }
@@ -6,6 +6,7 @@ export declare class AuthClient {
6
6
  login(input: {
7
7
  email: string;
8
8
  password: string;
9
+ projectId?: string;
9
10
  }): Promise<AuthSession>;
10
11
  register(input: {
11
12
  email: string;
@@ -4,5 +4,7 @@ export declare class PlatformHttpClient {
4
4
  private readonly fetchImpl;
5
5
  private readonly options;
6
6
  constructor(options: PlatformClientOptions);
7
+ private send;
7
8
  request<T>(path: string, requestOptions?: PlatformRequestOptions): Promise<T>;
9
+ requestRaw(path: string, requestOptions?: PlatformRequestOptions): Promise<Response>;
8
10
  }
@@ -15,9 +15,10 @@ export class PlatformHttpClient {
15
15
  constructor(options) {
16
16
  this.options = options;
17
17
  this.baseUrl = options.baseUrl.replace(/\/+$/, '');
18
- this.fetchImpl = options.fetchImpl ?? fetch;
18
+ const fetchImpl = options.fetchImpl ?? fetch;
19
+ this.fetchImpl = fetchImpl.bind(globalThis);
19
20
  }
20
- async request(path, requestOptions = {}) {
21
+ async send(path, requestOptions = {}) {
21
22
  const headers = new Headers(this.options.defaultHeaders);
22
23
  headers.set('Content-Type', 'application/json');
23
24
  if (requestOptions.headers) {
@@ -53,16 +54,23 @@ export class PlatformHttpClient {
53
54
  const message = error instanceof Error ? error.message : 'Unknown transport error';
54
55
  throw new PlatformTransportError(message);
55
56
  }
57
+ return response;
58
+ }
59
+ async request(path, requestOptions = {}) {
60
+ const response = await this.send(path, requestOptions);
56
61
  let payload = null;
57
62
  try {
58
63
  payload = (await response.json());
59
64
  }
60
65
  catch {
61
- throw new PlatformTransportError(`Platform API returned a non-JSON response for ${url}`);
66
+ throw new PlatformTransportError(`Platform API returned a non-JSON response for ${response.url}`);
62
67
  }
63
68
  if (!response.ok) {
64
69
  throw new PlatformApiError(payload.message, response.status, payload.code, payload.data);
65
70
  }
66
71
  return payload.data;
67
72
  }
73
+ async requestRaw(path, requestOptions = {}) {
74
+ return this.send(path, requestOptions);
75
+ }
68
76
  }
@@ -28,6 +28,27 @@ export interface AuthUser {
28
28
  avatar?: string | null;
29
29
  role: 'user' | 'admin' | 'super_admin';
30
30
  creditsBalance?: number;
31
+ projectId?: string | null;
32
+ projectName?: string | null;
33
+ projectSlug?: string | null;
34
+ membership?: {
35
+ tier: string;
36
+ power?: number;
37
+ endDate?: number | null;
38
+ } | null;
39
+ projectPermission?: {
40
+ id: string;
41
+ projectId: string;
42
+ projectName?: string | null;
43
+ projectSlug?: string | null;
44
+ role?: string | null;
45
+ tier?: string | null;
46
+ status?: string | null;
47
+ credits?: number;
48
+ startDate?: number | null;
49
+ endDate?: number | null;
50
+ autoRenew?: boolean;
51
+ } | null;
31
52
  }
32
53
  export interface AuthSession {
33
54
  user: AuthUser;
@@ -44,6 +65,8 @@ export interface ProjectSummary {
44
65
  export interface ProductSummary {
45
66
  id: string;
46
67
  projectId?: string | null;
68
+ projectName?: string | null;
69
+ projectSlug?: string | null;
47
70
  name: string;
48
71
  description?: string | null;
49
72
  price: number;
@@ -52,6 +75,9 @@ export interface ProductSummary {
52
75
  credits: number;
53
76
  tier: string;
54
77
  features: string[];
78
+ modelKeys?: string[];
79
+ models?: AiModelSummary[];
80
+ enabled?: boolean;
55
81
  sortOrder?: number;
56
82
  }
57
83
  export interface MembershipView {
@@ -82,6 +108,32 @@ export interface CreditsLedgerItem {
82
108
  description?: string | null;
83
109
  created_at: number;
84
110
  }
111
+ export interface UserApiKeyRecord {
112
+ id: string;
113
+ name: string;
114
+ keyPrefix: string;
115
+ active: boolean;
116
+ lastUsedAt?: number | null;
117
+ createdAt: number;
118
+ updatedAt: number;
119
+ }
120
+ export interface UserApiKeySecret {
121
+ id: string;
122
+ name: string;
123
+ keyPrefix: string;
124
+ secret: string;
125
+ createdAt: number;
126
+ }
127
+ export interface UserSettingDefinition {
128
+ label: string;
129
+ description: string;
130
+ defaultValue: string;
131
+ maxLength: number;
132
+ }
133
+ export interface UserSettingsPayload {
134
+ settings: Record<string, string>;
135
+ definitions?: Record<string, UserSettingDefinition>;
136
+ }
85
137
  export interface PaymentCreateResponse {
86
138
  paymentType: string;
87
139
  orderNo: string;
@@ -104,6 +156,22 @@ export interface PaymentQueryResponse {
104
156
  paidAt?: number | null;
105
157
  };
106
158
  }
159
+ export interface OrderSummary {
160
+ id: string;
161
+ productId?: string;
162
+ orderNo: string;
163
+ amount: number;
164
+ status: string;
165
+ productName?: string;
166
+ productTier?: string;
167
+ paymentMethod?: string | null;
168
+ createdAt?: number;
169
+ paidAt?: number | null;
170
+ }
171
+ export interface OrderDetail extends OrderSummary {
172
+ paymentIntentId?: string | null;
173
+ productDescription?: string | null;
174
+ }
107
175
  export interface AiModelSummary {
108
176
  key: string;
109
177
  id: string;
@@ -119,3 +187,152 @@ export interface AiModelSummary {
119
187
  outputPricing?: number;
120
188
  locked?: boolean;
121
189
  }
190
+ export interface AdminProject {
191
+ id: string;
192
+ name: string;
193
+ slug: string;
194
+ description?: string | null;
195
+ logoUrl?: string | null;
196
+ status: 'active' | 'inactive';
197
+ settings?: Record<string, unknown> | null;
198
+ createdAt: number;
199
+ updatedAt: number;
200
+ stats?: {
201
+ productCount: number;
202
+ userCount: number;
203
+ };
204
+ }
205
+ export type AdminProjectExportFormat = 'openapi' | 'markdown';
206
+ export interface AdminProduct {
207
+ id: string;
208
+ projectId?: string | null;
209
+ name: string;
210
+ description?: string | null;
211
+ price?: number;
212
+ discount_price?: number | null;
213
+ duration_days?: number;
214
+ credits?: number;
215
+ tier?: string;
216
+ features?: string[];
217
+ enabled?: boolean;
218
+ sort_order?: number;
219
+ }
220
+ export interface AdminMembershipRecord {
221
+ id: string;
222
+ scopeType: 'project' | 'global';
223
+ role: string;
224
+ tier: string;
225
+ status: string;
226
+ credits: number;
227
+ startDate?: number | null;
228
+ endDate?: number | null;
229
+ autoRenew: boolean;
230
+ createdAt: number;
231
+ updatedAt: number;
232
+ user: {
233
+ id: string;
234
+ email: string;
235
+ name?: string | null;
236
+ role: string;
237
+ status: string;
238
+ };
239
+ project: {
240
+ id: string;
241
+ name: string;
242
+ slug: string;
243
+ status: string;
244
+ } | null;
245
+ }
246
+ export interface AdminMembershipFilters {
247
+ scope?: 'project' | 'global';
248
+ projectId?: string;
249
+ status?: string;
250
+ tier?: string;
251
+ search?: string;
252
+ }
253
+ export interface AdminUserRecord {
254
+ id: string;
255
+ email: string;
256
+ name?: string | null;
257
+ role: string;
258
+ status: string;
259
+ createdAt: number;
260
+ updatedAt: number;
261
+ currentProject: {
262
+ id: string;
263
+ name: string;
264
+ slug: string;
265
+ } | null;
266
+ globalMembership: {
267
+ id: string;
268
+ tier: string | null;
269
+ status: string | null;
270
+ credits: number;
271
+ startDate?: number | null;
272
+ endDate?: number | null;
273
+ autoRenew: boolean;
274
+ } | null;
275
+ selectedProjectPermission: {
276
+ id: string;
277
+ role: string | null;
278
+ tier: string | null;
279
+ status: string | null;
280
+ credits: number;
281
+ startDate?: number | null;
282
+ endDate?: number | null;
283
+ autoRenew: boolean;
284
+ project: {
285
+ id: string;
286
+ name: string;
287
+ slug: string;
288
+ } | null;
289
+ } | null;
290
+ projectPermissionCount: number;
291
+ credits: {
292
+ balance: number;
293
+ reserved: number;
294
+ totalEarned: number;
295
+ totalSpent: number;
296
+ };
297
+ }
298
+ export interface AdminOrderRecord {
299
+ id: string;
300
+ orderNo: string;
301
+ amount: number;
302
+ currency: string;
303
+ status: string;
304
+ paymentMethod?: string | null;
305
+ paymentIntentId?: string | null;
306
+ createdAt: number;
307
+ updatedAt: number;
308
+ paidAt?: number | null;
309
+ product: {
310
+ id: string;
311
+ name: string;
312
+ tier?: string | null;
313
+ };
314
+ project: {
315
+ id: string;
316
+ name: string;
317
+ slug: string;
318
+ } | null;
319
+ user: {
320
+ id: string;
321
+ email: string;
322
+ name?: string | null;
323
+ };
324
+ }
325
+ export interface AdminOrderFilters {
326
+ search?: string;
327
+ status?: string;
328
+ projectId?: string;
329
+ userId?: string;
330
+ limit?: number;
331
+ }
332
+ export interface AdminConfigItem {
333
+ key: string;
334
+ value: string;
335
+ type?: string;
336
+ description?: string;
337
+ updated_at?: number;
338
+ }
package/dist/index.d.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  import { PlatformHttpClient } from './core/client';
2
2
  import type { PlatformClientOptions } from './core/types';
3
3
  import { AuthClient } from './auth/client';
4
- import { ProjectsClient } from './projects/client';
5
4
  import { CreditsClient } from './credits/client';
6
- import { PaymentClient } from './payment/client';
7
- import { AiClient } from './ai/client';
5
+ import { UserApiKeysClient } from './user/api-keys-client';
6
+ import { UserSettingsClient } from './user/settings-client';
8
7
  export * from './core/errors';
9
- export * from './core/types';
10
- export declare class PlatformAClient {
8
+ export type { AuthSession, AuthUser, CreditsBalance, CreditsLedgerItem, PlatformClientOptions, PlatformEnvelope, PlatformRequestOptions, UserApiKeyRecord, UserApiKeySecret, UserSettingDefinition, UserSettingsPayload, } from './core/types';
9
+ export declare class BasePlatformClient {
11
10
  readonly http: PlatformHttpClient;
12
11
  readonly auth: AuthClient;
13
- readonly projects: ProjectsClient;
14
12
  readonly credits: CreditsClient;
15
- readonly payment: PaymentClient;
16
- readonly ai: AiClient;
13
+ readonly apiKeys: UserApiKeysClient;
14
+ readonly settings: UserSettingsClient;
17
15
  constructor(options: PlatformClientOptions);
18
16
  }
19
- export declare function createPlatformAClient(options: PlatformClientOptions): PlatformAClient;
17
+ export declare function createBasePlatformClient(options: PlatformClientOptions): BasePlatformClient;
18
+ export { BasePlatformClient as PlatformAClient };
19
+ export declare const createPlatformAClient: typeof createBasePlatformClient;
package/dist/index.js CHANGED
@@ -1,21 +1,20 @@
1
1
  import { PlatformHttpClient } from './core/client';
2
2
  import { AuthClient } from './auth/client';
3
- import { ProjectsClient } from './projects/client';
4
3
  import { CreditsClient } from './credits/client';
5
- import { PaymentClient } from './payment/client';
6
- import { AiClient } from './ai/client';
4
+ import { UserApiKeysClient } from './user/api-keys-client';
5
+ import { UserSettingsClient } from './user/settings-client';
7
6
  export * from './core/errors';
8
- export * from './core/types';
9
- export class PlatformAClient {
7
+ export class BasePlatformClient {
10
8
  constructor(options) {
11
9
  this.http = new PlatformHttpClient(options);
12
10
  this.auth = new AuthClient(this.http);
13
- this.projects = new ProjectsClient(this.http);
14
11
  this.credits = new CreditsClient(this.http);
15
- this.payment = new PaymentClient(this.http);
16
- this.ai = new AiClient(this.http);
12
+ this.apiKeys = new UserApiKeysClient(this.http);
13
+ this.settings = new UserSettingsClient(this.http);
17
14
  }
18
15
  }
19
- export function createPlatformAClient(options) {
20
- return new PlatformAClient(options);
16
+ export function createBasePlatformClient(options) {
17
+ return new BasePlatformClient(options);
21
18
  }
19
+ export { BasePlatformClient as PlatformAClient };
20
+ export const createPlatformAClient = createBasePlatformClient;
@@ -0,0 +1,16 @@
1
+ import { PlatformHttpClient } from '../core/client';
2
+ import type { OrderDetail, OrderSummary } from '../core/types';
3
+ export declare class OrdersClient {
4
+ private readonly http;
5
+ constructor(http: PlatformHttpClient);
6
+ create(input: {
7
+ productId: string;
8
+ accessToken?: string;
9
+ }): Promise<OrderSummary>;
10
+ list(accessToken?: string): Promise<{
11
+ orders: OrderSummary[];
12
+ }>;
13
+ get(orderId: string, accessToken?: string): Promise<{
14
+ order: OrderDetail;
15
+ }>;
16
+ }
@@ -0,0 +1,24 @@
1
+ export class OrdersClient {
2
+ constructor(http) {
3
+ this.http = http;
4
+ }
5
+ create(input) {
6
+ return this.http.request('/api/v1/orders', {
7
+ method: 'POST',
8
+ accessToken: input.accessToken,
9
+ body: {
10
+ productId: input.productId,
11
+ },
12
+ });
13
+ }
14
+ list(accessToken) {
15
+ return this.http.request('/api/v1/orders', {
16
+ accessToken,
17
+ });
18
+ }
19
+ get(orderId, accessToken) {
20
+ return this.http.request(`/api/v1/orders/${orderId}`, {
21
+ accessToken,
22
+ });
23
+ }
24
+ }
@@ -1,5 +1,9 @@
1
1
  import { PlatformHttpClient } from '../core/client';
2
2
  import type { MembershipView, ProductSummary, ProjectSummary } from '../core/types';
3
+ type MembershipRequestOptions = {
4
+ accessToken?: string;
5
+ headers?: Record<string, string>;
6
+ };
3
7
  export declare class ProjectsClient {
4
8
  private readonly http;
5
9
  constructor(http: PlatformHttpClient);
@@ -8,7 +12,12 @@ export declare class ProjectsClient {
8
12
  products: ProductSummary[];
9
13
  total?: number;
10
14
  }>;
11
- getMembership(projectId: string, accessToken?: string): Promise<{
15
+ getCatalogProducts(projectId: string): Promise<{
16
+ project: ProjectSummary | null;
17
+ products: ProductSummary[];
18
+ total?: number;
19
+ }>;
20
+ getMembership(projectId: string, options?: string | MembershipRequestOptions): Promise<{
12
21
  project: ProjectSummary;
13
22
  membership: MembershipView;
14
23
  }>;
@@ -20,3 +29,4 @@ export declare class ProjectsClient {
20
29
  permissions?: unknown[];
21
30
  }>;
22
31
  }
32
+ export {};
@@ -5,8 +5,19 @@ export class ProjectsClient {
5
5
  getProducts(projectId) {
6
6
  return this.http.request(`/api/v1/projects/${projectId}/products`);
7
7
  }
8
- getMembership(projectId, accessToken) {
9
- return this.http.request(`/api/v1/projects/${projectId}/membership`, { accessToken });
8
+ getCatalogProducts(projectId) {
9
+ return this.http.request('/api/v1/products', {
10
+ query: { projectId },
11
+ });
12
+ }
13
+ getMembership(projectId, options) {
14
+ const normalizedOptions = typeof options === 'string'
15
+ ? { accessToken: options }
16
+ : (options ?? {});
17
+ return this.http.request(`/api/v1/projects/${projectId}/membership`, {
18
+ accessToken: normalizedOptions.accessToken,
19
+ headers: normalizedOptions.headers,
20
+ });
10
21
  }
11
22
  getPermissions(input) {
12
23
  return this.http.request('/api/v1/user/project-permissions', {
@@ -0,0 +1,19 @@
1
+ import { PlatformHttpClient } from '../core/client';
2
+ import type { UserApiKeyRecord, UserApiKeySecret } from '../core/types';
3
+ export declare class UserApiKeysClient {
4
+ private readonly http;
5
+ constructor(http: PlatformHttpClient);
6
+ list(accessToken?: string): Promise<{
7
+ keys: UserApiKeyRecord[];
8
+ }>;
9
+ create(input: {
10
+ name?: string;
11
+ }, accessToken?: string): Promise<{
12
+ key: UserApiKeySecret;
13
+ }>;
14
+ update(id: string, input: {
15
+ name?: string;
16
+ active?: boolean;
17
+ }, accessToken?: string): Promise<null>;
18
+ delete(id: string, accessToken?: string): Promise<null>;
19
+ }
@@ -0,0 +1,30 @@
1
+ export class UserApiKeysClient {
2
+ constructor(http) {
3
+ this.http = http;
4
+ }
5
+ list(accessToken) {
6
+ return this.http.request('/api/v1/user/api-keys', {
7
+ accessToken,
8
+ });
9
+ }
10
+ create(input, accessToken) {
11
+ return this.http.request('/api/v1/user/api-keys', {
12
+ method: 'POST',
13
+ accessToken,
14
+ body: input,
15
+ });
16
+ }
17
+ update(id, input, accessToken) {
18
+ return this.http.request(`/api/v1/user/api-keys/${encodeURIComponent(id)}`, {
19
+ method: 'PATCH',
20
+ accessToken,
21
+ body: input,
22
+ });
23
+ }
24
+ delete(id, accessToken) {
25
+ return this.http.request(`/api/v1/user/api-keys/${encodeURIComponent(id)}`, {
26
+ method: 'DELETE',
27
+ accessToken,
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,11 @@
1
+ import { PlatformHttpClient } from '../core/client';
2
+ import type { UserSettingsPayload } from '../core/types';
3
+ export declare class UserSettingsClient {
4
+ private readonly http;
5
+ constructor(http: PlatformHttpClient);
6
+ get(accessToken?: string): Promise<UserSettingsPayload>;
7
+ update(settings: Record<string, string | number | boolean>, accessToken?: string): Promise<{
8
+ updated: string[];
9
+ settings: Record<string, string>;
10
+ }>;
11
+ }
@@ -0,0 +1,17 @@
1
+ export class UserSettingsClient {
2
+ constructor(http) {
3
+ this.http = http;
4
+ }
5
+ get(accessToken) {
6
+ return this.http.request('/api/v1/user/settings', {
7
+ accessToken,
8
+ });
9
+ }
10
+ update(settings, accessToken) {
11
+ return this.http.request('/api/v1/user/settings', {
12
+ method: 'PUT',
13
+ accessToken,
14
+ body: settings,
15
+ });
16
+ }
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api2key-base-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TypeScript SDK for consuming the Api2Key API stable APIs",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",