apaas-oapi-client 0.1.36 → 0.1.38

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
@@ -43,6 +43,698 @@ async function functionLimiter(fn, options = {}) {
43
43
  return wrapped();
44
44
  }
45
45
 
46
+ /**
47
+ * aPaaS 数据对象 Schema 管理完整规范
48
+ *
49
+ * 本文档包含:
50
+ * 1. Schema 接口规范(创建、更新对象)
51
+ * 2. 字段类型完整定义(20+ 字段类型)
52
+ * 3. 系统字段说明(6 个自动创建字段)
53
+ * 4. 最佳实践和注意事项
54
+ */
55
+ /**
56
+ * Schema 接口最佳实践和限制说明
57
+ */
58
+ const SCHEMA_GUIDELINES = {
59
+ /** 批量操作限制 */
60
+ limits: {
61
+ batch_size: 10, // 单次请求最多 10 个对象
62
+ },
63
+ /** 系统字段说明 */
64
+ system_fields: {
65
+ description: '系统字段会自动创建,不需要在 fields 数组中定义',
66
+ fields: ['_id', '_name', '_createdBy', '_createdAt', '_updatedBy', '_updatedAt'],
67
+ },
68
+ /** display_name 限制 */
69
+ display_name: {
70
+ restriction: '不能使用 _name 作为 display_name',
71
+ reason: '系统会误认为是包含 NOW/TODAY 函数的公式',
72
+ solution: '使用自定义字段(如 code、name 等)',
73
+ example: 'display_name: "code"',
74
+ },
75
+ /** allow_search_fields 限制 */
76
+ allow_search_fields: {
77
+ restriction: '不能包含 _name 字段',
78
+ reason: '系统不允许在可搜索字段中使用包含公式的字段',
79
+ solution: '只包含 _id 和其他自定义字段',
80
+ example: 'allow_search_fields: ["_id", "code", "name"]',
81
+ },
82
+ /** encrypt_type 说明 */
83
+ encrypt_type: {
84
+ required: true,
85
+ description: '建议每个字段都显式指定 encrypt_type',
86
+ options: {
87
+ none: '不加密(默认)',
88
+ rand: '非确定性加密',
89
+ fix: '固定加密',
90
+ ope: '保序加密',
91
+ },
92
+ },
93
+ /** operator 说明(用于 update) */
94
+ operator: {
95
+ required: true,
96
+ description: '更新字段时必须指定操作类型',
97
+ options: {
98
+ add: { description: '添加新字段', required_fields: ['api_name', 'label', 'type'] },
99
+ replace: { description: '修改现有字段', required_fields: ['api_name'], note: '只传需要修改的属性' },
100
+ remove: { description: '删除字段', required_fields: ['api_name'], note: '只需要 api_name' },
101
+ },
102
+ },
103
+ /** 关联字段说明 */
104
+ reference_fields: {
105
+ description: '关联字段用于在对象之间建立关联关系',
106
+ types: {
107
+ lookup: {
108
+ description: '关联对象(单值)- 关联另一个对象的单条记录',
109
+ settings: {
110
+ objectAPIName: '目标对象的 API 名称(必填)',
111
+ required: '是否必填(可选)',
112
+ displayStyle: '显示样式(可选)'
113
+ },
114
+ example: 'type: { name: "lookup", settings: { objectAPIName: "supplier" } }',
115
+ write_format: '写入时只需要 _id:{ supplier: { _id: 123456 } }'
116
+ },
117
+ lookup_multi: {
118
+ description: '关联对象(多值)- 关联另一个对象的多条记录',
119
+ settings: {
120
+ objectAPIName: '目标对象的 API 名称(必填)',
121
+ multiple: 'true(多选)'
122
+ },
123
+ limit: '最多可以关联 200 条记录',
124
+ example: 'type: { name: "lookup_multi", settings: { objectAPIName: "category", multiple: true } }',
125
+ write_format: '写入时提供多个 _id:{ categories: [{ _id: 111 }, { _id: 222 }] }'
126
+ },
127
+ referenceField: {
128
+ description: '引用字段 - 引用关联对象中的字段值(系统自动维护,不可直接写入)',
129
+ settings: {
130
+ guideFieldAPIName: '引导字段(lookup 字段)',
131
+ fieldAPIName: '引用的目标字段',
132
+ referenceObjectApiName: '引用的对象'
133
+ },
134
+ example: 'type: { name: "referenceField", settings: { guideFieldAPIName: "supplier", fieldAPIName: "name", referenceObjectApiName: "supplier" } }',
135
+ note: '系统根据 lookup 字段自动计算,不能直接写入数据'
136
+ },
137
+ rollup: {
138
+ description: '汇总字段 - 对关联对象的数据进行聚合计算(系统自动维护,不可直接写入)',
139
+ settings: {
140
+ objectAPIName: '被汇总的对象',
141
+ lookupFieldAPIName: '关联字段(当前对象中的 lookup 字段)',
142
+ fieldAPIName: '要汇总的字段',
143
+ functionType: '汇总函数:sum/avg/count/max/min/countDistinct',
144
+ rangeFilter: '过滤条件(可选)'
145
+ },
146
+ example: 'type: { name: "rollup", settings: { objectAPIName: "order_item", lookupFieldAPIName: "order", fieldAPIName: "amount", functionType: "sum" } }',
147
+ note: '系统根据关联数据自动汇总,不能直接写入数据'
148
+ }
149
+ },
150
+ prerequisites: {
151
+ description: '创建关联字段的前置条件',
152
+ rules: [
153
+ '目标对象必须已存在',
154
+ 'objectAPIName 必须准确(区分大小写)',
155
+ 'referenceField 和 rollup 依赖的 lookup 字段必须先创建',
156
+ '删除 lookup 字段前,需要先删除依赖它的 referenceField 和 rollup 字段'
157
+ ]
158
+ },
159
+ system_maintained: {
160
+ description: '系统自动维护的字段不能直接写入数据',
161
+ fields: ['referenceField', 'rollup', 'formula'],
162
+ reason: '这些字段的值由系统根据其他字段或公式自动计算'
163
+ }
164
+ },
165
+ /** 响应结构说明 */
166
+ response: {
167
+ structure: '双层响应结构',
168
+ top_level: {
169
+ code: '0 表示请求格式正确',
170
+ msg: 'success',
171
+ data: '包含 items 数组',
172
+ },
173
+ item_level: {
174
+ description: '每个对象的实际创建/更新状态',
175
+ location: 'data.items[].status',
176
+ check: '需要检查 status.code 判断是否真正成功',
177
+ },
178
+ },
179
+ };
180
+ /**
181
+ * 创建对象示例
182
+ */
183
+ const CREATE_OBJECT_EXAMPLE = {
184
+ api_name: 'product',
185
+ label: {
186
+ zh_cn: '产品',
187
+ en_us: 'Product',
188
+ },
189
+ settings: {
190
+ display_name: 'code', // ✅ 使用自定义字段
191
+ allow_search_fields: ['_id', 'code', 'name'], // ✅ 不包含 _name
192
+ search_layout: ['code', 'name'],
193
+ },
194
+ fields: [
195
+ {
196
+ api_name: 'code',
197
+ label: { zh_cn: '产品编号', en_us: 'Product Code' },
198
+ type: {
199
+ name: 'text',
200
+ settings: {
201
+ required: true,
202
+ unique: true,
203
+ case_sensitive: false,
204
+ multiline: false,
205
+ max_length: 50,
206
+ },
207
+ },
208
+ encrypt_type: 'none', // ✅ 显式指定
209
+ },
210
+ {
211
+ api_name: 'name',
212
+ label: { zh_cn: '产品名称', en_us: 'Product Name' },
213
+ type: {
214
+ name: 'text',
215
+ settings: {
216
+ required: true,
217
+ unique: false,
218
+ case_sensitive: false,
219
+ multiline: false,
220
+ max_length: 200,
221
+ },
222
+ },
223
+ encrypt_type: 'none',
224
+ },
225
+ {
226
+ api_name: 'price',
227
+ label: { zh_cn: '价格', en_us: 'Price' },
228
+ type: {
229
+ name: 'decimal',
230
+ settings: {
231
+ required: true,
232
+ unique: false,
233
+ display_as_percentage: false,
234
+ decimal_places: 2,
235
+ },
236
+ },
237
+ encrypt_type: 'none',
238
+ },
239
+ ],
240
+ };
241
+ /**
242
+ * 更新对象示例(添加字段)
243
+ */
244
+ const UPDATE_OBJECT_ADD_FIELD_EXAMPLE = {
245
+ api_name: 'product',
246
+ fields: [
247
+ {
248
+ operator: 'add', // 添加新字段
249
+ api_name: 'description',
250
+ label: { zh_cn: '产品描述', en_us: 'Description' },
251
+ type: {
252
+ name: 'text',
253
+ settings: {
254
+ required: false,
255
+ unique: false,
256
+ case_sensitive: false,
257
+ multiline: true,
258
+ max_length: 1000,
259
+ },
260
+ },
261
+ encrypt_type: 'none',
262
+ },
263
+ ],
264
+ };
265
+ /**
266
+ * 更新对象示例(修改字段)
267
+ */
268
+ const UPDATE_OBJECT_REPLACE_FIELD_EXAMPLE = {
269
+ api_name: 'product',
270
+ fields: [
271
+ {
272
+ operator: 'replace', // 修改现有字段
273
+ api_name: 'price',
274
+ label: { zh_cn: '销售价格', en_us: 'Sale Price' }, // 修改标签
275
+ // 可以只传需要修改的属性
276
+ },
277
+ ],
278
+ };
279
+ /**
280
+ * 更新对象示例(删除字段)
281
+ */
282
+ const UPDATE_OBJECT_REMOVE_FIELD_EXAMPLE = {
283
+ api_name: 'product',
284
+ fields: [
285
+ {
286
+ operator: 'remove', // 删除字段
287
+ api_name: 'description', // 只需要 api_name
288
+ },
289
+ ],
290
+ };
291
+ /**
292
+ * 更新对象示例(只修改标签和设置)
293
+ */
294
+ const UPDATE_OBJECT_SETTINGS_EXAMPLE = {
295
+ api_name: 'product',
296
+ label: {
297
+ zh_cn: '产品信息', // 修改标签
298
+ en_us: 'Product Information',
299
+ },
300
+ settings: {
301
+ display_name: 'name', // 修改展示名称字段
302
+ allow_search_fields: ['_id', 'code', 'name', 'description'],
303
+ search_layout: ['code', 'name', 'description'],
304
+ },
305
+ // 不传 fields,表示不修改字段
306
+ };
307
+ /**
308
+ * aPaaS 平台所有字段类型定义
309
+ */
310
+ const FIELD_TYPES = {
311
+ // ==================== 系统默认字段(6个,不可修改)====================
312
+ _id: {
313
+ api_name: '_id',
314
+ label: 'ID',
315
+ storage_type: 'Number',
316
+ is_system: true,
317
+ description: '系统默认字段,数据的关键 ID,唯一键,可被其他对象引用为外键',
318
+ example: 1766662402370564,
319
+ notes: '16位数字,注意该 ID 并不会随着记录的增多而递增生成'
320
+ },
321
+ _name: {
322
+ api_name: '_name',
323
+ label: '展示名称',
324
+ storage_type: 'Array',
325
+ is_system: true,
326
+ description: '系统默认字段,记录的展示名称',
327
+ example: [
328
+ {
329
+ language_code: 2052,
330
+ text: '1766662402370564'
331
+ }
332
+ ],
333
+ notes: '以多语本形式存储,language_code: 2052=中文, 1033=英文'
334
+ },
335
+ _createdBy: {
336
+ api_name: '_createdBy',
337
+ label: '创建人',
338
+ storage_type: 'Object',
339
+ is_system: true,
340
+ description: '系统默认字段,记录创建人信息',
341
+ example: {
342
+ _id: 1766661610377271,
343
+ _name: [
344
+ { language_code: 1033, text: 'San Zhang' },
345
+ { language_code: 2052, text: '张三' }
346
+ ],
347
+ avatar: {
348
+ color: null,
349
+ color_id: '',
350
+ content: null,
351
+ image: {
352
+ large: 'https://s1-imfile.feishucdn.com/static-resource/v1/52a9a370-1967-42b2-9c30-730fed90d81g~?image_size=noop&cut_type=&quality=&format=png&sticker_format=.webp'
353
+ },
354
+ source: 'image'
355
+ },
356
+ i18n_name: [
357
+ { language_code: 1033, text: 'San Zhang' },
358
+ { language_code: 2052, text: '张三' }
359
+ ],
360
+ id: 1766661610377271,
361
+ is_deleted: false,
362
+ name: '张三'
363
+ },
364
+ notes: '以关联对象的形式存储,关联系统的用户对象。包含 _id、_name(多语数组)、id、name(中文字符串)、avatar 头像信息'
365
+ },
366
+ _createdAt: {
367
+ api_name: '_createdAt',
368
+ label: '创建时间',
369
+ storage_type: 'Number',
370
+ is_system: true,
371
+ description: '系统默认字段,记录创建时间',
372
+ example: 1684823950061,
373
+ notes: '属于日期时间字段,以 13 位毫秒时间戳存储'
374
+ },
375
+ _updatedBy: {
376
+ api_name: '_updatedBy',
377
+ label: '更新人',
378
+ storage_type: 'Object',
379
+ is_system: true,
380
+ description: '系统默认字段,记录最后更新人信息',
381
+ example: {
382
+ _id: 1766661610377271,
383
+ _name: [
384
+ { language_code: 1033, text: 'San Zhang' },
385
+ { language_code: 2052, text: '张三' }
386
+ ],
387
+ avatar: {
388
+ color: null,
389
+ color_id: '',
390
+ content: null,
391
+ image: {
392
+ large: 'https://s1-imfile.feishucdn.com/static-resource/v1/52a9a370-1967-42b2-9c30-730fed90d81g~?image_size=noop&cut_type=&quality=&format=png&sticker_format=.webp'
393
+ },
394
+ source: 'image'
395
+ },
396
+ i18n_name: [
397
+ { language_code: 1033, text: 'San Zhang' },
398
+ { language_code: 2052, text: '张三' }
399
+ ],
400
+ id: 1766661610377271,
401
+ is_deleted: false,
402
+ name: '张三'
403
+ },
404
+ notes: '以关联对象的形式存储,关联系统的用户对象'
405
+ },
406
+ _updatedAt: {
407
+ api_name: '_updatedAt',
408
+ label: '更新时间',
409
+ storage_type: 'Number',
410
+ is_system: true,
411
+ description: '系统默认字段,记录最后更新时间',
412
+ example: 1688610057236,
413
+ notes: '属于日期时间字段,以 13 位毫秒时间戳存储'
414
+ },
415
+ // ==================== 基础字段类型 ====================
416
+ text: {
417
+ api_name: 'text',
418
+ label: '文本',
419
+ storage_type: 'String',
420
+ is_system: false,
421
+ description: '单行文本字段',
422
+ example: '文本'
423
+ },
424
+ bigint: {
425
+ api_name: 'bigint',
426
+ label: '整数',
427
+ storage_type: 'String',
428
+ is_system: false,
429
+ description: '整数字段',
430
+ example: '10',
431
+ notes: '存储为字符串格式'
432
+ },
433
+ number: {
434
+ api_name: 'number',
435
+ label: '浮点数',
436
+ storage_type: 'Number',
437
+ is_system: false,
438
+ description: '数字字段,可带小数点',
439
+ example: 99.991
440
+ },
441
+ date: {
442
+ api_name: 'date',
443
+ label: '日期',
444
+ storage_type: 'String',
445
+ is_system: false,
446
+ description: '日期字段',
447
+ example: '2023-05-10',
448
+ notes: '格式固定为 "YYYY-MM-DD",读取和写入都需要按照此格式'
449
+ },
450
+ datetime: {
451
+ api_name: 'datetime',
452
+ label: '日期时间',
453
+ storage_type: 'Number',
454
+ is_system: false,
455
+ description: '日期时间字段',
456
+ example: 1683698580000,
457
+ notes: '以 13 位毫秒时间戳存储'
458
+ },
459
+ phone: {
460
+ api_name: 'phone',
461
+ label: '手机号码',
462
+ storage_type: 'Object',
463
+ is_system: false,
464
+ description: '手机号码字段',
465
+ example: {
466
+ code: '+86',
467
+ key: '+86(CN)',
468
+ number: '17624863925'
469
+ },
470
+ notes: '包含国家/地区 code 和手机号'
471
+ },
472
+ email: {
473
+ api_name: 'email',
474
+ label: '邮箱',
475
+ storage_type: 'String',
476
+ is_system: false,
477
+ description: '邮箱字段',
478
+ example: 'zhaoyizhe@bytedance.com'
479
+ },
480
+ option: {
481
+ api_name: 'option',
482
+ label: '选项',
483
+ storage_type: 'String',
484
+ is_system: false,
485
+ description: '单选字段',
486
+ example: 'enable',
487
+ notes: '字符串内的内容为选项的 API 名称。可通过 context.metadata.object("objectApiName").getField("optionApiName") 获取选项的元数据信息'
488
+ },
489
+ boolean: {
490
+ api_name: 'boolean',
491
+ label: '布尔',
492
+ storage_type: 'Boolean',
493
+ is_system: false,
494
+ description: '布尔值字段',
495
+ example: true
496
+ },
497
+ avatar: {
498
+ api_name: 'avatar',
499
+ label: '头像/标识',
500
+ storage_type: 'Object',
501
+ is_system: false,
502
+ description: '头像或标识字段',
503
+ example: {
504
+ color: null,
505
+ color_id: '',
506
+ content: null,
507
+ image: {
508
+ large: 'https://s1-imfile.feishucdn.com/static-resource/v1/52a9a370-1967-42b2-9c30-730fed90d81g~?image_size=noop&cut_type=&quality=&format=png&sticker_format=.webp'
509
+ },
510
+ source: 'image'
511
+ }
512
+ },
513
+ multilingual: {
514
+ api_name: 'multilingual',
515
+ label: '多语文本',
516
+ storage_type: 'Array',
517
+ is_system: false,
518
+ description: '多语言文本字段',
519
+ example: [
520
+ {
521
+ language_code: 1033,
522
+ text: 'Multilingual-English'
523
+ },
524
+ {
525
+ language_code: 2052,
526
+ text: '多语言-中文'
527
+ }
528
+ ],
529
+ notes: '包含两个对象,中文文本的 language_code 为 2052,英文文本的 language_code 为 1033'
530
+ },
531
+ richText: {
532
+ api_name: 'richText',
533
+ label: '富文本',
534
+ storage_type: 'Object',
535
+ is_system: false,
536
+ description: '富文本字段',
537
+ example: {
538
+ config: [
539
+ {
540
+ resourceId: 'BIZ_74da2122261247e6bda16834222c8f74',
541
+ resourceType: 'img',
542
+ token: '022a7279add24dcca7c5e2ae62afcc5c'
543
+ }
544
+ ],
545
+ preview: '',
546
+ raw: '<div style="white-space: pre;"><span style="color: rgb(245, 74, 69);">红色文本</span>\n</div><div style="white-space: pre;"><span style="text-decoration: underline;"><i><span style="font-weight: bold;">加粗文本</span></i></span>\n</div><div style="white-space: pre;">下面是图片\n</div><div style="white-space: pre;"><img src="/ui/attachment?token=f02efe6d990846eba6d2b6aafe053a6c&amp;preview=true&amp;imgId=BIZ_74da2122261247e6bda16834222c8f74" alt="20230523-143736.jpeg">\n</div>'
547
+ },
548
+ notes: '包含了文件的 token 信息和原始的 html 信息'
549
+ },
550
+ attachment: {
551
+ api_name: 'attachment',
552
+ label: '文件',
553
+ storage_type: 'Array',
554
+ is_system: false,
555
+ description: '文件附件字段',
556
+ example: [
557
+ {
558
+ id: 'BIZ_b38406e0f3a048c2a245ffeb9a14e42a',
559
+ mime_type: 'mp4',
560
+ name: 'test.mp4',
561
+ size: 14216083,
562
+ token: '6a4cb16d29bb43f5bed9735b8c980793'
563
+ }
564
+ ],
565
+ notes: '注意文件的存储只能是数组的形式,即使是设置了最多可上传数量为1,仍然为数组。下载文件:域名前缀 + /ae/api/v1/assets/attachment/download?token=token'
566
+ },
567
+ autoid: {
568
+ api_name: 'autoid',
569
+ label: '自动编号',
570
+ storage_type: 'String',
571
+ is_system: false,
572
+ description: '自动编号字段',
573
+ example: '5'
574
+ },
575
+ decimal: {
576
+ api_name: 'decimal',
577
+ label: '定点数',
578
+ storage_type: 'String',
579
+ is_system: false,
580
+ description: '定点数字段,高精度数字',
581
+ example: '123456789.987654321',
582
+ notes: '存储为字符串格式,保证精度'
583
+ },
584
+ // ==================== 高级字段类型 ====================
585
+ formula: {
586
+ api_name: 'formula',
587
+ label: '公式',
588
+ storage_type: 'String',
589
+ is_system: false,
590
+ description: '公式字段',
591
+ example: '文本',
592
+ notes: '公式字段的返回值取决于选择的返回类型,各个类型的存储请参考文档其他部分'
593
+ },
594
+ rollup: {
595
+ api_name: 'rollup',
596
+ label: '汇总',
597
+ storage_type: 'Number',
598
+ is_system: false,
599
+ description: '汇总字段',
600
+ example: 0,
601
+ notes: '可带有小数点'
602
+ },
603
+ lookup: {
604
+ api_name: 'lookup',
605
+ label: '关联对象',
606
+ storage_type: 'Object',
607
+ is_system: false,
608
+ description: '关联对象字段(单值)',
609
+ example: {
610
+ _id: 1767211281913907,
611
+ _name: '关联其他表的一条记录',
612
+ id: 1767211281913907,
613
+ is_deleted: false,
614
+ name: '关联其他表的一条记录'
615
+ },
616
+ notes: '与关联的用户对象一致,包含 _id 和 _name 之外,也包含了 id 和 name。此处的 _name 并不是多语文本,因为在这个数据对象下的展示名称就为普通文本。向关联对象字段写入数据时,仅写入 _id 属性即可,示例:lookup: { _id: 1767211281913907 }'
617
+ },
618
+ lookup_multi: {
619
+ api_name: 'lookup_multi',
620
+ label: '关联对象-多值',
621
+ storage_type: 'Array',
622
+ is_system: false,
623
+ description: '关联对象字段(多值)',
624
+ example: [
625
+ {
626
+ _id: 1767211281913907,
627
+ _name: '关联其他表的一条记录',
628
+ id: 1767211281913907,
629
+ is_deleted: false,
630
+ name: '关联其他表的一条记录'
631
+ },
632
+ {
633
+ _id: 1767211039388715,
634
+ _name: '关联其他表的另一条记录',
635
+ id: 1767211039388715,
636
+ is_deleted: false,
637
+ name: '关联其他表的另一条记录'
638
+ }
639
+ ],
640
+ notes: '数组里的内容和单条的关联对象字段一致。注意对于多条记录的关联对象,最多可以关联 200 条'
641
+ },
642
+ referenceField: {
643
+ api_name: 'referenceField',
644
+ label: '引用字段',
645
+ storage_type: 'Array',
646
+ is_system: false,
647
+ description: '引用字段',
648
+ example: [
649
+ {
650
+ language_code: 1033,
651
+ text: 'San Zhang'
652
+ },
653
+ {
654
+ language_code: 2052,
655
+ text: '张三'
656
+ }
657
+ ],
658
+ notes: '与公式类似。引用字段的返回值取决于选择的返回类型,各个类型的存储请参考文档其他部分'
659
+ },
660
+ region: {
661
+ api_name: 'region',
662
+ label: '行政区划',
663
+ storage_type: 'Object',
664
+ is_system: false,
665
+ description: '行政区划字段',
666
+ example: {
667
+ _isDeleted: false,
668
+ fullPath: [
669
+ {
670
+ language_code: 1033,
671
+ text: 'Xihu / Hangzhou / Zhejiang / Chinese mainland'
672
+ },
673
+ {
674
+ language_code: 2052,
675
+ text: '中国大陆 / 浙江 / 杭州市 / 西湖区'
676
+ }
677
+ ],
678
+ id: 1747012778430564,
679
+ level: 4,
680
+ regionCode: '330106'
681
+ },
682
+ notes: '行政区域字段对象内包含了 fullPath 多语文本,以及 id 和 level 层级。行政区划对象中,以 regionCode 作为唯一值。如果想获取某一行政区划的详细记录,可以通过 context.db.object("_region").select("_id", "_cityLevel").where({ _name: application.operator.contain("北京") }).findOne() 获取'
683
+ }
684
+ };
685
+ /**
686
+ * 系统默认字段列表(每个对象都会自动创建)
687
+ */
688
+ const SYSTEM_FIELDS = ['_id', '_name', '_createdBy', '_createdAt', '_updatedBy', '_updatedAt'];
689
+ /**
690
+ * 获取系统字段
691
+ */
692
+ function getSystemFields() {
693
+ return SYSTEM_FIELDS.map(fieldName => FIELD_TYPES[fieldName]);
694
+ }
695
+ /**
696
+ * 获取自定义字段类型
697
+ */
698
+ function getCustomFieldTypes() {
699
+ return Object.values(FIELD_TYPES).filter(field => !field.is_system);
700
+ }
701
+ /**
702
+ * 根据 API 名称获取字段类型信息
703
+ */
704
+ function getFieldType(apiName) {
705
+ return FIELD_TYPES[apiName];
706
+ }
707
+ /**
708
+ * 判断是否为系统字段
709
+ */
710
+ function isSystemField(apiName) {
711
+ return SYSTEM_FIELDS.includes(apiName);
712
+ }
713
+ /**
714
+ * 语言代码常量
715
+ */
716
+ const LANGUAGE_CODES = {
717
+ EN_US: 1033,
718
+ ZH_CN: 2052
719
+ };
720
+ /**
721
+ * 多语文本辅助函数:创建多语文本对象
722
+ */
723
+ function createMultilingualText(zhCn, enUs) {
724
+ return [
725
+ { language_code: LANGUAGE_CODES.ZH_CN, text: zhCn },
726
+ { language_code: LANGUAGE_CODES.EN_US, text: enUs || zhCn }
727
+ ];
728
+ }
729
+ /**
730
+ * 多语文本辅助函数:从多语文本对象中提取文本
731
+ */
732
+ function extractMultilingualText(multilingualText, languageCode = LANGUAGE_CODES.ZH_CN) {
733
+ var _a;
734
+ const found = multilingualText.find(item => item.language_code === languageCode);
735
+ return found ? found.text : ((_a = multilingualText[0]) === null || _a === void 0 ? void 0 : _a.text) || '';
736
+ }
737
+
46
738
  /**
47
739
  * 判断错误是否可重试
48
740
  */
