apaas-oapi-client 0.1.19 → 0.1.22

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 CHANGED
@@ -191,16 +191,30 @@ const res = await client.object.create.record({
191
191
  console.log(res);
192
192
  ```
193
193
 
194
- ### **批量创建**
194
+ ### **批量创建(最多 100 条)**
195
195
 
196
- > ⚠️ 每次最多创建 100 条,SDK 已自动分组限流
196
+ ```JavaScript
197
+ const res = await client.object.create.records({
198
+ object_name: 'object_event_log',
199
+ records: [
200
+ { name: 'Sample text 1', content: 'Sample text 1' },
201
+ { name: 'Sample text 2', content: 'Sample text 2' }
202
+ ]
203
+ });
204
+ console.log(res);
205
+ ```
206
+
207
+ ### **批量创建(支持超过 100 条,自动拆分)**
208
+
209
+ > ⚠️ 超过 100 条会自动拆分为多次请求,SDK 已自动分组限流
197
210
 
198
211
  ```JavaScript
199
212
  const { total, items } = await client.object.create.recordsWithIterator({
200
213
  object_name: 'object_event_log',
201
214
  records: [
202
215
  { name: 'Sample text 1', content: 'Sample text 1' },
203
- { name: 'Sample text 2', content: 'Sample text 2' }
216
+ { name: 'Sample text 2', content: 'Sample text 2' },
217
+ // ... 可以超过 100 条
204
218
  ]
205
219
  });
206
220
  console.log('Total:', total);
@@ -224,12 +238,10 @@ console.log(res);
224
238
 
225
239
  ***
226
240
 
227
- ### **批量更新**
228
-
229
- > ⚠️ 每次最多更新 100 条,SDK 已自动分组限流
241
+ ### **批量更新(最多 100 条)**
230
242
 
231
243
  ```JavaScript
232
- const res = await client.object.update.recordsBatchUpdate({
244
+ const res = await client.object.update.records({
233
245
  object_name: 'object_store',
234
246
  records: [
235
247
  { _id: 'id1', field1: 'value1' },
@@ -239,6 +251,22 @@ const res = await client.object.update.recordsBatchUpdate({
239
251
  console.log(res);
240
252
  ```
241
253
 
254
+ ### **批量更新(支持超过 100 条,自动拆分)**
255
+
256
+ > ⚠️ 超过 100 条会自动拆分为多次请求,SDK 已自动分组限流
257
+
258
+ ```JavaScript
259
+ const results = await client.object.update.recordsWithIterator({
260
+ object_name: 'object_store',
261
+ records: [
262
+ { _id: 'id1', field1: 'value1' },
263
+ { _id: 'id2', field1: 'value2' },
264
+ // ... 可以超过 100 条
265
+ ]
266
+ });
267
+ console.log(results); // 返回所有子请求的结果数组
268
+ ```
269
+
242
270
  ***
243
271
 
244
272
 
@@ -257,18 +285,28 @@ console.log(res);
257
285
 
258
286
  ***
259
287
 
260
- ### **批量删除**
261
-
262
- > ⚠️ 每次最多删除 100 条,SDK 已自动分组限流
288
+ ### **批量删除(最多 100 条)**
263
289
 
264
290
  ```JavaScript
265
- const res = await client.object.delete.recordsBatchDelete({
291
+ const res = await client.object.delete.records({
266
292
  object_name: 'object_store',
267
293
  ids: ['id1', 'id2', 'id3']
268
294
  });
269
295
  console.log(res);
270
296
  ```
271
297
 
298
+ ### **批量删除(支持超过 100 条,自动拆分)**
299
+
300
+ > ⚠️ 超过 100 条会自动拆分为多次请求,SDK 已自动分组限流
301
+
302
+ ```JavaScript
303
+ const results = await client.object.delete.recordsWithIterator({
304
+ object_name: 'object_store',
305
+ ids: ['id1', 'id2', 'id3', /* ... 可以超过 100 条 */]
306
+ });
307
+ console.log(results); // 返回所有子请求的结果数组
308
+ ```
309
+
272
310
  ***
273
311
 
274
312
 
package/dist/index.js CHANGED
@@ -165,35 +165,44 @@ class Client {
165
165
  recordsWithIterator: async (params) => {
166
166
  const { object_name, data } = params;
167
167
  let results = [];
168
- let nextPageToken = '';
168
+ let nextPageToken = undefined;
169
169
  let total = 0;
170
170
  let page = 0;
171
171
  let totalPages = 0;
172
172
  const pageSize = data.page_size || 100;
173
173
  do {
174
174
  await functionLimiter(async () => {
175
- var _a, _b;
176
- const mergedData = { ...data, page_token: nextPageToken || '' };
175
+ var _a, _b, _c, _d;
176
+ const mergedData = { ...data };
177
+ if (nextPageToken) {
178
+ mergedData.page_token = nextPageToken;
179
+ }
177
180
  const res = await this.object.search.records({
178
181
  object_name,
179
182
  data: mergedData
180
183
  });
184
+ if (res.code !== '0') {
185
+ this.log(LoggerLevel.error, `[object.search.recordsWithIterator] Error querying records: code=${res.code}, msg=${res.msg}`);
186
+ throw new Error(res.msg || `Query failed with code ${res.code}`);
187
+ }
181
188
  page += 1;
182
189
  if (res.data && Array.isArray(res.data.items)) {
183
190
  results = results.concat(res.data.items);
184
191
  }
192
+ if (res.data && (res.data.total !== undefined && res.data.total !== null)) {
193
+ total = res.data.total;
194
+ }
185
195
  if (page === 1) {
186
- total = res.data.total || 0;
187
196
  totalPages = Math.ceil(total / pageSize);
188
197
  this.log(LoggerLevel.info, `[object.search.recordsWithIterator] Starting paginated query: ${object_name}, total=${total}, pages=${totalPages}`);
189
198
  }
190
- nextPageToken = res.data.next_page_token;
199
+ nextPageToken = (_a = res.data) === null || _a === void 0 ? void 0 : _a.next_page_token;
191
200
  const padLength = totalPages.toString().length;
192
201
  const pageStr = page.toString().padStart(padLength, '0');
193
202
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
194
203
  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)}`);
204
+ this.log(LoggerLevel.debug, `[object.search.recordsWithIterator] Page ${page} details: items=${(_c = (_b = res.data) === null || _b === void 0 ? void 0 : _b.items) === null || _c === void 0 ? void 0 : _c.length}, nextToken=${nextPageToken || 'none'}`);
205
+ this.log(LoggerLevel.trace, `[object.search.recordsWithIterator] Page ${page} data: ${JSON.stringify((_d = res.data) === null || _d === void 0 ? void 0 : _d.items)}`);
197
206
  return res;
198
207
  });
199
208
  } while (nextPageToken);
@@ -249,6 +258,15 @@ class Client {
249
258
  */
250
259
  recordsWithIterator: async (params) => {
251
260
  const { object_name, records } = params;
261
+ // 参数校验
262
+ if (!records || !Array.isArray(records)) {
263
+ this.log(LoggerLevel.error, '[object.create.recordsWithIterator] Invalid records parameter: must be a non-empty array');
264
+ throw new Error('参数 records 必须是一个数组');
265
+ }
266
+ if (records.length === 0) {
267
+ this.log(LoggerLevel.warn, '[object.create.recordsWithIterator] Empty records array provided, returning empty result');
268
+ return { total: 0, items: [] };
269
+ }
252
270
  let results = [];
253
271
  let total = records.length;
254
272
  const chunkSize = 100;
@@ -262,16 +280,24 @@ class Client {
262
280
  page += 1;
263
281
  this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Processing chunk ${index + 1}/${chunks.length}: ${chunk.length} records`);
264
282
  await functionLimiter(async () => {
283
+ var _a, _b, _c;
265
284
  const res = await this.object.create.records({
266
285
  object_name,
267
286
  records: chunk
268
287
  });
288
+ if (res.code !== '0') {
289
+ this.log(LoggerLevel.error, `[object.create.recordsWithIterator] Error creating records: code=${res.code}, msg=${res.msg}`);
290
+ // Should we throw? Probably yes, to stop partial creation or notify user.
291
+ // But maybe user wants partial success?
292
+ // Given other methods throw, I'll throw here too.
293
+ throw new Error(res.msg || `Creation failed with code ${res.code}`);
294
+ }
269
295
  if (res.data && Array.isArray(res.data.items)) {
270
296
  results = results.concat(res.data.items);
271
297
  }
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)}`);
298
+ this.log(LoggerLevel.info, `[object.create.recordsWithIterator] Chunk ${page} completed: ${object_name}, created=${(_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.items) === null || _b === void 0 ? void 0 : _b.length}`);
299
+ this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Chunk ${page} result: ${object_name}, code=${res.code}`);
300
+ this.log(LoggerLevel.trace, `[object.create.recordsWithIterator] Chunk ${page} data: ${JSON.stringify((_c = res.data) === null || _c === void 0 ? void 0 : _c.items)}`);
275
301
  return res;
276
302
  });
277
303
  }
