openyida 2026.5.21 → 2026.5.25

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.
Files changed (51) hide show
  1. package/README.md +5 -1
  2. package/bin/yida.js +7 -1
  3. package/lib/app/app-list.js +20 -1
  4. package/lib/app/check-page.js +2 -2
  5. package/lib/app/compile.js +3 -2
  6. package/lib/app/externalize-form.js +642 -0
  7. package/lib/app/import-app.js +39 -11
  8. package/lib/app/page-compat.js +258 -2
  9. package/lib/app/page-compiler.js +4 -1
  10. package/lib/app/page-linter.js +271 -0
  11. package/lib/app/publish.js +3 -2
  12. package/lib/auth/cdp-browser-login.js +7 -3
  13. package/lib/auth/login.js +2 -3
  14. package/lib/core/command-manifest.js +3 -0
  15. package/lib/core/copy.js +50 -8
  16. package/lib/core/env-manager.js +24 -16
  17. package/lib/core/locales/ar.js +7 -0
  18. package/lib/core/locales/de.js +7 -0
  19. package/lib/core/locales/en.js +7 -0
  20. package/lib/core/locales/es.js +7 -0
  21. package/lib/core/locales/fr.js +7 -0
  22. package/lib/core/locales/hi.js +7 -0
  23. package/lib/core/locales/ja.js +7 -0
  24. package/lib/core/locales/ko.js +7 -0
  25. package/lib/core/locales/pt.js +7 -0
  26. package/lib/core/locales/vi.js +7 -0
  27. package/lib/core/locales/zh-HK.js +7 -0
  28. package/lib/core/locales/zh.js +7 -0
  29. package/lib/core/utils.js +2 -2
  30. package/lib/process/configure-process.js +552 -20
  31. package/package.json +1 -1
  32. package/project/pages/src/demo-agent-chatbox.oyd.jsx +78 -3
  33. package/scripts/e2e-real/full-runner.js +257 -8
  34. package/scripts/e2e-real/skill-coverage.js +2 -2
  35. package/yida-skills/SKILL.md +1 -1
  36. package/yida-skills/skills/yida-chart/SKILL.md +1 -1
  37. package/yida-skills/skills/yida-create-process/SKILL.md +3 -2
  38. package/yida-skills/skills/yida-custom-page/SKILL.md +7 -2
  39. package/yida-skills/skills/yida-custom-page/examples/attachment-upload.js +14 -12
  40. package/yida-skills/skills/yida-custom-page/references/attachment-upload-guide.md +3 -1
  41. package/yida-skills/skills/yida-custom-page/references/coding-guide.md +4 -0
  42. package/yida-skills/skills/yida-custom-page/references/component-jsx-guide.md +31 -22
  43. package/yida-skills/skills/yida-dashboard/SKILL.md +10 -9
  44. package/yida-skills/skills/yida-dashboard/references/interaction-patterns.md +2 -0
  45. package/yida-skills/skills/yida-dashboard/references/pitfalls.md +13 -4
  46. package/yida-skills/skills/yida-dashboard/references/structure-and-layout.md +1 -1
  47. package/yida-skills/skills/yida-ppt-slider/SKILL.md +47 -37
  48. package/yida-skills/skills/yida-ppt-slider/references/examples.md +5 -4
  49. package/yida-skills/skills/yida-process-rule/SKILL.md +93 -3
  50. package/yida-skills/skills/yida-process-rule/references/official-component-nodes.md +93 -0
  51. package/yida-skills/skills/yida-publish-page/SKILL.md +6 -4
@@ -61,6 +61,172 @@ const COMPONENT_TO_RULE_TYPE = {
61
61
  EmployeeField: 'rule_employee',
62
62
  };
63
63
 
