apaas-oapi-client 0.1.39 → 1.0.0

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/src/index.ts CHANGED
@@ -29,6 +29,68 @@ import {
29
29
  type CreateObjectDefinition,
30
30
  type UpdateObjectDefinition
31
31
  } from './field-types';
32
+ import {
33
+ SCHEMA_TYPE_BY_METADATA_TYPE,
34
+ OPTION_COLOR_LIST,
35
+ OPTION_COLOR_CODE_BY_NAME,
36
+ OPTION_COLOR_NAME_BY_CODE,
37
+ OPTION_COLOR_RULES,
38
+ FIELD_SCHEMA_RULES,
39
+ SCHEMA_TYPE_MISMATCHES,
40
+ SQL_TYPE_TO_SCHEMA_TYPE,
41
+ COLUMN_NAME_SEMANTIC_RULES,
42
+ SQL_CONSTRAINT_TO_SETTINGS,
43
+ BATCH_UPDATE_REQUIREMENTS,
44
+ getOptionColor,
45
+ getOptionColorCode,
46
+ normalizeOptionColorForSchema,
47
+ type MetadataFieldType,
48
+ type SchemaFieldType,
49
+ type FieldCreateRule,
50
+ type OptionColor,
51
+ type OptionColorCode,
52
+ type SqlTypeMapping,
53
+ type ColumnNameSemanticRule,
54
+ type SqlConstraintMapping
55
+ } from './field-schema-rules';
56
+ import {
57
+ SCHEMA_BATCH_SIZE,
58
+ addFieldsIdempotent,
59
+ batchExecute,
60
+ buildFieldRemovalPlan,
61
+ checkSchemaResponse,
62
+ createSchemaObjectShells,
63
+ createSchemaObjectsInStages,
64
+ deleteAllCustomObjects,
65
+ isSystemSchemaName,
66
+ normalizeSchemaObjectsForWrite,
67
+ splitSchemaFieldsByDependency,
68
+ validateSchemaResponse,
69
+ verifySchemaObjects,
70
+ type DeleteAllCustomObjectsOptions,
71
+ type DeleteAllCustomObjectsResult,
72
+ type SchemaAddFieldsOptions,
73
+ type SchemaAddFieldsResult,
74
+ type SchemaBatchExecuteOptions,
75
+ type SchemaBatchExecuteResult,
76
+ type SchemaBatchInfo,
77
+ type SchemaCreateObjectsInStagesOptions,
78
+ type SchemaCreateObjectsInStagesResult,
79
+ type SchemaCreateShellsOptions,
80
+ type SchemaCreateShellsResult,
81
+ type SchemaFieldRemovalPlan,
82
+ type SchemaManagedObjectDefinition,
83
+ type SchemaObjectVerification,
84
+ type SchemaResponse,
85
+ type SchemaResponseFailure,
86
+ type SchemaResponseFailureLayer,
87
+ type SchemaResponseItem,
88
+ type SchemaResponseValidationOptions,
89
+ type SchemaResponseValidationResult,
90
+ type SchemaStageFieldDefinition,
91
+ type SchemaVerificationOptions,
92
+ type SchemaVerificationResult
93
+ } from './schema-utils';
32
94
 
33
95
  /**
34
96
  * 批量操作结果
@@ -311,6 +373,12 @@ class Client {
311
373
  return this.namespace;
312
374
  }
313
375
 
376
+ private authHeaders(includeContentType = false) {
377
+ return includeContentType
378
+ ? { Authorization: `${this.accessToken}`, 'Content-Type': 'application/json' }
379
+ : { Authorization: `${this.accessToken}` };
380
+ }
381
+
314
382
  /**
315
383
  * 对象模块
316
384
  */
@@ -984,9 +1052,112 @@ class Client {
984
1052
  total: total,
985
1053
  msg: res.msg
986
1054
  };