@@ -307,13 +333,17 @@ class Client {
307
333
  */
308
334
  records: async (params) => {
309
335
  const { object_name, records } = params;
310
- const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/records_batch`;
336
+ const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
311
337
  this.log(LoggerLevel.info, `[object.update.records] Updating ${records.length} records`);
312
- const response = await this.axiosInstance.patch(url, { records }, { headers: { Authorization: `${this.accessToken}` } });
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)}`);
316
- return response.data;
338
+ const response = await functionLimiter(async () => {
339
+ await this.ensureTokenValid();
340
+ const res = await this.axiosInstance.patch(url, { records }, { headers: { Authorization: `${this.accessToken}` } });
341
+ this.log(LoggerLevel.info, `[object.update.records] Records updated: ${object_name}`);
342
+ this.log(LoggerLevel.debug, `[object.update.records] Records updated: ${object_name}, code=${res.data.code}`);
343
+ this.log(LoggerLevel.trace, `[object.update.records] Response: ${JSON.stringify(res.data)}`);
344
+ return res.data;
345
+ });
346
+ return response;
317
347
  },
318
348
  /**
319
349
  * 批量更新 - 支持超过 100 条数据,自动拆分
@@ -323,6 +353,15 @@ class Client {
323
353
  */
324
354
  recordsWithIterator: async (params) => {
325
355
  const { object_name, records } = params;
356
+ // 参数校验
357
+ if (!records || !Array.isArray(records)) {
358
+ this.log(LoggerLevel.error, '[object.update.recordsWithIterator] Invalid records parameter: must be a non-empty array');
359
+ throw new Error('参数 records 必须是一个数组');
360
+ }
361
+ if (records.length === 0) {
362
+ this.log(LoggerLevel.warn, '[object.update.recordsWithIterator] Empty records array provided, returning empty result');
363
+ return [];
364
+ }
326
365
  const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
327
366
  const chunkSize = 100;
328
367
  const chunks = [];
@@ -399,6 +438,15 @@ class Client {
399
438
  */
400
439
  recordsWithIterator: async (params) => {
401
440
  const { object_name, ids } = params;
441
+ // 参数校验
442
+ if (!ids || !Array.isArray(ids)) {
443
+ this.log(LoggerLevel.error, '[object.delete.recordsWithIterator] Invalid ids parameter: must be a non-empty array');
444
+ throw new Error('参数 ids 必须是一个数组');
445
+ }
446
+ if (ids.length === 0) {
447
+ this.log(LoggerLevel.warn, '[object.delete.recordsWithIterator] Empty ids array provided, returning empty result');
448
+ return [];
449
+ }
402
450
  const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
403
451
  const chunkSize = 100;
404
452
  const chunks = [];
@@ -452,7 +500,11 @@ class Client {
452
500
  });
453
501
  this.log(LoggerLevel.debug, `[department.exchange] Department ID exchanged: ${department_id}, code=${response.data.code}`);
454
502
  this.log(LoggerLevel.trace, `[department.exchange] Response: ${JSON.stringify(response.data)}`);
455
- return response.data.data[0]; // 返回第一个元素
503
+ if (response.data.code !== '0') {
504
+ this.log(LoggerLevel.error, `[department.exchange] Error exchanging department: code=${response.data.code}, msg=${response.data.msg}`);
505
+ throw new Error(response.data.msg || `Exchange failed with code ${response.data.code}`);
506
+ }
507
+ return response.data.data && response.data.data[0]; // 返回第一个元素
456
508
  });