64
+ const NODE_TYPE_ALIASES = {
65
+ approval: 'approval',
66
+ approver: 'approval',
67
+ approvalnode: 'approval',
68
+ operator: 'operator',
69
+ executor: 'operator',
70
+ handler: 'operator',
71
+ fill: 'operator',
72
+ filler: 'operator',
73
+ formfill: 'operator',
74
+ operatornode: 'operator',
75
+ multiapproval: 'multiApproval',
76
+ multiapprover: 'multiApproval',
77
+ multiapprovalnode: 'multiApproval',
78
+ carbon: 'carbon',
79
+ cc: 'carbon',
80
+ copy: 'carbon',
81
+ copynode: 'carbon',
82
+ carbonnode: 'carbon',
83
+ route: 'route',
84
+ branch: 'route',
85
+ branchnode: 'route',
86
+ conditioncontainer: 'route',
87
+ conditionnode: 'route',
88
+ parallel: 'parallel',
89
+ parallelbranch: 'parallel',
90
+ connector: 'ConnectorNode',
91
+ connectornode: 'ConnectorNode',
92
+ groovy: 'GroovyNode',
93
+ groovynode: 'GroovyNode',
94
+ javascript: 'JavaScriptNode',
95
+ js: 'JavaScriptNode',
96
+ javascriptnode: 'JavaScriptNode',
97
+ initiateapproval: 'InitiateApprovalNode',
98
+ subprocess: 'InitiateApprovalNode',
99
+ initiateapprovalnode: 'InitiateApprovalNode',
100
+ sendmessage: 'SendMessageNode',
101
+ message: 'SendMessageNode',
102
+ sendmessagenode: 'SendMessageNode',
103
+ sendemail: 'SendEmailNode',
104
+ email: 'SendEmailNode',
105
+ sendemailnode: 'SendEmailNode',
106
+ getdata: 'GetSingleDataNode',
107
+ getsingledata: 'GetSingleDataNode',
108
+ getsingledatanode: 'GetSingleDataNode',
109
+ getbatchdata: 'GetBatchDataNode',
110
+ getbatchdatanode: 'GetBatchDataNode',
111
+ adddata: 'AddDataNode',
112
+ createdata: 'AddDataNode',
113
+ adddatanode: 'AddDataNode',
114
+ updatedata: 'UpdateDataNode',
115
+ updatedatanode: 'UpdateDataNode',
116
+ deletedata: 'DeleteDataNode',
117
+ deletedatanode: 'DeleteDataNode',
118
+ sendcard: 'SendCardNode',
119
+ sendcardnode: 'SendCardNode',
120
+ cardnode: 'CardNode',
121
+ updatecard: 'UpdateCardNode',
122
+ updatecardnode: 'UpdateCardNode',
123
+ cardupdate: 'CardUpdateNode',
124
+ cardupdatenode: 'CardUpdateNode',
125
+ cycle: 'CycleContainer',
126
+ foreach: 'CycleContainer',
127
+ cyclecontainer: 'CycleContainer',
128
+ ai: 'AINode',
129
+ ainode: 'AINode',
130
+ };
131
+
132
+ const CONNECTOR_MODE_TO_PROCESS_TYPE = {
133
+ 1: 'innerConnector',
134
+ 3: 'thirdConnector',
135
+ 5: 'httpConnector',
136
+ 9: 'faasConnector',
137
+ };
138
+
139
+ const GENERIC_NODE_CONFIGS = {
140
+ ConnectorNode: {
141
+ processType: 'innerConnector',
142
+ title: ['连接器', 'Connector', 'コネクタ'],
143
+ propKeys: ['connectorRules'],
144
+ },
145
+ GroovyNode: {
146
+ processType: 'CodeExecutor',
147
+ title: ['Groovy', 'Groovy', 'Groovy'],
148
+ propKeys: ['groovy'],
149
+ },
150
+ JavaScriptNode: {
151
+ processType: 'CodeExecutor',
152
+ title: ['JavaScript', 'JavaScript', 'JavaScript'],
153
+ propKeys: ['JavaScript'],
154
+ propAliases: { javascript: 'JavaScript' },
155
+ },
156
+ InitiateApprovalNode: {
157
+ processType: 'initiateApproval',
158
+ title: ['子流程', 'Sub process', 'サブプロセス'],
159
+ propKeys: ['initiateApprovalRules'],
160
+ },
161
+ SendMessageNode: {
162
+ processType: 'sendMessage',
163
+ title: ['消息通知', 'Message notification', 'メッセージ通知'],
164
+ propKeys: ['sendMessageRules'],
165
+ },
166
+ SendEmailNode: {
167
+ processType: 'sendEmail',
168
+ title: ['发送邮件', 'Send email', 'メール送信'],
169
+ propKeys: ['sendEmailRules'],
170
+ },
171
+ GetSingleDataNode: {
172
+ processType: 'dataRetrieve',
173
+ title: ['获取单条数据', 'Get single data', '単一データ取得'],
174
+ propKeys: ['getData'],
175
+ },
176
+ GetBatchDataNode: {
177
+ processType: 'dataRetrieve',
178
+ title: ['获取多条数据', 'Get batch data', '複数データ取得'],
179
+ propKeys: ['getData'],
180
+ },
181
+ AddDataNode: {
182
+ processType: 'dataCreate',
183
+ title: ['新增数据', 'Add data', 'データ追加'],
184
+ propKeys: ['addDataRules'],
185
+ },
186
+ UpdateDataNode: {
187
+ processType: 'dataUpdate',
188
+ title: ['更新数据', 'Update data', 'データ更新'],
189
+ propKeys: ['updateDataRules'],
190
+ },
191
+ DeleteDataNode: {
192
+ processType: 'dataDelete',
193
+ title: ['删除数据', 'Delete data', 'データ削除'],
194
+ propKeys: ['deleteData'],
195
+ },
196
+ SendCardNode: {
197
+ processType: 'sendCard',
198
+ title: ['发送卡片', 'Send card', 'カード送信'],
199
+ propKeys: ['sendCardRules', 'cardRules'],
200
+ },
201
+ CardNode: {
202
+ processType: 'sendCard',
203
+ title: ['发送卡片', 'Send card', 'カード送信'],
204
+ propKeys: ['sendCardRules', 'cardRules'],
205
+ },
206
+ UpdateCardNode: {
207
+ processType: 'updateCard',
208
+ title: ['更新卡片', 'Update card', 'カード更新'],
209
+ propKeys: ['updateCardRules', 'cardUpdateRules'],
210
+ },
211
+ CardUpdateNode: {
212
+ processType: 'updateCard',
213
+ title: ['更新卡片', 'Update card', 'カード更新'],
214
+ propKeys: ['updateCardRules', 'cardUpdateRules'],
215
+ },
216
+ CycleContainer: {
217
+ processType: 'foreach',
218
+ title: ['循环', 'Loop', 'ループ'],
219
+ propKeys: ['cycleContainerRules'],
220
+ propAliases: { cycleRules: 'cycleContainerRules', foreachRules: 'cycleContainerRules' },
221
+ },
222
+ AINode: {
223
+ processType: 'AIExecutor',
224
+ title: ['AI 工作流', 'AI workflow', 'AI ワークフロー'],
225
+ propKeys: ['workFlowRules'],
226
+ propAliases: { workflowRules: 'workFlowRules' },
227
+ },
228
+ };
229
+
64
230
  // ── 辅助函数 ─────────────────────────────────────────
