apaas-oapi-client 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/UserManual.md +251 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.js +239 -46
- package/package.json +2 -3
- package/src/index.ts +312 -20
- package/CHANGELOG.md +0 -19
package/UserManual.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# 背景
|
|
2
|
+
|
|
3
|
+
aPaaS 平台有完整的 Open API 能力,但是目前这些能力全都以单独接口的形式提供给开发者,不方便开发者调试和调用。
|
|
4
|
+
在此背景下,我们在一店一群项目的基础上,封装 aPaaS 平台 RESTful API 的 Node.js SDK,简化接口调用,内置限流与 token 缓存功能。
|
|
5
|
+
|
|
6
|
+
## ✨ **功能特性**
|
|
7
|
+
|
|
8
|
+
- ✅ 获取 accessToken,自动管理 token 有效期
|
|
9
|
+
|
|
10
|
+
- ✅ record 单条查询、 records 记录列表查询(支持分页迭代)
|
|
11
|
+
|
|
12
|
+
- ✅ record 单条更新、批量更新
|
|
13
|
+
|
|
14
|
+
- ✅ record 单条删除、批量删除
|
|
15
|
+
|
|
16
|
+
- ✅ 内置 Bottleneck 限流器,基于 API 接口配置限流规则
|
|
17
|
+
|
|
18
|
+
- ✅ 自定义日志等级
|
|
19
|
+
|
|
20
|
+
- ……
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<br>
|
|
24
|
+
|
|
25
|
+
<br>
|
|
26
|
+
|
|
27
|
+
**📦 安装**
|
|
28
|
+
|
|
29
|
+
```Bash
|
|
30
|
+
npm install apaas-oapi-client
|
|
31
|
+
# or
|
|
32
|
+
yarn add apaas-oapi-client
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
***
|
|
36
|
+
|
|
37
|
+
<br>
|
|
38
|
+
|
|
39
|
+
# **🚀 快速开始**
|
|
40
|
+
|
|
41
|
+
```JavaScript
|
|
42
|
+
const { apaas } = require('apaas-oapi-client');
|
|
43
|
+
|
|
44
|
+
async function main() {
|
|
45
|
+
const client = new apaas.Client({
|
|
46
|
+
clientId: 'your_client_id',
|
|
47
|
+
clientSecret: 'your_client_secret',
|
|
48
|
+
namespace: 'app_xxx'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await client.init();
|
|
52
|
+
client.setLoggerLevel(3); // 设置日志等级 (0-5)
|
|
53
|
+
|
|
54
|
+
console.log('Access Token:', client.token);
|
|
55
|
+
console.log('Namespace:', client.currentNamespace);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
main();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
***
|
|
62
|
+
|
|
63
|
+
<br>
|
|
64
|
+
|
|
65
|
+
## **🔐 认证**
|
|
66
|
+
|
|
67
|
+
### **初始化 Client**
|
|
68
|
+
|
|
69
|
+
| **参数** | **类型** | **说明** |
|
|
70
|
+
| :-- | :-- | :-- |
|
|
71
|
+
| clientId | string | 应用 clientId |
|
|
72
|
+
| clientSecret | string | 应用 clientSecret |
|
|
73
|
+
| namespace | string | 命名空间 |
|
|
74
|
+
| disableTokenCache | boolean | 是否禁用 token 缓存,默认 false |
|
|
75
|
+
|
|
76
|
+
***
|
|
77
|
+
|
|
78
|
+
<br>
|
|
79
|
+
|
|
80
|
+
## **📝 日志等级**
|
|
81
|
+
|
|
82
|
+
可调用 setLoggerLevel(level) 设置日志等级。
|
|
83
|
+
|
|
84
|
+
| **Level** | **名称** | **说明** |
|
|
85
|
+
| :-- | :-- | :-- |
|
|
86
|
+
| 0 | fatal | 严重错误 |
|
|
87
|
+
| 1 | error | 错误 |
|
|
88
|
+
| 2 | warn | 警告 |
|
|
89
|
+
| 3 | info | 信息(默认) |
|
|
90
|
+
| 4 | debug | 调试信息 |
|
|
91
|
+
| 5 | trace | 追踪 |
|
|
92
|
+
|
|
93
|
+
***
|
|
94
|
+
|
|
95
|
+
<br>
|
|
96
|
+
|
|
97
|
+
## **🔍 查询接口**
|
|
98
|
+
|
|
99
|
+
查询条件请根据实际需求自行拼装。详情参考 API 接口文档示例。
|
|
100
|
+
|
|
101
|
+
### **单条查询**
|
|
102
|
+
|
|
103
|
+
```JavaScript
|
|
104
|
+
const res = await client.object.search.record({
|
|
105
|
+
object_name: 'object_store',
|
|
106
|
+
record_id: 'your_record_id',
|
|
107
|
+
select: ['field1', 'field2']
|
|
108
|
+
});
|
|
109
|
+
console.log(res);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
***
|
|
113
|
+
|
|
114
|
+
### **批量查询**
|
|
115
|
+
|
|
116
|
+
每次查询最多返回 100 条记录。
|
|
117
|
+
|
|
118
|
+
```JavaScript
|
|
119
|
+
const res = await client.object.search.records({
|
|
120
|
+
object_name: 'object_store',
|
|
121
|
+
data: {
|
|
122
|
+
need_total_count: true,
|
|
123
|
+
page_size: 100,
|
|
124
|
+
offset: 0
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
console.log(res);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
***
|
|
131
|
+
|
|
132
|
+
### **分页查询所有记录**
|
|
133
|
+
|
|
134
|
+
在上一个请求的基础上,封装每次查询最多返回 100 条记录。
|
|
135
|
+
|
|
136
|
+
```JavaScript
|
|
137
|
+
const { total, items } = await client.object.search.recordsWithIterator({
|
|
138
|
+
object_name: 'object_store',
|
|
139
|
+
data: {
|
|
140
|
+
need_total_count: true,
|
|
141
|
+
page_size: 100,
|
|
142
|
+
offset: 0
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
console.log('Total:', total);
|
|
147
|
+
console.log('Items:', items);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
***
|
|
151
|
+
|
|
152
|
+
<br>
|
|
153
|
+
|
|
154
|
+
## **✏️ 更新接口**
|
|
155
|
+
|
|
156
|
+
### **单条更新**
|
|
157
|
+
|
|
158
|
+
```JavaScript
|
|
159
|
+
const res = await client.object.update.record({
|
|
160
|
+
object_name: 'object_store',
|
|
161
|
+
record_id: 'your_record_id',
|
|
162
|
+
record: { field1: 'newValue' }
|
|
163
|
+
});
|
|
164
|
+
console.log(res);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
***
|
|
168
|
+
|
|
169
|
+
### **批量更新**
|
|
170
|
+
|
|
171
|
+
> ⚠️ 每次最多更新 100 条,SDK 已自动分组限流
|
|
172
|
+
|
|
173
|
+
```JavaScript
|
|
174
|
+
const res = await client.object.update.recordsBatchUpdate({
|
|
175
|
+
object_name: 'object_store',
|
|
176
|
+
records: [
|
|
177
|
+
{ _id: 'id1', field1: 'value1' },
|
|
178
|
+
{ _id: 'id2', field1: 'value2' }
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
console.log(res);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
***
|
|
185
|
+
|
|
186
|
+
<br>
|
|
187
|
+
|
|
188
|
+
## **🗑️ 删除接口**
|
|
189
|
+
|
|
190
|
+
### **单条删除**
|
|
191
|
+
|
|
192
|
+
```JavaScript
|
|
193
|
+
const res = await client.object.delete.record({
|
|
194
|
+
object_name: 'object_store',
|
|
195
|
+
record_id: 'your_record_id'
|
|
196
|
+
});
|
|
197
|
+
console.log(res);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
***
|
|
201
|
+
|
|
202
|
+
### **批量删除**
|
|
203
|
+
|
|
204
|
+
> ⚠️ 每次最多删除 100 条,SDK 已自动分组限流
|
|
205
|
+
|
|
206
|
+
```JavaScript
|
|
207
|
+
const res = await client.object.delete.recordsBatchDelete({
|
|
208
|
+
object_name: 'object_store',
|
|
209
|
+
ids: ['id1', 'id2', 'id3']
|
|
210
|
+
});
|
|
211
|
+
console.log(res);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
***
|
|
215
|
+
|
|
216
|
+
## **🛠️ 高级**
|
|
217
|
+
|
|
218
|
+
### **获取当前** **token**
|
|
219
|
+
|
|
220
|
+
```JavaScript
|
|
221
|
+
console.log(client.token);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### **获取当前 namespace**
|
|
225
|
+
|
|
226
|
+
```JavaScript
|
|
227
|
+
console.log(client.currentNamespace);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
***
|
|
231
|
+
|
|
232
|
+
<br>
|
|
233
|
+
|
|
234
|
+
## **💡 备注**
|
|
235
|
+
|
|
236
|
+
- 本 SDK 默认使用 [axios](https://www.npmjs.com/package/axios) 请求。
|
|
237
|
+
|
|
238
|
+
- 内置 [bottleneck](https://www.npmjs.com/package/bottleneck) 进行请求限流。
|
|
239
|
+
|
|
240
|
+
- 日志打印默认使用 console.log 并带时间戳,可通过 setLoggerLevel 动态控制输出等级。
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
***
|
|
244
|
+
|
|
245
|
+
<br>
|
|
246
|
+
|
|
247
|
+
<br>
|
|
248
|
+
|
|
249
|
+
> 由 [aPaaS OAPI Client SDK](https://www.npmjs.com/package/apaas-oapi-client) 提供支持,如有问题请提交 Issue 反馈。
|
|
250
|
+
|
|
251
|
+
<br>
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,25 @@ declare class Client {
|
|
|
73
73
|
* 对象模块
|
|
74
74
|
*/
|
|
75
75
|
object: {
|
|
76
|
+
metadata: {
|
|
77
|
+
/**
|
|
78
|
+
* 获取指定对象下指定字段的元数据
|
|
79
|
+
* @param params 请求参数 { object_name, field_name }
|
|
80
|
+
* @returns 接口返回结果
|
|
81
|
+
*/
|
|
82
|
+
field: (params: {
|
|
83
|
+
object_name: string;
|
|
84
|
+
field_name: string;
|
|
85
|
+
}) => Promise<any>;
|
|
86
|
+
/**
|
|
87
|
+
* 获取指定对象的所有字段信息
|
|
88
|
+
* @param params 请求参数 { object_name }
|
|
89
|
+
* @returns 接口返回结果
|
|
90
|
+
*/
|
|
91
|
+
fields: (params: {
|
|
92
|
+
object_name: string;
|
|
93
|
+
}) => Promise<any>;
|
|
94
|
+
};
|
|
76
95
|
search: {
|
|
77
96
|
/**
|
|
78
97
|
* 单条记录查询
|
|
@@ -100,6 +119,38 @@ declare class Client {
|
|
|
100
119
|
items: any[];
|
|
101
120
|
}>;
|
|
102
121
|
};
|
|
122
|
+
create: {
|
|
123
|
+
/**
|
|
124
|
+
* 单条记录创建
|
|
125
|
+
* @param params 请求参数 { object_name, record }
|
|
126
|
+
* @returns 接口返回结果
|
|
127
|
+
*/
|
|
128
|
+
record: (params: {
|
|
129
|
+
object_name: string;
|
|
130
|
+
record: any;
|
|
131
|
+
}) => Promise<any>;
|
|
132
|
+
/**
|
|
133
|
+
* 批量创建记录
|
|
134
|
+
* @param params 请求参数 { object_name, records }
|
|
135
|
+
* @returns 接口返回结果
|
|
136
|
+
*/
|
|
137
|
+
records: (params: {
|
|
138
|
+
object_name: string;
|
|
139
|
+
records: any[];
|
|
140
|
+
}) => Promise<any>;
|
|
141
|
+
/**
|
|
142
|
+
* 分批创建所有记录
|
|
143
|
+
* @param params 请求参数 { object_name, records }
|
|
144
|
+
* @returns { total, items }
|
|
145
|
+
*/
|
|
146
|
+
recordsWithIterator: (params: {
|
|
147
|
+
object_name: string;
|
|
148
|
+
records: any[];
|
|
149
|
+
}) => Promise<{
|
|
150
|
+
total: number;
|
|
151
|
+
items: any[];
|
|
152
|
+
}>;
|
|
153
|
+
};
|
|
103
154
|
update: {
|
|
104
155
|
/**
|
|
105
156
|
* 单条更新
|
|
@@ -142,6 +193,43 @@ declare class Client {
|
|
|
142
193
|
}) => Promise<any[]>;
|
|
143
194
|
};
|
|
144
195
|
};
|
|
196
|
+
/**
|
|
197
|
+
* 部门 ID 交换模块
|
|
198
|
+
*/
|
|
199
|
+
department: {
|
|
200
|
+
/**
|
|
201
|
+
* 单个部门 ID 交换
|
|
202
|
+
* @param params 请求参数
|
|
203
|
+
* @returns 单个部门映射结果
|
|
204
|
+
*/
|
|
205
|
+
exchange: (params: {
|
|
206
|
+
department_id_type: "department_id" | "external_department_id" | "external_open_department_id";
|
|
207
|
+
department_id: string;
|
|
208
|
+
}) => Promise<any>;
|
|
209
|
+
/**
|
|
210
|
+
* 批量部门 ID 交换
|
|
211
|
+
* @param params 请求参数
|
|
212
|
+
* @returns 所有子请求的返回结果数组
|
|
213
|
+
*/
|
|
214
|
+
batchExchange: (params: {
|
|
215
|
+
department_id_type: "department_id" | "external_department_id" | "external_open_department_id";
|
|
216
|
+
department_ids: string[];
|
|
217
|
+
}) => Promise<any[]>;
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* 云函数模块
|
|
221
|
+
*/
|
|
222
|
+
function: {
|
|
223
|
+
/**
|
|
224
|
+
* 调用云函数
|
|
225
|
+
* @param params 请求参数 { name: string; params: any }
|
|
226
|
+
* @returns 接口返回结果
|
|
227
|
+
*/
|
|
228
|
+
invoke: (params: {
|
|
229
|
+
name: string;
|
|
230
|
+
params: any;
|
|
231
|
+
}) => Promise<any>;
|
|
232
|
+
};
|
|
145
233
|
}
|
|
146
234
|
export declare const apaas: {
|
|
147
235
|
Client: typeof Client;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var dayjs = require('dayjs');
|
|
4
4
|
var axios = require('axios');
|
|
5
|
-
var Bottleneck = require('bottleneck');
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* 日志等级枚举
|
|
@@ -17,32 +16,7 @@ var LoggerLevel;
|
|
|
17
16
|
LoggerLevel[LoggerLevel["trace"] = 5] = "trace";
|
|
18
17
|
})(LoggerLevel || (LoggerLevel = {}));
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
* 默认 apaas 限流配置
|
|
22
|
-
*/
|
|
23
|
-
const apaasLimiterOptions = {
|
|
24
|
-
minTime: 200, // 每秒最多发起 5 个数据库操作
|
|
25
|
-
reservoir: 20, // 最多同时查询 50 个数据库操作
|
|
26
|
-
reservoirRefreshAmount: 20, // 每次查询完毕后,重置为 50 个数据库操作
|
|
27
|
-
reservoirRefreshInterval: 1000 // 重置时间间隔为 1 秒
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* 创建限流器
|
|
31
|
-
* @param fn 被限流函数
|
|
32
|
-
* @param options 自定义限流配置
|
|
33
|
-
* @returns 包装后的限流函数
|
|
34
|
-
*/
|
|
35
|
-
async function functionLimiter(fn, options = {}) {
|
|
36
|
-
const limiter = new Bottleneck({
|
|
37
|
-
minTime: options.minTime || apaasLimiterOptions.minTime,
|
|
38
|
-
reservoir: options.reservoir || apaasLimiterOptions.reservoir,
|
|
39
|
-
reservoirRefreshAmount: options.reservoirRefreshAmount || apaasLimiterOptions.reservoirRefreshAmount,
|
|
40
|
-
reservoirRefreshInterval: options.reservoirRefreshInterval || apaasLimiterOptions.reservoirRefreshInterval
|
|
41
|
-
});
|
|
42
|
-
const wrapped = limiter.wrap(fn);
|
|
43
|
-
return wrapped();
|
|
44
|
-
}
|
|
45
|
-
|
|
19
|
+
const { functionLimiter } = require('./limiter');
|
|
46
20
|
/**
|
|
47
21
|
* aPaaS OpenAPI 客户端
|
|
48
22
|
*/
|
|
@@ -59,6 +33,42 @@ class Client {
|
|
|
59
33
|
* 对象模块
|
|
60
34
|
*/
|
|
61
35
|
this.object = {
|
|
36
|
+
metadata: {
|
|
37
|
+
/**
|
|
38
|
+
* 获取指定对象下指定字段的元数据
|
|
39
|
+
* @param params 请求参数 { object_name, field_name }
|
|
40
|
+
* @returns 接口返回结果
|
|
41
|
+
*/
|
|
42
|
+
field: async (params) => {
|
|
43
|
+
const { object_name, field_name } = params;
|
|
44
|
+
await this.ensureTokenValid();
|
|
45
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}/fields/${field_name}`;
|
|
46
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 开始获取字段元数据 object_name=${object_name}, field_name=${field_name}`);
|
|
47
|
+
const res = await this.axiosInstance.get(url, {
|
|
48
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
49
|
+
});
|
|
50
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 调用完成,返回状态=${res.data.code}`);
|
|
51
|
+
this.log(LoggerLevel.trace, `[对象字段查询] 📄 调用完成,返回信息=${JSON.stringify(res.data)}`);
|
|
52
|
+
return res.data;
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* 获取指定对象的所有字段信息
|
|
56
|
+
* @param params 请求参数 { object_name }
|
|
57
|
+
* @returns 接口返回结果
|
|
58
|
+
*/
|
|
59
|
+
fields: async (params) => {
|
|
60
|
+
const { object_name } = params;
|
|
61
|
+
await this.ensureTokenValid();
|
|
62
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}`;
|
|
63
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 开始获取对象字段元数据 object_name=${object_name}`);
|
|
64
|
+
const res = await this.axiosInstance.get(url, {
|
|
65
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
66
|
+
});
|
|
67
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 调用完成,返回状态=${res.data.code}`);
|
|
68
|
+
this.log(LoggerLevel.trace, `[对象字段查询] 📄 调用完成,返回信息=${JSON.stringify(res.data)}`);
|
|
69
|
+
return res.data;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
62
72
|
search: {
|
|
63
73
|
/**
|
|
64
74
|
* 单条记录查询
|
|
@@ -72,7 +82,8 @@ class Client {
|
|
|
72
82
|
const res = await functionLimiter(async () => {
|
|
73
83
|
await this.ensureTokenValid();
|
|
74
84
|
const response = await this.axiosInstance.post(url, { select }, { headers: { Authorization: `${this.accessToken}` } });
|
|
75
|
-
this.log(LoggerLevel.
|
|
85
|
+
this.log(LoggerLevel.debug, `[单条查询记录] 🔍 查询 record_id: ${record_id} 调用完成,返回状态: ${response.data.code}`);
|
|
86
|
+
this.log(LoggerLevel.trace, `[单条查询记录] 🔍 查询 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
76
87
|
return response.data;
|
|
77
88
|
});
|
|
78
89
|
return res;
|
|
@@ -83,13 +94,16 @@ class Client {
|
|
|
83
94
|
* @returns 接口返回结果
|
|
84
95
|
*/
|
|
85
96
|
records: async (params) => {
|
|
97
|
+
var _a, _b;
|
|
86
98
|
const { object_name, data } = params;
|
|
87
99
|
await this.ensureTokenValid();
|
|
88
100
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_query`;
|
|
89
101
|
const res = await this.axiosInstance.post(url, data, {
|
|
90
102
|
headers: { Authorization: `${this.accessToken}` }
|
|
91
103
|
});
|
|
92
|
-
this.log(LoggerLevel.
|
|
104
|
+
this.log(LoggerLevel.info, `[批量查询记录] 🔍 接口调用完成`);
|
|
105
|
+
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 调用完成,返回状态: ${res.data.code},返回数据总数${((_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.total) || 'unknown'}`);
|
|
106
|
+
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 调用完成,返回信息: ${JSON.stringify(res.data)}`);
|
|
93
107
|
return res.data;
|
|
94
108
|
},
|
|
95
109
|
/**
|
|
@@ -119,13 +133,92 @@ class Client {
|
|
|
119
133
|
this.log(LoggerLevel.info, '[批量查询记录] 🔍 接口返回 total:', total);
|
|
120
134
|
}
|
|
121
135
|
nextPageToken = res.data.next_page_token;
|
|
136
|
+
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 第 ${page} 页查询,nextPageToken: ${nextPageToken || ''}`);
|
|
122
137
|
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 第 ${page} 页查询完成,items.length: ${res.data.items.length}`);
|
|
138
|
+
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 第 ${page} 页查询结果: ${JSON.stringify(res.data.items)}`);
|
|
123
139
|
return res;
|
|
124
140
|
});
|
|
125
141
|
} while (nextPageToken);
|
|
126
142
|
return { total, items: results };
|
|
127
143
|
}
|
|
128
144
|
},
|
|
145
|
+
create: {
|
|
146
|
+
/**
|
|
147
|
+
* 单条记录创建
|
|
148
|
+
* @param params 请求参数 { object_name, record }
|
|
149
|
+
* @returns 接口返回结果
|
|
150
|
+
*/
|
|
151
|
+
record: async (params) => {
|
|
152
|
+
const { object_name, record } = params;
|
|
153
|
+
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records`;
|
|
154
|
+
this.log(LoggerLevel.info, `[单条创建记录] ➕ 开始向对象 ${object_name} 创建记录`);
|
|
155
|
+
const res = await functionLimiter(async () => {
|
|
156
|
+
await this.ensureTokenValid();
|
|
157
|
+
const response = await this.axiosInstance.post(url, { record }, {
|
|
158
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
159
|
+
});
|
|
160
|
+
this.log(LoggerLevel.info, `[单条创建记录] ➕ 向对象 ${object_name} 内创建记录,调用完成`);
|
|
161
|
+
this.log(LoggerLevel.debug, `[单条创建记录] ➕ 向对象 ${object_name} 内创建数据,调用完成,返回状态: ${response.data.code}`);
|
|
162
|
+
this.log(LoggerLevel.trace, `[单条创建记录] ➕ 向对象 ${object_name} 内创建数据,调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
163
|
+
return response.data;
|
|
164
|
+
});
|
|
165
|
+
return res;
|
|
166
|
+
},
|
|
167
|
+
/**
|
|
168
|
+
* 批量创建记录
|
|
169
|
+
* @param params 请求参数 { object_name, records }
|
|
170
|
+
* @returns 接口返回结果
|
|
171
|
+
*/
|
|
172
|
+
records: async (params) => {
|
|
173
|
+
const { object_name, records } = params;
|
|
174
|
+
await this.ensureTokenValid();
|
|
175
|
+
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
|
|
176
|
+
const res = await this.axiosInstance.post(url, { records }, {
|
|
177
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
178
|
+
});
|
|
179
|
+
this.log(LoggerLevel.info, `[批量创建记录] ➕ 开始向对象 ${object_name} 批量创建记录`);
|
|
180
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 向对象 ${object_name} 批量创建记录,调用完成,返回状态: ${res.data.code}`);
|
|
181
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 向对象 ${object_name} 批量创建记录,调用完成,返回信息: ${JSON.stringify(res.data)}`);
|
|
182
|
+
return res.data;
|
|
183
|
+
},
|
|
184
|
+
/**
|
|
185
|
+
* 分批创建所有记录
|
|
186
|
+
* @param params 请求参数 { object_name, records }
|
|
187
|
+
* @returns { total, items }
|
|
188
|
+
*/
|
|
189
|
+
recordsWithIterator: async (params) => {
|
|
190
|
+
const { object_name, records } = params;
|
|
191
|
+
let results = [];
|
|
192
|
+
let total = records.length;
|
|
193
|
+
const chunkSize = 100;
|
|
194
|
+
let page = 0;
|
|
195
|
+
const chunks = [];
|
|
196
|
+
for (let i = 0; i < records.length; i += chunkSize) {
|
|
197
|
+
chunks.push(records.slice(i, i + chunkSize));
|
|
198
|
+
}
|
|
199
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
200
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
201
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
202
|
+
page += 1;
|
|
203
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 开始创建第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
204
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 开始创建第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
205
|
+
await functionLimiter(async () => {
|
|
206
|
+
const res = await this.object.create.records({
|
|
207
|
+
object_name,
|
|
208
|
+
records: chunk
|
|
209
|
+
});
|
|
210
|
+
if (res.data && Array.isArray(res.data.items)) {
|
|
211
|
+
results = results.concat(res.data.items);
|
|
212
|
+
}
|
|
213
|
+
this.log(LoggerLevel.info, `[批量创建记录] ➕ 创建第 ${page} 页数据,调用完成,创建数量: ${res.data.items.length}`);
|
|
214
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 创建第 ${page} 页页数据,调用完成,返回状态: ${res.data.code}`);
|
|
215
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 创建第 ${page} 页页数据,调用结果: ${JSON.stringify(res.data.items)}`);
|
|
216
|
+
return res;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return { total, items: results };
|
|
220
|
+
}
|
|
221
|
+
},
|
|
129
222
|
update: {
|
|
130
223
|
/**
|
|
131
224
|
* 单条更新
|
|
@@ -139,7 +232,9 @@ class Client {
|
|
|
139
232
|
const res = await functionLimiter(async () => {
|
|
140
233
|
await this.ensureTokenValid();
|
|
141
234
|
const response = await this.axiosInstance.patch(url, { record }, { headers: { Authorization: `${this.accessToken}` } });
|
|
142
|
-
this.log(LoggerLevel.info, `[单条更新记录] 💾 record_id: ${record_id}
|
|
235
|
+
this.log(LoggerLevel.info, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成`);
|
|
236
|
+
this.log(LoggerLevel.debug, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成,返回状态: ${response.data.code}`);
|
|
237
|
+
this.log(LoggerLevel.trace, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
143
238
|
return response.data;
|
|
144
239
|
});
|
|
145
240
|
return res;
|
|
@@ -157,14 +252,17 @@ class Client {
|
|
|
157
252
|
for (let i = 0; i < records.length; i += chunkSize) {
|
|
158
253
|
chunks.push(records.slice(i, i + chunkSize));
|
|
159
254
|
}
|
|
160
|
-
this.log(LoggerLevel.
|
|
255
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
256
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
161
257
|
const results = [];
|
|
162
258
|
for (const [index, chunk] of chunks.entries()) {
|
|
163
|
-
this.log(LoggerLevel.
|
|
259
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 开始更新第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
260
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 开始更新第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
164
261
|
const res = await functionLimiter(async () => {
|
|
165
262
|
await this.ensureTokenValid();
|
|
166
263
|
const response = await this.axiosInstance.patch(url, { records: chunk }, { headers: { Authorization: `${this.accessToken}` } });
|
|
167
|
-
this.log(LoggerLevel.
|
|
264
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 更新第 ${index + 1} 组调用完成,返回状态: ${JSON.stringify(response.data)}`);
|
|
265
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 更新第 ${index + 1} 组调用完成,返回信息: ${response.data}`);
|
|
168
266
|
return response.data;
|
|
169
267
|
});
|
|
170
268
|
results.push(res);
|
|
@@ -181,13 +279,13 @@ class Client {
|
|
|
181
279
|
record: async (params) => {
|
|
182
280
|
const { object_name, record_id } = params;
|
|
183
281
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/${record_id}`;
|
|
184
|
-
this.log(LoggerLevel.
|
|
282
|
+
this.log(LoggerLevel.trace, `[单条删除记录] 🗑️ 开始删除 record_id: ${record_id}`);
|
|
185
283
|
const res = await functionLimiter(async () => {
|
|
186
284
|
await this.ensureTokenValid();
|
|
187
285
|
const response = await this.axiosInstance.delete(url, {
|
|
188
286
|
headers: { Authorization: `${this.accessToken}` }
|
|
189
287
|
});
|
|
190
|
-
this.log(LoggerLevel.info, `[单条删除记录] 🗑️ record_id: ${record_id}
|
|
288
|
+
this.log(LoggerLevel.info, `[单条删除记录] 🗑️ 删除 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
191
289
|
return response.data;
|
|
192
290
|
});
|
|
193
291
|
return res;
|
|
@@ -205,7 +303,7 @@ class Client {
|
|
|
205
303
|
for (let i = 0; i < ids.length; i += chunkSize) {
|
|
206
304
|
chunks.push(ids.slice(i, i + chunkSize));
|
|
207
305
|
}
|
|
208
|
-
this.log(LoggerLevel.
|
|
306
|
+
this.log(LoggerLevel.debug, `[批量删除记录] 🗑️ 总共 ${ids.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
209
307
|
const results = [];
|
|
210
308
|
for (const [index, chunk] of chunks.entries()) {
|
|
211
309
|
this.log(LoggerLevel.info, `[批量删除记录] 🗑️ 开始删除第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
@@ -215,7 +313,8 @@ class Client {
|
|
|
215
313
|
headers: { Authorization: `${this.accessToken}` },
|
|
216
314
|
data: { ids: chunk }
|
|
217
315
|
});
|
|
218
|
-
this.log(LoggerLevel.
|
|
316
|
+
this.log(LoggerLevel.debug, `[批量删除记录] 🗑️ 第 ${index + 1} 组删除完成,返回状态: ${response.data.code}`);
|
|
317
|
+
this.log(LoggerLevel.trace, `[批量删除记录] 🗑️ 第 ${index + 1} 组删除完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
219
318
|
return response.data;
|
|
220
319
|
});
|
|
221
320
|
results.push(res);
|
|
@@ -224,6 +323,100 @@ class Client {
|
|
|
224
323
|
}
|
|
225
324
|
}
|
|
226
325
|
};
|
|
326
|
+
/**
|
|
327
|
+
* 部门 ID 交换模块
|
|
328
|
+
*/
|
|
329
|
+
this.department = {
|
|
330
|
+
/**
|
|
331
|
+
* 单个部门 ID 交换
|
|
332
|
+
* @param params 请求参数
|
|
333
|
+
* @returns 单个部门映射结果
|
|
334
|
+
*/
|
|
335
|
+
exchange: async (params) => {
|
|
336
|
+
const { department_id_type, department_id } = params;
|
|
337
|
+
// department_id_type 可选值:
|
|
338
|
+
// - 'department_id' (如 "1758534140403815")
|
|
339
|
+
// - 'external_department_id' (外部平台 department_id,无固定格式)
|
|
340
|
+
// - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
|
|
341
|
+
const url = '/api/integration/v2/feishu/getDepartments';
|
|
342
|
+
this.log(LoggerLevel.info, `[部门ID交换] 🔄 开始交换单个部门 ID: ${department_id}`);
|
|
343
|
+
const res = await functionLimiter(async () => {
|
|
344
|
+
await this.ensureTokenValid();
|
|
345
|
+
const response = await this.axiosInstance.post(url, {
|
|
346
|
+
department_id_type,
|
|
347
|
+
department_ids: [department_id]
|
|
348
|
+
}, {
|
|
349
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
350
|
+
});
|
|
351
|
+
this.log(LoggerLevel.debug, `[部门ID交换] 🔄 交换部门 ID: ${department_id} 调用完成,返回状态: ${response.data.code}`);
|
|
352
|
+
this.log(LoggerLevel.debug, `[部门ID交换] 🔄 交换部门 ID: ${department_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
353
|
+
return response.data.data[0]; // 返回第一个元素
|
|
354
|
+
});
|
|
355
|
+
return res;
|
|
356
|
+
},
|
|
357
|
+
/**
|
|
358
|
+
* 批量部门 ID 交换
|
|
359
|
+
* @param params 请求参数
|
|
360
|
+
* @returns 所有子请求的返回结果数组
|
|
361
|
+
*/
|
|
362
|
+
batchExchange: async (params) => {
|
|
363
|
+
const { department_id_type, department_ids } = params;
|
|
364
|
+
// department_id_type 可选值:
|
|
365
|
+
// - 'department_id' (如 "1758534140403815")
|
|
366
|
+
// - 'external_department_id' (外部平台 department_id,无固定格式)
|
|
367
|
+
// - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
|
|
368
|
+
const url = '/api/integration/v2/feishu/getDepartments';
|
|
369
|
+
const chunkSize = 100;
|
|
370
|
+
const chunks = [];
|
|
371
|
+
for (let i = 0; i < department_ids.length; i += chunkSize) {
|
|
372
|
+
chunks.push(department_ids.slice(i, i + chunkSize));
|
|
373
|
+
}
|
|
374
|
+
this.log(LoggerLevel.info, `[批量部门ID交换] 🔄 总共 ${department_ids.length} 个部门 ID,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 个`);
|
|
375
|
+
const results = [];
|
|
376
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
377
|
+
this.log(LoggerLevel.info, `[批量部门ID交换] 🔄 开始交换第 ${index + 1} 组,共 ${chunk.length} 个`);
|
|
378
|
+
const res = await functionLimiter(async () => {
|
|
379
|
+
await this.ensureTokenValid();
|
|
380
|
+
const response = await this.axiosInstance.post(url, {
|
|
381
|
+
department_id_type,
|
|
382
|
+
department_ids: chunk
|
|
383
|
+
}, {
|
|
384
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
385
|
+
});
|
|
386
|
+
this.log(LoggerLevel.debug, `[批量部门ID交换] 🔄 交换第 ${index + 1} 组调用完成,返回状态: ${response.data.code}`);
|
|
387
|
+
this.log(LoggerLevel.trace, `[批量部门ID交换] 🔄 交换第 ${index + 1} 组调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
388
|
+
return response.data.data;
|
|
389
|
+
});
|
|
390
|
+
results.push(...res);
|
|
391
|
+
}
|
|
392
|
+
return results;
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* 云函数模块
|
|
397
|
+
*/
|
|
398
|
+
this.function = {
|
|
399
|
+
/**
|
|
400
|
+
* 调用云函数
|
|
401
|
+
* @param params 请求参数 { name: string; params: any }
|
|
402
|
+
* @returns 接口返回结果
|
|
403
|
+
*/
|
|
404
|
+
invoke: async (params) => {
|
|
405
|
+
const { name, params: functionParams } = params;
|
|
406
|
+
await this.ensureTokenValid();
|
|
407
|
+
const url = `/api/cloudfunction/v1/namespaces/${this.namespace}/invoke/${name}`;
|
|
408
|
+
this.log(LoggerLevel.info, `[调用云函数] ☁️ 云函数 ${name} 开始调用`);
|
|
409
|
+
const res = await this.axiosInstance.post(url, { params: functionParams }, {
|
|
410
|
+
headers: {
|
|
411
|
+
Authorization: `${this.accessToken}`,
|
|
412
|
+
'Content-Type': 'application/json'
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
this.log(LoggerLevel.debug, `[调用云函数] ☁️ 云函数 ${name} 调用完成,返回状态: code=${res.data.code}`);
|
|
416
|
+
this.log(LoggerLevel.trace, `[调用云函数] ☁️ 云函数 ${name} 调用完成,返回信息: code=${JSON.stringify(res.data)}`);
|
|
417
|
+
return res.data;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
227
420
|
this.clientId = options.clientId;
|
|
228
421
|
this.clientSecret = options.clientSecret;
|
|
229
422
|
this.namespace = options.namespace;
|
|
@@ -232,7 +425,7 @@ class Client {
|
|
|
232
425
|
baseURL: 'https://ae-openapi.feishu.cn',
|
|
233
426
|
headers: { 'Content-Type': 'application/json' }
|
|
234
427
|
});
|
|
235
|
-
this.log(LoggerLevel.info, 'client initialized');
|
|
428
|
+
this.log(LoggerLevel.info, '[client] initialized');
|
|
236
429
|
}
|
|
237
430
|
/**
|
|
238
431
|
* 设置日志等级
|
|
@@ -240,7 +433,7 @@ class Client {
|
|
|
240
433
|
*/
|
|
241
434
|
setLoggerLevel(level) {
|
|
242
435
|
this.loggerLevel = level;
|
|
243
|
-
this.log(LoggerLevel.info, `logger level set to ${LoggerLevel[level]}`);
|
|
436
|
+
this.log(LoggerLevel.info, `[logger] logger level set to ${LoggerLevel[level]}`);
|
|
244
437
|
}
|
|
245
438
|
/**
|
|
246
439
|
* 日志打印方法
|
|
@@ -259,7 +452,7 @@ class Client {
|
|
|
259
452
|
*/
|
|
260
453
|
async init() {
|
|
261
454
|
await this.ensureTokenValid();
|
|
262
|
-
this.log(LoggerLevel.info, 'client ready');
|
|
455
|
+
this.log(LoggerLevel.info, '[client] ready');
|
|
263
456
|
}
|
|
264
457
|
/**
|
|
265
458
|
* 获取 accessToken
|
|
@@ -271,30 +464,30 @@ class Client {
|
|
|
271
464
|
clientSecret: this.clientSecret
|
|
272
465
|
});
|
|
273
466
|
if (res.data.code !== '0') {
|
|
274
|
-
this.log(LoggerLevel.error, `[
|
|
467
|
+
this.log(LoggerLevel.error, `[fetch token] 获取 accessToken 失败: ${res.data.msg}`);
|
|
275
468
|
throw new Error(`获取 accessToken 失败: ${res.data.msg}`);
|
|
276
469
|
}
|
|
277
470
|
this.accessToken = res.data.data.accessToken;
|
|
278
471
|
this.expireTime = res.data.data.expireTime;
|
|
279
|
-
this.log(LoggerLevel.info, '[
|
|
472
|
+
this.log(LoggerLevel.info, '[client] token refreshed');
|
|
280
473
|
}
|
|
281
474
|
/**
|
|
282
475
|
* 确保 token 有效,若过期则刷新
|
|
283
476
|
*/
|
|
284
477
|
async ensureTokenValid() {
|
|
285
478
|
if (this.disableTokenCache) {
|
|
286
|
-
this.log(LoggerLevel.debug, '[
|
|
479
|
+
this.log(LoggerLevel.debug, '[client] token cache disabled, refreshing token');
|
|
287
480
|
await this.getAccessToken();
|
|
288
481
|
return;
|
|
289
482
|
}
|
|
290
483
|
if (!this.accessToken || !this.expireTime) {
|
|
291
|
-
this.log(LoggerLevel.debug, '[
|
|
484
|
+
this.log(LoggerLevel.debug, '[client] no token cached, fetching new token');
|
|
292
485
|
await this.getAccessToken();
|
|
293
486
|
return;
|
|
294
487
|
}
|
|
295
488
|
const now = dayjs().valueOf();
|
|
296
489
|
if (now + 60 * 1000 > this.expireTime) {
|
|
297
|
-
this.log(LoggerLevel.debug, '[
|
|
490
|
+
this.log(LoggerLevel.debug, '[client] token expired, refreshing');
|
|
298
491
|
await this.getAccessToken();
|
|
299
492
|
}
|
|
300
493
|
}
|
|
@@ -308,7 +501,7 @@ class Client {
|
|
|
308
501
|
* 获取当前 namespace
|
|
309
502
|
*/
|
|
310
503
|
get currentNamespace() {
|
|
311
|
-
this.log(LoggerLevel.debug,
|
|
504
|
+
this.log(LoggerLevel.debug, `🏷️ [获取命名空间] 当前命名空间: ${this.namespace}`);
|
|
312
505
|
return this.namespace;
|
|
313
506
|
}
|
|
314
507
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
2
|
import axios, { AxiosInstance } from 'axios';
|
|
3
3
|
import { LoggerLevel } from './logger';
|
|
4
|
-
|
|
4
|
+
const { functionLimiter } = require('./limiter');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Client 初始化配置
|
|
@@ -66,7 +66,7 @@ class Client {
|
|
|
66
66
|
baseURL: 'https://ae-openapi.feishu.cn',
|
|
67
67
|
headers: { 'Content-Type': 'application/json' }
|
|
68
68
|
});
|
|
69
|
-
this.log(LoggerLevel.info, 'client initialized');
|
|
69
|
+
this.log(LoggerLevel.info, '[client] initialized');
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -75,7 +75,7 @@ class Client {
|
|
|
75
75
|
*/
|
|
76
76
|
setLoggerLevel(level: LoggerLevel) {
|
|
77
77
|
this.loggerLevel = level;
|
|
78
|
-
this.log(LoggerLevel.info, `logger level set to ${LoggerLevel[level]}`);
|
|
78
|
+
this.log(LoggerLevel.info, `[logger] logger level set to ${LoggerLevel[level]}`);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -96,7 +96,7 @@ class Client {
|
|
|
96
96
|
*/
|
|
97
97
|
async init() {
|
|
98
98
|
await this.ensureTokenValid();
|
|
99
|
-
this.log(LoggerLevel.info, 'client ready');
|
|
99
|
+
this.log(LoggerLevel.info, '[client] ready');
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
@@ -110,13 +110,13 @@ class Client {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
if (res.data.code !== '0') {
|
|
113
|
-
this.log(LoggerLevel.error, `[
|
|
113
|
+
this.log(LoggerLevel.error, `[fetch token] 获取 accessToken 失败: ${res.data.msg}`);
|
|
114
114
|
throw new Error(`获取 accessToken 失败: ${res.data.msg}`);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
this.accessToken = res.data.data.accessToken;
|
|
118
118
|
this.expireTime = res.data.data.expireTime;
|
|
119
|
-
this.log(LoggerLevel.info, '[
|
|
119
|
+
this.log(LoggerLevel.info, '[client] token refreshed');
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
@@ -124,20 +124,20 @@ class Client {
|
|
|
124
124
|
*/
|
|
125
125
|
private async ensureTokenValid() {
|
|
126
126
|
if (this.disableTokenCache) {
|
|
127
|
-
this.log(LoggerLevel.debug, '[
|
|
127
|
+
this.log(LoggerLevel.debug, '[client] token cache disabled, refreshing token');
|
|
128
128
|
await this.getAccessToken();
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
if (!this.accessToken || !this.expireTime) {
|
|
133
|
-
this.log(LoggerLevel.debug, '[
|
|
133
|
+
this.log(LoggerLevel.debug, '[client] no token cached, fetching new token');
|
|
134
134
|
await this.getAccessToken();
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
const now = dayjs().valueOf();
|
|
139
139
|
if (now + 60 * 1000 > this.expireTime) {
|
|
140
|
-
this.log(LoggerLevel.debug, '[
|
|
140
|
+
this.log(LoggerLevel.debug, '[client] token expired, refreshing');
|
|
141
141
|
await this.getAccessToken();
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -153,7 +153,7 @@ class Client {
|
|
|
153
153
|
* 获取当前 namespace
|
|
154
154
|
*/
|
|
155
155
|
get currentNamespace() {
|
|
156
|
-
this.log(LoggerLevel.debug,
|
|
156
|
+
this.log(LoggerLevel.debug, `🏷️ [获取命名空间] 当前命名空间: ${this.namespace}`);
|
|
157
157
|
return this.namespace;
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -161,6 +161,50 @@ class Client {
|
|
|
161
161
|
* 对象模块
|
|
162
162
|
*/
|
|
163
163
|
public object = {
|
|
164
|
+
metadata: {
|
|
165
|
+
/**
|
|
166
|
+
* 获取指定对象下指定字段的元数据
|
|
167
|
+
* @param params 请求参数 { object_name, field_name }
|
|
168
|
+
* @returns 接口返回结果
|
|
169
|
+
*/
|
|
170
|
+
field: async (params: { object_name: string; field_name: string }): Promise<any> => {
|
|
171
|
+
const { object_name, field_name } = params;
|
|
172
|
+
await this.ensureTokenValid();
|
|
173
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}/fields/${field_name}`;
|
|
174
|
+
|
|
175
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 开始获取字段元数据 object_name=${object_name}, field_name=${field_name}`);
|
|
176
|
+
|
|
177
|
+
const res = await this.axiosInstance.get(url, {
|
|
178
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 调用完成,返回状态=${res.data.code}`);
|
|
182
|
+
this.log(LoggerLevel.trace, `[对象字段查询] 📄 调用完成,返回信息=${JSON.stringify(res.data)}`);
|
|
183
|
+
return res.data;
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 获取指定对象的所有字段信息
|
|
188
|
+
* @param params 请求参数 { object_name }
|
|
189
|
+
* @returns 接口返回结果
|
|
190
|
+
*/
|
|
191
|
+
fields: async (params: { object_name: string }): Promise<any> => {
|
|
192
|
+
const { object_name } = params;
|
|
193
|
+
await this.ensureTokenValid();
|
|
194
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}`;
|
|
195
|
+
|
|
196
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 开始获取对象字段元数据 object_name=${object_name}`);
|
|
197
|
+
|
|
198
|
+
const res = await this.axiosInstance.get(url, {
|
|
199
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
this.log(LoggerLevel.debug, `[对象字段查询] 📄 调用完成,返回状态=${res.data.code}`);
|
|
203
|
+
this.log(LoggerLevel.trace, `[对象字段查询] 📄 调用完成,返回信息=${JSON.stringify(res.data)}`);
|
|
204
|
+
return res.data;
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
|
|
164
208
|
search: {
|
|
165
209
|
/**
|
|
166
210
|
* 单条记录查询
|
|
@@ -178,7 +222,9 @@ class Client {
|
|
|
178
222
|
|
|
179
223
|
const response = await this.axiosInstance.post(url, { select }, { headers: { Authorization: `${this.accessToken}` } });
|
|
180
224
|
|
|
181
|
-
this.log(LoggerLevel.
|
|
225
|
+
this.log(LoggerLevel.debug, `[单条查询记录] 🔍 查询 record_id: ${record_id} 调用完成,返回状态: ${response.data.code}`);
|
|
226
|
+
this.log(LoggerLevel.trace, `[单条查询记录] 🔍 查询 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
227
|
+
|
|
182
228
|
return response.data;
|
|
183
229
|
});
|
|
184
230
|
|
|
@@ -200,7 +246,9 @@ class Client {
|
|
|
200
246
|
headers: { Authorization: `${this.accessToken}` }
|
|
201
247
|
});
|
|
202
248
|
|
|
203
|
-
this.log(LoggerLevel.
|
|
249
|
+
this.log(LoggerLevel.info, `[批量查询记录] 🔍 接口调用完成`);
|
|
250
|
+
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 调用完成,返回状态: ${res.data.code},返回数据总数${res.data?.data?.total || 'unknown'}`);
|
|
251
|
+
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 调用完成,返回信息: ${JSON.stringify(res.data)}`);
|
|
204
252
|
return res.data;
|
|
205
253
|
},
|
|
206
254
|
|
|
@@ -239,7 +287,9 @@ class Client {
|
|
|
239
287
|
|
|
240
288
|
nextPageToken = res.data.next_page_token;
|
|
241
289
|
|
|
290
|
+
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 第 ${page} 页查询,nextPageToken: ${nextPageToken || ''}`);
|
|
242
291
|
this.log(LoggerLevel.debug, `[批量查询记录] 🔍 第 ${page} 页查询完成,items.length: ${res.data.items.length}`);
|
|
292
|
+
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 第 ${page} 页查询结果: ${JSON.stringify(res.data.items)}`);
|
|
243
293
|
return res;
|
|
244
294
|
});
|
|
245
295
|
} while (nextPageToken);
|
|
@@ -248,6 +298,113 @@ class Client {
|
|
|
248
298
|
}
|
|
249
299
|
},
|
|
250
300
|
|
|
301
|
+
create: {
|
|
302
|
+
/**
|
|
303
|
+
* 单条记录创建
|
|
304
|
+
* @param params 请求参数 { object_name, record }
|
|
305
|
+
* @returns 接口返回结果
|
|
306
|
+
*/
|
|
307
|
+
record: async (params: { object_name: string; record: any }): Promise<any> => {
|
|
308
|
+
const { object_name, record } = params;
|
|
309
|
+
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records`;
|
|
310
|
+
|
|
311
|
+
this.log(LoggerLevel.info, `[单条创建记录] ➕ 开始向对象 ${object_name} 创建记录`);
|
|
312
|
+
|
|
313
|
+
const res = await functionLimiter(async () => {
|
|
314
|
+
await this.ensureTokenValid();
|
|
315
|
+
|
|
316
|
+
const response = await this.axiosInstance.post(
|
|
317
|
+
url,
|
|
318
|
+
{ record },
|
|
319
|
+
{
|
|
320
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
this.log(LoggerLevel.info, `[单条创建记录] ➕ 向对象 ${object_name} 内创建记录,调用完成`);
|
|
325
|
+
this.log(LoggerLevel.debug, `[单条创建记录] ➕ 向对象 ${object_name} 内创建数据,调用完成,返回状态: ${response.data.code}`);
|
|
326
|
+
this.log(LoggerLevel.trace, `[单条创建记录] ➕ 向对象 ${object_name} 内创建数据,调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
327
|
+
|
|
328
|
+
return response.data;
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
return res;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* 批量创建记录
|
|
336
|
+
* @param params 请求参数 { object_name, records }
|
|
337
|
+
* @returns 接口返回结果
|
|
338
|
+
*/
|
|
339
|
+
records: async (params: { object_name: string; records: any[] }): Promise<any> => {
|
|
340
|
+
const { object_name, records } = params;
|
|
341
|
+
await this.ensureTokenValid();
|
|
342
|
+
|
|
343
|
+
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
|
|
344
|
+
|
|
345
|
+
const res = await this.axiosInstance.post(
|
|
346
|
+
url,
|
|
347
|
+
{ records },
|
|
348
|
+
{
|
|
349
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
350
|
+
}
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
this.log(LoggerLevel.info, `[批量创建记录] ➕ 开始向对象 ${object_name} 批量创建记录`);
|
|
354
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 向对象 ${object_name} 批量创建记录,调用完成,返回状态: ${res.data.code}`);
|
|
355
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 向对象 ${object_name} 批量创建记录,调用完成,返回信息: ${JSON.stringify(res.data)}`);
|
|
356
|
+
return res.data;
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* 分批创建所有记录
|
|
361
|
+
* @param params 请求参数 { object_name, records }
|
|
362
|
+
* @returns { total, items }
|
|
363
|
+
*/
|
|
364
|
+
recordsWithIterator: async (params: { object_name: string; records: any[] }): Promise<{ total: number; items: any[] }> => {
|
|
365
|
+
const { object_name, records } = params;
|
|
366
|
+
|
|
367
|
+
let results: any[] = [];
|
|
368
|
+
let total = records.length;
|
|
369
|
+
const chunkSize = 100;
|
|
370
|
+
let page = 0;
|
|
371
|
+
|
|
372
|
+
const chunks: any[][] = [];
|
|
373
|
+
for (let i = 0; i < records.length; i += chunkSize) {
|
|
374
|
+
chunks.push(records.slice(i, i + chunkSize));
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
378
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
379
|
+
|
|
380
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
381
|
+
page += 1;
|
|
382
|
+
|
|
383
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 开始创建第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
384
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 开始创建第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
385
|
+
|
|
386
|
+
const pageRes = await functionLimiter(async () => {
|
|
387
|
+
const res = await this.object.create.records({
|
|
388
|
+
object_name,
|
|
389
|
+
records: chunk
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
if (res.data && Array.isArray(res.data.items)) {
|
|
393
|
+
results = results.concat(res.data.items);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
this.log(LoggerLevel.info, `[批量创建记录] ➕ 创建第 ${page} 页数据,调用完成,创建数量: ${res.data.items.length}`);
|
|
397
|
+
this.log(LoggerLevel.debug, `[批量创建记录] ➕ 创建第 ${page} 页页数据,调用完成,返回状态: ${res.data.code}`);
|
|
398
|
+
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 创建第 ${page} 页页数据,调用结果: ${JSON.stringify(res.data.items)}`);
|
|
399
|
+
|
|
400
|
+
return res;
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return { total, items: results };
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
|
|
251
408
|
update: {
|
|
252
409
|
/**
|
|
253
410
|
* 单条更新
|
|
@@ -265,7 +422,9 @@ class Client {
|
|
|
265
422
|
|
|
266
423
|
const response = await this.axiosInstance.patch(url, { record }, { headers: { Authorization: `${this.accessToken}` } });
|
|
267
424
|
|
|
268
|
-
this.log(LoggerLevel.info, `[单条更新记录] 💾 record_id: ${record_id}
|
|
425
|
+
this.log(LoggerLevel.info, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成`);
|
|
426
|
+
this.log(LoggerLevel.debug, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成,返回状态: ${response.data.code}`);
|
|
427
|
+
this.log(LoggerLevel.trace, `[单条更新记录] 💾 更新 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
269
428
|
return response.data;
|
|
270
429
|
});
|
|
271
430
|
|
|
@@ -287,18 +446,21 @@ class Client {
|
|
|
287
446
|
chunks.push(records.slice(i, i + chunkSize));
|
|
288
447
|
}
|
|
289
448
|
|
|
290
|
-
this.log(LoggerLevel.
|
|
449
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
450
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 总共 ${records.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
291
451
|
|
|
292
452
|
const results: any[] = [];
|
|
293
453
|
for (const [index, chunk] of chunks.entries()) {
|
|
294
|
-
this.log(LoggerLevel.
|
|
454
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 开始更新第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
455
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 开始更新第 ${index + 1} 组,共 ${chunk.length} 条`);
|
|
295
456
|
|
|
296
457
|
const res = await functionLimiter(async () => {
|
|
297
458
|
await this.ensureTokenValid();
|
|
298
459
|
|
|
299
460
|
const response = await this.axiosInstance.patch(url, { records: chunk }, { headers: { Authorization: `${this.accessToken}` } });
|
|
300
461
|
|
|
301
|
-
this.log(LoggerLevel.
|
|
462
|
+
this.log(LoggerLevel.debug, `[批量更新记录] 💾 更新第 ${index + 1} 组调用完成,返回状态: ${JSON.stringify(response.data)}`);
|
|
463
|
+
this.log(LoggerLevel.trace, `[批量更新记录] 💾 更新第 ${index + 1} 组调用完成,返回信息: ${response.data}`);
|
|
302
464
|
return response.data;
|
|
303
465
|
});
|
|
304
466
|
|
|
@@ -319,7 +481,7 @@ class Client {
|
|
|
319
481
|
const { object_name, record_id } = params;
|
|
320
482
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/${record_id}`;
|
|
321
483
|
|
|
322
|
-
this.log(LoggerLevel.
|
|
484
|
+
this.log(LoggerLevel.trace, `[单条删除记录] 🗑️ 开始删除 record_id: ${record_id}`);
|
|
323
485
|
|
|
324
486
|
const res = await functionLimiter(async () => {
|
|
325
487
|
await this.ensureTokenValid();
|
|
@@ -328,7 +490,7 @@ class Client {
|
|
|
328
490
|
headers: { Authorization: `${this.accessToken}` }
|
|
329
491
|
});
|
|
330
492
|
|
|
331
|
-
this.log(LoggerLevel.info, `[单条删除记录] 🗑️ record_id: ${record_id}
|
|
493
|
+
this.log(LoggerLevel.info, `[单条删除记录] 🗑️ 删除 record_id: ${record_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
332
494
|
return response.data;
|
|
333
495
|
});
|
|
334
496
|
|
|
@@ -350,7 +512,7 @@ class Client {
|
|
|
350
512
|
chunks.push(ids.slice(i, i + chunkSize));
|
|
351
513
|
}
|
|
352
514
|
|
|
353
|
-
this.log(LoggerLevel.
|
|
515
|
+
this.log(LoggerLevel.debug, `[批量删除记录] 🗑️ 总共 ${ids.length} 条记录,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 条`);
|
|
354
516
|
|
|
355
517
|
const results: any[] = [];
|
|
356
518
|
for (const [index, chunk] of chunks.entries()) {
|
|
@@ -364,7 +526,8 @@ class Client {
|
|
|
364
526
|
data: { ids: chunk }
|
|
365
527
|
});
|
|
366
528
|
|
|
367
|
-
this.log(LoggerLevel.
|
|
529
|
+
this.log(LoggerLevel.debug, `[批量删除记录] 🗑️ 第 ${index + 1} 组删除完成,返回状态: ${response.data.code}`);
|
|
530
|
+
this.log(LoggerLevel.trace, `[批量删除记录] 🗑️ 第 ${index + 1} 组删除完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
368
531
|
return response.data;
|
|
369
532
|
});
|
|
370
533
|
|
|
@@ -375,6 +538,135 @@ class Client {
|
|
|
375
538
|
}
|
|
376
539
|
}
|
|
377
540
|
};
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* 部门 ID 交换模块
|
|
544
|
+
*/
|
|
545
|
+
public department = {
|
|
546
|
+
/**
|
|
547
|
+
* 单个部门 ID 交换
|
|
548
|
+
* @param params 请求参数
|
|
549
|
+
* @returns 单个部门映射结果
|
|
550
|
+
*/
|
|
551
|
+
exchange: async (params: { department_id_type: 'department_id' | 'external_department_id' | 'external_open_department_id'; department_id: string }): Promise<any> => {
|
|
552
|
+
const { department_id_type, department_id } = params;
|
|
553
|
+
// department_id_type 可选值:
|
|
554
|
+
// - 'department_id' (如 "1758534140403815")
|
|
555
|
+
// - 'external_department_id' (外部平台 department_id,无固定格式)
|
|
556
|
+
// - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
|
|
557
|
+
|
|
558
|
+
const url = '/api/integration/v2/feishu/getDepartments';
|
|
559
|
+
|
|
560
|
+
this.log(LoggerLevel.info, `[部门ID交换] 🔄 开始交换单个部门 ID: ${department_id}`);
|
|
561
|
+
|
|
562
|
+
const res = await functionLimiter(async () => {
|
|
563
|
+
await this.ensureTokenValid();
|
|
564
|
+
|
|
565
|
+
const response = await this.axiosInstance.post(
|
|
566
|
+
url,
|
|
567
|
+
{
|
|
568
|
+
department_id_type,
|
|
569
|
+
department_ids: [department_id]
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
573
|
+
}
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
this.log(LoggerLevel.debug, `[部门ID交换] 🔄 交换部门 ID: ${department_id} 调用完成,返回状态: ${response.data.code}`);
|
|
577
|
+
this.log(LoggerLevel.debug, `[部门ID交换] 🔄 交换部门 ID: ${department_id} 调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
578
|
+
return response.data.data[0]; // 返回第一个元素
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
return res;
|
|
582
|
+
},
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* 批量部门 ID 交换
|
|
586
|
+
* @param params 请求参数
|
|
587
|
+
* @returns 所有子请求的返回结果数组
|
|
588
|
+
*/
|
|
589
|
+
batchExchange: async (params: { department_id_type: 'department_id' | 'external_department_id' | 'external_open_department_id'; department_ids: string[] }): Promise<any[]> => {
|
|
590
|
+
const { department_id_type, department_ids } = params;
|
|
591
|
+
// department_id_type 可选值:
|
|
592
|
+
// - 'department_id' (如 "1758534140403815")
|
|
593
|
+
// - 'external_department_id' (外部平台 department_id,无固定格式)
|
|
594
|
+
// - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
|
|
595
|
+
|
|
596
|
+
const url = '/api/integration/v2/feishu/getDepartments';
|
|
597
|
+
|
|
598
|
+
const chunkSize = 100;
|
|
599
|
+
const chunks: string[][] = [];
|
|
600
|
+
for (let i = 0; i < department_ids.length; i += chunkSize) {
|
|
601
|
+
chunks.push(department_ids.slice(i, i + chunkSize));
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
this.log(LoggerLevel.info, `[批量部门ID交换] 🔄 总共 ${department_ids.length} 个部门 ID,拆分为 ${chunks.length} 组,每组最多 ${chunkSize} 个`);
|
|
605
|
+
|
|
606
|
+
const results: any[] = [];
|
|
607
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
608
|
+
this.log(LoggerLevel.info, `[批量部门ID交换] 🔄 开始交换第 ${index + 1} 组,共 ${chunk.length} 个`);
|
|
609
|
+
|
|
610
|
+
const res = await functionLimiter(async () => {
|
|
611
|
+
await this.ensureTokenValid();
|
|
612
|
+
|
|
613
|
+
const response = await this.axiosInstance.post(
|
|
614
|
+
url,
|
|
615
|
+
{
|
|
616
|
+
department_id_type,
|
|
617
|
+
department_ids: chunk
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
621
|
+
}
|
|
622
|
+
);
|
|
623
|
+
|
|
624
|
+
this.log(LoggerLevel.debug, `[批量部门ID交换] 🔄 交换第 ${index + 1} 组调用完成,返回状态: ${response.data.code}`);
|
|
625
|
+
this.log(LoggerLevel.trace, `[批量部门ID交换] 🔄 交换第 ${index + 1} 组调用完成,返回信息: ${JSON.stringify(response.data)}`);
|
|
626
|
+
return response.data.data;
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
results.push(...res);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
return results;
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* 云函数模块
|
|
638
|
+
*/
|
|
639
|
+
public function = {
|
|
640
|
+
/**
|
|
641
|
+
* 调用云函数
|
|
642
|
+
* @param params 请求参数 { name: string; params: any }
|
|
643
|
+
* @returns 接口返回结果
|
|
644
|
+
*/
|
|
645
|
+
invoke: async (params: { name: string; params: any }): Promise<any> => {
|
|
646
|
+
const { name, params: functionParams } = params;
|
|
647
|
+
await this.ensureTokenValid();
|
|
648
|
+
|
|
649
|
+
const url = `/api/cloudfunction/v1/namespaces/${this.namespace}/invoke/${name}`;
|
|
650
|
+
|
|
651
|
+
this.log(LoggerLevel.info, `[调用云函数] ☁️ 云函数 ${name} 开始调用`);
|
|
652
|
+
|
|
653
|
+
const res = await this.axiosInstance.post(
|
|
654
|
+
url,
|
|
655
|
+
{ params: functionParams },
|
|
656
|
+
{
|
|
657
|
+
headers: {
|
|
658
|
+
Authorization: `${this.accessToken}`,
|
|
659
|
+
'Content-Type': 'application/json'
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
this.log(LoggerLevel.debug, `[调用云函数] ☁️ 云函数 ${name} 调用完成,返回状态: code=${res.data.code}`);
|
|
665
|
+
this.log(LoggerLevel.trace, `[调用云函数] ☁️ 云函数 ${name} 调用完成,返回信息: code=${JSON.stringify(res.data)}`);
|
|
666
|
+
|
|
667
|
+
return res.data;
|
|
668
|
+
}
|
|
669
|
+
};
|
|
378
670
|
}
|
|
379
671
|
|
|
380
672
|
export const apaas = {
|
package/CHANGELOG.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
## [0.1.0] - 2025-06-30
|
|
6
|
-
### Added
|
|
7
|
-
- 🎉 初始化 aPaaS OpenAPI Node.js SDK
|
|
8
|
-
- ✅ 获取 accessToken
|
|
9
|
-
- ✅ records 查询(支持分页迭代)
|
|
10
|
-
- ✅ record 单条查询
|
|
11
|
-
- ✅ record 单条更新、批量更新
|
|
12
|
-
- ✅ record 单条删除、批量删除
|
|
13
|
-
- ✅ 内置 Bottleneck 限流器
|
|
14
|
-
- ✅ 自定义日志等级
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## [Unreleased]
|
|
19
|
-
- ✨ 新功能开发中...
|