1055
+ },
1056
+
1057
+ /**
1058
+ * 跨对象搜索记录
1059
+ * @description 在最多 5 个对象中按搜索词查询记录
1060
+ * @param params 请求体,包含 q、search_objects、page_token、page_size、metadata 等
1061
+ */
1062
+ recordsAcrossObjects: async (params: {
1063
+ q: string;
1064
+ search_objects: Array<{
1065
+ api_name: string;
1066
+ select?: string[];
1067
+ search_fields?: string[];
1068
+ filter?: any;
1069
+ order_by?: any[];
1070
+ }>;
1071
+ page_token?: string;
1072
+ page_size?: number;
1073
+ metadata?: 'Label' | 'SearchLayout' | string;
1074
+ }): Promise<any> => {
1075
+ await this.ensureTokenValid();
1076
+
1077
+ const url = `/v1/namespaces/${this.namespace}/objects/records/search`;
1078
+
1079
+ this.log(LoggerLevel.info, `[object.search.recordsAcrossObjects] Searching records: q=${params.q}`);
1080
+
1081
+ const res = await this.axiosInstance.post(url, params, {
1082
+ headers: this.authHeaders(true)
1083
+ });
1084
+
1085
+ this.log(LoggerLevel.debug, `[object.search.recordsAcrossObjects] Records searched: code=${res.data.code}`);
1086
+ this.log(LoggerLevel.trace, `[object.search.recordsAcrossObjects] Response: ${JSON.stringify(res.data)}`);
1087
+
1088
+ return res.data;
1089
+ },
1090
+
1091
+ /**
1092
+ * 跨对象搜索记录 - 自动 page_token 分页
1093
+ */
1094
+ recordsAcrossObjectsWithIterator: async (params: {
1095
+ q: string;
1096
+ search_objects: Array<{
1097
+ api_name: string;
1098
+ select?: string[];
1099
+ search_fields?: string[];
1100
+ filter?: any;
1101
+ order_by?: any[];
1102
+ }>;
1103
+ page_token?: string;
1104
+ page_size?: number;
1105
+ metadata?: 'Label' | 'SearchLayout' | string;
1106
+ }): Promise<{ items: any[]; lastResponse: any }> => {
1107
+ const pageSize = params.page_size || 20;
1108
+ let pageToken = params.page_token || '';
1109
+ let hasMore = true;
1110
+ const items: any[] = [];
1111
+ let lastResponse: any = null;
1112
+
1113
+ while (hasMore) {
1114
+ const res = await this.object.search.recordsAcrossObjects({
1115
+ ...params,
1116
+ page_size: pageSize,
1117
+ page_token: pageToken
1118
+ });
1119
+
1120
+ if (res.code !== '0') {
1121
+ this.log(LoggerLevel.error, `[object.search.recordsAcrossObjectsWithIterator] Error searching records: code=${res.code}, msg=${res.msg}`);
1122
+ throw new Error(res.msg || `Search failed with code ${res.code}`);
1123
+ }
1124
+
1125
+ const pageItems = res.data?.items || res.data?.records || res.data?.search_results || [];
1126
+ if (Array.isArray(pageItems)) {
1127
+ items.push(...pageItems);
1128
+ }
1129
+
1130
+ lastResponse = res;
1131
+ const nextPageToken = res.data?.next_page_token || res.data?.page_token || '';
1132
+ hasMore = Boolean(res.data?.has_more && nextPageToken);
1133
+ pageToken = nextPageToken;
1134
+ }
1135
+
1136
+ return { items, lastResponse };
987
1137
  }
988
1138
  },
989
1139
 