65
231
 
66
232
  function generateUuid() {
@@ -95,9 +261,53 @@ function normalizeList(value) {
95
261
  }
96
262
 
97
263
  function clonePlain(value) {
264
+ if (value === undefined) {
265
+ return undefined;
266
+ }
98
267
  return JSON.parse(JSON.stringify(value));
99
268
  }
100
269
 
270
+ function normalizeNodeType(node) {
271
+ if (!node) {
272
+ return '';
273
+ }
274
+ if (node.componentName && GENERIC_NODE_CONFIGS[node.componentName]) {
275
+ return node.componentName;
276
+ }
277
+ const rawType = pickFirstDefined(node.type, node.kind, node.nodeType, node.componentName);
278
+ if (!rawType) {
279
+ return '';
280
+ }
281
+ const raw = String(rawType).trim();
282
+ const normalized = raw.toLowerCase().replace(/[-_\s]/g, '');
283
+ return NODE_TYPE_ALIASES[normalized] || raw;
284
+ }
285
+
286
+ function getNodeName(node, fallback) {
287
+ const value = pickFirstDefined(
288
+ node && node.name,
289
+ node && node.title,
290
+ node && node.props && node.props.name,
291
+ fallback
292
+ );
293
+ if (isPlainObject(value)) {
294
+ return pickFirstDefined(value.zh_CN, value.en_US, value.ja_JP, fallback) || fallback;
295
+ }
296
+ return String(value || fallback || '');
297
+ }
298
+
299
+ function getNodeDescription(node) {
300
+ const value = pickFirstDefined(
301
+ node && node.description,
302
+ node && node.props && node.props.description,
303
+ ''
304
+ );
305
+ if (isPlainObject(value)) {
306
+ return pickFirstDefined(value.zh_CN, value.en_US, value.ja_JP, '') || '';
307
+ }
308
+ return String(value || '');
309
+ }
310
+
101
311
  function pickFirstDefined() {
102
312
  for (let i = 0; i < arguments.length; i++) {
103
313
  if (arguments[i] !== undefined && arguments[i] !== null && arguments[i] !== '') {
@@ -621,7 +831,8 @@ function buildRouteRule(routeRuleDefs, currentNodeId, nodeNameToIdMap) {
621
831
 
622
832
  function assignNodeIdsRecursive(nodes, nameToIdMap) {
623
833
  nodes.forEach(function (node) {
624
- if (node.type === 'route') {
834
+ const nodeType = normalizeNodeType(node);
835
+ if (nodeType === 'route') {
625
836
  node._nodeId = generateNodeId();
626
837
  const conditions = node.conditions || [];
627
838
  conditions.forEach(function (cond) {
@@ -630,7 +841,7 @@ function assignNodeIdsRecursive(nodes, nameToIdMap) {
630
841
  assignNodeIdsRecursive(cond.childNodes, nameToIdMap);
631
842
  }
632
843
  });
633
- } else if (node.type === 'parallel') {
844
+ } else if (nodeType === 'parallel') {
634
845
  node._nodeId = generateNodeId();
635
846
  if (node.name) {
636
847
  nameToIdMap[node.name] = node._nodeId;
@@ -643,6 +854,15 @@ function assignNodeIdsRecursive(nodes, nameToIdMap) {
643
854
  assignNodeIdsRecursive(childNodes, nameToIdMap);
644
855
  }
645
856
  });
857
+ } else if (GENERIC_NODE_CONFIGS[nodeType]) {
858
+ node._nodeId = generateNodeId();
859
+ if (node.name) {
860
+ nameToIdMap[node.name] = node._nodeId;
861
+ }
862
+ const childNodes = getGenericChildNodes(node);
863
+ if (childNodes.length > 0) {
864
+ assignNodeIdsRecursive(childNodes, nameToIdMap);
865
+ }
646
866
  } else {
647
867
  node._nodeId = generateNodeId();
648
868
  if (node.name) {
@@ -661,23 +881,30 @@ function buildNodeListRecursive(nodes, exitNodeId, nameToIdMap) {
661
881
  for (let i = 0; i < nodes.length; i++) {
662
882
  const node = nodes[i];
663
883
  const nextNodeId = i + 1 < nodes.length ? nodes[i + 1]._nodeId : exitNodeId;
884
+ const nodeType = normalizeNodeType(node);
664
885
 
665
- if (node.type === 'route') {
886
+ if (nodeType === 'route') {
666
887
  const routeResult = buildRouteNode(node, nextNodeId, nameToIdMap);
667
888
  processNodes.push(routeResult.processNode);
668
889
  viewNodes.push(routeResult.viewNode);
669
- } else if (node.type === 'parallel') {
890
+ } else if (nodeType === 'parallel') {
670
891
  const parallelResult = buildParallelNode(node, nextNodeId, nameToIdMap);
671
892
  processNodes.push(parallelResult.processNode);
672
893
  viewNodes.push(parallelResult.viewNode);
673
- } else if (node.type === 'approval') {
674
- const approvalResult = buildApprovalNode(node, nextNodeId, nameToIdMap);
894
+ } else if (nodeType === 'approval' || nodeType === 'operator' || nodeType === 'multiApproval') {
895
+ const approvalResult = buildApprovalNode(node, nextNodeId, nameToIdMap, nodeType);
675
896
  processNodes.push(approvalResult.processNode);
676
897
  viewNodes.push(approvalResult.viewNode);
677
- } else if (node.type === 'carbon') {
898
+ } else if (nodeType === 'carbon') {
678
899
  const carbonResult = buildCarbonNode(node, nextNodeId);
679
900
  processNodes.push(carbonResult.processNode);
680
901
  viewNodes.push(carbonResult.viewNode);
902
+ } else if (GENERIC_NODE_CONFIGS[nodeType]) {
903
+ const genericResult = buildGenericNode(node, nextNodeId, nameToIdMap, nodeType);
904
+ processNodes.push(genericResult.processNode);
905
+ viewNodes.push(genericResult.viewNode);
906
+ } else {
907
+ throw new Error('不支持的流程节点类型: ' + (node.type || node.componentName || node.kind || JSON.stringify(node)));
681
908
  }
682
909
  }
683
910
 
@@ -697,12 +924,18 @@ function wireChildProcessNodes(childProcessNodes, parentNodeId) {
697
924
  // ── 构建审批节点 ─────────────────────────────────────
698
925
 
699
926
  function buildApproverConfig(node) {
700
- const friendlyApprover = buildFriendlyApproverConfig(node, node.approverConfig || node.approver);
927
+ const approverInput = node.approverConfig
928
+ || node.approver
929
+ || node.executor
930
+ || node.operator
931
+ || node.receiver
932
+ || node.receivers;
933
+ const friendlyApprover = buildFriendlyApproverConfig(node, approverInput);
701
934
  if (friendlyApprover) {
702
935
  return friendlyApprover;
703
936
  }
704
937
 
705
- const rawApprover = node.approverConfig || (node.approver && typeof node.approver === 'object' ? node.approver : null);
938
+ const rawApprover = node.approverConfig || (approverInput && typeof approverInput === 'object' ? approverInput : null);
706
939
  if (rawApprover) {
707
940
  return {
708
941
  approvalType: rawApprover.approvalType || rawApprover.type || 'ext_target_approval_originator',
@@ -742,10 +975,22 @@ function buildApproverConfig(node) {
742
975
  return buildOriginatorApproverConfig(node, {});
743
976
  }
744
977
 
745
- function buildApprovalNode(node, nextNodeId, nameToIdMap) {
978
+ function buildApprovalNode(node, nextNodeId, nameToIdMap, nodeType) {
746
979
  const nodeId = node._nodeId;
747
980
  const routeRule = buildRouteRule(node.routeRules || [], nodeId, nameToIdMap);
748
981
  const approverConfig = buildApproverConfig(node);
982
+ const approvalNodeType = nodeType || normalizeNodeType(node);
983
+ const componentName = approvalNodeType === 'operator'
984
+ ? 'OperatorNode'
985
+ : (approvalNodeType === 'multiApproval' ? 'MultiApprovalNode' : 'ApprovalNode');
986
+ const titleText = approvalNodeType === 'operator'
987
+ ? ['办理人', 'Executor', '実行者']
988
+ : (approvalNodeType === 'multiApproval'
989
+ ? ['审批人', 'Approver', '承認者']
990
+ : ['审批人', 'Approver', '承認者']);
991
+ const defaultName = approvalNodeType === 'operator' ? '办理人' : '审批人';
992
+ const displayName = getNodeName(node, defaultName);
993
+ const nodeDescription = approverConfig.description || getNodeDescription(node) || '请选择审批人';
749
994
 
750
995
  // 构建字段权限(formConfig.behaviorList)
751
996
  // 兼容两种输入格式:
@@ -787,8 +1032,8 @@ function buildApprovalNode(node, nextNodeId, nameToIdMap) {
787
1032
  }
788
1033
 
789
1034
  const processNode = {
790
- name: i18n(node.name || '审批人', 'Approver', node.name || '承認者'),
791
- description: approverConfig.description,
1035
+ name: i18n(displayName, titleText[1], displayName),
1036
+ description: nodeDescription,
792
1037
  type: 'approval',
793
1038
  approvalType: approverConfig.approvalType,
794
1039
  nodeId: nodeId,
@@ -799,9 +1044,9 @@ function buildApprovalNode(node, nextNodeId, nameToIdMap) {
799
1044
  };
800
1045
 
801
1046
  const viewNodeProps = {
802
- nodeName: 'ApprovalNode',
803
- name: i18n(node.name || '审批人', 'Approver', node.name || '承認者'),
804
- description: approverConfig.description,
1047
+ nodeName: componentName,
1048
+ name: i18n(displayName, titleText[1], displayName),
1049
+ description: nodeDescription,
805
1050
  approverRules: approverConfig.approverRules,
806
1051
  actions: {
807
1052
  normalActions: buildActions(),
@@ -814,10 +1059,10 @@ function buildApprovalNode(node, nextNodeId, nameToIdMap) {
814
1059
  }
815
1060
 
816
1061
  const viewNode = {
817
- componentName: 'ApprovalNode',
1062
+ componentName: componentName,
818
1063
  id: nodeId,
819
1064
  props: viewNodeProps,
820
- title: i18n('审批人', 'Approver', '承認者'),
1065
+ title: i18n(titleText[0], titleText[1], titleText[2]),
821
1066
  };
822
1067
 
823
1068
  return { processNode, viewNode };
@@ -829,9 +1074,11 @@ function buildCarbonNode(node, nextNodeId) {
829
1074
  const nodeId = node._nodeId;
830
1075
  const approverConfig = buildApproverConfig(node);
831
1076
  const carbonReceiver = approverConfig.carbonReceiver || { type: 'VARIABLE', value: approverConfig.approvals || [['originator']] };
1077
+ const displayName = getNodeName(node, '抄送人');
1078
+ const nodeDescription = getNodeDescription(node) || '请选择抄送人';
832
1079
 
833
1080
  const processNode = {
834
- name: i18n(node.name || '抄送人', 'CC', node.name || '共有先'),
1081
+ name: i18n(displayName, 'CC', displayName),
835
1082
  description: '',
836
1083
  type: 'carbon',
837
1084
  approvalType: approverConfig.approvalType,
@@ -856,8 +1103,8 @@ function buildCarbonNode(node, nextNodeId) {
856
1103
  id: nodeId,
857
1104
  props: {
858
1105
  nodeName: 'CarbonNode',
859
- name: i18n(node.name || '抄送人', 'CC', node.name || '共有先'),
860
- description: node.description || '请选择抄送人',
1106
+ name: i18n(displayName, 'CC', displayName),
1107
+ description: nodeDescription,
861
1108
  approverRules: approverConfig.approverRules,
862
1109
  },
863
1110
  title: i18n('抄送人', 'CC', '共有先'),
@@ -866,6 +1113,291 @@ function buildCarbonNode(node, nextNodeId) {
866
1113
  return { processNode, viewNode };
867
1114
  }
868
1115
 
1116
+ // ── 构建真实组件节点(连接器、数据、消息、代码、子流程等)──
1117
+
1118
+ function getGenericChildNodes(node) {
1119
+ const childNodes = node.childNodes || node.children || node.nodes || [];
1120
+ return Array.isArray(childNodes) ? childNodes : [];
1121
+ }
1122
+
1123
+ function buildGenericNodeProps(node, componentName) {
1124
+ const config = GENERIC_NODE_CONFIGS[componentName] || {};
1125
+ const props = Object.assign({}, node.props || {});
1126
+ const displayName = getNodeName(node, config.title ? config.title[0] : componentName);
1127
+ const description = getNodeDescription(node);
1128
+
1129
+ if (!props.name) {
1130
+ props.name = i18n(displayName, config.title ? config.title[1] : displayName, displayName);
1131
+ }
1132
+ if (!props.nodeName) {
1133
+ props.nodeName = componentName;
1134
+ }
1135
+ if (!props.description && description) {
1136
+ props.description = description;
1137
+ }
1138
+
1139
+ Object.keys(config.propAliases || {}).forEach(function (sourceKey) {
1140
+ const targetKey = config.propAliases[sourceKey];
1141
+ if (node[sourceKey] !== undefined && props[targetKey] === undefined) {
1142
+ props[targetKey] = clonePlain(node[sourceKey]);
1143
+ }
1144
+ });
1145
+
1146
+ (config.propKeys || []).forEach(function (key) {
1147
+ if (node[key] !== undefined && props[key] === undefined) {
1148
+ props[key] = clonePlain(node[key]);
1149
+ }
1150
+ });
1151
+
1152
+ if (node.viewProps && isPlainObject(node.viewProps)) {
1153
+ Object.assign(props, clonePlain(node.viewProps));
1154
+ }
1155
+
1156
+ return props;
1157
+ }
1158
+
1159
+ function getGenericProcessType(componentName, node, props) {
1160
+ if (node.processType || node.processNodeType) {
1161
+ return node.processType || node.processNodeType;
1162
+ }
1163
+
1164
+ if (componentName === 'ConnectorNode') {
1165
+ const connectorRules = props.connectorRules || {};
1166
+ const connector = connectorRules.connector || {};
1167
+ const mode = connector.mode || connectorRules.mode;
1168
+ return CONNECTOR_MODE_TO_PROCESS_TYPE[mode] || GENERIC_NODE_CONFIGS[componentName].processType;
1169
+ }
1170
+
1171
+ return GENERIC_NODE_CONFIGS[componentName].processType;
1172
+ }
1173
+
1174
+ function pickRuleAssignments(ruleContainer) {
1175
+ if (!ruleContainer) {
1176
+ return [];
1177
+ }
1178
+ if (Array.isArray(ruleContainer.assignments)) {
1179
+ return clonePlain(ruleContainer.assignments);
1180
+ }
1181
+ if (ruleContainer.inputs && Array.isArray(ruleContainer.inputs.assignments)) {
1182
+ return clonePlain(ruleContainer.inputs.assignments);
1183
+ }
1184
+ if (Array.isArray(ruleContainer.rules)) {
1185
+ return ruleContainer.rules
1186
+ .map(function (rule) {
1187
+ if (Array.isArray(rule && rule.rules)) {
1188
+ return clonePlain(rule.rules);
1189
+ }
1190
+ return null;
1191
+ })
1192
+ .filter(Boolean)
1193
+ .reduce(function (all, rules) {
1194
+ return all.concat(rules);
1195
+ }, []);
1196
+ }
1197
+ return [];
1198
+ }
1199
+
1200
+ function buildConnectorProcessProps(props) {
1201
+ const connectorRules = props.connectorRules || {};
1202
+ const inputs = Object.assign({}, clonePlain(connectorRules.inputs || {}), {
1203
+ url: connectorRules.url,
1204
+ method: connectorRules.method,
1205
+ body: connectorRules.body,
1206
+ connection: connectorRules.connectionId || connectorRules.connection,
1207
+ connectorId: connectorRules.connectorId,
1208
+ actionId: connectorRules.actionId,
1209
+ });
1210
+ const assignments = pickRuleAssignments(connectorRules);
1211
+
1212
+ if (assignments.length > 0) {
1213
+ inputs.assignments = assignments;
1214
+ }
1215
+ if (connectorRules.openDevSchemaType === 'integrationObject') {
1216
+ inputs.openDevSchemaType = 'integrationObject';
1217
+ inputs.connectorOrgId = connectorRules.connector && connectorRules.connector.orgId;
1218
+ inputs.integrationObject = connectorRules.integrationObject;
1219
+ inputs.integrationObjectPath = connectorRules.integrationObjectPath;
1220
+ }
1221
+
1222
+ Object.keys(inputs).forEach(function (key) {
1223
+ if (inputs[key] === undefined) {
1224
+ delete inputs[key];
1225
+ }
1226
+ });
1227
+
1228
+ return { inputs };
1229
+ }
1230
+
1231
+ function buildCodeExecutorProcessProps(props, componentName) {
1232
+ const codeConfig = componentName === 'GroovyNode' ? props.groovy : props.JavaScript;
1233
+ if (!codeConfig) {
1234
+ return {};
1235
+ }
1236
+ const outputs = Array.isArray(codeConfig.outputs)
1237
+ ? codeConfig.outputs.map(function (output) {
1238
+ return {
1239
+ description: output.desc || output.description,
1240
+ name: output.name,
1241
+ type: output.type,
1242
+ valueType: output.valueType,
1243
+ };
1244
+ })
1245
+ : undefined;
1246
+ return {
1247
+ inputs: clonePlain(codeConfig.inputs),
1248
+ action: clonePlain(codeConfig.action),
1249
+ scriptType: codeConfig.scriptType,
1250
+ outputsSchema: outputs,
1251
+ };
1252
+ }
1253
+
1254
+ function buildGetDataProcessProps(props) {
1255
+ const getData = props.getData || {};
1256
+ return {
1257
+ type: props.type,
1258
+ filterType: getData.filterType,
1259
+ sort: clonePlain(getData.sort),
1260
+ sourceId: getData.sourceId,
1261
+ appType: getData.appType,
1262
+ originalType: getData.originalType,
1263
+ subSourceId: getData.subSourceId,
1264
+ condition: clonePlain(getData.condition),
1265
+ quantity: getData.quantity === undefined ? undefined : String(getData.quantity),
1266
+ dataRules: clonePlain(getData.dataRules),
1267
+ assignments: clonePlain(getData.assignments),
1268
+ };
1269
+ }
1270
+
1271
+ function buildAddDataProcessProps(props) {
1272
+ const addDataRules = props.addDataRules || {};
1273
+ return {
1274
+ formUuid: addDataRules.formUuid || '',
1275
+ appType: addDataRules.appType || '',
1276
+ subFormUuid: addDataRules.subFormUuid || '',
1277
+ insertType: addDataRules.insertType || '',
1278
+ type: addDataRules.type || '',
1279
+ sourceId: addDataRules.sourceId || '',
1280
+ assignments: pickRuleAssignments(addDataRules),
1281
+ };
1282
+ }
1283
+
1284
+ function buildAIProcessProps(props) {
1285
+ const workFlowRules = props.workFlowRules || {};
1286
+ return {
1287
+ type: 'aiFlow',
1288
+ action: workFlowRules.flowId ? { flowId: workFlowRules.flowId } : undefined,
1289
+ outputs: clonePlain(workFlowRules.outputs),
1290
+ yidaFieldIdList: clonePlain(workFlowRules.yidaFieldIdList),
1291
+ };
1292
+ }
1293
+
1294
+ function pruneUndefined(value) {
1295
+ if (!isPlainObject(value)) {
1296
+ return value;
1297
+ }
1298
+ Object.keys(value).forEach(function (key) {
1299
+ if (value[key] === undefined) {
1300
+ delete value[key];
1301
+ }
1302
+ });
1303
+ return value;
1304
+ }
1305
+
1306
+ function buildGenericProcessProps(props, node, componentName) {
1307
+ let processProps;
1308
+
1309
+ if (componentName === 'ConnectorNode') {
1310
+ processProps = buildConnectorProcessProps(props);
1311
+ } else if (componentName === 'GroovyNode' || componentName === 'JavaScriptNode') {
1312
+ processProps = buildCodeExecutorProcessProps(props, componentName);
1313
+ } else if (componentName === 'InitiateApprovalNode') {
1314
+ processProps = clonePlain(props.initiateApprovalRules || {});
1315
+ } else if (componentName === 'SendMessageNode') {
1316
+ processProps = clonePlain(props.sendMessageRules || {});
1317
+ delete processProps.description;
1318
+ } else if (componentName === 'SendEmailNode') {
1319
+ processProps = clonePlain(props.sendEmailRules || {});
1320
+ } else if (componentName === 'GetSingleDataNode' || componentName === 'GetBatchDataNode') {
1321
+ processProps = buildGetDataProcessProps(props);
1322
+ } else if (componentName === 'AddDataNode') {
1323
+ processProps = buildAddDataProcessProps(props);
1324
+ } else if (componentName === 'UpdateDataNode') {
1325
+ processProps = clonePlain(props.updateDataRules || {});
1326
+ } else if (componentName === 'DeleteDataNode') {
1327
+ processProps = clonePlain(props.deleteData || {});
1328
+ } else if (componentName === 'SendCardNode') {
1329
+ processProps = clonePlain(props.sendCardRules || {});
1330
+ } else if (componentName === 'UpdateCardNode') {
1331
+ processProps = clonePlain(props.updateCardRules || {});
1332
+ } else if (componentName === 'CardNode') {
1333
+ processProps = clonePlain(props.cardRules || {});
1334
+ } else if (componentName === 'CardUpdateNode') {
1335
+ processProps = clonePlain(props.cardUpdateRules || {});
1336
+ } else if (componentName === 'CycleContainer') {
1337
+ processProps = clonePlain(props.cycleContainerRules || {});
1338
+ } else if (componentName === 'AINode') {
1339
+ processProps = buildAIProcessProps(props);
1340
+ } else {
1341
+ processProps = clonePlain(props);
1342
+ }
1343
+
1344
+ delete processProps.name;
1345
+ delete processProps.nodeName;
1346
+ delete processProps.description;
1347
+ delete processProps.title;
1348
+ pruneUndefined(processProps);
1349
+ if (node.processProps && isPlainObject(node.processProps)) {
1350
+ Object.assign(processProps, clonePlain(node.processProps));
1351
+ }
1352
+ return processProps;
1353
+ }
1354
+
1355
+ function buildGenericNode(node, nextNodeId, nameToIdMap, componentName) {
1356
+ const nodeId = node._nodeId;
1357
+ const config = GENERIC_NODE_CONFIGS[componentName];
1358
+ const props = buildGenericNodeProps(node, componentName);
1359
+ const displayName = getNodeName(node, config.title[0]);
1360
+ const description = getNodeDescription(node);
1361
+ const childNodes = getGenericChildNodes(node);
1362
+ let childProcessNodes = [];
1363
+ let childViewNodes = [];
1364
+
1365
+ if (childNodes.length > 0) {
1366
+ const childResult = buildNodeListRecursive(childNodes, nextNodeId, nameToIdMap);
1367
+ childProcessNodes = childResult.processNodes;
1368
+ childViewNodes = childResult.viewNodes;
1369
+ wireChildProcessNodes(childProcessNodes, nodeId);
1370
+ }
1371
+
1372
+ const processNode = {
1373
+ name: i18n(displayName, config.title[1], displayName),
1374
+ description: description,
1375
+ type: getGenericProcessType(componentName, node, props),
1376
+ nodeId: nodeId,
1377
+ prevId: '',
1378
+ nextId: childProcessNodes.length > 0 ? [childProcessNodes[0].nodeId] : [nextNodeId],
1379
+ props: buildGenericProcessProps(props, node, componentName),
1380
+ childNodes: childProcessNodes.map(clonePlain),
1381
+ };
1382
+
1383
+ if (node.approvalType) {
1384
+ processNode.approvalType = node.approvalType;
1385
+ }
1386
+
1387
+ const viewNode = {
1388
+ componentName: componentName,
1389
+ id: nodeId,
1390
+ props: props,
1391
+ title: i18n(config.title[0], config.title[1], config.title[2]),
1392
+ };
1393
+
1394
+ if (childViewNodes.length > 0) {
1395
+ viewNode.children = childViewNodes;
1396
+ }
1397
+
1398
+ return { processNode, viewNode };
1399
+ }
1400
+
869
1401
  // ── 构建条件分支路由节点 ─────────────────────────────
870
1402
 
871
1403
  function buildRouteNode(node, exitNodeId, nameToIdMap) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.5.21",
3
+ "version": "2026.5.25",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",