apaas-oapi-client 0.1.31 → 0.1.33

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/dist/index.js CHANGED
@@ -119,11 +119,14 @@ class Client {
119
119
  this.object = {
120
120
  /**
121
121
  * 列出所有对象(数据表)
122
- * @param params 请求参数 { offset, filter?, limit }
123
- * @returns 接口返回结果
122
+ * @param params 请求参数 { offset?, filter?, limit? }
123
+ * @returns 接口返回结果,包含 has_more 字段表示是否还有更多数据
124
124
  */
125
125
  list: async (params) => {
126
- const { offset, filter, limit } = params;
126
+ var _a, _b;
127
+ const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
128
+ const limit = (_b = params === null || params === void 0 ? void 0 : params.limit) !== null && _b !== void 0 ? _b : 50;
129
+ const filter = params === null || params === void 0 ? void 0 : params.filter;
127
130
  await this.ensureTokenValid();
128
131
  const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/list`;
129
132
  this.log(LoggerLevel.debug, `[object.list] Fetching objects list: offset=${offset}, limit=${limit}`);
@@ -136,8 +139,66 @@ class Client {
136
139
  });
137
140
  this.log(LoggerLevel.debug, `[object.list] Objects list fetched successfully: code=${res.data.code}`);
138
141
  this.log(LoggerLevel.trace, `[object.list] Response: ${JSON.stringify(res.data)}`);
142
+ // 添加 has_more 字段判断是否还有更多数据
143
+ if (res.data && res.data.data) {
144
+ const total = res.data.data.total || 0;
145
+ const currentEnd = offset + limit;
146
+ res.data.has_more = currentEnd < total;
147
+ this.log(LoggerLevel.debug, `[object.list] has_more=${res.data.has_more}, total=${total}, currentEnd=${currentEnd}`);
148
+ }
139
149
  return res.data;
140
150
  },
151
+ /**
152
+ * 列出所有对象(数据表)- 支持自动分页查询
153
+ * @description 该方法会自动处理分页,直到没有更多数据为止
154
+ * @param params 请求参数 { filter?, limit? }
155
+ * @returns { total, items }
156
+ */
157
+ listWithIterator: async (params) => {
158
+ var _a, _b, _c, _d;
159
+ const filter = params === null || params === void 0 ? void 0 : params.filter;
160
+ const limit = (_a = params === null || params === void 0 ? void 0 : params.limit) !== null && _a !== void 0 ? _a : 50;
161
+ let results = [];
162
+ let offset = 0;
163
+ let total = 0;
164
+ let hasMore = true;
165
+ let page = 0;
166
+ let totalPages = 0;
167
+ this.log(LoggerLevel.info, `[object.listWithIterator] Starting paginated query with limit=${limit}`);
168
+ while (hasMore) {
169
+ const res = await this.object.list({
170
+ offset,
171
+ limit,
172
+ filter
173
+ });
174
+ if (res.code !== '0') {
175
+ this.log(LoggerLevel.error, `[object.listWithIterator] Error querying objects: code=${res.code}, msg=${res.msg}`);
176
+ throw new Error(res.msg || `Query failed with code ${res.code}`);
177
+ }
178
+ page += 1;
179
+ if (res.data && Array.isArray(res.data.items)) {
180
+ results = results.concat(res.data.items);
181
+ }
182
+ if (res.data && (res.data.total !== undefined && res.data.total !== null)) {
183
+ total = res.data.total;
184
+ }
185
+ if (page === 1) {
186
+ totalPages = Math.ceil(total / limit);
187
+ this.log(LoggerLevel.info, `[object.listWithIterator] Total objects: ${total}, pages: ${totalPages}`);
188
+ }
189
+ // 判断是否还有更多数据
190
+ hasMore = res.has_more === true;
191
+ offset += limit;
192
+ const padLength = totalPages.toString().length;
193
+ const pageStr = page.toString().padStart(padLength, '0');
194
+ const totalPagesStr = totalPages.toString().padStart(padLength, '0');
195
+ this.log(LoggerLevel.info, `[object.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
196
+ this.log(LoggerLevel.debug, `[object.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}, hasMore=${hasMore}`);
197
+ this.log(LoggerLevel.trace, `[object.listWithIterator] Page ${page} data: ${JSON.stringify((_d = res.data) === null || _d === void 0 ? void 0 : _d.items)}`);
198
+ }
199
+ this.log(LoggerLevel.info, `[object.listWithIterator] Completed: total=${total}, fetched=${results.length}`);
200
+ return { total, items: results };
201
+ },
141
202
  metadata: {
142
203
  /**
143
204
  * 获取指定对象下指定字段的元数据
@@ -272,6 +333,45 @@ class Client {
272
333
  });
273
334
  }
274
335
  return { total, items: results };
336
+ },
337
+ /**
338
+ * 统计记录数量
339
+ * @description 统计指定对象中的记录总数,支持按条件统计
340
+ * @param params 请求参数 { object_name, data? }
341
+ * @returns 接口返回结果 { code, total, msg }
342
+ */
343
+ count: async (params) => {
344
+ var _a;
345
+ const { object_name, data } = params;
346
+ // 默认查询参数:最小化数据传输,只获取总数
347
+ const defaultData = {
348
+ offset: 0,
349
+ page_size: 1,
350
+ need_total_count: true,
351
+ use_page_token: true,
352
+ select: ['_id'],
353
+ query_deleted_record: false
354
+ };
355
+ // 合并用户传入的参数(用户参数优先)
356
+ const queryData = data ? { ...defaultData, ...data } : defaultData;
357
+ this.log(LoggerLevel.info, `[object.search.count] Counting records in: ${object_name}`);
358
+ this.log(LoggerLevel.debug, `[object.search.count] Query data: ${JSON.stringify(queryData)}`);
359
+ const res = await this.object.search.records({
360
+ object_name,
361
+ data: queryData
362
+ });
363
+ if (res.code !== '0') {
364
+ this.log(LoggerLevel.error, `[object.search.count] Error counting records: code=${res.code}, msg=${res.msg}`);
365
+ throw new Error(res.msg || `Count failed with code ${res.code}`);
366
+ }
367
+ const total = ((_a = res.data) === null || _a === void 0 ? void 0 : _a.total) || 0;
368
+ this.log(LoggerLevel.info, `[object.search.count] Total records in ${object_name}: ${total}`);
369
+ // 返回格式:{ code, total, msg }
370
+ return {
371
+ code: res.code,
372
+ total: total,
373
+ msg: res.msg
374
+ };
275
375
  }
276
376
  },
277
377
  create: {
@@ -102,17 +102,33 @@ declare class Client {
102
102
  object: {
103
103
  /**
104
104
  * 列出所有对象(数据表)
105
- * @param params 请求参数 { offset, filter?, limit }
106
- * @returns 接口返回结果
105
+ * @param params 请求参数 { offset?, filter?, limit? }
106
+ * @returns 接口返回结果,包含 has_more 字段表示是否还有更多数据
107
107
  */
108
- list: (params: {
109
- offset: number;
108
+ list: (params?: {
109
+ offset?: number;
110
110
  filter?: {
111
111
  type?: string;
112
112
  quickQuery?: string;
113
113
  };
114
- limit: number;
114
+ limit?: number;
115
115
  }) => Promise<any>;
116
+ /**
117
+ * 列出所有对象(数据表)- 支持自动分页查询
118
+ * @description 该方法会自动处理分页,直到没有更多数据为止
119
+ * @param params 请求参数 { filter?, limit? }
120
+ * @returns { total, items }
121
+ */
122
+ listWithIterator: (params?: {
123
+ filter?: {
124
+ type?: string;
125
+ quickQuery?: string;
126
+ };
127
+ limit?: number;
128
+ }) => Promise<{
129
+ total: number;
130
+ items: any[];
131
+ }>;
116
132
  metadata: {
117
133
  /**
118
134
  * 获取指定对象下指定字段的元数据
@@ -169,6 +185,16 @@ declare class Client {
169
185
  total: number;
170
186
  items: any[];
171
187
  }>;
188
+ /**
189
+ * 统计记录数量
190
+ * @description 统计指定对象中的记录总数,支持按条件统计
191
+ * @param params 请求参数 { object_name, data? }
192
+ * @returns 接口返回结果 { code, total, msg }
193
+ */
194
+ count: (params: {
195
+ object_name: string;
196
+ data?: any;
197
+ }) => Promise<any>;
172
198
  };
173
199
  create: {
174
200
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apaas-oapi-client",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "main": "dist/index.js",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
package/src/index.ts CHANGED
@@ -290,11 +290,13 @@ class Client {
290
290
  public object = {
291
291
  /**
292
292
  * 列出所有对象(数据表)
293
- * @param params 请求参数 { offset, filter?, limit }
294
- * @returns 接口返回结果
293
+ * @param params 请求参数 { offset?, filter?, limit? }
294
+ * @returns 接口返回结果,包含 has_more 字段表示是否还有更多数据
295
295
  */
296
- list: async (params: { offset: number; filter?: { type?: string; quickQuery?: string }; limit: number }): Promise<any> => {
297
- const { offset, filter, limit } = params;
296
+ list: async (params?: { offset?: number; filter?: { type?: string; quickQuery?: string }; limit?: number }): Promise<any> => {
297
+ const offset = params?.offset ?? 0;
298
+ const limit = params?.limit ?? 50;
299
+ const filter = params?.filter;
298
300
  await this.ensureTokenValid();
299
301
  const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/list`;
300
302
 
@@ -311,9 +313,81 @@ class Client {
311
313
 
312
314
  this.log(LoggerLevel.debug, `[object.list] Objects list fetched successfully: code=${res.data.code}`);
313
315
  this.log(LoggerLevel.trace, `[object.list] Response: ${JSON.stringify(res.data)}`);
316
+
317
+ // 添加 has_more 字段判断是否还有更多数据
318
+ if (res.data && res.data.data) {
319
+ const total = res.data.data.total || 0;
320
+ const currentEnd = offset + limit;
321
+ res.data.has_more = currentEnd < total;
322
+ this.log(LoggerLevel.debug, `[object.list] has_more=${res.data.has_more}, total=${total}, currentEnd=${currentEnd}`);
323
+ }
324
+
314
325
  return res.data;
315
326
  },
316
327
 
328
+ /**
329
+ * 列出所有对象(数据表)- 支持自动分页查询
330
+ * @description 该方法会自动处理分页,直到没有更多数据为止
331
+ * @param params 请求参数 { filter?, limit? }
332
+ * @returns { total, items }
333
+ */
334
+ listWithIterator: async (params?: { filter?: { type?: string; quickQuery?: string }; limit?: number }): Promise<{ total: number; items: any[] }> => {
335
+ const filter = params?.filter;
336
+ const limit = params?.limit ?? 50;
337
+
338
+ let results: any[] = [];
339
+ let offset = 0;
340
+ let total = 0;
341
+ let hasMore = true;
342
+ let page = 0;
343
+ let totalPages = 0;
344
+
345
+ this.log(LoggerLevel.info, `[object.listWithIterator] Starting paginated query with limit=${limit}`);
346
+
347
+ while (hasMore) {
348
+ const res = await this.object.list({
349
+ offset,
350
+ limit,
351
+ filter
352
+ });
353
+
354
+ if (res.code !== '0') {
355
+ this.log(LoggerLevel.error, `[object.listWithIterator] Error querying objects: code=${res.code}, msg=${res.msg}`);
356
+ throw new Error(res.msg || `Query failed with code ${res.code}`);
357
+ }
358
+
359
+ page += 1;
360
+
361
+ if (res.data && Array.isArray(res.data.items)) {
362
+ results = results.concat(res.data.items);
363
+ }
364
+
365
+ if (res.data && (res.data.total !== undefined && res.data.total !== null)) {
366
+ total = res.data.total;
367
+ }
368
+
369
+ if (page === 1) {
370
+ totalPages = Math.ceil(total / limit);
371
+ this.log(LoggerLevel.info, `[object.listWithIterator] Total objects: ${total}, pages: ${totalPages}`);
372
+ }
373
+
374
+ // 判断是否还有更多数据
375
+ hasMore = res.has_more === true;
376
+ offset += limit;
377
+
378
+ const padLength = totalPages.toString().length;
379
+ const pageStr = page.toString().padStart(padLength, '0');
380
+ const totalPagesStr = totalPages.toString().padStart(padLength, '0');
381
+
382
+ this.log(LoggerLevel.info, `[object.listWithIterator] Page completed: [${pageStr}/${totalPagesStr}]`);
383
+ this.log(LoggerLevel.debug, `[object.listWithIterator] Page ${page} details: items=${res.data?.items?.length}, hasMore=${hasMore}`);
384
+ this.log(LoggerLevel.trace, `[object.listWithIterator] Page ${page} data: ${JSON.stringify(res.data?.items)}`);
385
+ }
386
+
387
+ this.log(LoggerLevel.info, `[object.listWithIterator] Completed: total=${total}, fetched=${results.length}`);
388
+ return { total, items: results };
389
+ },
390
+
317
391
  metadata: {
318
392
  /**
319
393
  * 获取指定对象下指定字段的元数据
@@ -479,6 +553,52 @@ class Client {
479
553
  }
480
554
 
481
555
  return { total, items: results };
556
+ },
557
+
558
+ /**
559
+ * 统计记录数量
560
+ * @description 统计指定对象中的记录总数,支持按条件统计
561
+ * @param params 请求参数 { object_name, data? }
562
+ * @returns 接口返回结果 { code, total, msg }
563
+ */
564
+ count: async (params: { object_name: string; data?: any }): Promise<any> => {
565
+ const { object_name, data } = params;
566
+
567
+ // 默认查询参数:最小化数据传输,只获取总数
568
+ const defaultData = {
569
+ offset: 0,
570
+ page_size: 1,
571
+ need_total_count: true,
572
+ use_page_token: true,
573
+ select: ['_id'],
574
+ query_deleted_record: false
575
+ };
576
+
577
+ // 合并用户传入的参数(用户参数优先)
578
+ const queryData = data ? { ...defaultData, ...data } : defaultData;
579
+
580
+ this.log(LoggerLevel.info, `[object.search.count] Counting records in: ${object_name}`);
581
+ this.log(LoggerLevel.debug, `[object.search.count] Query data: ${JSON.stringify(queryData)}`);
582
+
583
+ const res = await this.object.search.records({
584
+ object_name,
585
+ data: queryData
586
+ });
587
+
588
+ if (res.code !== '0') {
589
+ this.log(LoggerLevel.error, `[object.search.count] Error counting records: code=${res.code}, msg=${res.msg}`);
590
+ throw new Error(res.msg || `Count failed with code ${res.code}`);
591
+ }
592
+
593
+ const total = res.data?.total || 0;
594
+ this.log(LoggerLevel.info, `[object.search.count] Total records in ${object_name}: ${total}`);
595
+
596
+ // 返回格式:{ code, total, msg }
597
+ return {
598
+ code: res.code,
599
+ total: total,
600
+ msg: res.msg
601
+ };
482
602
  }
483
603
  },
484
604