1140
+ /**
1141
+ * 执行 OQL
1142
+ * @description 执行对象查询语言,支持匿名参数 args 和具名参数 namedArgs
1143
+ */
1144
+ oql: async (params: { query: string; args?: any[]; namedArgs?: Record<string, any> }): Promise<any> => {
1145
+ await this.ensureTokenValid();
1146
+
1147
+ const url = `/api/data/v1/namespaces/${this.namespace}/records/query`;
1148
+
1149
+ this.log(LoggerLevel.info, '[object.oql] Executing OQL');
1150
+
1151
+ const res = await this.axiosInstance.post(url, params, {
1152
+ headers: this.authHeaders(true)
1153
+ });
1154
+
1155
+ this.log(LoggerLevel.debug, `[object.oql] OQL executed: code=${res.data.code}`);
1156
+ this.log(LoggerLevel.trace, `[object.oql] Response: ${JSON.stringify(res.data)}`);
1157
+
1158
+ return res.data;
1159
+ },
1160
+
990
1161
  create: {
991
1162
  /**
992
1163
  * 单条记录创建
@@ -1461,6 +1632,108 @@ class Client {
1461
1632
  }
1462
1633
  };
1463
1634
 
1635
+ /**
1636
+ * 常量对象模块
1637
+ */
1638
+ public constant = {
1639
+ /**
1640
+ * 查询常量对象列表。object_name 可取 _currency、_country、_timeZone。
1641
+ */
1642
+ records: async (params: {
1643
+ object_name: '_currency' | '_country' | '_timeZone' | string;
1644
+ data?: {
1645
+ limit?: number;
1646
+ offset?: number;
1647
+ count?: boolean;
1648
+ fields?: string[] | string;
1649
+ quickSearch?: string;
1650
+ filter?: any[];
1651
+ sort?: any[];
1652
+ };
1653
+ }): Promise<any> => {
1654
+ const { object_name, data = {} } = params;
1655
+ await this.ensureTokenValid();
1656
+
1657
+ const url = `/api/data/v1/namespaces/${this.namespace}/objects/${object_name}/records`;
1658
+
1659
+ this.log(LoggerLevel.info, `[constant.records] Fetching constant records: ${object_name}`);
1660
+
1661
+ const res = await this.axiosInstance.post(url, data, {
1662
+ headers: this.authHeaders(true)
1663
+ });
1664
+
1665
+ this.log(LoggerLevel.debug, `[constant.records] Constant records fetched: ${object_name}, code=${res.data.code}`);
1666
+ this.log(LoggerLevel.trace, `[constant.records] Response: ${JSON.stringify(res.data)}`);
1667
+
1668
+ return res.data;
1669
+ },
1670
+
1671
+ /**
1672
+ * 查询常量对象单条记录详情。
1673
+ */
1674
+ record: async (params: { object_name: '_currency' | '_country' | '_timeZone' | string; record_id: string }): Promise<any> => {
1675
+ const { object_name, record_id } = params;
1676
+ await this.ensureTokenValid();
1677
+
1678
+ const url = `/api/data/v1/namespaces/${this.namespace}/objects/${object_name}/${record_id}`;
1679
+
1680
+ this.log(LoggerLevel.info, `[constant.record] Fetching constant record: ${object_name}.${record_id}`);
1681
+
1682
+ const res = await this.axiosInstance.get(url, {
1683
+ headers: this.authHeaders()
1684
+ });
1685
+
1686
+ this.log(LoggerLevel.debug, `[constant.record] Constant record fetched: ${object_name}.${record_id}, code=${res.data.code}`);
1687
+ this.log(LoggerLevel.trace, `[constant.record] Response: ${JSON.stringify(res.data)}`);
1688
+
1689
+ return res.data;
1690
+ },
1691
+
1692
+ metadata: {
1693
+ /**
1694
+ * 获取常量对象元数据。
1695
+ */
1696
+ fields: async (params: { object_name: '_currency' | '_country' | '_timeZone' | string }): Promise<any> => {
1697
+ const { object_name } = params;
1698
+ await this.ensureTokenValid();
1699
+
1700
+ const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}`;
1701
+
1702
+ this.log(LoggerLevel.info, `[constant.metadata.fields] Fetching constant metadata: ${object_name}`);
1703
+
1704
+ const res = await this.axiosInstance.get(url, {
1705
+ headers: this.authHeaders()
1706
+ });
1707
+
1708
+ this.log(LoggerLevel.debug, `[constant.metadata.fields] Constant metadata fetched: ${object_name}, code=${res.data.code}`);
1709
+ this.log(LoggerLevel.trace, `[constant.metadata.fields] Response: ${JSON.stringify(res.data)}`);
1710
+
1711
+ return res.data;
1712
+ },
1713
+
1714
+ /**
1715
+ * 获取常量对象字段详情。
1716
+ */
1717
+ field: async (params: { object_name: '_currency' | '_country' | '_timeZone' | string; field_name: string }): Promise<any> => {
1718
+ const { object_name, field_name } = params;
1719
+ await this.ensureTokenValid();
1720
+
1721
+ const url = `/api/data/v1/namespaces/${this.namespace}/meta/objects/${object_name}/fields/${field_name}`;
1722
+
1723
+ this.log(LoggerLevel.info, `[constant.metadata.field] Fetching constant field metadata: ${object_name}.${field_name}`);
1724
+
1725
+ const res = await this.axiosInstance.get(url, {
1726
+ headers: this.authHeaders()
1727
+ });
1728
+
1729
+ this.log(LoggerLevel.debug, `[constant.metadata.field] Constant field metadata fetched: ${object_name}.${field_name}, code=${res.data.code}`);
1730
+ this.log(LoggerLevel.trace, `[constant.metadata.field] Response: ${JSON.stringify(res.data)}`);
1731
+
1732
+ return res.data;
1733
+ }
1734
+ }
1735
+ };
1736
+
1464
1737
  /**
1465
1738
  * 部门 ID 交换模块
1466
1739
  */
@@ -1774,6 +2047,95 @@ class Client {
1774
2047
  }
1775
2048
  };
1776
2049
 
2050
+ /**
2051
+ * 集成模块
2052
+ */
2053
+ public integration = {
2054
+ lark: {
2055
+ /**
2056
+ * 获取默认飞书集成 tenantAccessToken。
2057
+ */
2058
+ defaultTenantAccessToken: async (): Promise<any> => {
2059
+ await this.ensureTokenValid();
2060
+
2061
+ const url = `/api/integration/v1/namespaces/${this.namespace}/defaultLark/tenantAccessToken`;
2062
+
2063
+ this.log(LoggerLevel.info, '[integration.lark.defaultTenantAccessToken] Fetching default tenant token');
2064
+
2065
+ const res = await this.axiosInstance.get(url, {
2066
+ headers: this.authHeaders()
2067
+ });
2068
+
2069
+ this.log(LoggerLevel.debug, `[integration.lark.defaultTenantAccessToken] Token fetched: code=${res.data.code}`);
2070
+ this.log(LoggerLevel.trace, `[integration.lark.defaultTenantAccessToken] Response: ${JSON.stringify(res.data)}`);
2071
+
2072
+ return res.data;
2073
+ },
2074
+
2075
+ /**
2076
+ * 获取默认飞书集成 appAccessToken。
2077
+ */
2078
+ defaultAppAccessToken: async (): Promise<any> => {
2079
+ await this.ensureTokenValid();
2080
+
2081
+ const url = `/api/integration/v1/namespaces/${this.namespace}/defaultLark/appAccessToken`;
2082
+
2083
+ this.log(LoggerLevel.info, '[integration.lark.defaultAppAccessToken] Fetching default app token');
2084
+
2085
+ const res = await this.axiosInstance.get(url, {
2086
+ headers: this.authHeaders()
2087
+ });
2088
+
2089
+ this.log(LoggerLevel.debug, `[integration.lark.defaultAppAccessToken] Token fetched: code=${res.data.code}`);
2090
+ this.log(LoggerLevel.trace, `[integration.lark.defaultAppAccessToken] Response: ${JSON.stringify(res.data)}`);
2091
+
2092
+ return res.data;
2093
+ },
2094
+
2095
+ /**
2096
+ * 获取自定义飞书集成 tenantAccessToken。
2097
+ */
2098
+ tenantAccessToken: async (params: { lark_integration_api_name: string }): Promise<any> => {
2099
+ const { lark_integration_api_name } = params;
2100
+ await this.ensureTokenValid();
2101
+
2102
+ const url = `/api/integration/v1/namespaces/${this.namespace}/lark/tenantAccessToken/${lark_integration_api_name}`;
2103
+
2104
+ this.log(LoggerLevel.info, `[integration.lark.tenantAccessToken] Fetching tenant token: ${lark_integration_api_name}`);
2105
+
2106
+ const res = await this.axiosInstance.get(url, {
2107
+ headers: this.authHeaders()
2108
+ });
2109
+
2110
+ this.log(LoggerLevel.debug, `[integration.lark.tenantAccessToken] Token fetched: ${lark_integration_api_name}, code=${res.data.code}`);
2111
+ this.log(LoggerLevel.trace, `[integration.lark.tenantAccessToken] Response: ${JSON.stringify(res.data)}`);
2112
+
2113
+ return res.data;
2114
+ },
2115
+
2116
+ /**
2117
+ * 获取自定义飞书集成 appAccessToken。
2118
+ */
2119
+ appAccessToken: async (params: { lark_integration_api_name: string }): Promise<any> => {
2120
+ const { lark_integration_api_name } = params;
2121
+ await this.ensureTokenValid();
2122
+
2123
+ const url = `/api/integration/v1/namespaces/${this.namespace}/lark/appAccessToken/${lark_integration_api_name}`;
2124
+
2125
+ this.log(LoggerLevel.info, `[integration.lark.appAccessToken] Fetching app token: ${lark_integration_api_name}`);
2126
+
2127
+ const res = await this.axiosInstance.get(url, {
2128
+ headers: this.authHeaders()
2129
+ });
2130
+
2131
+ this.log(LoggerLevel.debug, `[integration.lark.appAccessToken] Token fetched: ${lark_integration_api_name}, code=${res.data.code}`);
2132
+ this.log(LoggerLevel.trace, `[integration.lark.appAccessToken] Response: ${JSON.stringify(res.data)}`);
2133
+
2134
+ return res.data;
2135
+ }
2136
+ }
2137
+ };
2138
+
1777
2139
  /**
1778
2140
  * 云函数模块
1779
2141
  */
@@ -2346,6 +2708,85 @@ class Client {
2346
2708
  }
2347
2709
  };
2348
2710
 
2711
+ /**
2712
+ * 数据集模块
2713
+ */
2714
+ public dataset = {
2715
+ /**
2716
+ * 查询数据集列表。
2717
+ */
2718
+ list: async (params?: {
2719
+ keyword?: string;
2720
+ order_by?: { field?: 'create_time' | 'update_time' | string; direction?: 'asc' | 'desc' | string } | string;
2721
+ page_type?: 'cursor' | 'offset';
2722
+ page_size?: number;
2723
+ page_token?: string;
2724
+ offset?: number | string;
2725
+ created_by?: string[];
2726
+ updated_by?: string[];
2727
+ }): Promise<any> => {
2728
+ await this.ensureTokenValid();
2729
+
2730
+ const url = `/v1/namespaces/${this.namespace}/datasets`;
2731
+ const requestData = params || {};
2732
+
2733
+ this.log(LoggerLevel.info, '[dataset.list] Fetching datasets');
2734
+
2735
+ const res = await this.axiosInstance.post(url, requestData, {
2736
+ headers: this.authHeaders(true)
2737
+ });
2738
+
2739
+ this.log(LoggerLevel.debug, `[dataset.list] Datasets fetched: code=${res.data.code}`);
2740
+ this.log(LoggerLevel.trace, `[dataset.list] Response: ${JSON.stringify(res.data)}`);
2741
+
2742
+ return res.data;
2743
+ },
2744
+
2745
+ /**
2746
+ * 查询全部数据集 - 默认使用 cursor 分页。
2747
+ */
2748
+ listWithIterator: async (params?: {
2749
+ keyword?: string;
2750
+ order_by?: { field?: 'create_time' | 'update_time' | string; direction?: 'asc' | 'desc' | string } | string;
2751
+ page_size?: number;
2752
+ created_by?: string[];
2753
+ updated_by?: string[];
2754
+ }): Promise<{ total: number; datasets: any[]; lastResponse: any }> => {
2755
+ const pageSize = params?.page_size || 100;
2756
+ let pageToken = '';
2757
+ let hasMore = true;
2758
+ let total = 0;
2759
+ const datasets: any[] = [];
2760
+ let lastResponse: any = null;
2761
+
2762
+ while (hasMore) {
2763
+ const res = await this.dataset.list({
2764
+ ...params,
2765
+ page_type: 'cursor',
2766
+ page_size: pageSize,
2767
+ page_token: pageToken
2768
+ });
2769
+
2770
+ if (res.code !== '0') {
2771
+ this.log(LoggerLevel.error, `[dataset.listWithIterator] Error fetching datasets: code=${res.code}, msg=${res.msg}`);
2772
+ throw new Error(res.msg || `Fetch failed with code ${res.code}`);
2773
+ }
2774
+
2775
+ const pageDatasets = res.data?.datasets || res.data?.items || [];
2776
+ if (Array.isArray(pageDatasets)) {
2777
+ datasets.push(...pageDatasets);
2778
+ }
2779
+
2780
+ total = res.data?.total ?? total;
2781
+ lastResponse = res;
2782
+ pageToken = res.data?.next_page_token || res.data?.page_token || '';
2783
+ hasMore = Boolean(res.data?.has_more && pageToken);
2784
+ }
2785
+
2786
+ return { total, datasets, lastResponse };
2787
+ }
2788
+ };
2789
+
2349
2790
  /**
2350
2791
  * 自动化流程模块
2351
2792
  */
@@ -2438,6 +2879,306 @@ class Client {
2438
2879
  }
2439
2880
  };
2440
2881
 
2882
+ /**
2883
+ * 流程模块
2884
+ */
2885
+ public workflow = {
2886
+ execution: {
2887
+ /**
2888
+ * 查询异步流程状态。
2889
+ */
2890
+ status: async (params: { execution_id: string | number }): Promise<any> => {
2891
+ const { execution_id } = params;
2892
+ await this.ensureTokenValid();
2893
+
2894
+ const url = `/api/v2/workflow/namespaces/${this.namespace}/open_api/execution`;
2895
+
2896
+ this.log(LoggerLevel.info, `[workflow.execution.status] Fetching execution status: ${execution_id}`);
2897
+
2898
+ const res = await this.axiosInstance.get(url, {
2899
+ headers: this.authHeaders(true),
2900
+ params: { executionId: execution_id }
2901
+ });
2902
+
2903
+ this.log(LoggerLevel.debug, `[workflow.execution.status] Execution status fetched: code=${res.data.code}`);
2904
+ this.log(LoggerLevel.trace, `[workflow.execution.status] Response: ${JSON.stringify(res.data)}`);
2905
+
2906
+ return res.data;
2907
+ }
2908
+ },
2909
+
2910
+ definition: {
2911
+ /**
2912
+ * 获取流程定义详情。
2913
+ */
2914
+ detail: async (params: { flow_api_name: string }): Promise<any> => {
2915
+ const { flow_api_name } = params;
2916
+ await this.ensureTokenValid();
2917
+
2918
+ const url = `/api/flow/v1/namespaces/${this.namespace}/flow/${flow_api_name}`;
2919
+
2920
+ this.log(LoggerLevel.info, `[workflow.definition.detail] Fetching flow definition: ${flow_api_name}`);
2921
+
2922
+ const res = await this.axiosInstance.get(url, {
2923
+ headers: this.authHeaders()
2924
+ });
2925
+
2926
+ this.log(LoggerLevel.debug, `[workflow.definition.detail] Flow definition fetched: ${flow_api_name}, code=${res.data.code}`);
2927
+ this.log(LoggerLevel.trace, `[workflow.definition.detail] Response: ${JSON.stringify(res.data)}`);
2928
+
2929
+ return res.data;
2930
+ }
2931
+ },
2932
+
2933
+ userTask: {
2934
+ /**
2935
+ * 获取包含人工任务的流程列表。
2936
+ */
2937
+ flows: async (params: { limit: number; offset?: number }): Promise<any> => {
2938
+ await this.ensureTokenValid();
2939
+
2940
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/flow_list`;
2941
+
2942
+ this.log(LoggerLevel.info, '[workflow.userTask.flows] Fetching user-task flows');
2943
+
2944
+ const res = await this.axiosInstance.post(url, params, {
2945
+ headers: this.authHeaders(true)
2946
+ });
2947
+
2948
+ this.log(LoggerLevel.debug, `[workflow.userTask.flows] User-task flows fetched: code=${res.data.code}`);
2949
+ this.log(LoggerLevel.trace, `[workflow.userTask.flows] Response: ${JSON.stringify(res.data)}`);
2950
+
2951
+ return res.data;
2952
+ },
2953
+
2954
+ /**
2955
+ * 获取包含人工任务的流程实例 ID 列表。
2956
+ */
2957
+ instanceIds: async (params: {
2958
+ page_size?: number;
2959
+ page_token?: string;
2960
+ start_time?: string | number;
2961
+ end_time?: string | number;
2962
+ api_ids?: string[];
2963
+ }): Promise<any> => {
2964
+ const { page_size, page_token, start_time, end_time, api_ids } = params;
2965
+ await this.ensureTokenValid();
2966
+
2967
+ const url = `/api/flow/v1/namespaces/${this.namespace}/instances/listids`;
2968
+ const data: any = {};
2969
+ if (start_time !== undefined) data.start_time = String(start_time);
2970
+ if (end_time !== undefined) data.end_time = String(end_time);
2971
+ if (api_ids !== undefined) data.api_ids = api_ids;
2972
+
2973
+ this.log(LoggerLevel.info, '[workflow.userTask.instanceIds] Fetching workflow instance IDs');
2974
+
2975
+ const res = await this.axiosInstance.get(url, {
2976
+ headers: this.authHeaders(true),
2977
+ params: { page_size, page_token },
2978
+ data
2979
+ });
2980
+
2981
+ this.log(LoggerLevel.debug, `[workflow.userTask.instanceIds] Workflow instance IDs fetched: code=${res.data.code}`);
2982
+ this.log(LoggerLevel.trace, `[workflow.userTask.instanceIds] Response: ${JSON.stringify(res.data)}`);
2983
+
2984
+ return res.data;
2985
+ },
2986
+
2987
+ /**
2988
+ * 获取流程实例详情。
2989
+ */
2990
+ instanceDetail: async (params: { approval_instance_id: string; includes?: string[] }): Promise<any> => {
2991
+ const { approval_instance_id, includes } = params;
2992
+ await this.ensureTokenValid();
2993
+
2994
+ const url = `/api/flow/v1/namespaces/${this.namespace}/instances/${approval_instance_id}`;
2995
+
2996
+ this.log(LoggerLevel.info, `[workflow.userTask.instanceDetail] Fetching workflow instance: ${approval_instance_id}`);
2997
+
2998
+ const res = await this.axiosInstance.get(url, {
2999
+ headers: this.authHeaders(),
3000
+ params: includes ? { includes } : undefined
3001
+ });
3002
+
3003
+ this.log(LoggerLevel.debug, `[workflow.userTask.instanceDetail] Workflow instance fetched: ${approval_instance_id}, code=${res.data.code}`);
3004
+ this.log(LoggerLevel.trace, `[workflow.userTask.instanceDetail] Response: ${JSON.stringify(res.data)}`);
3005
+
3006
+ return res.data;
3007
+ },
3008
+
3009
+ /**
3010
+ * 批量获取流程实例的任务列表。
3011
+ */
3012
+ instanceTasks: async (params: { approval_instance_ids: Array<string | number>; task_status?: string }): Promise<any> => {
3013
+ const { approval_instance_ids, task_status } = params;
3014
+ await this.ensureTokenValid();
3015
+
3016
+ const url = `/api/flow/v1/namespaces/${this.namespace}/instances/usertasks`;
3017
+
3018
+ this.log(LoggerLevel.info, '[workflow.userTask.instanceTasks] Fetching workflow instance tasks');
3019
+
3020
+ const res = await this.axiosInstance.get(url, {
3021
+ headers: this.authHeaders(true),
3022
+ params: task_status ? { task_status } : undefined,
3023
+ data: { approval_instance_ids }
3024
+ });
3025
+
3026
+ this.log(LoggerLevel.debug, `[workflow.userTask.instanceTasks] Workflow instance tasks fetched: code=${res.data.code}`);
3027
+ this.log(LoggerLevel.trace, `[workflow.userTask.instanceTasks] Response: ${JSON.stringify(res.data)}`);
3028
+
3029
+ return res.data;
3030
+ },
3031
+
3032
+ /**
3033
+ * 获取任务列表。
3034
+ */
3035
+ tasks: async (params: {
3036
+ type: 'archived' | 'pending' | string;
3037
+ source: 'fromMe' | 'assignMe' | 'CCMe' | string;
3038
+ kunlun_user_id: string;
3039
+ limit?: number | string;
3040
+ offset?: number | string;
3041
+ start_time?: string | number;
3042
+ end_time?: string | number;
3043
+ api_ids?: string[];
3044
+ }): Promise<any> => {
3045
+ await this.ensureTokenValid();
3046
+
3047
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_tasks`;
3048
+
3049
+ this.log(LoggerLevel.info, '[workflow.userTask.tasks] Fetching user tasks');
3050
+
3051
+ const res = await this.axiosInstance.post(url, params, {
3052
+ headers: this.authHeaders(true)
3053
+ });
3054
+
3055
+ this.log(LoggerLevel.debug, `[workflow.userTask.tasks] User tasks fetched: code=${res.data.code}`);
3056
+ this.log(LoggerLevel.trace, `[workflow.userTask.tasks] Response: ${JSON.stringify(res.data)}`);
3057
+
3058
+ return res.data;
3059
+ },
3060
+
3061
+ /**
3062
+ * 获取任务详情。
3063
+ */
3064
+ detail: async (params: { task_id: string }): Promise<any> => {
3065
+ const { task_id } = params;
3066
+ await this.ensureTokenValid();
3067
+
3068
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/detail`;
3069
+
3070
+ this.log(LoggerLevel.info, `[workflow.userTask.detail] Fetching user task: ${task_id}`);
3071
+
3072
+ const res = await this.axiosInstance.get(url, {
3073
+ headers: this.authHeaders()
3074
+ });
3075
+
3076
+ this.log(LoggerLevel.debug, `[workflow.userTask.detail] User task fetched: ${task_id}, code=${res.data.code}`);
3077
+ this.log(LoggerLevel.trace, `[workflow.userTask.detail] Response: ${JSON.stringify(res.data)}`);
3078
+
3079
+ return res.data;
3080
+ },
3081
+
3082
+ agree: async (params: { approval_task_id: string; user_id: string; opinion?: string }): Promise<any> => {
3083
+ const { approval_task_id, ...data } = params;
3084
+ await this.ensureTokenValid();
3085
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${approval_task_id}/agree`;
3086
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3087
+ return res.data;
3088
+ },
3089
+
3090
+ reject: async (params: { approval_task_id: string; user_id: string; opinion?: string }): Promise<any> => {
3091
+ const { approval_task_id, ...data } = params;
3092
+ await this.ensureTokenValid();
3093
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${approval_task_id}/reject`;
3094
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3095
+ return res.data;
3096
+ },
3097
+
3098
+ transfer: async (params: {
3099
+ approval_task_id: string;
3100
+ user_id: string;
3101
+ from_user_ids: string[];
3102
+ to_user_ids: string[];
3103
+ opinion?: string;
3104
+ }): Promise<any> => {
3105
+ const { approval_task_id, ...data } = params;
3106
+ await this.ensureTokenValid();
3107
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${approval_task_id}/trans`;
3108
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3109
+ return res.data;
3110
+ },
3111
+
3112
+ addAssignee: async (params: {
3113
+ approval_task_id: string;
3114
+ user_id: string;
3115
+ approvers: string[];
3116
+ add_assignee_type: 'currentAndAddAssign' | 'afterAndAddAssign' | string;
3117
+ opinion?: string;
3118
+ }): Promise<any> => {
3119
+ const { approval_task_id, ...data } = params;
3120
+ await this.ensureTokenValid();
3121
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${approval_task_id}/add_assignee`;
3122
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3123
+ return res.data;
3124
+ },
3125
+
3126
+ cc: async (params: { task_id: string; cc_user_ids: string[]; operator_user_id: string }): Promise<any> => {
3127
+ const { task_id, ...data } = params;
3128
+ await this.ensureTokenValid();
3129
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/cc`;
3130
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3131
+ return res.data;
3132
+ },
3133
+
3134
+ expedite: async (params: { task_id: string; expediting_user_ids: string[]; operator_user_id: string; opinion?: string }): Promise<any> => {
3135
+ const { task_id, ...data } = params;
3136
+ await this.ensureTokenValid();
3137
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/expediting`;
3138
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3139
+ return res.data;
3140
+ },
3141
+
3142
+ cancelInstance: async (params: { approval_instance_id: string; user_id: string; opinion?: string }): Promise<any> => {
3143
+ const { approval_instance_id, ...data } = params;
3144
+ await this.ensureTokenValid();
3145
+ const url = `/api/flow/v1/namespaces/${this.namespace}/instance/${approval_instance_id}/cancel`;
3146
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3147
+ return res.data;
3148
+ },
3149
+
3150
+ rollbackPoints: async (params: { task_id: string; operator_user_id: string }): Promise<any> => {
3151
+ const { task_id, ...data } = params;
3152
+ await this.ensureTokenValid();
3153
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/rollback_points`;
3154
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3155
+ return res.data;
3156
+ },
3157
+
3158
+ rollback: async (params: { task_id: string; operator_user_id: string; to_task_id: string; opinion?: string }): Promise<any> => {
3159
+ const { task_id, ...data } = params;
3160
+ await this.ensureTokenValid();
3161
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/rollback`;
3162
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3163
+ return res.data;
3164
+ },
3165
+
3166
+ startChat: async (params: {
3167
+ task_id: string;
3168
+ operator_user_id: string;
3169
+ invite_user_ids?: string[];
3170
+ chat_id?: string;
3171
+ chat_name?: string;
3172
+ }): Promise<any> => {
3173
+ const { task_id, ...data } = params;
3174
+ await this.ensureTokenValid();
3175
+ const url = `/api/flow/v1/namespaces/${this.namespace}/user_task/${task_id}/chat`;
3176
+ const res = await this.axiosInstance.post(url, data, { headers: this.authHeaders(true) });
3177
+ return res.data;
3178
+ }
3179
+ }
3180
+ };
3181
+
2441
3182
  /**
2442
3183
  * 数据对象结构管理模块(Schema)
2443
3184
  */