@@ -1815,6 +2507,131 @@ class Client {
1815
2507
  }
1816
2508
  }
1817
2509
  };
2510
+ /**
2511
+ * 数据对象结构管理模块(Schema)
2512
+ */
2513
+ this.schema = {
2514
+ /**
2515
+ * 批量创建数据对象(表)
2516
+ * @description 批量创建一个或多个数据对象
2517
+ * @param params 请求参数 { objects: Array }
2518
+ * @returns 接口返回结果
2519
+ */
2520
+ create: async (params) => {
2521
+ const { objects } = params;
2522
+ await this.ensureTokenValid();
2523
+ const url = `/v1/namespaces/${this.namespace}/objects/batch_create`;
2524
+ this.log(LoggerLevel.info, `[schema.create] Creating ${objects.length} object(s)`);
2525
+ this.log(LoggerLevel.trace, `[schema.create] Request URL: ${this.axiosInstance.defaults.baseURL}${url}`);
2526
+ this.log(LoggerLevel.trace, `[schema.create] Request Body: ${JSON.stringify({ objects }, null, 2)}`);
2527
+ const res = await this.axiosInstance.post(url, { objects }, {
2528
+ headers: {
2529
+ Authorization: `${this.accessToken}`,
2530
+ 'Content-Type': 'application/json'
2531
+ }
2532
+ });
2533
+ this.log(LoggerLevel.debug, `[schema.create] Objects created: code=${res.data.code}`);
2534
+ this.log(LoggerLevel.trace, `[schema.create] Response: ${JSON.stringify(res.data)}`);
2535
+ return res.data;
2536
+ },
2537
+ /**
2538
+ * 批量更新数据对象(表)
2539
+ * @description 批量更新一个或多个数据对象的配置
2540
+ * @param params 请求参数 { objects: Array }
2541
+ * @returns 接口返回结果
2542
+ * @example
2543
+ * ```typescript
2544
+ * // 添加新字段
2545
+ * await client.schema.update({
2546
+ * objects: [{
2547
+ * api_name: 'my_object',
2548
+ * fields: [{
2549
+ * operator: 'add',
2550
+ * api_name: 'new_field',
2551
+ * label: { zh_cn: '新字段', en_us: 'New Field' },
2552
+ * type: { name: 'text', settings: { required: false } },
2553
+ * encrypt_type: 'none'
2554
+ * }]
2555
+ * }]
2556
+ * });
2557
+ *
2558
+ * // 修改现有字段
2559
+ * await client.schema.update({
2560
+ * objects: [{
2561
+ * api_name: 'my_object',
2562
+ * fields: [{
2563
+ * operator: 'replace',
2564
+ * api_name: 'existing_field',
2565
+ * label: { zh_cn: '新标签', en_us: 'New Label' }
2566
+ * }]
2567
+ * }]
2568
+ * });
2569
+ *
2570
+ * // 删除字段
2571
+ * await client.schema.update({
2572
+ * objects: [{
2573
+ * api_name: 'my_object',
2574
+ * fields: [{
2575
+ * operator: 'remove',
2576
+ * api_name: 'field_to_delete'
2577
+ * }]
2578
+ * }]
2579
+ * });
2580
+ * ```
2581
+ */
2582
+ update: async (params) => {
2583
+ const { objects } = params;
2584
+ await this.ensureTokenValid();
2585
+ const url = `/v1/namespaces/${this.namespace}/objects/batch_update`;
2586
+ this.log(LoggerLevel.info, `[schema.update] Updating ${objects.length} object(s)`);
2587
+ this.log(LoggerLevel.trace, `[schema.update] Request URL: ${this.axiosInstance.defaults.baseURL}${url}`);
2588
+ this.log(LoggerLevel.trace, `[schema.update] Request Body: ${JSON.stringify({ objects }, null, 2)}`);
2589
+ const res = await this.axiosInstance.post(url, { objects }, {
2590
+ headers: {
2591
+ Authorization: `${this.accessToken}`,
2592
+ 'Content-Type': 'application/json'
2593
+ }
2594
+ });
2595
+ this.log(LoggerLevel.debug, `[schema.update] Objects updated: code=${res.data.code}`);
2596
+ this.log(LoggerLevel.trace, `[schema.update] Response: ${JSON.stringify(res.data)}`);
2597
+ return res.data;
2598
+ },
2599
+ /**
2600
+ * 批量删除数据对象(表)
2601
+ * @description 批量删除一个或多个数据对象
2602
+ * @param params 请求参数 { api_names: string[] }
2603
+ * @returns 接口返回结果
2604
+ * @example
2605
+ * ```typescript
2606
+ * // 删除单个对象
2607
+ * await client.schema.delete({ api_names: ['object_abc'] });
2608
+ *
2609
+ * // 删除多个对象
2610
+ * await client.schema.delete({ api_names: ['object_abc', 'object_def'] });
2611
+ * ```
2612
+ */
2613
+ delete: async (params) => {
2614
+ const { api_names } = params;
2615
+ await this.ensureTokenValid();
2616
+ const url = `/v1/namespaces/${this.namespace}/objects/batch_delete`;
2617
+ this.log(LoggerLevel.info, `[schema.delete] Deleting ${api_names.length} object(s): ${api_names.join(', ')}`);
2618
+ // 直接传递字符串数组
2619
+ const requestBody = {
2620
+ api_names
2621
+ };
2622
+ this.log(LoggerLevel.trace, `[schema.delete] Request URL: ${this.axiosInstance.defaults.baseURL}${url}`);
2623
+ this.log(LoggerLevel.trace, `[schema.delete] Request Body: ${JSON.stringify(requestBody, null, 2)}`);
2624
+ const res = await this.axiosInstance.post(url, requestBody, {
2625
+ headers: {
2626
+ Authorization: `${this.accessToken}`,
2627
+ 'Content-Type': 'application/json'
2628
+ }
2629
+ });
2630
+ this.log(LoggerLevel.debug, `[schema.delete] Objects deleted: code=${res.data.code}`);
2631
+ this.log(LoggerLevel.trace, `[schema.delete] Response: ${JSON.stringify(res.data)}`);
2632
+ return res.data;
2633
+ }
2634
+ };
1818
2635
  this.clientId = options.clientId;