457
509
  return res;
458
510
  },
@@ -467,6 +519,15 @@ class Client {
467
519
  // - 'department_id' (如 "1758534140403815")
468
520
  // - 'external_department_id' (外部平台 department_id, 无固定格式)
469
521
  // - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
522
+ // 参数校验
523
+ if (!department_ids || !Array.isArray(department_ids)) {
524
+ this.log(LoggerLevel.error, '[department.batchExchange] Invalid department_ids parameter: must be a non-empty array');
525
+ throw new Error('参数 department_ids 必须是一个数组');
526
+ }
527
+ if (department_ids.length === 0) {
528
+ this.log(LoggerLevel.warn, '[department.batchExchange] Empty department_ids array provided, returning empty result');
529
+ return [];
530
+ }
470
531
  const url = '/api/integration/v2/feishu/getDepartments';
471
532
  const chunkSize = 100;
472
533
  const chunks = [];
@@ -487,7 +548,11 @@ class Client {
487
548
  });
488
549
  this.log(LoggerLevel.debug, `[department.batchExchange] Chunk ${index + 1} completed: code=${response.data.code}`);
489
550
  this.log(LoggerLevel.trace, `[department.batchExchange] Chunk ${index + 1} response: ${JSON.stringify(response.data)}`);
490
- return response.data.data;
551
+ if (response.data.code !== '0') {
552
+ this.log(LoggerLevel.error, `[department.batchExchange] Error exchanging departments: code=${response.data.code}, msg=${response.data.msg}`);
553
+ throw new Error(response.data.msg || `Exchange failed with code ${response.data.code}`);
554
+ }
555
+ return response.data.data || [];
491
556
  });