@@ -2460,7 +3201,7 @@ class Client {
2460
3201
  display_name?: string;
2461
3202
  search_layout?: string[];
2462
3203
  };
2463
- fields: Array<{
3204
+ fields?: Array<{
2464
3205
  api_name: string;
2465
3206
  label: {
2466
3207
  zh_cn: string;
@@ -2475,17 +3216,18 @@ class Client {
2475
3216
  }>;
2476
3217
  }): Promise<any> => {
2477
3218
  const { objects } = params;
3219
+ const requestObjects = normalizeSchemaObjectsForWrite(objects);
2478
3220
  await this.ensureTokenValid();
2479
3221
 
2480
3222
  const url = `/v1/namespaces/${this.namespace}/objects/batch_create`;
2481
3223
 
2482
3224
  this.log(LoggerLevel.info, `[schema.create] Creating ${objects.length} object(s)`);
2483
3225
  this.log(LoggerLevel.trace, `[schema.create] Request URL: ${this.axiosInstance.defaults.baseURL}${url}`);
2484
- this.log(LoggerLevel.trace, `[schema.create] Request Body: ${JSON.stringify({ objects }, null, 2)}`);
3226
+ this.log(LoggerLevel.trace, `[schema.create] Request Body: ${JSON.stringify({ objects: requestObjects }, null, 2)}`);
2485
3227
 
2486
3228
  const res = await this.axiosInstance.post(
2487
3229
  url,
2488
- { objects },
3230
+ { objects: requestObjects },
2489
3231
  {
2490
3232
  headers: {
2491
3233
  Authorization: `${this.accessToken}`,
@@ -2578,17 +3320,18 @@ class Client {
2578
3320
  }>;
2579
3321
  }): Promise<any> => {
2580
3322
  const { objects } = params;
3323
+ const requestObjects = normalizeSchemaObjectsForWrite(objects);
2581
3324
  await this.ensureTokenValid();
2582
3325
 
2583
3326
  const url = `/v1/namespaces/${this.namespace}/objects/batch_update`;
2584
3327
 
2585
3328
  this.log(LoggerLevel.info, `[schema.update] Updating ${objects.length} object(s)`);
2586
3329
  this.log(LoggerLevel.trace, `[schema.update] Request URL: ${this.axiosInstance.defaults.baseURL}${url}`);
2587
- this.log(LoggerLevel.trace, `[schema.update] Request Body: ${JSON.stringify({ objects }, null, 2)}`);
3330
+ this.log(LoggerLevel.trace, `[schema.update] Request Body: ${JSON.stringify({ objects: requestObjects }, null, 2)}`);
2588
3331
 
2589
3332
  const res = await this.axiosInstance.post(
2590
3333
  url,
2591
- { objects },
3334
+ { objects: requestObjects },
2592
3335
  {
2593
3336
  headers: {
2594
3337
  Authorization: `${this.accessToken}`,
@@ -2648,6 +3391,63 @@ class Client {
2648
3391
  this.log(LoggerLevel.trace, `[schema.delete] Response: ${JSON.stringify(res.data)}`);
2649
3392
 
2650
3393
  return res.data;
3394
+ },
3395
+
3396
+ /**
3397
+ * 校验 schema 写接口响应,覆盖请求级错误、data=null 静默失败、item 级失败。
3398
+ */
3399
+ checkResponse: checkSchemaResponse,
3400
+
3401
+ /**
3402
+ * 返回 schema 写接口响应校验结果,不抛错。
3403
+ */
3404
+ validateResponse: validateSchemaResponse,
3405
+
3406
+ /**
3407
+ * 按 schema 单批 10 个对象的限制分批执行。
3408
+ */
3409
+ batchExecute,
3410
+
3411
+ /**
3412
+ * 创建对象空壳。会移除 fields,并将 display/search 临时指向 _id。
3413
+ */
3414
+ createShells: async (params: { objects: SchemaManagedObjectDefinition[] } & SchemaCreateShellsOptions): Promise<SchemaCreateShellsResult> => {
3415
+ return createSchemaObjectShells(this, params.objects, params);
3416
+ },
3417
+
3418
+ /**
3419
+ * 幂等添加字段:先读 metadata,跳过已存在字段,再调用 schema.update。
3420
+ */
3421
+ addFieldsIdempotent: async (params: {
3422
+ object_name: string;
3423
+ fields: SchemaStageFieldDefinition[];
3424
+ } & SchemaAddFieldsOptions): Promise<SchemaAddFieldsResult> => {
3425
+ return addFieldsIdempotent(this, params.object_name, params.fields, params);
3426
+ },
3427
+
3428
+ /**
3429
+ * 三阶段创建对象:空壳 -> 基础字段 -> lookup -> reference_field -> final settings。
3430
+ */
3431
+ createWithStages: async (params: {
3432
+ objects: SchemaManagedObjectDefinition[];
3433
+ } & SchemaCreateObjectsInStagesOptions): Promise<SchemaCreateObjectsInStagesResult> => {
3434
+ return createSchemaObjectsInStages(this, params.objects, params);
3435
+ },
3436
+
3437
+ /**
3438
+ * 写后验证对象和字段,可选导出 Markdown。
3439
+ */
3440
+ verifyObjects: async (params: {
3441
+ object_names: string[];
3442
+ } & SchemaVerificationOptions): Promise<SchemaVerificationResult> => {
3443
+ return verifySchemaObjects(this, params.object_names, params);
3444
+ },
3445
+
3446
+ /**
3447
+ * 删除全部自定义对象。高风险操作,必须显式传 confirm: true。
3448
+ */
3449
+ deleteAllCustomObjects: async (params: DeleteAllCustomObjectsOptions & { confirm: true }): Promise<DeleteAllCustomObjectsResult> => {
3450
+ return deleteAllCustomObjects(this, params);
2651
3451
  }
2652
3452
  };
2653
3453
  }
@@ -2669,7 +3469,38 @@ export type {
2669
3469
  CreateFieldDefinition,
2670
3470
  UpdateFieldDefinition,
2671
3471
  CreateObjectDefinition,
2672
- UpdateObjectDefinition
3472
+ UpdateObjectDefinition,
3473
+ MetadataFieldType,
3474
+ SchemaFieldType,
3475
+ FieldCreateRule,
3476
+ OptionColor,
3477
+ OptionColorCode,
3478
+ SqlTypeMapping,
3479
+ ColumnNameSemanticRule,
3480
+ SqlConstraintMapping,
3481
+ DeleteAllCustomObjectsOptions,
3482
+ DeleteAllCustomObjectsResult,
3483
+ SchemaAddFieldsOptions,
3484
+ SchemaAddFieldsResult,
3485
+ SchemaBatchExecuteOptions,
3486
+ SchemaBatchExecuteResult,
3487
+ SchemaBatchInfo,
3488
+ SchemaCreateObjectsInStagesOptions,
3489
+ SchemaCreateObjectsInStagesResult,
3490
+ SchemaCreateShellsOptions,
3491
+ SchemaCreateShellsResult,
3492
+ SchemaFieldRemovalPlan,
3493
+ SchemaManagedObjectDefinition,
3494
+ SchemaObjectVerification,
3495
+ SchemaResponse,
3496
+ SchemaResponseFailure,
3497
+ SchemaResponseFailureLayer,
3498
+ SchemaResponseItem,
3499
+ SchemaResponseValidationOptions,
3500
+ SchemaResponseValidationResult,
3501
+ SchemaStageFieldDefinition,
3502
+ SchemaVerificationOptions,
3503
+ SchemaVerificationResult
2673
3504
  };
2674
3505
 
2675
3506
  export {
@@ -2690,5 +3521,34 @@ export {
2690
3521
  getFieldType,
2691
3522
  isSystemField,
2692
3523
  createMultilingualText,
2693
- extractMultilingualText
3524
+ extractMultilingualText,
3525
+ // Schema rules
3526
+ SCHEMA_TYPE_BY_METADATA_TYPE,
3527
+ OPTION_COLOR_LIST,
3528
+ OPTION_COLOR_CODE_BY_NAME,
3529
+ OPTION_COLOR_NAME_BY_CODE,
3530
+ OPTION_COLOR_RULES,
3531
+ FIELD_SCHEMA_RULES,
3532
+ SCHEMA_TYPE_MISMATCHES,
3533
+ SQL_TYPE_TO_SCHEMA_TYPE,
3534
+ COLUMN_NAME_SEMANTIC_RULES,
3535
+ SQL_CONSTRAINT_TO_SETTINGS,
3536
+ BATCH_UPDATE_REQUIREMENTS,
3537
+ getOptionColor,
3538
+ getOptionColorCode,
3539
+ normalizeOptionColorForSchema,
3540
+ // Schema runtime helpers
3541
+ SCHEMA_BATCH_SIZE,
3542
+ addFieldsIdempotent,
3543
+ batchExecute,
3544
+ buildFieldRemovalPlan,
3545
+ checkSchemaResponse,
3546
+ createSchemaObjectShells,
3547
+ createSchemaObjectsInStages,
3548
+ deleteAllCustomObjects,
3549
+ isSystemSchemaName,
3550
+ normalizeSchemaObjectsForWrite,
3551
+ splitSchemaFieldsByDependency,
3552
+ validateSchemaResponse,
3553
+ verifySchemaObjects
2694
3554
  };