1819
2636
  this.clientSecret = options.clientSecret;
1820
2637
  this.namespace = options.namespace;
@@ -1927,4 +2744,19 @@ const apaas = {
1927
2744
  Client
1928
2745
  };
1929
2746
 
2747
+ exports.CREATE_OBJECT_EXAMPLE = CREATE_OBJECT_EXAMPLE;
2748
+ exports.FIELD_TYPES = FIELD_TYPES;
2749
+ exports.LANGUAGE_CODES = LANGUAGE_CODES;
2750
+ exports.SCHEMA_GUIDELINES = SCHEMA_GUIDELINES;
2751
+ exports.SYSTEM_FIELDS = SYSTEM_FIELDS;
2752
+ exports.UPDATE_OBJECT_ADD_FIELD_EXAMPLE = UPDATE_OBJECT_ADD_FIELD_EXAMPLE;
2753
+ exports.UPDATE_OBJECT_REMOVE_FIELD_EXAMPLE = UPDATE_OBJECT_REMOVE_FIELD_EXAMPLE;
2754
+ exports.UPDATE_OBJECT_REPLACE_FIELD_EXAMPLE = UPDATE_OBJECT_REPLACE_FIELD_EXAMPLE;
2755
+ exports.UPDATE_OBJECT_SETTINGS_EXAMPLE = UPDATE_OBJECT_SETTINGS_EXAMPLE;
1930
2756
  exports.apaas = apaas;
2757
+ exports.createMultilingualText = createMultilingualText;
2758
+ exports.extractMultilingualText = extractMultilingualText;
2759
+ exports.getCustomFieldTypes = getCustomFieldTypes;
2760
+ exports.getFieldType = getFieldType;
2761
+ exports.getSystemFields = getSystemFields;
2762
+ exports.isSystemField = isSystemField;