492
557
  results.push(...res);
493
558
  }
@@ -558,14 +623,18 @@ class Client {
558
623
  let totalPages = 0;
559
624
  do {
560
625
  await functionLimiter(async () => {
561
- var _a, _b;
626
+ var _a, _b, _c, _d;
562
627
  const res = await this.page.list({ limit, offset });
628
+ if (res.code !== '0') {
629
+ this.log(LoggerLevel.error, `[page.listWithIterator] Error fetching pages: code=${res.code}, msg=${res.msg}`);
630
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
631
+ }
563
632
  page += 1;
564
633
  if (res.data && Array.isArray(res.data.items)) {
565
634
  results = results.concat(res.data.items);
566
635
  }
567
636
  if (page === 1) {
568
- total = res.data.total || 0;
637
+ total = ((_a = res.data) === null || _a === void 0 ? void 0 : _a.total) || 0;
569
638
  totalPages = Math.ceil(total / limit);
570
639
  this.log(LoggerLevel.info, `[page.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
571
640
  }
@@ -574,8 +643,8 @@ class Client {
574
643
  const pageStr = page.toString().padStart(padLength, '0');
575
644
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
576
645
  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)}`);
646
+ this.log(LoggerLevel.debug, `[page.listWithIterator] Page ${page} details: items=${(_c = (_b = res.data) === null || _b === void 0 ? void 0 : _b.items) === null || _c === void 0 ? void 0 : _c.length}, offset=${offset}`);
647
+ this.log(LoggerLevel.trace, `[page.listWithIterator] Page ${page} data: ${JSON.stringify((_d = res.data) === null || _d === void 0 ? void 0 : _d.items)}`);
579
648
  return res;
580
649
  });
581
650
  } while (results.length < total);
@@ -815,18 +884,22 @@ class Client {
815
884
  let totalPages = 0;
816
885
  do {
817
886
  await functionLimiter(async () => {
818
- var _a, _b;
887
+ var _a, _b, _c, _d;
819
888
  const requestParams = { limit, offset };
820
889
  if (filter) {
821
890
  requestParams.filter = filter;
822
891
  }
823
892
  const res = await this.global.options.list(requestParams);
893
+ if (res.code !== '0') {
894
+ this.log(LoggerLevel.error, `[global.options.listWithIterator] Error fetching global options: code=${res.code}, msg=${res.msg}`);
895
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
896
+ }
824
897
  page += 1;
825
898
  if (res.data && Array.isArray(res.data.items)) {
826
899
  results = results.concat(res.data.items);
827
900
  }
828
901
  if (page === 1) {
829
- total = res.data.total || 0;
902
+ total = ((_a = res.data) === null || _a === void 0 ? void 0 : _a.total) || 0;
830
903
  totalPages = Math.ceil(total / limit);
831
904
  this.log(LoggerLevel.info, `[global.options.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
832
905
  }
@@ -835,8 +908,8 @@ class Client {
835
908
  const pageStr = page.toString().padStart(padLength, '0');
836
909
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
837
910
  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)}`);
911
+ this.log(LoggerLevel.debug, `[global.options.listWithIterator] Page ${page} details: items=${(_c = (_b = res.data) === null || _b === void 0 ? void 0 : _b.items) === null || _c === void 0 ? void 0 : _c.length}, offset=${offset}`);
912
+ this.log(LoggerLevel.trace, `[global.options.listWithIterator] Page ${page} data: ${JSON.stringify((_d = res.data) === null || _d === void 0 ? void 0 : _d.items)}`);
840
913
  return res;
841
914
  });
842
915
  } while (results.length < total);
@@ -906,18 +979,22 @@ class Client {
906
979
  let totalPages = 0;
907
980
  do {
908
981
  await functionLimiter(async () => {
909
- var _a, _b;
982
+ var _a, _b, _c, _d;
910
983
  const requestParams = { limit, offset };
911
984
  if (filter) {
912
985
  requestParams.filter = filter;
913
986
  }
914
987
  const res = await this.global.variables.list(requestParams);
988
+ if (res.code !== '0') {
989
+ this.log(LoggerLevel.error, `[global.variables.listWithIterator] Error fetching global variables: code=${res.code}, msg=${res.msg}`);
990
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
991
+ }
915
992
  page += 1;
916
993
  if (res.data && Array.isArray(res.data.items)) {
917
994
  results = results.concat(res.data.items);
918
995
  }
919
996
  if (page === 1) {
920
- total = res.data.total || 0;
997
+ total = ((_a = res.data) === null || _a === void 0 ? void 0 : _a.total) || 0;
921
998
  totalPages = Math.ceil(total / limit);
922
999
  this.log(LoggerLevel.info, `[global.variables.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
923
1000
  }
@@ -926,8 +1003,8 @@ class Client {
926
1003
  const pageStr = page.toString().padStart(padLength, '0');
927
1004
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
928
1005
  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)}`);
1006
+ this.log(LoggerLevel.debug, `[global.variables.listWithIterator] Page ${page} details: items=${(_c = (_b = res.data) === null || _b === void 0 ? void 0 : _b.items) === null || _c === void 0 ? void 0 : _c.length}, offset=${offset}`);
1007
+ this.log(LoggerLevel.trace, `[global.variables.listWithIterator] Page ${page} data: ${JSON.stringify((_d = res.data) === null || _d === void 0 ? void 0 : _d.items)}`);
931
1008
  return res;
932
1009
  });
933
1010
  } while (results.length < total);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apaas-oapi-client",
3
- "version": "0.1.19",
3
+ "version": "0.1.22",
4
4
  "main": "dist/index.js",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  "build": "rollup -c",
13
13
  "test": "jest",
14
14
  "dev": "ts-node src/index.ts",
15
- "release": "npm run build && git add . && git commit -m 'chore(release): publish new version' && npm version patch && git push origin main --follow-tags"
15
+ "release": "npm run build && npm version patch && git push origin main --follow-tags"
16
16
  },
17
17
  "keywords": [],
18
18
  "author": "",
package/src/index.ts CHANGED
@@ -305,7 +305,7 @@ class Client {
305
305
  const { object_name, data } = params;
306
306
 
307
307
  let results: any[] = [];
308
- let nextPageToken: string | undefined = '';
308
+ let nextPageToken: string | undefined = undefined;
309
309
  let total = 0;
310
310
  let page = 0;
311
311
  let totalPages = 0;
@@ -314,33 +314,44 @@ class Client {
314
314
 
315
315
  do {
316
316
  const pageRes = await functionLimiter(async () => {
317
- const mergedData = { ...data, page_token: nextPageToken || '' };
317
+ const mergedData: any = { ...data };
318
+ if (nextPageToken) {
319
+ mergedData.page_token = nextPageToken;
320
+ }
318
321
 
319
322
  const res = await this.object.search.records({
320
323
  object_name,
321
324
  data: mergedData
322
325
  });
323
326
 
327
+ if (res.code !== '0') {
328
+ this.log(LoggerLevel.error, `[object.search.recordsWithIterator] Error querying records: code=${res.code}, msg=${res.msg}`);
329
+ throw new Error(res.msg || `Query failed with code ${res.code}`);
330
+ }
331
+
324
332
  page += 1;
325
333
 
326
334
  if (res.data && Array.isArray(res.data.items)) {
327
335
  results = results.concat(res.data.items);
328
336
  }
329
337
 
338
+ if (res.data && (res.data.total !== undefined && res.data.total !== null)) {
339
+ total = res.data.total;
340
+ }
341
+
330
342
  if (page === 1) {
331
- total = res.data.total || 0;
332
343
  totalPages = Math.ceil(total / pageSize);
333
344
  this.log(LoggerLevel.info, `[object.search.recordsWithIterator] Starting paginated query: ${object_name}, total=${total}, pages=${totalPages}`);
334
345
  }
335
346
 
336
- nextPageToken = res.data.next_page_token;
347
+ nextPageToken = res.data?.next_page_token;
337
348
 
338
349
  const padLength = totalPages.toString().length;
339
350
  const pageStr = page.toString().padStart(padLength, '0');
340
351
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
341
352
 
342
353
  this.log(LoggerLevel.info, `[object.search.recordsWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
343
- this.log(LoggerLevel.debug, `[object.search.recordsWithIterator] Page ${page} details: items=${res.data.items?.length}, nextToken=${nextPageToken || 'none'}`);
354
+ this.log(LoggerLevel.debug, `[object.search.recordsWithIterator] Page ${page} details: items=${res.data?.items?.length}, nextToken=${nextPageToken || 'none'}`);
344
355
  this.log(LoggerLevel.trace, `[object.search.recordsWithIterator] Page ${page} data: ${JSON.stringify(res.data?.items)}`);
345
356
 
346
357
  return res;
@@ -420,6 +431,17 @@ class Client {
420
431
  recordsWithIterator: async (params: { object_name: string; records: any[] }): Promise<{ total: number; items: any[] }> => {
421
432
  const { object_name, records } = params;
422
433
 
434
+ // 参数校验
435
+ if (!records || !Array.isArray(records)) {
436
+ this.log(LoggerLevel.error, '[object.create.recordsWithIterator] Invalid records parameter: must be a non-empty array');
437
+ throw new Error('参数 records 必须是一个数组');
438
+ }
439
+
440
+ if (records.length === 0) {
441
+ this.log(LoggerLevel.warn, '[object.create.recordsWithIterator] Empty records array provided, returning empty result');
442
+ return { total: 0, items: [] };
443
+ }
444
+
423
445
  let results: any[] = [];
424
446
  let total = records.length;
425
447
  const chunkSize = 100;
@@ -443,13 +465,21 @@ class Client {
443
465
  records: chunk
444
466
  });
445
467
 
468
+ if (res.code !== '0') {
469
+ this.log(LoggerLevel.error, `[object.create.recordsWithIterator] Error creating records: code=${res.code}, msg=${res.msg}`);
470
+ // Should we throw? Probably yes, to stop partial creation or notify user.
471
+ // But maybe user wants partial success?
472
+ // Given other methods throw, I'll throw here too.
473
+ throw new Error(res.msg || `Creation failed with code ${res.code}`);
474
+ }
475
+
446
476
  if (res.data && Array.isArray(res.data.items)) {
447
477
  results = results.concat(res.data.items);
448
478
  }
449
479
 
450
- this.log(LoggerLevel.info, `[object.create.recordsWithIterator] Chunk ${page} completed: ${object_name}, created=${res.data.items.length}`);
451
- this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Chunk ${page} result: ${object_name}, code=${res.data.code}`);
452
- this.log(LoggerLevel.trace, `[object.create.recordsWithIterator] Chunk ${page} data: ${JSON.stringify(res.data.items)}`);
480
+ this.log(LoggerLevel.info, `[object.create.recordsWithIterator] Chunk ${page} completed: ${object_name}, created=${res.data?.items?.length}`);
481
+ this.log(LoggerLevel.debug, `[object.create.recordsWithIterator] Chunk ${page} result: ${object_name}, code=${res.code}`);
482
+ this.log(LoggerLevel.trace, `[object.create.recordsWithIterator] Chunk ${page} data: ${JSON.stringify(res.data?.items)}`);
453
483
 
454
484
  return res;
455
485
  });
@@ -494,17 +524,23 @@ class Client {
494
524
  */
495
525
  records: async (params: { object_name: string; records: any[] }): Promise<any> => {
496
526
  const { object_name, records } = params;
497
- const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records/records_batch`;
527
+ const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
498
528
 
499
529
  this.log(LoggerLevel.info, `[object.update.records] Updating ${records.length} records`);
500
530
 
501
- const response = await this.axiosInstance.patch(url, { records }, { headers: { Authorization: `${this.accessToken}` } });
531
+ const response = await functionLimiter(async () => {
532
+ await this.ensureTokenValid();
533
+
534
+ const res = await this.axiosInstance.patch(url, { records }, { headers: { Authorization: `${this.accessToken}` } });
502
535
 
503
- this.log(LoggerLevel.info, `[object.update.records] Records updated: ${object_name}`);
504
- this.log(LoggerLevel.debug, `[object.update.records] Records updated: ${object_name}, code=${response.data.code}`);
505
- this.log(LoggerLevel.trace, `[object.update.records] Response: ${JSON.stringify(response.data)}`);
536
+ this.log(LoggerLevel.info, `[object.update.records] Records updated: ${object_name}`);
537
+ this.log(LoggerLevel.debug, `[object.update.records] Records updated: ${object_name}, code=${res.data.code}`);
538
+ this.log(LoggerLevel.trace, `[object.update.records] Response: ${JSON.stringify(res.data)}`);
506
539
 
507
- return response.data;
540
+ return res.data;
541
+ });
542
+
543
+ return response;
508
544
  },
509
545
 
510
546
  /**
@@ -515,6 +551,18 @@ class Client {
515
551
  */
516
552
  recordsWithIterator: async (params: { object_name: string; records: any[] }): Promise<any[]> => {
517
553
  const { object_name, records } = params;
554
+
555
+ // 参数校验
556
+ if (!records || !Array.isArray(records)) {
557
+ this.log(LoggerLevel.error, '[object.update.recordsWithIterator] Invalid records parameter: must be a non-empty array');
558
+ throw new Error('参数 records 必须是一个数组');
559
+ }
560
+
561
+ if (records.length === 0) {
562
+ this.log(LoggerLevel.warn, '[object.update.recordsWithIterator] Empty records array provided, returning empty result');
563
+ return [];
564
+ }
565
+
518
566
  const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
519
567
 
520
568
  const chunkSize = 100;
@@ -613,6 +661,18 @@ class Client {
613
661
  */
614
662
  recordsWithIterator: async (params: { object_name: string; ids: string[] }): Promise<any[]> => {
615
663
  const { object_name, ids } = params;
664
+
665
+ // 参数校验
666
+ if (!ids || !Array.isArray(ids)) {
667
+ this.log(LoggerLevel.error, '[object.delete.recordsWithIterator] Invalid ids parameter: must be a non-empty array');
668
+ throw new Error('参数 ids 必须是一个数组');
669
+ }
670
+
671
+ if (ids.length === 0) {
672
+ this.log(LoggerLevel.warn, '[object.delete.recordsWithIterator] Empty ids array provided, returning empty result');
673
+ return [];
674
+ }
675
+
616
676
  const url = `/v1/data/namespaces/${this.namespace}/objects/${object_name}/records_batch`;
617
677
 
618
678
  const chunkSize = 100;
@@ -684,7 +744,13 @@ class Client {
684
744
 
685
745
  this.log(LoggerLevel.debug, `[department.exchange] Department ID exchanged: ${department_id}, code=${response.data.code}`);
686
746
  this.log(LoggerLevel.trace, `[department.exchange] Response: ${JSON.stringify(response.data)}`);
687
- return response.data.data[0]; // 返回第一个元素
747
+
748
+ if (response.data.code !== '0') {
749
+ this.log(LoggerLevel.error, `[department.exchange] Error exchanging department: code=${response.data.code}, msg=${response.data.msg}`);
750
+ throw new Error(response.data.msg || `Exchange failed with code ${response.data.code}`);
751
+ }
752
+
753
+ return response.data.data && response.data.data[0]; // 返回第一个元素
688
754
  });
689
755
 
690
756
  return res;
@@ -702,6 +768,17 @@ class Client {
702
768
  // - 'external_department_id' (外部平台 department_id, 无固定格式)
703
769
  // - 'external_open_department_id' (以 'oc_' 开头的 open_department_id)
704
770
 
771
+ // 参数校验
772
+ if (!department_ids || !Array.isArray(department_ids)) {
773
+ this.log(LoggerLevel.error, '[department.batchExchange] Invalid department_ids parameter: must be a non-empty array');
774
+ throw new Error('参数 department_ids 必须是一个数组');
775
+ }
776
+
777
+ if (department_ids.length === 0) {
778
+ this.log(LoggerLevel.warn, '[department.batchExchange] Empty department_ids array provided, returning empty result');
779
+ return [];
780
+ }
781
+
705
782
  const url = '/api/integration/v2/feishu/getDepartments';
706
783
 
707
784
  const chunkSize = 100;
@@ -732,7 +809,13 @@ class Client {
732
809
 
733
810
  this.log(LoggerLevel.debug, `[department.batchExchange] Chunk ${index + 1} completed: code=${response.data.code}`);
734
811
  this.log(LoggerLevel.trace, `[department.batchExchange] Chunk ${index + 1} response: ${JSON.stringify(response.data)}`);
735
- return response.data.data;
812
+
813
+ if (response.data.code !== '0') {
814
+ this.log(LoggerLevel.error, `[department.batchExchange] Error exchanging departments: code=${response.data.code}, msg=${response.data.msg}`);
815
+ throw new Error(response.data.msg || `Exchange failed with code ${response.data.code}`);
816
+ }
817
+
818
+ return response.data.data || [];
736
819
  });
737
820
 
738
821
  results.push(...res);
@@ -829,6 +912,11 @@ class Client {
829
912
  const pageRes = await functionLimiter(async () => {
830
913
  const res = await this.page.list({ limit, offset });
831
914
 
915
+ if (res.code !== '0') {
916
+ this.log(LoggerLevel.error, `[page.listWithIterator] Error fetching pages: code=${res.code}, msg=${res.msg}`);
917
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
918
+ }
919
+
832
920
  page += 1;
833
921
 
834
922
  if (res.data && Array.isArray(res.data.items)) {
@@ -836,7 +924,7 @@ class Client {
836
924
  }
837
925
 
838
926
  if (page === 1) {
839
- total = res.data.total || 0;
927
+ total = res.data?.total || 0;
840
928
  totalPages = Math.ceil(total / limit);
841
929
  this.log(LoggerLevel.info, `[page.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
842
930
  }
@@ -848,7 +936,7 @@ class Client {
848
936
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
849
937
 
850
938
  this.log(LoggerLevel.info, `[page.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
851
- this.log(LoggerLevel.debug, `[page.listWithIterator] Page ${page} details: items=${res.data.items?.length}, offset=${offset}`);
939
+ this.log(LoggerLevel.debug, `[page.listWithIterator] Page ${page} details: items=${res.data?.items?.length}, offset=${offset}`);
852
940
  this.log(LoggerLevel.trace, `[page.listWithIterator] Page ${page} data: ${JSON.stringify(res.data?.items)}`);
853
941
 
854
942
  return res;
@@ -1154,6 +1242,11 @@ class Client {
1154
1242
 
1155
1243
  const res = await this.global.options.list(requestParams);
1156
1244
 
1245
+ if (res.code !== '0') {
1246
+ this.log(LoggerLevel.error, `[global.options.listWithIterator] Error fetching global options: code=${res.code}, msg=${res.msg}`);
1247
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
1248
+ }
1249
+
1157
1250
  page += 1;
1158
1251
 
1159
1252
  if (res.data && Array.isArray(res.data.items)) {
@@ -1161,7 +1254,7 @@ class Client {
1161
1254
  }
1162
1255
 
1163
1256
  if (page === 1) {
1164
- total = res.data.total || 0;
1257
+ total = res.data?.total || 0;
1165
1258
  totalPages = Math.ceil(total / limit);
1166
1259
  this.log(LoggerLevel.info, `[global.options.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
1167
1260
  }
@@ -1173,7 +1266,7 @@ class Client {
1173
1266
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
1174
1267
 
1175
1268
  this.log(LoggerLevel.info, `[global.options.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
1176
- this.log(LoggerLevel.debug, `[global.options.listWithIterator] Page ${page} details: items=${res.data.items?.length}, offset=${offset}`);
1269
+ this.log(LoggerLevel.debug, `[global.options.listWithIterator] Page ${page} details: items=${res.data?.items?.length}, offset=${offset}`);
1177
1270
  this.log(LoggerLevel.trace, `[global.options.listWithIterator] Page ${page} data: ${JSON.stringify(res.data?.items)}`);
1178
1271
 
1179
1272
  return res;
@@ -1268,6 +1361,11 @@ class Client {
1268
1361
 
1269
1362
  const res = await this.global.variables.list(requestParams);
1270
1363
 
1364
+ if (res.code !== '0') {
1365
+ this.log(LoggerLevel.error, `[global.variables.listWithIterator] Error fetching global variables: code=${res.code}, msg=${res.msg}`);
1366
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
1367
+ }
1368
+
1271
1369
  page += 1;
1272
1370
 
1273
1371
  if (res.data && Array.isArray(res.data.items)) {
@@ -1275,7 +1373,7 @@ class Client {
1275
1373
  }
1276
1374
 
1277
1375
  if (page === 1) {
1278
- total = res.data.total || 0;
1376
+ total = res.data?.total || 0;
1279
1377
  totalPages = Math.ceil(total / limit);
1280
1378
  this.log(LoggerLevel.info, `[global.variables.listWithIterator] Starting paginated query: total=${total}, pages=${totalPages}`);
1281
1379
  }
@@ -1287,7 +1385,7 @@ class Client {
1287
1385
  const totalPagesStr = totalPages.toString().padStart(padLength, '0');
1288
1386
 
1289
1387
  this.log(LoggerLevel.info, `[global.variables.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
1290
- this.log(LoggerLevel.debug, `[global.variables.listWithIterator] Page ${page} details: items=${res.data.items?.length}, offset=${offset}`);
1388
+ this.log(LoggerLevel.debug, `[global.variables.listWithIterator] Page ${page} details: items=${res.data?.items?.length}, offset=${offset}`);
1291
1389
  this.log(LoggerLevel.trace, `[global.variables.listWithIterator] Page ${page} data: ${JSON.stringify(res.data?.items)}`);
1292
1390
 
1293
1391
  return res;