openyida 2026.9.7 → 2026.9.8
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/lib/core/locales/en.js +8 -3
- package/lib/core/locales/zh.js +8 -3
- package/lib/integration/integration-create.js +151 -4
- package/lib/integration/integration-diagnostics.js +12 -12
- package/lib/integration/integration-form-metadata.js +136 -0
- package/lib/integration/integration-process-builder.js +31 -4
- package/lib/integration/integration-spec-builder.js +570 -73
- package/lib/integration/integration-view-builder.js +240 -15
- package/package.json +1 -1
- package/yida-skills/SKILL.md +1 -0
- package/yida-skills/skills/yida-integration/SKILL.md +44 -5
- package/yida-skills/skills/yida-integration/references/integration-node-schemas.md +21 -0
|
@@ -16,11 +16,33 @@ const {
|
|
|
16
16
|
resolveConnectorMode,
|
|
17
17
|
validateAssignments,
|
|
18
18
|
} = require('./integration-process-builder');
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
buildAddDataChildList,
|
|
21
|
+
buildSubTableAddDataChildList,
|
|
22
|
+
resolveTableFieldLabel,
|
|
23
|
+
listTableFieldSummaries,
|
|
24
|
+
buildSubTableRelativeItem,
|
|
25
|
+
assertAssignmentFieldsExist,
|
|
26
|
+
} = require('./integration-view-builder');
|
|
20
27
|
const {
|
|
21
28
|
lookupConnectorPreset,
|
|
22
29
|
buildConnectorRulesFromInputs,
|
|
23
30
|
} = require('./connector-presets');
|
|
31
|
+
const {
|
|
32
|
+
normalizeSourceFormType,
|
|
33
|
+
resolveSourceFormUuid,
|
|
34
|
+
resolveDataSourceFormName,
|
|
35
|
+
resolveDataSourceFormType,
|
|
36
|
+
resolveDataOriginalType,
|
|
37
|
+
resolveDataFormItemType,
|
|
38
|
+
isSubTableOriginalType,
|
|
39
|
+
resolveDataQueryField,
|
|
40
|
+
toRuntimeDataQueryField,
|
|
41
|
+
toDesignerDataQueryField,
|
|
42
|
+
normalizeDataQueryFieldName,
|
|
43
|
+
resolveDesignerDataQueryField,
|
|
44
|
+
resolveDataQueryFieldName,
|
|
45
|
+
} = require('./integration-form-metadata');
|
|
24
46
|
const { t } = require('../core/i18n');
|
|
25
47
|
|
|
26
48
|
function readIntegrationSpec(filePath) {
|
|
@@ -54,7 +76,7 @@ function mapSpecEventTypes(spec, fallbackEvents) {
|
|
|
54
76
|
return mapEventTypes(getSpecEventInput(spec, fallbackEvents));
|
|
55
77
|
}
|
|
56
78
|
|
|
57
|
-
function validateIntegrationSpec(spec, fallbackEvents = ['insert']) {
|
|
79
|
+
function validateIntegrationSpec(spec, fallbackEvents = ['insert'], options = {}) {
|
|
58
80
|
if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {
|
|
59
81
|
throw new Error('--spec must point to a JSON object');
|
|
60
82
|
}
|
|
@@ -81,14 +103,27 @@ function validateIntegrationSpec(spec, fallbackEvents = ['insert']) {
|
|
|
81
103
|
}
|
|
82
104
|
aliases.add(explicitAlias);
|
|
83
105
|
}
|
|
84
|
-
if (type === 'dataRetrieve'
|
|
85
|
-
|
|
106
|
+
if (type === 'dataRetrieve') {
|
|
107
|
+
if (isSubTableRetrieve(node)) {
|
|
108
|
+
if (!getSourceAlias(node) || !node.subSourceId) {
|
|
109
|
+
throw new Error('dataRetrieve sub_table node source and subSourceId are required');
|
|
110
|
+
}
|
|
111
|
+
} else if (!(node.formUuid || node.sourceId)) {
|
|
112
|
+
throw new Error('dataRetrieve node formUuid is required');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (type === 'getSelf' || type === 'dataRetrieve') {
|
|
116
|
+
resolveDeclaredSourceFormType(node);
|
|
86
117
|
}
|
|
87
118
|
if (type === 'dataRetrieve' && asArray(node.conditions || node.dataConditions).length === 0) {
|
|
88
119
|
throw new Error(t('integration.spec_data_retrieve_conditions_required'));
|
|
89
120
|
}
|
|
90
121
|
if (type === 'dataCreate') {
|
|
91
|
-
if (
|
|
122
|
+
if (isSubTableInsert(node)) {
|
|
123
|
+
if (!getSourceAlias(node) || !node.subFormUuid) {
|
|
124
|
+
throw new Error('dataCreate sub_table node source and subFormUuid are required');
|
|
125
|
+
}
|
|
126
|
+
} else if (!(node.formUuid || node.targetFormUuid)) {
|
|
92
127
|
throw new Error('dataCreate node formUuid is required');
|
|
93
128
|
}
|
|
94
129
|
validateAssignments(asArray(node.assignments), 'dataCreate assignment');
|
|
@@ -174,6 +209,7 @@ function validateIntegrationSpec(spec, fallbackEvents = ['insert']) {
|
|
|
174
209
|
}
|
|
175
210
|
}
|
|
176
211
|
validateNodes(getSpecNodes(spec));
|
|
212
|
+
assertSubTableSources(spec, options.formUuid || options.triggerFormUuid);
|
|
177
213
|
}
|
|
178
214
|
|
|
179
215
|
function normalizeLogic(logic) {
|
|
@@ -188,6 +224,217 @@ function getNodeAlias(node, fallback) {
|
|
|
188
224
|
return node.id || node.key || fallback;
|
|
189
225
|
}
|
|
190
226
|
|
|
227
|
+
function isSubTableValue(value) {
|
|
228
|
+
return String(value || '').trim().toLowerCase() === 'sub_table';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function isSubTableRetrieve(node = {}) {
|
|
232
|
+
return isSubTableValue(node.originalType);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function isSubTableInsert(node = {}) {
|
|
236
|
+
return isSubTableValue(node.insertType);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function getSourceAlias(node = {}) {
|
|
240
|
+
return node.source || node.from || '';
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const SUB_TABLE_SOURCE_TYPES = new Set(['getSelf', 'dataRetrieve']);
|
|
244
|
+
|
|
245
|
+
function getNodeType(node = {}) {
|
|
246
|
+
return normalizeNodeType(node.type || node.componentName);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function getDeclaredAlias(node = {}) {
|
|
250
|
+
return node.id || node.key || '';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function collectBranchNodes(branch) {
|
|
254
|
+
return branch && (branch.nodes || branch.childNodes || branch.children);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function indexSpecNodesByAlias(spec) {
|
|
258
|
+
const byAlias = new Map();
|
|
259
|
+
visitSpecNodes(spec, (node) => {
|
|
260
|
+
const alias = getDeclaredAlias(node);
|
|
261
|
+
if (alias && !byAlias.has(alias)) {
|
|
262
|
+
byAlias.set(alias, node);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
return byAlias;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function collectUpstreamAliasMaps(spec) {
|
|
269
|
+
const upstreamByNode = new WeakMap();
|
|
270
|
+
function visit(nodes, inheritedUpstream) {
|
|
271
|
+
const seen = new Map(inheritedUpstream);
|
|
272
|
+
for (const node of asArray(nodes)) {
|
|
273
|
+
if (!node || typeof node !== 'object') {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
upstreamByNode.set(node, new Map(seen));
|
|
277
|
+
const type = getNodeType(node);
|
|
278
|
+
if (type === 'route') {
|
|
279
|
+
const branchUpstream = new Map(seen);
|
|
280
|
+
const routeAlias = getDeclaredAlias(node);
|
|
281
|
+
if (routeAlias) {
|
|
282
|
+
branchUpstream.set(routeAlias, node);
|
|
283
|
+
}
|
|
284
|
+
for (const branch of asArray(node.branches || node.conditions)) {
|
|
285
|
+
visit(collectBranchNodes(branch), branchUpstream);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const alias = getDeclaredAlias(node);
|
|
289
|
+
if (alias) {
|
|
290
|
+
seen.set(alias, node);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
visit(getSpecNodes(spec), new Map());
|
|
295
|
+
return upstreamByNode;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function assertSubTableSources(spec, triggerFormUuid) {
|
|
299
|
+
const nodesByAlias = indexSpecNodesByAlias(spec);
|
|
300
|
+
const upstreamByNode = collectUpstreamAliasMaps(spec);
|
|
301
|
+
visitSpecNodes(spec, (node) => {
|
|
302
|
+
if (!isSubTableRetrieve(node) && !isSubTableInsert(node)) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const sourceAlias = getSourceAlias(node);
|
|
306
|
+
if (!sourceAlias) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const sourceNode = nodesByAlias.get(sourceAlias);
|
|
310
|
+
if (!sourceNode) {
|
|
311
|
+
throw new Error(`Unknown integration spec node alias: ${sourceAlias}`);
|
|
312
|
+
}
|
|
313
|
+
const sourceType = getNodeType(sourceNode);
|
|
314
|
+
if (!SUB_TABLE_SOURCE_TYPES.has(sourceType)) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`sub_table source must be a getSelf or dataRetrieve node: ${sourceAlias}`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const upstream = upstreamByNode.get(node);
|
|
320
|
+
if (!upstream || !upstream.has(sourceAlias)) {
|
|
321
|
+
throw new Error(`sub_table source must be an upstream node: ${sourceAlias}`);
|
|
322
|
+
}
|
|
323
|
+
resolveSubTableParentFormUuidFromSource(node, sourceNode, triggerFormUuid);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function visitSpecNodes(spec, visitor) {
|
|
328
|
+
function visit(nodes) {
|
|
329
|
+
for (const node of asArray(nodes)) {
|
|
330
|
+
if (!node || typeof node !== 'object') {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
visitor(node);
|
|
334
|
+
const type = normalizeNodeType(node.type || node.componentName);
|
|
335
|
+
if (type === 'route') {
|
|
336
|
+
for (const branch of asArray(node.branches || node.conditions)) {
|
|
337
|
+
visit(branch && (branch.nodes || branch.childNodes || branch.children));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
visit(getSpecNodes(spec));
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function findSpecNodeByAlias(spec, alias) {
|
|
346
|
+
if (!alias) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
let found = null;
|
|
350
|
+
visitSpecNodes(spec, (node) => {
|
|
351
|
+
if (!found && (node.id || node.key) === alias) {
|
|
352
|
+
found = node;
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
return found;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function inferSubTableParentFormUuid(sourceNode, triggerFormUuid) {
|
|
359
|
+
if (!sourceNode) {
|
|
360
|
+
return '';
|
|
361
|
+
}
|
|
362
|
+
if (getNodeType(sourceNode) === 'getSelf') {
|
|
363
|
+
return triggerFormUuid || '';
|
|
364
|
+
}
|
|
365
|
+
return sourceNode.formUuid || sourceNode.sourceId || sourceNode.targetFormUuid || '';
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function resolveSubTableParentFormUuidFromSource(node, sourceNode, triggerFormUuid) {
|
|
369
|
+
const inferred = inferSubTableParentFormUuid(sourceNode, triggerFormUuid);
|
|
370
|
+
const explicit = node.parentFormUuid ? String(node.parentFormUuid) : '';
|
|
371
|
+
if (explicit && inferred && explicit !== String(inferred)) {
|
|
372
|
+
throw new Error(
|
|
373
|
+
`sub_table parentFormUuid must match the source form: ${explicit} != ${inferred}`
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
return explicit || inferred || '';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function resolveSubTableParentFormUuid(node, spec, triggerFormUuid) {
|
|
380
|
+
return resolveSubTableParentFormUuidFromSource(
|
|
381
|
+
node,
|
|
382
|
+
findSpecNodeByAlias(spec, getSourceAlias(node)),
|
|
383
|
+
triggerFormUuid
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function resolveContextSourceNode(node, context) {
|
|
388
|
+
const sourceAlias = getSourceAlias(node);
|
|
389
|
+
if (!sourceAlias || !context.aliasToSpecNode) {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
return context.aliasToSpecNode.get(sourceAlias) || null;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function resolveSubTableParentFormUuidFromContext(node, context) {
|
|
396
|
+
return resolveSubTableParentFormUuidFromSource(
|
|
397
|
+
node,
|
|
398
|
+
resolveContextSourceNode(node, context),
|
|
399
|
+
context.formUuid
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function resolveDeclaredSourceFormType(node = {}) {
|
|
404
|
+
const declarations = [
|
|
405
|
+
['formType', node.formType],
|
|
406
|
+
['sourceFormType', node.sourceFormType],
|
|
407
|
+
['originalType', node.originalType],
|
|
408
|
+
].filter(([field, value]) => value !== undefined
|
|
409
|
+
&& value !== null
|
|
410
|
+
&& String(value).trim() !== ''
|
|
411
|
+
&& !(field === 'originalType' && isSubTableOriginalType(value)))
|
|
412
|
+
.map(([field, value]) => ({
|
|
413
|
+
field,
|
|
414
|
+
rawValue: value,
|
|
415
|
+
normalized: normalizeSourceFormType(value),
|
|
416
|
+
}));
|
|
417
|
+
if (declarations.length === 0) {
|
|
418
|
+
return { rawValue: undefined, normalized: '' };
|
|
419
|
+
}
|
|
420
|
+
const unsupported = declarations.find((declaration) => !declaration.normalized);
|
|
421
|
+
if (unsupported) {
|
|
422
|
+
throw new Error(`Unsupported source form type: ${unsupported.rawValue}`);
|
|
423
|
+
}
|
|
424
|
+
const normalizedTypes = new Set(declarations.map((declaration) => declaration.normalized));
|
|
425
|
+
if (normalizedTypes.size > 1) {
|
|
426
|
+
throw new Error(
|
|
427
|
+
`Conflicting source form types on node: ${declarations.map((declaration) => (
|
|
428
|
+
`${declaration.field}=${declaration.rawValue}`
|
|
429
|
+
)).join(', ')}`
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
return {
|
|
433
|
+
rawValue: declarations[0].rawValue,
|
|
434
|
+
normalized: declarations[0].normalized,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
191
438
|
function registerNodeId(node, context, prefix) {
|
|
192
439
|
if (node._nodeId) {
|
|
193
440
|
return node._nodeId;
|
|
@@ -201,6 +448,9 @@ function registerNodeId(node, context, prefix) {
|
|
|
201
448
|
node._nodeId = nodeId;
|
|
202
449
|
context.aliasToNodeId.set(alias, nodeId);
|
|
203
450
|
context.nodeIdToAlias.set(nodeId, alias);
|
|
451
|
+
if (context.aliasToSpecNode) {
|
|
452
|
+
context.aliasToSpecNode.set(alias, node);
|
|
453
|
+
}
|
|
204
454
|
return nodeId;
|
|
205
455
|
}
|
|
206
456
|
|
|
@@ -273,7 +523,7 @@ function normalizeToUsers(value, fallback = []) {
|
|
|
273
523
|
}).filter(Boolean);
|
|
274
524
|
}
|
|
275
525
|
|
|
276
|
-
function normalizeDataConditions(conditions, context) {
|
|
526
|
+
function normalizeDataConditions(conditions, context, sourceFormType) {
|
|
277
527
|
return asArray(conditions).map((condition) => {
|
|
278
528
|
const bFieldId = condition.bFieldId || condition.fieldId || condition.id;
|
|
279
529
|
const conditionValue = getFirstNonNullishOwnValue(condition, ['aFieldId', 'value', 'ruleValue']);
|
|
@@ -284,9 +534,11 @@ function normalizeDataConditions(conditions, context) {
|
|
|
284
534
|
if (!['literal', 'processVar', 'column'].includes(valueType)) {
|
|
285
535
|
throw new Error(`dataRetrieve condition valueType is unsupported: ${valueType}`);
|
|
286
536
|
}
|
|
537
|
+
const bFieldName = condition.bFieldName || condition.fieldName || condition.name || condition.label || bFieldId;
|
|
538
|
+
const runtimeFieldId = toRuntimeDataQueryField(resolveNodeRefs(bFieldId, context), sourceFormType);
|
|
287
539
|
return {
|
|
288
|
-
bFieldId:
|
|
289
|
-
bFieldName:
|
|
540
|
+
bFieldId: runtimeFieldId,
|
|
541
|
+
bFieldName: normalizeDataQueryFieldName(runtimeFieldId, sourceFormType, bFieldName),
|
|
290
542
|
aFieldId: resolveNodeRefs(conditionValue.value, context),
|
|
291
543
|
componentType: condition.componentType || 'TextField',
|
|
292
544
|
opCode: condition.opCode || condition.op || 'Contain',
|
|
@@ -473,19 +725,58 @@ function buildMessageViewNode(node, nodeId, context) {
|
|
|
473
725
|
};
|
|
474
726
|
}
|
|
475
727
|
|
|
728
|
+
function resolveRetrieveSourceId(node, context) {
|
|
729
|
+
if (isSubTableRetrieve(node)) {
|
|
730
|
+
return resolveAlias(getSourceAlias(node), context);
|
|
731
|
+
}
|
|
732
|
+
return node.formUuid || node.sourceId || (node.type === 'getSelf' ? context.formUuid : undefined);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function resolveRetrieveSourceLabel(node, context, sourceId) {
|
|
736
|
+
if (isSubTableRetrieve(node)) {
|
|
737
|
+
const sourceNode = context.aliasToSpecNode && context.aliasToSpecNode.get(getSourceAlias(node));
|
|
738
|
+
return (sourceNode && (sourceNode.name || sourceNode.formName))
|
|
739
|
+
|| node.formName
|
|
740
|
+
|| getSourceAlias(node);
|
|
741
|
+
}
|
|
742
|
+
return resolveDataSourceFormName(node, context)
|
|
743
|
+
|| node.formName
|
|
744
|
+
|| (context.formNamesByUuid && context.formNamesByUuid.get(sourceId))
|
|
745
|
+
|| sourceId;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function isUsedAsSubTableSource(node, context) {
|
|
749
|
+
const alias = node.id || node.key;
|
|
750
|
+
if (!alias || !context.aliasToSpecNode) {
|
|
751
|
+
return false;
|
|
752
|
+
}
|
|
753
|
+
for (const specNode of context.aliasToSpecNode.values()) {
|
|
754
|
+
if (getSourceAlias(specNode) !== alias) {
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
if (isSubTableRetrieve(specNode) || isSubTableInsert(specNode)) {
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
|
|
476
764
|
function buildDataRetrieveProcessNode(node, nodeId, nextNodeId, context) {
|
|
477
|
-
const
|
|
478
|
-
const
|
|
765
|
+
const sourceId = resolveRetrieveSourceId(node, context);
|
|
766
|
+
const dataSourceFormType = isSubTableRetrieve(node)
|
|
767
|
+
? ''
|
|
768
|
+
: resolveDataSourceFormType(node, context);
|
|
769
|
+
const formName = resolveRetrieveSourceLabel(node, context, sourceId);
|
|
479
770
|
const rawConditions = node.type === 'getSelf' || node.getSelf
|
|
480
771
|
? [{
|
|
481
|
-
bFieldId: node
|
|
482
|
-
bFieldName:
|
|
772
|
+
bFieldId: resolveDataQueryField(node, dataSourceFormType),
|
|
773
|
+
bFieldName: resolveDataQueryFieldName(dataSourceFormType),
|
|
483
774
|
aFieldId: node.triggerField || '__masterdata_form_inst_id',
|
|
484
775
|
componentType: 'TextField',
|
|
485
776
|
opCode: 'Equal',
|
|
486
777
|
valueType: 'processVar',
|
|
487
778
|
}]
|
|
488
|
-
: normalizeDataConditions(node.conditions || node.dataConditions, context);
|
|
779
|
+
: normalizeDataConditions(node.conditions || node.dataConditions, context, dataSourceFormType);
|
|
489
780
|
const conditions = rawConditions.length > 0
|
|
490
781
|
? buildDataRetrieveCondition(rawConditions, node.logic || node.conditionLogic)
|
|
491
782
|
: { condition: 'AND', rules: [], ruleId: generateRuleGroupId(), conditionCode: '&&' };
|
|
@@ -500,9 +791,11 @@ function buildDataRetrieveProcessNode(node, nodeId, nextNodeId, context) {
|
|
|
500
791
|
type: 'single',
|
|
501
792
|
filterType: 'condition',
|
|
502
793
|
sort: node.sort || { type: 'none', column: '' },
|
|
503
|
-
sourceId
|
|
794
|
+
sourceId,
|
|
504
795
|
appType: context.appType,
|
|
505
|
-
originalType: node
|
|
796
|
+
originalType: isSubTableRetrieve(node)
|
|
797
|
+
? 'sub_table'
|
|
798
|
+
: resolveDataOriginalType(dataSourceFormType),
|
|
506
799
|
subSourceId: node.subSourceId || '',
|
|
507
800
|
condition: conditions,
|
|
508
801
|
quantity: String(node.quantity || '1'),
|
|
@@ -528,7 +821,78 @@ function buildDataRetrieveProcessNode(node, nodeId, nextNodeId, context) {
|
|
|
528
821
|
function buildDataRetrieveViewNode(node, nodeId, context) {
|
|
529
822
|
const processNode = buildDataRetrieveProcessNode(node, nodeId, nodeId, context);
|
|
530
823
|
const props = processNode.props;
|
|
531
|
-
const
|
|
824
|
+
const dataSourceFormType = isSubTableRetrieve(node)
|
|
825
|
+
? ''
|
|
826
|
+
: resolveDataSourceFormType(node, context);
|
|
827
|
+
const dataSourceFormName = isSubTableRetrieve(node)
|
|
828
|
+
? ''
|
|
829
|
+
: resolveDataSourceFormName(node, context);
|
|
830
|
+
const formName = resolveRetrieveSourceLabel(node, context, props.sourceId);
|
|
831
|
+
let viewCondition;
|
|
832
|
+
if (node.type === 'getSelf' || node.getSelf) {
|
|
833
|
+
viewCondition = buildDataRetrieveCondition([{
|
|
834
|
+
bFieldId: resolveDesignerDataQueryField(node, dataSourceFormType),
|
|
835
|
+
bFieldName: resolveDataQueryFieldName(dataSourceFormType),
|
|
836
|
+
aFieldId: node.triggerField || '__masterdata_form_inst_id',
|
|
837
|
+
componentType: 'TextField',
|
|
838
|
+
opCode: 'Equal',
|
|
839
|
+
valueType: 'processVar',
|
|
840
|
+
}]);
|
|
841
|
+
} else if (isSubTableRetrieve(node)) {
|
|
842
|
+
viewCondition = props.condition;
|
|
843
|
+
} else {
|
|
844
|
+
viewCondition = {
|
|
845
|
+
...props.condition,
|
|
846
|
+
rules: (props.condition.rules || []).map((rule) => {
|
|
847
|
+
const designerFieldId = toDesignerDataQueryField(rule.id, dataSourceFormType);
|
|
848
|
+
const designerFieldName = normalizeDataQueryFieldName(
|
|
849
|
+
rule.id,
|
|
850
|
+
dataSourceFormType,
|
|
851
|
+
rule.name,
|
|
852
|
+
);
|
|
853
|
+
return designerFieldId === rule.id && designerFieldName === rule.name
|
|
854
|
+
? rule
|
|
855
|
+
: {
|
|
856
|
+
...rule,
|
|
857
|
+
id: designerFieldId,
|
|
858
|
+
name: designerFieldName,
|
|
859
|
+
};
|
|
860
|
+
}),
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
let targetItem;
|
|
864
|
+
let relativeItem = {};
|
|
865
|
+
if (isSubTableRetrieve(node)) {
|
|
866
|
+
const parentFormUuid = resolveSubTableParentFormUuidFromContext(node, context);
|
|
867
|
+
const schemaComponents = parentFormUuid
|
|
868
|
+
? (context.formSchemasByUuid.get(parentFormUuid) || [])
|
|
869
|
+
: [];
|
|
870
|
+
const subTableLabel = node.subSourceLabel
|
|
871
|
+
|| resolveTableFieldLabel(schemaComponents, props.subSourceId, props.subSourceId);
|
|
872
|
+
targetItem = {
|
|
873
|
+
deep: 0,
|
|
874
|
+
value: props.sourceId,
|
|
875
|
+
label: formName,
|
|
876
|
+
};
|
|
877
|
+
relativeItem = buildSubTableRelativeItem(props.subSourceId, subTableLabel);
|
|
878
|
+
} else {
|
|
879
|
+
const schemaComponents = context.formSchemasByUuid.get(props.sourceId) || [];
|
|
880
|
+
const tableFields = isUsedAsSubTableSource(node, context)
|
|
881
|
+
? listTableFieldSummaries(schemaComponents)
|
|
882
|
+
: [];
|
|
883
|
+
targetItem = {
|
|
884
|
+
appType: context.appType,
|
|
885
|
+
appName: '',
|
|
886
|
+
formItem: {
|
|
887
|
+
formType: resolveDataFormItemType(dataSourceFormType),
|
|
888
|
+
advanceProc: 'n',
|
|
889
|
+
formUuid: props.sourceId,
|
|
890
|
+
title: dataSourceFormName || formName,
|
|
891
|
+
fields: tableFields.length > 0 ? tableFields : null,
|
|
892
|
+
hasTableField: tableFields.length > 0 ? true : null,
|
|
893
|
+
},
|
|
894
|
+
};
|
|
895
|
+
}
|
|
532
896
|
return {
|
|
533
897
|
componentName: 'GetSingleDataNode',
|
|
534
898
|
id: nodeId,
|
|
@@ -542,22 +906,11 @@ function buildDataRetrieveViewNode(node, nodeId, context) {
|
|
|
542
906
|
originalType: props.originalType,
|
|
543
907
|
appType: context.appType,
|
|
544
908
|
sourceId: props.sourceId,
|
|
545
|
-
targetItem
|
|
546
|
-
appType: context.appType,
|
|
547
|
-
appName: '',
|
|
548
|
-
formItem: {
|
|
549
|
-
formType: 'receipt',
|
|
550
|
-
advanceProc: 'n',
|
|
551
|
-
formUuid: props.sourceId,
|
|
552
|
-
title: formName,
|
|
553
|
-
fields: null,
|
|
554
|
-
hasTableField: null,
|
|
555
|
-
},
|
|
556
|
-
},
|
|
909
|
+
targetItem,
|
|
557
910
|
subSourceId: props.subSourceId,
|
|
558
|
-
relativeItem
|
|
911
|
+
relativeItem,
|
|
559
912
|
filterType: 'condition',
|
|
560
|
-
condition:
|
|
913
|
+
condition: viewCondition,
|
|
561
914
|
sort: props.sort,
|
|
562
915
|
rulesFilter: [],
|
|
563
916
|
outputs: [],
|
|
@@ -570,24 +923,63 @@ function buildDataRetrieveViewNode(node, nodeId, context) {
|
|
|
570
923
|
};
|
|
571
924
|
}
|
|
572
925
|
|
|
573
|
-
function
|
|
926
|
+
function resolveCreateTarget(node, context) {
|
|
927
|
+
if (isSubTableInsert(node)) {
|
|
928
|
+
const sourceAlias = getSourceAlias(node);
|
|
929
|
+
const sourceNodeId = resolveAlias(sourceAlias, context);
|
|
930
|
+
const sourceNode = resolveContextSourceNode(node, context) || {};
|
|
931
|
+
const parentFormUuid = resolveSubTableParentFormUuidFromContext(node, context);
|
|
932
|
+
const parentFormName = resolveDataSourceFormName(sourceNode, context)
|
|
933
|
+
|| (parentFormUuid && context.formNamesByUuid.get(parentFormUuid))
|
|
934
|
+
|| sourceNode.formName
|
|
935
|
+
|| parentFormUuid;
|
|
936
|
+
const formName = sourceNode.name
|
|
937
|
+
|| sourceNode.formName
|
|
938
|
+
|| node.formName
|
|
939
|
+
|| parentFormName
|
|
940
|
+
|| sourceAlias;
|
|
941
|
+
return {
|
|
942
|
+
formUuid: sourceNodeId,
|
|
943
|
+
insertType: 'sub_table',
|
|
944
|
+
subFormUuid: node.subFormUuid,
|
|
945
|
+
sourceId: '',
|
|
946
|
+
parentFormUuid,
|
|
947
|
+
parentFormName,
|
|
948
|
+
parentFormType: resolveDataSourceFormType(sourceNode, context),
|
|
949
|
+
formName,
|
|
950
|
+
subFormLabel: node.subSourceLabel || node.subFormLabel || node.subFormUuid,
|
|
951
|
+
isSubTable: true,
|
|
952
|
+
};
|
|
953
|
+
}
|
|
574
954
|
const formUuid = node.formUuid || node.targetFormUuid;
|
|
575
|
-
|
|
955
|
+
return {
|
|
956
|
+
formUuid,
|
|
957
|
+
insertType: node.insertType || 'form',
|
|
958
|
+
subFormUuid: node.subFormUuid || '',
|
|
959
|
+
sourceId: node.sourceId || '',
|
|
960
|
+
parentFormUuid: formUuid,
|
|
961
|
+
formName: node.formName || context.formNamesByUuid.get(formUuid) || formUuid,
|
|
962
|
+
isSubTable: false,
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
function buildDataCreateProcessNode(node, nodeId, nextNodeId, context) {
|
|
967
|
+
const target = resolveCreateTarget(node, context);
|
|
576
968
|
const assignments = normalizeAssignments(node.assignments, context);
|
|
577
969
|
return {
|
|
578
970
|
name: { zh_CN: node.name || '新增数据', en_US: '' },
|
|
579
|
-
description: configuredDescription(node, t('integration.spec_desc_create', formName, assignments.length)),
|
|
971
|
+
description: configuredDescription(node, t('integration.spec_desc_create', target.formName, assignments.length)),
|
|
580
972
|
type: 'dataCreate',
|
|
581
973
|
nodeId,
|
|
582
974
|
prevId: '',
|
|
583
975
|
nextId: [nextNodeId],
|
|
584
976
|
props: {
|
|
585
|
-
formUuid,
|
|
977
|
+
formUuid: target.formUuid,
|
|
586
978
|
appType: context.appType,
|
|
587
|
-
subFormUuid:
|
|
588
|
-
insertType:
|
|
979
|
+
subFormUuid: target.subFormUuid || '',
|
|
980
|
+
insertType: target.insertType,
|
|
589
981
|
type: node.createType || 'single',
|
|
590
|
-
sourceId:
|
|
982
|
+
sourceId: target.sourceId,
|
|
591
983
|
assignments: buildDataCreateAssignments(assignments),
|
|
592
984
|
},
|
|
593
985
|
childNodes: [],
|
|
@@ -595,18 +987,25 @@ function buildDataCreateProcessNode(node, nodeId, nextNodeId, context) {
|
|
|
595
987
|
}
|
|
596
988
|
|
|
597
989
|
function buildDataCreateViewNode(node, nodeId, context) {
|
|
598
|
-
const
|
|
599
|
-
const
|
|
600
|
-
const
|
|
601
|
-
|
|
990
|
+
const target = resolveCreateTarget(node, context);
|
|
991
|
+
const schemaComponents = context.formSchemasByUuid.get(target.parentFormUuid) || [];
|
|
992
|
+
const inputChildList = target.isSubTable
|
|
993
|
+
? buildSubTableAddDataChildList(schemaComponents, target.subFormUuid)
|
|
994
|
+
: buildAddDataChildList(schemaComponents);
|
|
995
|
+
const columnList = inputChildList.filter((item) => item.componentName !== 'TableField');
|
|
602
996
|
const normalizedAssignments = normalizeAssignments(node.assignments, context);
|
|
603
|
-
assertAssignmentFieldsExist(normalizedAssignments,
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
997
|
+
assertAssignmentFieldsExist(normalizedAssignments, columnList);
|
|
998
|
+
const inputOptionMap = {};
|
|
999
|
+
inputChildList.forEach((item) => {
|
|
1000
|
+
inputOptionMap[item.fieldId] = item.componentOption || '[]';
|
|
1001
|
+
});
|
|
1002
|
+
const columnOptionMap = {};
|
|
1003
|
+
columnList.forEach((item) => {
|
|
1004
|
+
columnOptionMap[item.fieldId] = item.componentOption || '[]';
|
|
607
1005
|
});
|
|
608
1006
|
const assignmentRules = normalizedAssignments.map((assignment) => {
|
|
609
|
-
const matchedField =
|
|
1007
|
+
const matchedField = columnList.find((item) => item.fieldId === assignment.column);
|
|
1008
|
+
const label = matchedField ? matchedField.label : assignment.column;
|
|
610
1009
|
return {
|
|
611
1010
|
name: assignment.column,
|
|
612
1011
|
componentName: matchedField ? matchedField.componentName : 'TextField',
|
|
@@ -614,8 +1013,9 @@ function buildDataCreateViewNode(node, nodeId, context) {
|
|
|
614
1013
|
value: assignment.value,
|
|
615
1014
|
required: false,
|
|
616
1015
|
ruleId: generateDataRuleId(),
|
|
617
|
-
componentOption: '[]',
|
|
618
|
-
label
|
|
1016
|
+
componentOption: matchedField && matchedField.componentOption ? matchedField.componentOption : '[]',
|
|
1017
|
+
label,
|
|
1018
|
+
valueLabel: label,
|
|
619
1019
|
componentProps: {
|
|
620
1020
|
defaultDataSource: {},
|
|
621
1021
|
relateAppType: '',
|
|
@@ -624,7 +1024,58 @@ function buildDataCreateViewNode(node, nodeId, context) {
|
|
|
624
1024
|
},
|
|
625
1025
|
};
|
|
626
1026
|
});
|
|
627
|
-
const description = node.description
|
|
1027
|
+
const description = node.description
|
|
1028
|
+
|| (target.isSubTable
|
|
1029
|
+
? `在 [${target.formName}] 中新增数据`
|
|
1030
|
+
: `在[${target.formName}]中新增 ${assignmentRules.length} 个字段`);
|
|
1031
|
+
const addDataRules = {
|
|
1032
|
+
description,
|
|
1033
|
+
formUuid: target.formUuid,
|
|
1034
|
+
appType: context.appType,
|
|
1035
|
+
insertType: target.insertType,
|
|
1036
|
+
type: node.createType || 'single',
|
|
1037
|
+
subFormUuid: target.subFormUuid || '',
|
|
1038
|
+
sourceId: target.sourceId,
|
|
1039
|
+
assignments: assignmentRules,
|
|
1040
|
+
inputs: { childList: inputChildList, componentOptionMap: inputOptionMap },
|
|
1041
|
+
rules: {
|
|
1042
|
+
childList: columnList,
|
|
1043
|
+
componentOptionMap: columnOptionMap,
|
|
1044
|
+
ruleId: generateDataRuleId(),
|
|
1045
|
+
rules: assignmentRules,
|
|
1046
|
+
},
|
|
1047
|
+
};
|
|
1048
|
+
if (target.isSubTable) {
|
|
1049
|
+
const tableFields = listTableFieldSummaries(schemaComponents);
|
|
1050
|
+
const parentFormName = target.parentFormName || target.formName;
|
|
1051
|
+
const targetItem = {
|
|
1052
|
+
deep: 0,
|
|
1053
|
+
value: target.formUuid,
|
|
1054
|
+
label: target.formName,
|
|
1055
|
+
appType: context.appType,
|
|
1056
|
+
appName: '',
|
|
1057
|
+
};
|
|
1058
|
+
if (target.parentFormUuid) {
|
|
1059
|
+
targetItem.formItem = {
|
|
1060
|
+
formType: resolveDataFormItemType(target.parentFormType),
|
|
1061
|
+
advanceProc: 'n',
|
|
1062
|
+
formUuid: target.parentFormUuid,
|
|
1063
|
+
title: parentFormName,
|
|
1064
|
+
fields: null,
|
|
1065
|
+
hasTableField: tableFields.length > 0 ? true : null,
|
|
1066
|
+
};
|
|
1067
|
+
addDataRules.formItem = targetItem.formItem;
|
|
1068
|
+
}
|
|
1069
|
+
addDataRules.targetItem = targetItem;
|
|
1070
|
+
addDataRules.crossForm = targetItem;
|
|
1071
|
+
addDataRules.relativeItem = buildSubTableRelativeItem(
|
|
1072
|
+
target.subFormUuid,
|
|
1073
|
+
resolveTableFieldLabel(schemaComponents, target.subFormUuid, target.subFormLabel)
|
|
1074
|
+
);
|
|
1075
|
+
addDataRules.relativeList = [addDataRules.relativeItem];
|
|
1076
|
+
addDataRules.subFormItem = addDataRules.relativeItem;
|
|
1077
|
+
addDataRules.subFormName = addDataRules.relativeItem.label;
|
|
1078
|
+
}
|
|
628
1079
|
return {
|
|
629
1080
|
componentName: 'AddDataNode',
|
|
630
1081
|
id: nodeId,
|
|
@@ -632,23 +1083,7 @@ function buildDataCreateViewNode(node, nodeId, context) {
|
|
|
632
1083
|
nodeName: 'AddDataNode',
|
|
633
1084
|
name: node.name || '新增数据',
|
|
634
1085
|
description,
|
|
635
|
-
addDataRules
|
|
636
|
-
description,
|
|
637
|
-
formUuid,
|
|
638
|
-
appType: context.appType,
|
|
639
|
-
insertType: node.insertType || 'form',
|
|
640
|
-
type: node.createType || 'single',
|
|
641
|
-
subFormUuid: node.subFormUuid || '',
|
|
642
|
-
sourceId: node.sourceId || '',
|
|
643
|
-
assignments: assignmentRules,
|
|
644
|
-
inputs: { childList, componentOptionMap },
|
|
645
|
-
rules: {
|
|
646
|
-
childList,
|
|
647
|
-
componentOptionMap,
|
|
648
|
-
ruleId: generateDataRuleId(),
|
|
649
|
-
rules: assignmentRules,
|
|
650
|
-
},
|
|
651
|
-
},
|
|
1086
|
+
addDataRules,
|
|
652
1087
|
},
|
|
653
1088
|
title: node.name || '新增数据',
|
|
654
1089
|
};
|
|
@@ -1172,14 +1607,24 @@ function buildFinishNodes(endNodeId) {
|
|
|
1172
1607
|
|
|
1173
1608
|
function buildSpecProcessAndViewJson(options) {
|
|
1174
1609
|
const spec = options.spec || {};
|
|
1175
|
-
validateIntegrationSpec(spec, options.formEventTypes || ['insert']
|
|
1610
|
+
validateIntegrationSpec(spec, options.formEventTypes || ['insert'], {
|
|
1611
|
+
formUuid: options.formUuid,
|
|
1612
|
+
});
|
|
1176
1613
|
const nodes = getSpecNodes(spec);
|
|
1614
|
+
// Validate all source declarations, including duplicate UUIDs, before any
|
|
1615
|
+
// caller can serialize the generated payload for a remote write.
|
|
1616
|
+
collectDataSourceFormDescriptors(spec, options.formUuid);
|
|
1177
1617
|
|
|
1178
1618
|
const context = {
|
|
1179
1619
|
appType: options.appType,
|
|
1180
1620
|
formUuid: options.formUuid,
|
|
1181
1621
|
flowName: options.flowName || '',
|
|
1182
1622
|
defaultFormEventTypes: options.formEventTypes || ['insert'],
|
|
1623
|
+
formEventTypes: mapSpecEventTypes(spec, options.formEventTypes || ['insert']),
|
|
1624
|
+
defaultFormType: options.dataFormType || options.formType || '',
|
|
1625
|
+
defaultFormName: options.dataFormName || options.dataSourceFormName || options.formName || '',
|
|
1626
|
+
dataSourceForm: options.dataSourceForm || null,
|
|
1627
|
+
dataSourceFormsByUuid: options.dataSourceFormsByUuid || new Map(),
|
|
1183
1628
|
defaultNotificationTitle: options.notificationTitle,
|
|
1184
1629
|
defaultNotificationContent: options.notificationContent,
|
|
1185
1630
|
defaultToUsers: options.toUsers || [],
|
|
@@ -1190,6 +1635,7 @@ function buildSpecProcessAndViewJson(options) {
|
|
|
1190
1635
|
processCode: options.processCode,
|
|
1191
1636
|
aliasToNodeId: new Map(),
|
|
1192
1637
|
nodeIdToAlias: new Map(),
|
|
1638
|
+
aliasToSpecNode: new Map(),
|
|
1193
1639
|
generatedIndex: 1,
|
|
1194
1640
|
};
|
|
1195
1641
|
const canvasId = options.canvasId || generateNodeId();
|
|
@@ -1226,25 +1672,74 @@ function buildSpecProcessAndViewJson(options) {
|
|
|
1226
1672
|
};
|
|
1227
1673
|
}
|
|
1228
1674
|
|
|
1229
|
-
function
|
|
1230
|
-
const result = new
|
|
1675
|
+
function collectDataSourceFormDescriptors(spec, triggerFormUuid) {
|
|
1676
|
+
const result = new Map();
|
|
1677
|
+
|
|
1231
1678
|
function visit(nodes) {
|
|
1232
1679
|
for (const node of asArray(nodes)) {
|
|
1680
|
+
if (!node || typeof node !== 'object') {
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1233
1683
|
const type = normalizeNodeType(node.type || node.componentName);
|
|
1234
|
-
if (type === '
|
|
1235
|
-
const
|
|
1684
|
+
if (type === 'getSelf' || type === 'dataRetrieve') {
|
|
1685
|
+
const declaredType = resolveDeclaredSourceFormType(node);
|
|
1686
|
+
const formUuid = resolveSourceFormUuid({ ...node, type }, { formUuid: triggerFormUuid });
|
|
1236
1687
|
if (formUuid) {
|
|
1237
|
-
|
|
1688
|
+
const key = String(formUuid);
|
|
1689
|
+
const existing = result.get(key) || { formUuid: key };
|
|
1690
|
+
if (declaredType.normalized) {
|
|
1691
|
+
if (existing.formType
|
|
1692
|
+
&& normalizeSourceFormType(existing.formType) !== declaredType.normalized) {
|
|
1693
|
+
throw new Error(
|
|
1694
|
+
`Conflicting source form types for ${key}: ${existing.formType} and ${declaredType.rawValue}`
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
existing.formType = declaredType.normalized;
|
|
1698
|
+
}
|
|
1699
|
+
if (node.formName || node.sourceFormName || node.dataFormName) {
|
|
1700
|
+
existing.formName = node.formName || node.sourceFormName || node.dataFormName;
|
|
1701
|
+
}
|
|
1702
|
+
result.set(key, existing);
|
|
1238
1703
|
}
|
|
1239
1704
|
}
|
|
1240
1705
|
if (type === 'route') {
|
|
1241
1706
|
for (const branch of asArray(node.branches || node.conditions)) {
|
|
1242
|
-
visit(branch.nodes || branch.childNodes || branch.children);
|
|
1707
|
+
visit(branch && (branch.nodes || branch.childNodes || branch.children));
|
|
1243
1708
|
}
|
|
1244
1709
|
}
|
|
1245
1710
|
}
|
|
1246
1711
|
}
|
|
1712
|
+
|
|
1247
1713
|
visit(getSpecNodes(spec));
|
|
1714
|
+
return Array.from(result.values());
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
function collectAddDataFormUuids(spec, triggerFormUuid, options = {}) {
|
|
1718
|
+
const kind = options.kind || 'all';
|
|
1719
|
+
const result = new Set();
|
|
1720
|
+
visitSpecNodes(spec, (node) => {
|
|
1721
|
+
const type = normalizeNodeType(node.type || node.componentName);
|
|
1722
|
+
if (type !== 'dataCreate') {
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
if (isSubTableInsert(node)) {
|
|
1726
|
+
if (kind === 'direct') {
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
const parentFormUuid = resolveSubTableParentFormUuid(node, spec, triggerFormUuid);
|
|
1730
|
+
if (parentFormUuid) {
|
|
1731
|
+
result.add(parentFormUuid);
|
|
1732
|
+
}
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
if (kind === 'sub_table') {
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
const formUuid = node.formUuid || node.targetFormUuid;
|
|
1739
|
+
if (formUuid) {
|
|
1740
|
+
result.add(formUuid);
|
|
1741
|
+
}
|
|
1742
|
+
});
|
|
1248
1743
|
return Array.from(result);
|
|
1249
1744
|
}
|
|
1250
1745
|
|
|
@@ -1294,6 +1789,7 @@ module.exports = {
|
|
|
1294
1789
|
validateIntegrationSpec,
|
|
1295
1790
|
buildSpecProcessAndViewJson,
|
|
1296
1791
|
collectAddDataFormUuids,
|
|
1792
|
+
collectDataSourceFormDescriptors,
|
|
1297
1793
|
collectInitiateApprovalFormUuids,
|
|
1298
1794
|
hasSpecNodeType,
|
|
1299
1795
|
_private: {
|
|
@@ -1301,6 +1797,7 @@ module.exports = {
|
|
|
1301
1797
|
mapSpecEventTypes,
|
|
1302
1798
|
normalizeNodeType,
|
|
1303
1799
|
resolveNodeRefs,
|
|
1800
|
+
resolveDesignerSourceRefs,
|
|
1304
1801
|
buildSpecNodeList,
|
|
1305
1802
|
buildDataUpdateRules,
|
|
1306
1803
|
},
|