apaas-oapi-client 0.1.15 → 0.1.17
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 copy.md +568 -0
- package/UserManual.md +253 -36
- package/dist/index.d.ts +199 -0
- package/dist/index.js +511 -78
- package/package.json +1 -1
- package/src/index.ts +622 -78
package/dist/index.js
CHANGED
|
@@ -59,6 +59,27 @@ class Client {
|
|
|
59
59
|
* 对象模块
|
|
60
60
|
*/
|
|
61
61
|
this.object = {
|
|
62
|
+
/**
|
|
63
|
+
* 列出所有对象(数据表)
|
|
64
|
+
* @param params 请求参数 { offset, filter?, limit }
|
|
65
|
+
* @returns 接口返回结果
|
|
66
|
+
*/
|
|
67
|
+
list: async (params) => {
|
|
68
|
+
const { offset, filter, limit } = params;
|
|
69
|
+
await this.ensureTokenValid();
|
|
70
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/list`;
|
|
71
|
+
this.log(LoggerLevel.debug, `[object.list] Fetching objects list: offset=${offset}, limit=${limit}`);
|
|
72
|
+
const requestData = { offset, limit };
|
|
73
|
+
if (filter) {
|
|
74
|
+
requestData.filter = filter;
|
|
75
|
+
}
|
|
76
|
+
const res = await this.axiosInstance.post(url, requestData, {
|
|
77
|
+
headers: { Authorization: `${this.accessToken}` }
|
|
78
|
+
});
|
|
79
|
+
this.log(LoggerLevel.debug, `[object.list] Objects list fetched successfully: code=${res.data.code}`);
|
|
80
|
+
this.log(LoggerLevel.trace, `[object.list] Response: ${JSON.stringify(res.data)}`);
|
|
81
|
+
return res.data;
|
|
82
|
+
},
|
|
62
83
|
metadata: {
|
|
63
84
|
/**
|
|
64
85
|
* 获取指定对象下指定字段的元数据
|
|
@@ -70,12 +91,12 @@ class Client {
|
|
|
70
91
|
const { object_name, field_name } = params;
|
|
71
92
|
await this.ensureTokenValid();
|
|
72
93
|
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}/fields/${field_name}`;
|
|
73
|
-
this.log(LoggerLevel.debug, `[
|
|
94
|
+
this.log(LoggerLevel.debug, `[object.metadata.field] Fetching field metadata: ${object_name}.${field_name}`);
|
|
74
95
|
const res = await this.axiosInstance.get(url, {
|
|
75
96
|
headers: { Authorization: `${this.accessToken}` }
|
|
76
97
|
});
|
|
77
|
-
this.log(LoggerLevel.debug, `[
|
|
78
|
-
this.log(LoggerLevel.trace, `[
|
|
98
|
+
this.log(LoggerLevel.debug, `[object.metadata.field] Field metadata fetched: ${object_name}.${field_name}, code=${res.data.code}`);
|
|
99
|
+
this.log(LoggerLevel.trace, `[object.metadata.field] Response: ${JSON.stringify(res.data)}`);
|
|
79
100
|
return res.data;
|
|
80
101
|
},
|
|
81
102
|
/**
|
|
@@ -88,12 +109,12 @@ class Client {
|
|
|
88
109
|
const { object_name } = params;
|
|
89
110
|
await this.ensureTokenValid();
|
|
90
111
|
const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}`;
|
|
91
|
-
this.log(LoggerLevel.debug, `[
|
|
112
|
+
this.log(LoggerLevel.debug, `[object.metadata.fields] Fetching all fields metadata: ${object_name}`);
|
|
92
113
|
const res = await this.axiosInstance.get(url, {
|
|
93
114
|
headers: { Authorization: `${this.accessToken}` }
|
|
94
115
|
});
|
|
95
|
-
this.log(LoggerLevel.debug, `[
|
|
96
|
-
this.log(LoggerLevel.trace, `[
|
|
116
|
+
this.log(LoggerLevel.debug, `[object.metadata.fields] All fields metadata fetched: ${object_name}, code=${res.data.code}`);
|
|
117
|
+
this.log(LoggerLevel.trace, `[object.metadata.fields] Response: ${JSON.stringify(res.data)}`);
|
|
97
118
|
return res.data;
|
|
98
119
|
}
|
|
99
120
|
},
|
|
@@ -107,12 +128,12 @@ class Client {
|
|
|
107
128
|
record: async (params) => {
|
|
108
129
|
const { object_name, record_id, select } = params;
|
|
109
130
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/${record_id}`;
|
|
110
|
-
this.log(LoggerLevel.info, `[
|
|
131
|
+
this.log(LoggerLevel.info, `[object.search.record] Querying record: ${record_id}`);
|
|
111
132
|
const res = await functionLimiter(async () => {
|
|
112
133
|
await this.ensureTokenValid();
|
|
113
134
|
const response = await this.axiosInstance.post(url, { select }, { headers: { Authorization: `${this.accessToken}` } });
|
|
114
|
-
this.log(LoggerLevel.debug, `[
|
|
115
|
-
this.log(LoggerLevel.trace, `[
|
|
135
|
+
this.log(LoggerLevel.debug, `[object.search.record] Record queried: ${object_name}.${record_id}, code=${response.data.code}`);
|
|
136
|
+
this.log(LoggerLevel.trace, `[object.search.record] Response: ${JSON.stringify(response.data)}`);
|
|
116
137
|
return response.data;
|
|
117
138
|
});
|
|
118
139
|
return res;
|
|
@@ -131,9 +152,8 @@ class Client {
|
|
|
131
152
|
const res = await this.axiosInstance.post(url, data, {
|
|
132
153
|
headers: { Authorization: `${this.accessToken}` }
|
|
133
154
|
});
|
|
134
|
-
this.log(LoggerLevel.
|
|
135
|
-
this.log(LoggerLevel.
|
|
136
|
-
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 查询 object_name=${object_name}, 调用完成, 返回信息: ${JSON.stringify(res.data)}`);
|
|
155
|
+
this.log(LoggerLevel.debug, `[object.search.records] Records queried: ${object_name}, code=${res.data.code}, total=${((_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.total) || 'unknown'}`);
|
|
156
|
+
this.log(LoggerLevel.trace, `[object.search.records] Response: ${JSON.stringify(res.data)}`);
|
|
137
157
|
return res.data;
|
|
138
158
|
},
|
|
139
159
|
/**
|
|
@@ -165,16 +185,15 @@ class Client {
|
|
|
165
185
|
if (page === 1) {
|
|
166
186
|
total = res.data.total || 0;
|
|
167
187
|
totalPages = Math.ceil(total / pageSize);
|
|
168
|
-
this.log(LoggerLevel.info, `[
|
|
188
|
+
this.log(LoggerLevel.info, `[object.search.recordsWithIterator] Starting paginated query: ${object_name}, total=${total}, pages=${totalPages}`);
|
|
169
189
|
}
|
|
170
190
|
nextPageToken = res.data.next_page_token;
|
|
171
191
|
const padLength = totalPages.toString().length;
|
|
172
192
|
const pageStr = page.toString().padStart(padLength, '0');
|
|
173
193
|
const totalPagesStr = totalPages.toString().padStart(padLength, '0');
|
|
174
|
-
this.log(LoggerLevel.info, `[
|
|
175
|
-
this.log(LoggerLevel.debug, `[
|
|
176
|
-
this.log(LoggerLevel.
|
|
177
|
-
this.log(LoggerLevel.trace, `[批量查询记录] 🔍 第 ${page} 页查询结果: ${JSON.stringify((_b = res.data) === null || _b === void 0 ? void 0 : _b.items)}`);
|
|
194
|
+
this.log(LoggerLevel.info, `[object.search.recordsWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
|
|
195
|
+
this.log(LoggerLevel.debug, `[object.search.recordsWithIterator] Page ${page} details: items=${(_a = res.data.items) === null || _a === void 0 ? void 0 : _a.length}, nextToken=${nextPageToken || 'none'}`);
|
|
196
|
+
this.log(LoggerLevel.trace, `[object.search.recordsWithIterator] Page ${page} data: ${JSON.stringify((_b = res.data) === null || _b === void 0 ? void 0 : _b.items)}`);
|
|
178
197
|
return res;
|
|
179
198
|
});
|
|
180
199
|
} while (nextPageToken);
|
|
@@ -191,15 +210,15 @@ class Client {
|
|
|
191
210
|
record: async (params) => {
|
|
192
211
|
const { object_name, record } = params;
|
|
193
212
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records`;
|
|
194
|
-
this.log(LoggerLevel.info, `[
|
|
213
|
+
this.log(LoggerLevel.info, `[object.create.record] Creating record in: ${object_name}`);
|
|
195
214
|
const res = await functionLimiter(async () => {
|
|
196
215
|
await this.ensureTokenValid();
|
|
197
216
|
const response = await this.axiosInstance.post(url, { record }, {
|
|
198
217
|
headers: { Authorization: `${this.accessToken}` }
|
|
199
218
|
});
|
|
200
|
-
this.log(LoggerLevel.info, `[
|
|
201
|
-
this.log(LoggerLevel.debug, `[
|
|
202
|
-
this.log(LoggerLevel.trace, `[
|
|
219
|
+
this.log(LoggerLevel.info, `[object.create.record] Record created: ${object_name}`);
|
|
220
|
+
this.log(LoggerLevel.debug, `[object.create.record] Record created: ${object_name}, code=${response.data.code}`);
|
|
221
|
+
this.log(LoggerLevel.trace, `[object.create.record] Response: ${JSON.stringify(response.data)}`);
|
|
203
222
|
return response.data;
|
|
204
223
|
});
|
|
205
224
|
return res;
|
|
@@ -217,9 +236,9 @@ class Client {
|
|
|
217
236
|
const res = await this.axiosInstance.post(url, { records }, {
|
|
218
237
|
headers: { Authorization: `${this.accessToken}` }
|
|
219
238
|
});
|
|
220
|
-
this.log(LoggerLevel.info, `[
|
|
221
|
-
this.log(LoggerLevel.debug, `[
|
|
222
|
-
this.log(LoggerLevel.trace, `[
|
|
239
|
+
this.log(LoggerLevel.info, `[object.create.records] Creating ${records.length} records in: ${object_name}`);
|
|
240
|
+
this.log(LoggerLevel.debug, `[object.create.records] Records created: ${object_name}, code=${res.data.code}`);
|
|
241
|
+
this.log(LoggerLevel.trace, `[object.create.records] Response: ${JSON.stringify(res.data)}`);
|
|
223
242
|
return res.data;
|
|
224
243
|
},
|
|
225
244
|
/**
|
|
@@ -238,12 +257,10 @@ class Client {
|
|
|
238
257
|
for (let i = 0; i < records.length; i += chunkSize) {
|
|
239
258
|
chunks.push(records.slice(i, i + chunkSize));
|
|
240
259
|
}
|
|
241
|
-
this.log(LoggerLevel.debug, `[
|
|
242
|
-
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 总共 ${records.length} 条记录, 拆分为 ${chunks.length} 组, 每组最多 ${chunkSize} 条`);
|
|
260
|
+
this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Chunking ${records.length} records into ${chunks.length} groups of ${chunkSize}`);
|
|
243
261
|
for (const [index, chunk] of chunks.entries()) {
|
|
244
262
|
page += 1;
|
|
245
|
-
this.log(LoggerLevel.debug, `[
|
|
246
|
-
this.log(LoggerLevel.trace, `[批量创建记录] ➕ 开始创建第 ${index + 1} 组, 共 ${chunk.length} 条`);
|
|
263
|
+
this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Processing chunk ${index + 1}/${chunks.length}: ${chunk.length} records`);
|
|
247
264
|
await functionLimiter(async () => {
|
|
248
265
|
const res = await this.object.create.records({
|
|
249
266
|
object_name,
|
|
@@ -252,9 +269,9 @@ class Client {
|
|
|
252
269
|
if (res.data && Array.isArray(res.data.items)) {
|
|
253
270
|
results = results.concat(res.data.items);
|
|
254
271
|
}
|
|
255
|
-
this.log(LoggerLevel.info, `[
|
|
256
|
-
this.log(LoggerLevel.debug, `[
|
|
257
|
-
this.log(LoggerLevel.trace, `[
|
|
272
|
+
this.log(LoggerLevel.info, `[object.create.recordsWithIterator] Chunk ${page} completed: ${object_name}, created=${res.data.items.length}`);
|
|
273
|
+
this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Chunk ${page} result: ${object_name}, code=${res.data.code}`);
|
|
274
|
+
this.log(LoggerLevel.trace, `[object.create.recordsWithIterator] Chunk ${page} data: ${JSON.stringify(res.data.items)}`);
|
|
258
275
|
return res;
|
|
259
276
|
});
|
|
260
277
|
}
|
|
@@ -271,13 +288,13 @@ class Client {
|
|
|
271
288
|
record: async (params) => {
|
|
272
289
|
const { object_name, record_id, record } = params;
|
|
273
290
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/${record_id}`;
|
|
274
|
-
this.log(LoggerLevel.info, `[
|
|
291
|
+
this.log(LoggerLevel.info, `[object.update.record] Updating record: ${record_id}`);
|
|
275
292
|
const res = await functionLimiter(async () => {
|
|
276
293
|
await this.ensureTokenValid();
|
|
277
294
|
const response = await this.axiosInstance.patch(url, { record }, { headers: { Authorization: `${this.accessToken}` } });
|
|
278
|
-
this.log(LoggerLevel.info, `[
|
|
279
|
-
this.log(LoggerLevel.debug, `[
|
|
280
|
-
this.log(LoggerLevel.trace, `[
|
|
295
|
+
this.log(LoggerLevel.info, `[object.update.record] Record updated: ${object_name}.${record_id}`);
|
|
296
|
+
this.log(LoggerLevel.debug, `[object.update.record] Record updated: ${object_name}.${record_id}, code=${response.data.code}`);
|
|
297
|
+
this.log(LoggerLevel.trace, `[object.update.record] Response: ${JSON.stringify(response.data)}`);
|
|
281
298
|
return response.data;
|
|
282
299
|
});
|
|
283
300
|
return res;
|
|
@@ -291,11 +308,11 @@ class Client {
|
|
|
291
308
|
records: async (params) => {
|
|
292
309
|
const { object_name, records } = params;
|
|
293
310
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/records_batch`;
|
|
294
|
-
this.log(LoggerLevel.info, `[
|
|
311
|
+
this.log(LoggerLevel.info, `[object.update.records] Updating ${records.length} records`);
|
|
295
312
|
const response = await this.axiosInstance.patch(url, { records }, { headers: { Authorization: `${this.accessToken}` } });
|
|
296
|
-
this.log(LoggerLevel.info, `[
|
|
297
|
-
this.log(LoggerLevel.debug, `[
|
|
298
|
-
this.log(LoggerLevel.trace, `[
|
|
313
|
+
this.log(LoggerLevel.info, `[object.update.records] Records updated: ${object_name}`);
|
|
314
|
+
this.log(LoggerLevel.debug, `[object.update.records] Records updated: ${object_name}, code=${response.data.code}`);
|
|
315
|
+
this.log(LoggerLevel.trace, `[object.update.records] Response: ${JSON.stringify(response.data)}`);
|
|
299
316
|
return response.data;
|
|
300
317
|
},
|
|
301
318
|
/**
|
|
@@ -312,17 +329,15 @@ class Client {
|
|
|
312
329
|
for (let i = 0; i < records.length; i += chunkSize) {
|
|
313
330
|
chunks.push(records.slice(i, i + chunkSize));
|
|
314
331
|
}
|
|
315
|
-
this.log(LoggerLevel.debug, `[
|
|
316
|
-
this.log(LoggerLevel.trace, `[批量更新记录] 💾 总共 ${records.length} 条记录, 拆分为 ${chunks.length} 组, 每组最多 ${chunkSize} 条`);
|
|
332
|
+
this.log(LoggerLevel.debug, `[object.update.recordsWithIterator] Chunking ${records.length} records into ${chunks.length} groups of ${chunkSize}`);
|
|
317
333
|
const results = [];
|
|
318
334
|
for (const [index, chunk] of chunks.entries()) {
|
|
319
|
-
this.log(LoggerLevel.debug, `[
|
|
320
|
-
this.log(LoggerLevel.trace, `[批量更新记录] 💾 开始更新第 ${index + 1} 组, 共 ${chunk.length} 条`);
|
|
335
|
+
this.log(LoggerLevel.debug, `[object.update.recordsWithIterator] Processing chunk ${index + 1}/${chunks.length}: ${chunk.length} records`);
|
|
321
336
|
const res = await functionLimiter(async () => {
|
|
322
337
|
await this.ensureTokenValid();
|
|
323
338
|
const response = await this.axiosInstance.patch(url, { records: chunk }, { headers: { Authorization: `${this.accessToken}` } });
|
|
324
|
-
this.log(LoggerLevel.debug, `[
|
|
325
|
-
this.log(LoggerLevel.trace, `[
|
|
339
|
+
this.log(LoggerLevel.debug, `[object.update.recordsWithIterator] Chunk ${index + 1} completed: ${object_name}, code=${response.data.code}`);
|
|
340
|
+
this.log(LoggerLevel.trace, `[object.update.recordsWithIterator] Chunk ${index + 1} response: ${JSON.stringify(response.data)}`);
|
|
326
341
|
return response.data;
|
|
327
342
|
});
|
|
328
343
|
results.push(res);
|
|
@@ -340,13 +355,15 @@ class Client {
|
|
|
340
355
|
record: async (params) => {
|
|
341
356
|
const { object_name, record_id } = params;
|
|
342
357
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/${record_id}`;
|
|
343
|
-
this.log(LoggerLevel.
|
|
358
|
+
this.log(LoggerLevel.info, `[object.delete.record] Deleting record: ${object_name}.${record_id}`);
|
|
344
359
|
const res = await functionLimiter(async () => {
|
|
345
360
|
await this.ensureTokenValid();
|
|
346
361
|
const response = await this.axiosInstance.delete(url, {
|
|
347
362
|
headers: { Authorization: `${this.accessToken}` }
|
|
348
363
|
});
|
|
349
|
-
this.log(LoggerLevel.info, `[
|
|
364
|
+
this.log(LoggerLevel.info, `[object.delete.record] Record deleted: ${object_name}.${record_id}`);
|
|
365
|
+
this.log(LoggerLevel.debug, `[object.delete.record] Record deleted: ${object_name}.${record_id}, code=${response.data.code}`);
|
|
366
|
+
this.log(LoggerLevel.trace, `[object.delete.record] Response: ${JSON.stringify(response.data)}`);
|
|
350
367
|
return response.data;
|
|
351
368
|
});
|
|
352
369
|
return res;
|
|
@@ -360,16 +377,16 @@ class Client {
|
|
|
360
377
|
records: async (params) => {
|
|
361
378
|
const { object_name, ids } = params;
|
|
362
379
|
const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
|
|
363
|
-
this.log(LoggerLevel.info, `[
|
|
380
|
+
this.log(LoggerLevel.info, `[object.delete.records] Deleting ${ids.length} records from: ${object_name}`);
|
|
364
381
|
const res = await functionLimiter(async () => {
|
|
365
382
|
await this.ensureTokenValid();
|
|
366
383
|
const response = await this.axiosInstance.delete(url, {
|
|
367
384
|
data: { ids },
|
|
368
385
|
headers: { Authorization: `${this.accessToken}`, 'Content-Type': 'application/json' }
|
|
369
386
|
});
|
|
370
|
-
this.log(LoggerLevel.info, `[
|
|
371
|
-
this.log(LoggerLevel.debug, `[
|
|
372
|
-
this.log(LoggerLevel.trace, `[
|
|
387
|
+
this.log(LoggerLevel.info, `[object.delete.records] Records deleted: ${object_name}, count=${ids.length}`);
|
|
388
|
+
this.log(LoggerLevel.debug, `[object.delete.records] Records deleted: ${object_name}, count=${ids.length}, code=${response.data.code}`);
|
|
389
|
+
this.log(LoggerLevel.trace, `[object.delete.records] Response: ${JSON.stringify(response.data)}`);
|
|
373
390
|
return response.data;
|
|
374
391
|
});
|
|
375
392
|
return res;
|
|
@@ -388,18 +405,18 @@ class Client {
|
|
|
388
405
|
for (let i = 0; i < ids.length; i += chunkSize) {
|
|
389
406
|
chunks.push(ids.slice(i, i + chunkSize));
|
|
390
407
|
}
|
|
391
|
-
this.log(LoggerLevel.debug, `[
|
|
408
|
+
this.log(LoggerLevel.debug, `[object.delete.recordsWithIterator] Chunking ${ids.length} records into ${chunks.length} groups of ${chunkSize}`);
|
|
392
409
|
const results = [];
|
|
393
410
|
for (const [index, chunk] of chunks.entries()) {
|
|
394
|
-
this.log(LoggerLevel.info, `[
|
|
411
|
+
this.log(LoggerLevel.info, `[object.delete.recordsWithIterator] Processing chunk ${index + 1}/${chunks.length}: ${chunk.length} records`);
|
|
395
412
|
const res = await functionLimiter(async () => {
|
|
396
413
|
await this.ensureTokenValid();
|
|
397
414
|
const response = await this.axiosInstance.delete(url, {
|
|
398
415
|
headers: { Authorization: `${this.accessToken}` },
|
|
399
416
|
data: { ids: chunk }
|
|
400
417
|
});
|
|
401
|
-
this.log(LoggerLevel.debug, `[
|
|
402
|
-
this.log(LoggerLevel.trace, `[
|
|
418
|
+
this.log(LoggerLevel.debug, `[object.delete.recordsWithIterator] Chunk ${index + 1} completed: code=${response.data.code}`);
|
|
419
|
+
this.log(LoggerLevel.trace, `[object.delete.recordsWithIterator] Chunk ${index + 1} response: ${JSON.stringify(response.data)}`);
|
|
403
420
|
return response.data;
|
|
404
421
|
});
|
|
405
422
|
results.push(res);
|
|
@@ -424,7 +441,7 @@ class Client {
|
|
|
424
441
|
// - 'external_department_id' (外部平台 department_id, 无固定格式)
|
|
425
442
|
// - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
|
|
426
443
|
const url = '/api/integration/v2/feishu/getDepartments';
|
|
427
|
-
this.log(LoggerLevel.info, `[
|
|
444
|
+
this.log(LoggerLevel.info, `[department.exchange] Exchanging department ID: ${department_id}`);
|
|
428
445
|
const res = await functionLimiter(async () => {
|
|
429
446
|
await this.ensureTokenValid();
|
|
430
447
|
const response = await this.axiosInstance.post(url, {
|
|
@@ -433,8 +450,8 @@ class Client {
|
|
|
433
450
|
}, {
|
|
434
451
|
headers: { Authorization: `${this.accessToken}` }
|
|
435
452
|
});
|
|
436
|
-
this.log(LoggerLevel.debug, `[
|
|
437
|
-
this.log(LoggerLevel.
|
|
453
|
+
this.log(LoggerLevel.debug, `[department.exchange] Department ID exchanged: ${department_id}, code=${response.data.code}`);
|
|
454
|
+
this.log(LoggerLevel.trace, `[department.exchange] Response: ${JSON.stringify(response.data)}`);
|
|
438
455
|
return response.data.data[0]; // 返回第一个元素
|
|
439
456
|
});
|
|
440
457
|
return res;
|
|
@@ -456,10 +473,10 @@ class Client {
|
|
|
456
473
|
for (let i = 0; i < department_ids.length; i += chunkSize) {
|
|
457
474
|
chunks.push(department_ids.slice(i, i + chunkSize));
|
|
458
475
|
}
|
|
459
|
-
this.log(LoggerLevel.info, `[
|
|
476
|
+
this.log(LoggerLevel.info, `[department.batchExchange] Chunking ${department_ids.length} department IDs into ${chunks.length} groups of ${chunkSize}`);
|
|
460
477
|
const results = [];
|
|
461
478
|
for (const [index, chunk] of chunks.entries()) {
|
|
462
|
-
this.log(LoggerLevel.info, `[
|
|
479
|
+
this.log(LoggerLevel.info, `[department.batchExchange] Processing chunk ${index + 1}/${chunks.length}: ${chunk.length} IDs`);
|
|
463
480
|
const res = await functionLimiter(async () => {
|
|
464
481
|
await this.ensureTokenValid();
|
|
465
482
|
const response = await this.axiosInstance.post(url, {
|
|
@@ -468,8 +485,8 @@ class Client {
|
|
|
468
485
|
}, {
|
|
469
486
|
headers: { Authorization: `${this.accessToken}` }
|
|
470
487
|
});
|
|
471
|
-
this.log(LoggerLevel.debug, `[
|
|
472
|
-
this.log(LoggerLevel.trace, `[
|
|
488
|
+
this.log(LoggerLevel.debug, `[department.batchExchange] Chunk ${index + 1} completed: code=${response.data.code}`);
|
|
489
|
+
this.log(LoggerLevel.trace, `[department.batchExchange] Chunk ${index + 1} response: ${JSON.stringify(response.data)}`);
|
|
473
490
|
return response.data.data;
|
|
474
491
|
});
|
|
475
492
|
results.push(...res);
|
|
@@ -490,16 +507,432 @@ class Client {
|
|
|
490
507
|
const { name, params: functionParams } = params;
|
|
491
508
|
await this.ensureTokenValid();
|
|
492
509
|
const url = `/api/cloudfunction/v1/namespaces/${this.namespace}/invoke/${name}`;
|
|
493
|
-
this.log(LoggerLevel.info, `[
|
|
510
|
+
this.log(LoggerLevel.info, `[function.invoke] Invoking cloud function: ${name}`);
|
|
494
511
|
const res = await this.axiosInstance.post(url, { params: functionParams }, {
|
|
495
512
|
headers: {
|
|
496
513
|
Authorization: `${this.accessToken}`,
|
|
497
514
|
'Content-Type': 'application/json'
|
|
498
515
|
}
|
|
499
516
|
});
|
|
500
|
-
this.log(LoggerLevel.debug, `[
|
|
501
|
-
this.log(LoggerLevel.trace, `[
|
|
517
|
+
this.log(LoggerLevel.debug, `[function.invoke] Cloud function invoked: ${name}, code=${res.data.code}`);
|
|
518
|
+
this.log(LoggerLevel.trace, `[function.invoke] Response: ${JSON.stringify(res.data)}`);
|
|
519
|
+
return res.data;
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
/**
|
|
523
|
+
* 页面模块
|
|
524
|
+
*/
|
|
525
|
+
this.page = {
|
|
526
|
+
/**
|
|
527
|
+
* 获取所有页面
|
|
528
|
+
* @param params 请求参数 { limit: number (max 200), offset: number }
|
|
529
|
+
* @returns 接口返回结果
|
|
530
|
+
*/
|
|
531
|
+
list: async (params) => {
|
|
532
|
+
const { limit, offset } = params;
|
|
533
|
+
await this.ensureTokenValid();
|
|
534
|
+
const url = `/api/builder/v1/namespaces/${this.namespace}/meta/pages`;
|
|
535
|
+
this.log(LoggerLevel.info, `[page.list] Fetching pages list: offset=${offset}, limit=${limit}`);
|
|
536
|
+
const res = await this.axiosInstance.post(url, { limit, offset }, {
|
|
537
|
+
headers: {
|
|
538
|
+
Authorization: `${this.accessToken}`,
|
|
539
|
+
'Content-Type': 'application/json'
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
this.log(LoggerLevel.debug, `[page.list] Pages list fetched: code=${res.data.code}`);
|
|
543
|
+
this.log(LoggerLevel.trace, `[page.list] Response: ${JSON.stringify(res.data)}`);
|
|
544
|
+
return res.data;
|
|
545
|
+
},
|
|
546
|
+
/**
|
|
547
|
+
* 获取所有页面 - 支持自动分页,获取全部数据
|
|
548
|
+
* @description 该方法会自动处理分页,直到获取所有页面数据
|
|
549
|
+
* @param params 请求参数 { limit?: number }
|
|
550
|
+
* @returns { total, items }
|
|
551
|
+
*/
|
|
552
|
+
listWithIterator: async (params) => {
|
|
553
|
+
const limit = (params === null || params === void 0 ? void 0 : params.limit) || 100;
|
|
554
|
+
let results = [];
|
|
555
|
+
let offset = 0;
|
|
556
|
+
let total = 0;
|
|
557
|
+
let page = 0;
|
|
558
|
+
let totalPages = 0;
|
|
559
|
+
do {
|
|
560
|
+
await functionLimiter(async () => {
|
|
561
|
+
var _a, _b;
|
|
562
|
+
const res = await this.page.list({ limit, offset });
|
|
563
|
+
page += 1;
|
|
564
|
+
if (res.data && Array.isArray(res.data.items)) {
|
|
565
|
+
results = results.concat(res.data.items);
|
|
566
|
+
}
|
|
567
|
+
if (page === 1) {
|
|
568
|
+
total = res.data.total || 0;
|
|
569
|
+
totalPages = Math.ceil(total / limit);
|
|
570
|
+
this.log(LoggerLevel.info, `[page.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
|
|
571
|
+
}
|
|
572
|
+
offset += limit;
|
|
573
|
+
const padLength = totalPages.toString().length;
|
|
574
|
+
const pageStr = page.toString().padStart(padLength, '0');
|
|
575
|
+
const totalPagesStr = totalPages.toString().padStart(padLength, '0');
|
|
576
|
+
this.log(LoggerLevel.info, `[page.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
|
|
577
|
+
this.log(LoggerLevel.debug, `[page.listWithIterator] Page ${page} details: items=${(_a = res.data.items) === null || _a === void 0 ? void 0 : _a.length}, offset=${offset}`);
|
|
578
|
+
this.log(LoggerLevel.trace, `[page.listWithIterator] Page ${page} data: ${JSON.stringify((_b = res.data) === null || _b === void 0 ? void 0 : _b.items)}`);
|
|
579
|
+
return res;
|
|
580
|
+
});
|
|
581
|
+
} while (results.length < total);
|
|
582
|
+
return { total, items: results };
|
|
583
|
+
},
|
|
584
|
+
/**
|
|
585
|
+
* 获取页面详情
|
|
586
|
+
* @param params 请求参数 { page_id: string }
|
|
587
|
+
* @returns 接口返回结果
|
|
588
|
+
*/
|
|
589
|
+
detail: async (params) => {
|
|
590
|
+
const { page_id } = params;
|
|
591
|
+
await this.ensureTokenValid();
|
|
592
|
+
const url = `/api/builder/v1/namespaces/${this.namespace}/meta/pages/${page_id}`;
|
|
593
|
+
this.log(LoggerLevel.info, `[page.detail] Fetching page detail: ${page_id}`);
|
|
594
|
+
const res = await this.axiosInstance.get(url, {
|
|
595
|
+
headers: {
|
|
596
|
+
Authorization: `${this.accessToken}`
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
this.log(LoggerLevel.debug, `[page.detail] Page detail fetched: ${page_id}, code=${res.data.code}`);
|
|
600
|
+
this.log(LoggerLevel.trace, `[page.detail] Response: ${JSON.stringify(res.data)}`);
|
|
502
601
|
return res.data;
|
|
602
|
+
},
|
|
603
|
+
/**
|
|
604
|
+
* 获取页面访问地址
|
|
605
|
+
* @param params 请求参数 { page_id: string, pageParams?: any, parentPageParams?: any, navId?: string, tabId?: string }
|
|
606
|
+
* @returns 接口返回结果
|
|
607
|
+
*/
|
|
608
|
+
url: async (params) => {
|
|
609
|
+
const { page_id, pageParams, parentPageParams, navId, tabId } = params;
|
|
610
|
+
await this.ensureTokenValid();
|
|
611
|
+
const url = `/api/builder/v1/namespaces/${this.namespace}/meta/pages/${page_id}/link`;
|
|
612
|
+
this.log(LoggerLevel.info, `[page.url] Fetching page URL: ${page_id}`);
|
|
613
|
+
const requestData = {};
|
|
614
|
+
if (pageParams)
|
|
615
|
+
requestData.pageParams = pageParams;
|
|
616
|
+
if (parentPageParams)
|
|
617
|
+
requestData.parentPageParams = parentPageParams;
|
|
618
|
+
if (navId)
|
|
619
|
+
requestData.navId = navId;
|
|
620
|
+
if (tabId)
|
|
621
|
+
requestData.tabId = tabId;
|
|
622
|
+
const res = await this.axiosInstance.post(url, requestData, {
|
|
623
|
+
headers: {
|
|
624
|
+
Authorization: `${this.accessToken}`,
|
|
625
|
+
'Content-Type': 'application/json'
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
this.log(LoggerLevel.debug, `[page.url] Page URL fetched: ${page_id}, code=${res.data.code}`);
|
|
629
|
+
this.log(LoggerLevel.trace, `[page.url] Response: ${JSON.stringify(res.data)}`);
|
|
630
|
+
return res.data;
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* 附件模块
|
|
635
|
+
*/
|
|
636
|
+
this.attachment = {
|
|
637
|
+
/**
|
|
638
|
+
* 文件操作
|
|
639
|
+
*/
|
|
640
|
+
file: {
|
|
641
|
+
/**
|
|
642
|
+
* 上传文件
|
|
643
|
+
* @param params 请求参数 { file: any }
|
|
644
|
+
* @returns 接口返回结果
|
|
645
|
+
*/
|
|
646
|
+
upload: async (params) => {
|
|
647
|
+
const { file } = params;
|
|
648
|
+
await this.ensureTokenValid();
|
|
649
|
+
const url = '/api/attachment/v1/files';
|
|
650
|
+
this.log(LoggerLevel.info, '[attachment.file.upload] Uploading file');
|
|
651
|
+
const FormData = require('form-data');
|
|
652
|
+
const formData = new FormData();
|
|
653
|
+
formData.append('file', file);
|
|
654
|
+
const res = await this.axiosInstance.post(url, formData, {
|
|
655
|
+
headers: {
|
|
656
|
+
Authorization: `${this.accessToken}`,
|
|
657
|
+
...formData.getHeaders()
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
this.log(LoggerLevel.debug, `[attachment.file.upload] File uploaded: code=${res.data.code}`);
|
|
661
|
+
this.log(LoggerLevel.trace, `[attachment.file.upload] Response: ${JSON.stringify(res.data)}`);
|
|
662
|
+
return res.data;
|
|
663
|
+
},
|
|
664
|
+
/**
|
|
665
|
+
* 下载文件
|
|
666
|
+
* @param params 请求参数 { file_id: string }
|
|
667
|
+
* @returns 文件二进制流
|
|
668
|
+
*/
|
|
669
|
+
download: async (params) => {
|
|
670
|
+
const { file_id } = params;
|
|
671
|
+
await this.ensureTokenValid();
|
|
672
|
+
const url = `/api/attachment/v1/files/${file_id}`;
|
|
673
|
+
this.log(LoggerLevel.info, `[attachment.file.download] Downloading file: ${file_id}`);
|
|
674
|
+
const res = await this.axiosInstance.get(url, {
|
|
675
|
+
headers: {
|
|
676
|
+
Authorization: `${this.accessToken}`
|
|
677
|
+
},
|
|
678
|
+
responseType: 'arraybuffer'
|
|
679
|
+
});
|
|
680
|
+
this.log(LoggerLevel.debug, `[attachment.file.download] File downloaded: ${file_id}`);
|
|
681
|
+
return res.data;
|
|
682
|
+
},
|
|
683
|
+
/**
|
|
684
|
+
* 删除文件
|
|
685
|
+
* @param params 请求参数 { file_id: string }
|
|
686
|
+
* @returns 接口返回结果
|
|
687
|
+
*/
|
|
688
|
+
delete: async (params) => {
|
|
689
|
+
const { file_id } = params;
|
|
690
|
+
await this.ensureTokenValid();
|
|
691
|
+
const url = `/v1/files/${file_id}`;
|
|
692
|
+
this.log(LoggerLevel.info, `[attachment.file.delete] Deleting file: ${file_id}`);
|
|
693
|
+
const res = await this.axiosInstance.delete(url, {
|
|
694
|
+
headers: {
|
|
695
|
+
Authorization: `${this.accessToken}`
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
this.log(LoggerLevel.debug, `[attachment.file.delete] File deleted: ${file_id}, code=${res.data.code}`);
|
|
699
|
+
this.log(LoggerLevel.trace, `[attachment.file.delete] Response: ${JSON.stringify(res.data)}`);
|
|
700
|
+
return res.data;
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
/**
|
|
704
|
+
* 头像图片操作
|
|
705
|
+
*/
|
|
706
|
+
avatar: {
|
|
707
|
+
/**
|
|
708
|
+
* 上传头像图片
|
|
709
|
+
* @param params 请求参数 { image: any }
|
|
710
|
+
* @returns 接口返回结果
|
|
711
|
+
*/
|
|
712
|
+
upload: async (params) => {
|
|
713
|
+
const { image } = params;
|
|
714
|
+
await this.ensureTokenValid();
|
|
715
|
+
const url = '/api/attachment/v1/images';
|
|
716
|
+
this.log(LoggerLevel.info, '[attachment.avatar.upload] Uploading avatar image');
|
|
717
|
+
const FormData = require('form-data');
|
|
718
|
+
const formData = new FormData();
|
|
719
|
+
formData.append('image', image);
|
|
720
|
+
const res = await this.axiosInstance.post(url, formData, {
|
|
721
|
+
headers: {
|
|
722
|
+
Authorization: `${this.accessToken}`,
|
|
723
|
+
...formData.getHeaders()
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
this.log(LoggerLevel.debug, `[attachment.avatar.upload] Avatar image uploaded: code=${res.data.code}`);
|
|
727
|
+
this.log(LoggerLevel.trace, `[attachment.avatar.upload] Response: ${JSON.stringify(res.data)}`);
|
|
728
|
+
return res.data;
|
|
729
|
+
},
|
|
730
|
+
/**
|
|
731
|
+
* 下载头像图片
|
|
732
|
+
* @param params 请求参数 { image_id: string }
|
|
733
|
+
* @returns 图片二进制流
|
|
734
|
+
*/
|
|
735
|
+
download: async (params) => {
|
|
736
|
+
const { image_id } = params;
|
|
737
|
+
await this.ensureTokenValid();
|
|
738
|
+
const url = `/api/attachment/v1/images/${image_id}`;
|
|
739
|
+
this.log(LoggerLevel.info, `[attachment.avatar.download] Downloading avatar image: ${image_id}`);
|
|
740
|
+
const res = await this.axiosInstance.get(url, {
|
|
741
|
+
headers: {
|
|
742
|
+
Authorization: `${this.accessToken}`
|
|
743
|
+
},
|
|
744
|
+
responseType: 'arraybuffer'
|
|
745
|
+
});
|
|
746
|
+
this.log(LoggerLevel.debug, `[attachment.avatar.download] Avatar image downloaded: ${image_id}`);
|
|
747
|
+
return res.data;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* 全局数据模块
|
|
753
|
+
*/
|
|
754
|
+
this.global = {
|
|
755
|
+
/**
|
|
756
|
+
* 全局选项
|
|
757
|
+
*/
|
|
758
|
+
options: {
|
|
759
|
+
/**
|
|
760
|
+
* 查询全局选项详情
|
|
761
|
+
* @param params 请求参数 { api_name: string }
|
|
762
|
+
* @returns 接口返回结果
|
|
763
|
+
*/
|
|
764
|
+
detail: async (params) => {
|
|
765
|
+
const { api_name } = params;
|
|
766
|
+
await this.ensureTokenValid();
|
|
767
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/globalOptions/${api_name}`;
|
|
768
|
+
this.log(LoggerLevel.info, `[global.options.detail] Fetching global option detail: ${api_name}`);
|
|
769
|
+
const res = await this.axiosInstance.get(url, {
|
|
770
|
+
headers: {
|
|
771
|
+
Authorization: `${this.accessToken}`
|
|
772
|
+
}
|
|
773
|
+
});
|
|
774
|
+
this.log(LoggerLevel.debug, `[global.options.detail] Global option detail fetched: ${api_name}, code=${res.data.code}`);
|
|
775
|
+
this.log(LoggerLevel.trace, `[global.options.detail] Response: ${JSON.stringify(res.data)}`);
|
|
776
|
+
return res.data;
|
|
777
|
+
},
|
|
778
|
+
/**
|
|
779
|
+
* 查询全局选项列表
|
|
780
|
+
* @param params 请求参数 { limit: number, offset: number, filter?: { quickQuery?: string } }
|
|
781
|
+
* @returns 接口返回结果
|
|
782
|
+
*/
|
|
783
|
+
list: async (params) => {
|
|
784
|
+
const { limit, offset, filter } = params;
|
|
785
|
+
await this.ensureTokenValid();
|
|
786
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/globalOptions/list`;
|
|
787
|
+
this.log(LoggerLevel.info, `[global.options.list] Fetching global options list: offset=${offset}, limit=${limit}`);
|
|
788
|
+
const requestData = { limit, offset };
|
|
789
|
+
if (filter) {
|
|
790
|
+
requestData.filter = filter;
|
|
791
|
+
}
|
|
792
|
+
const res = await this.axiosInstance.post(url, requestData, {
|
|
793
|
+
headers: {
|
|
794
|
+
Authorization: `${this.accessToken}`,
|
|
795
|
+
'Content-Type': 'application/json'
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
this.log(LoggerLevel.debug, `[global.options.list] Global options list fetched: code=${res.data.code}`);
|
|
799
|
+
this.log(LoggerLevel.trace, `[global.options.list] Response: ${JSON.stringify(res.data)}`);
|
|
800
|
+
return res.data;
|
|
801
|
+
},
|
|
802
|
+
/**
|
|
803
|
+
* 查询所有全局选项 - 支持自动分页,获取全部数据
|
|
804
|
+
* @description 该方法会自动处理分页,直到获取所有全局选项数据
|
|
805
|
+
* @param params 请求参数 { limit?: number, filter?: { quickQuery?: string } }
|
|
806
|
+
* @returns { total, items }
|
|
807
|
+
*/
|
|
808
|
+
listWithIterator: async (params) => {
|
|
809
|
+
const limit = (params === null || params === void 0 ? void 0 : params.limit) || 100;
|
|
810
|
+
const filter = params === null || params === void 0 ? void 0 : params.filter;
|
|
811
|
+
let results = [];
|
|
812
|
+
let offset = 0;
|
|
813
|
+
let total = 0;
|
|
814
|
+
let page = 0;
|
|
815
|
+
let totalPages = 0;
|
|
816
|
+
do {
|
|
817
|
+
await functionLimiter(async () => {
|
|
818
|
+
var _a, _b;
|
|
819
|
+
const requestParams = { limit, offset };
|
|
820
|
+
if (filter) {
|
|
821
|
+
requestParams.filter = filter;
|
|
822
|
+
}
|
|
823
|
+
const res = await this.global.options.list(requestParams);
|
|
824
|
+
page += 1;
|
|
825
|
+
if (res.data && Array.isArray(res.data.items)) {
|
|
826
|
+
results = results.concat(res.data.items);
|
|
827
|
+
}
|
|
828
|
+
if (page === 1) {
|
|
829
|
+
total = res.data.total || 0;
|
|
830
|
+
totalPages = Math.ceil(total / limit);
|
|
831
|
+
this.log(LoggerLevel.info, `[global.options.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
|
|
832
|
+
}
|
|
833
|
+
offset += limit;
|
|
834
|
+
const padLength = totalPages.toString().length;
|
|
835
|
+
const pageStr = page.toString().padStart(padLength, '0');
|
|
836
|
+
const totalPagesStr = totalPages.toString().padStart(padLength, '0');
|
|
837
|
+
this.log(LoggerLevel.info, `[global.options.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
|
|
838
|
+
this.log(LoggerLevel.debug, `[global.options.listWithIterator] Page ${page} details: items=${(_a = res.data.items) === null || _a === void 0 ? void 0 : _a.length}, offset=${offset}`);
|
|
839
|
+
this.log(LoggerLevel.trace, `[global.options.listWithIterator] Page ${page} data: ${JSON.stringify((_b = res.data) === null || _b === void 0 ? void 0 : _b.items)}`);
|
|
840
|
+
return res;
|
|
841
|
+
});
|
|
842
|
+
} while (results.length < total);
|
|
843
|
+
return { total, items: results };
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
/**
|
|
847
|
+
* 环境变量
|
|
848
|
+
*/
|
|
849
|
+
variables: {
|
|
850
|
+
/**
|
|
851
|
+
* 查询环境变量详情
|
|
852
|
+
* @param params 请求参数 { api_name: string }
|
|
853
|
+
* @returns 接口返回结果
|
|
854
|
+
*/
|
|
855
|
+
detail: async (params) => {
|
|
856
|
+
const { api_name } = params;
|
|
857
|
+
await this.ensureTokenValid();
|
|
858
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/globalVariables/${api_name}`;
|
|
859
|
+
this.log(LoggerLevel.info, `[global.variables.detail] Fetching global variable detail: ${api_name}`);
|
|
860
|
+
const res = await this.axiosInstance.get(url, {
|
|
861
|
+
headers: {
|
|
862
|
+
Authorization: `${this.accessToken}`
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
this.log(LoggerLevel.debug, `[global.variables.detail] Global variable detail fetched: ${api_name}, code=${res.data.code}`);
|
|
866
|
+
this.log(LoggerLevel.trace, `[global.variables.detail] Response: ${JSON.stringify(res.data)}`);
|
|
867
|
+
return res.data;
|
|
868
|
+
},
|
|
869
|
+
/**
|
|
870
|
+
* 查询环境变量列表
|
|
871
|
+
* @param params 请求参数 { limit: number, offset: number, filter?: { quickQuery?: string } }
|
|
872
|
+
* @returns 接口返回结果
|
|
873
|
+
*/
|
|
874
|
+
list: async (params) => {
|
|
875
|
+
const { limit, offset, filter } = params;
|
|
876
|
+
await this.ensureTokenValid();
|
|
877
|
+
const url = `/api/data/v1/namespaces/${this.namespace}/globalVariables/list`;
|
|
878
|
+
this.log(LoggerLevel.info, `[global.variables.list] Fetching global variables list: offset=${offset}, limit=${limit}`);
|
|
879
|
+
const requestData = { limit, offset };
|
|
880
|
+
if (filter) {
|
|
881
|
+
requestData.filter = filter;
|
|
882
|
+
}
|
|
883
|
+
const res = await this.axiosInstance.post(url, requestData, {
|
|
884
|
+
headers: {
|
|
885
|
+
Authorization: `${this.accessToken}`,
|
|
886
|
+
'Content-Type': 'application/json'
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
this.log(LoggerLevel.debug, `[global.variables.list] Global variables list fetched: code=${res.data.code}`);
|
|
890
|
+
this.log(LoggerLevel.trace, `[global.variables.list] Response: ${JSON.stringify(res.data)}`);
|
|
891
|
+
return res.data;
|
|
892
|
+
},
|
|
893
|
+
/**
|
|
894
|
+
* 查询所有环境变量 - 支持自动分页,获取全部数据
|
|
895
|
+
* @description 该方法会自动处理分页,直到获取所有环境变量数据
|
|
896
|
+
* @param params 请求参数 { limit?: number, filter?: { quickQuery?: string } }
|
|
897
|
+
* @returns { total, items }
|
|
898
|
+
*/
|
|
899
|
+
listWithIterator: async (params) => {
|
|
900
|
+
const limit = (params === null || params === void 0 ? void 0 : params.limit) || 100;
|
|
901
|
+
const filter = params === null || params === void 0 ? void 0 : params.filter;
|
|
902
|
+
let results = [];
|
|
903
|
+
let offset = 0;
|
|
904
|
+
let total = 0;
|
|
905
|
+
let page = 0;
|
|
906
|
+
let totalPages = 0;
|
|
907
|
+
do {
|
|
908
|
+
await functionLimiter(async () => {
|
|
909
|
+
var _a, _b;
|
|
910
|
+
const requestParams = { limit, offset };
|
|
911
|
+
if (filter) {
|
|
912
|
+
requestParams.filter = filter;
|
|
913
|
+
}
|
|
914
|
+
const res = await this.global.variables.list(requestParams);
|
|
915
|
+
page += 1;
|
|
916
|
+
if (res.data && Array.isArray(res.data.items)) {
|
|
917
|
+
results = results.concat(res.data.items);
|
|
918
|
+
}
|
|
919
|
+
if (page === 1) {
|
|
920
|
+
total = res.data.total || 0;
|
|
921
|
+
totalPages = Math.ceil(total / limit);
|
|
922
|
+
this.log(LoggerLevel.info, `[global.variables.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
|
|
923
|
+
}
|
|
924
|
+
offset += limit;
|
|
925
|
+
const padLength = totalPages.toString().length;
|
|
926
|
+
const pageStr = page.toString().padStart(padLength, '0');
|
|
927
|
+
const totalPagesStr = totalPages.toString().padStart(padLength, '0');
|
|
928
|
+
this.log(LoggerLevel.info, `[global.variables.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
|
|
929
|
+
this.log(LoggerLevel.debug, `[global.variables.listWithIterator] Page ${page} details: items=${(_a = res.data.items) === null || _a === void 0 ? void 0 : _a.length}, offset=${offset}`);
|
|
930
|
+
this.log(LoggerLevel.trace, `[global.variables.listWithIterator] Page ${page} data: ${JSON.stringify((_b = res.data) === null || _b === void 0 ? void 0 : _b.items)}`);
|
|
931
|
+
return res;
|
|
932
|
+
});
|
|
933
|
+
} while (results.length < total);
|
|
934
|
+
return { total, items: results };
|
|
935
|
+
}
|
|
503
936
|
}
|
|
504
937
|
};
|
|
505
938
|
this.clientId = options.clientId;
|
|
@@ -510,7 +943,7 @@ class Client {
|
|
|
510
943
|
baseURL: 'https://ae-openapi.feishu.cn',
|
|
511
944
|
headers: { 'Content-Type': 'application/json' }
|
|
512
945
|
});
|
|
513
|
-
this.log(LoggerLevel.info, '[client] initialized');
|
|
946
|
+
this.log(LoggerLevel.info, '[client] Client initialized successfully');
|
|
514
947
|
}
|
|
515
948
|
/**
|
|
516
949
|
* 设置日志等级
|
|
@@ -518,7 +951,7 @@ class Client {
|
|
|
518
951
|
*/
|
|
519
952
|
setLoggerLevel(level) {
|
|
520
953
|
this.loggerLevel = level;
|
|
521
|
-
this.log(LoggerLevel.info, `[logger]
|
|
954
|
+
this.log(LoggerLevel.info, `[logger] Log level set to ${LoggerLevel[level]}`);
|
|
522
955
|
}
|
|
523
956
|
/**
|
|
524
957
|
* 日志打印方法
|
|
@@ -537,7 +970,7 @@ class Client {
|
|
|
537
970
|
*/
|
|
538
971
|
async init() {
|
|
539
972
|
await this.ensureTokenValid();
|
|
540
|
-
this.log(LoggerLevel.info, '[client] ready');
|
|
973
|
+
this.log(LoggerLevel.info, '[client] Client initialized and ready');
|
|
541
974
|
}
|
|
542
975
|
/**
|
|
543
976
|
* 获取 accessToken
|
|
@@ -549,30 +982,30 @@ class Client {
|
|
|
549
982
|
clientSecret: this.clientSecret
|
|
550
983
|
});
|
|
551
984
|
if (res.data.code !== '0') {
|
|
552
|
-
this.log(LoggerLevel.error, `[
|
|
985
|
+
this.log(LoggerLevel.error, `[auth] Failed to fetch access token: ${res.data.msg}`);
|
|
553
986
|
throw new Error(`获取 accessToken 失败: ${res.data.msg}`);
|
|
554
987
|
}
|
|
555
988
|
this.accessToken = res.data.data.accessToken;
|
|
556
989
|
this.expireTime = res.data.data.expireTime;
|
|
557
|
-
this.log(LoggerLevel.info, '[
|
|
990
|
+
this.log(LoggerLevel.info, '[auth] Access token refreshed successfully');
|
|
558
991
|
}
|
|
559
992
|
/**
|
|
560
993
|
* 确保 token 有效, 若过期则刷新
|
|
561
994
|
*/
|
|
562
995
|
async ensureTokenValid() {
|
|
563
996
|
if (this.disableTokenCache) {
|
|
564
|
-
this.log(LoggerLevel.debug, '[
|
|
997
|
+
this.log(LoggerLevel.debug, '[auth] Token cache disabled, refreshing token');
|
|
565
998
|
await this.getAccessToken();
|
|
566
999
|
return;
|
|
567
1000
|
}
|
|
568
1001
|
if (!this.accessToken || !this.expireTime) {
|
|
569
|
-
this.log(LoggerLevel.debug, '[
|
|
1002
|
+
this.log(LoggerLevel.debug, '[auth] No token cached, fetching new token');
|
|
570
1003
|
await this.getAccessToken();
|
|
571
1004
|
return;
|
|
572
1005
|
}
|
|
573
1006
|
const now = dayjs().valueOf();
|
|
574
1007
|
if (now + 60 * 1000 > this.expireTime) {
|
|
575
|
-
this.log(LoggerLevel.debug, '[
|
|
1008
|
+
this.log(LoggerLevel.debug, '[auth] Token expired, refreshing');
|
|
576
1009
|
await this.getAccessToken();
|
|
577
1010
|
}
|
|
578
1011
|
}
|
|
@@ -588,25 +1021,25 @@ class Client {
|
|
|
588
1021
|
*/
|
|
589
1022
|
get tokenExpireTime() {
|
|
590
1023
|
if (!this.accessToken || !this.expireTime) {
|
|
591
|
-
this.log(LoggerLevel.warn, '[
|
|
1024
|
+
this.log(LoggerLevel.warn, '[auth] No valid token available');
|
|
592
1025
|
return null;
|
|
593
1026
|
}
|
|
594
1027
|
const now = dayjs().valueOf();
|
|
595
1028
|
const remainMs = this.expireTime - now;
|
|
596
1029
|
if (remainMs <= 0) {
|
|
597
|
-
this.log(LoggerLevel.warn, '[
|
|
1030
|
+
this.log(LoggerLevel.warn, '[auth] Token has expired');
|
|
598
1031
|
return 0;
|
|
599
1032
|
}
|
|
600
1033
|
const remainSeconds = Math.floor(remainMs / 1000);
|
|
601
|
-
this.log(LoggerLevel.debug, `[
|
|
602
|
-
this.log(LoggerLevel.trace, `[
|
|
1034
|
+
this.log(LoggerLevel.debug, `[auth] Token expires in ${remainSeconds} seconds`);
|
|
1035
|
+
this.log(LoggerLevel.trace, `[auth] Token expiry details: remaining=${remainSeconds}s, expireTime=${this.expireTime}, now=${now}`);
|
|
603
1036
|
return remainSeconds;
|
|
604
1037
|
}
|
|
605
1038
|
/**
|
|
606
1039
|
* 获取当前 namespace
|
|
607
1040
|
*/
|
|
608
1041
|
get currentNamespace() {
|
|
609
|
-
this.log(LoggerLevel.debug,
|
|
1042
|
+
this.log(LoggerLevel.debug, `[namespace] Current namespace: ${this.namespace}`);
|
|
610
1043
|
return this.namespace;
|
|
611
1044
|
}
|
|
612
1045
|
}
|