@servicenow/sdk-build-plugins 4.6.1 → 4.7.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/dist/acl-plugin.js +0 -3
- package/dist/acl-plugin.js.map +1 -1
- package/dist/applicability-plugin.js +0 -2
- package/dist/applicability-plugin.js.map +1 -1
- package/dist/application-menu-plugin.js +0 -2
- package/dist/application-menu-plugin.js.map +1 -1
- package/dist/arrow-function-plugin.js +0 -1
- package/dist/arrow-function-plugin.js.map +1 -1
- package/dist/atf/test-plugin.js +0 -2
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +0 -1
- package/dist/basic-syntax-plugin.js.map +1 -1
- package/dist/business-rule-plugin.js +0 -1
- package/dist/business-rule-plugin.js.map +1 -1
- package/dist/call-expression-plugin.js +0 -1
- package/dist/call-expression-plugin.js.map +1 -1
- package/dist/claims-plugin.js +0 -1
- package/dist/claims-plugin.js.map +1 -1
- package/dist/client-script-plugin.js +0 -1
- package/dist/client-script-plugin.js.map +1 -1
- package/dist/column-plugin.js +24 -7
- package/dist/column-plugin.js.map +1 -1
- package/dist/cross-scope-privilege-plugin.js +0 -1
- package/dist/cross-scope-privilege-plugin.js.map +1 -1
- package/dist/dashboard/dashboard-plugin.js +0 -2
- package/dist/dashboard/dashboard-plugin.js.map +1 -1
- package/dist/data-plugin.js +0 -1
- package/dist/data-plugin.js.map +1 -1
- package/dist/data-policy-plugin.d.ts +2 -0
- package/dist/data-policy-plugin.js +276 -0
- package/dist/data-policy-plugin.js.map +1 -0
- package/dist/email-notification-plugin.js +2 -3
- package/dist/email-notification-plugin.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-constants.d.ts +2 -0
- package/dist/flow/flow-logic/flow-logic-constants.js +6 -1
- package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-diagnostics.js +192 -56
- package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +2 -1
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +44 -5
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-plugin.js +279 -29
- package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -1
- package/dist/flow/flow-logic/flow-logic-shapes.d.ts +15 -0
- package/dist/flow/flow-logic/flow-logic-shapes.js +25 -1
- package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -1
- package/dist/flow/plugins/approval-rules-plugin.js +0 -1
- package/dist/flow/plugins/approval-rules-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-action-definition-plugin.js +804 -205
- package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-data-pill-plugin.js +3 -5
- package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-definition-plugin.js +84 -17
- package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-diagnostics-plugin.js +65 -3
- package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-instance-plugin.js +13 -5
- package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/flow-trigger-instance-plugin.js +0 -1
- package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/inline-script-plugin.js +0 -1
- package/dist/flow/plugins/inline-script-plugin.js.map +1 -1
- package/dist/flow/plugins/step-definition-plugin.js +0 -2
- package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
- package/dist/flow/plugins/step-instance-plugin.js +216 -77
- package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
- package/dist/flow/plugins/trigger-plugin.js +0 -2
- package/dist/flow/plugins/trigger-plugin.js.map +1 -1
- package/dist/flow/plugins/wfa-datapill-plugin.js +0 -1
- package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
- package/dist/flow/utils/datapill-transformer.js +9 -5
- package/dist/flow/utils/datapill-transformer.js.map +1 -1
- package/dist/flow/utils/flow-constants.d.ts +12 -0
- package/dist/flow/utils/flow-constants.js +17 -3
- package/dist/flow/utils/flow-constants.js.map +1 -1
- package/dist/flow/utils/flow-io-to-record.d.ts +1 -1
- package/dist/flow/utils/flow-io-to-record.js +21 -13
- package/dist/flow/utils/flow-io-to-record.js.map +1 -1
- package/dist/flow/utils/flow-pill-utils.d.ts +26 -0
- package/dist/flow/utils/flow-pill-utils.js +50 -0
- package/dist/flow/utils/flow-pill-utils.js.map +1 -0
- package/dist/flow/utils/flow-stage-processor.d.ts +138 -0
- package/dist/flow/utils/flow-stage-processor.js +665 -0
- package/dist/flow/utils/flow-stage-processor.js.map +1 -0
- package/dist/flow/utils/pill-string-parser.js +28 -43
- package/dist/flow/utils/pill-string-parser.js.map +1 -1
- package/dist/flow/utils/utils.d.ts +11 -6
- package/dist/flow/utils/utils.js +37 -28
- package/dist/flow/utils/utils.js.map +1 -1
- package/dist/form-plugin.js +4 -14
- package/dist/form-plugin.js.map +1 -1
- package/dist/html-import-plugin.js +0 -1
- package/dist/html-import-plugin.js.map +1 -1
- package/dist/import-sets-plugin.js +0 -2
- package/dist/import-sets-plugin.js.map +1 -1
- package/dist/inbound-email-action-plugin.js +0 -1
- package/dist/inbound-email-action-plugin.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/instance-scan-plugin.js +0 -7
- package/dist/instance-scan-plugin.js.map +1 -1
- package/dist/json-plugin.js +0 -1
- package/dist/json-plugin.js.map +1 -1
- package/dist/list-plugin.js +4 -1
- package/dist/list-plugin.js.map +1 -1
- package/dist/now-attach-plugin.js +0 -1
- package/dist/now-attach-plugin.js.map +1 -1
- package/dist/now-config-plugin.js +0 -1
- package/dist/now-config-plugin.js.map +1 -1
- package/dist/now-id-plugin.js +0 -1
- package/dist/now-id-plugin.js.map +1 -1
- package/dist/now-include-plugin.js +0 -1
- package/dist/now-include-plugin.js.map +1 -1
- package/dist/now-ref-plugin.js +0 -1
- package/dist/now-ref-plugin.js.map +1 -1
- package/dist/now-unresolved-plugin.js +0 -1
- package/dist/now-unresolved-plugin.js.map +1 -1
- package/dist/package-json-plugin.js +3 -2
- package/dist/package-json-plugin.js.map +1 -1
- package/dist/property-plugin.js +0 -2
- package/dist/property-plugin.js.map +1 -1
- package/dist/record-plugin.d.ts +2 -0
- package/dist/record-plugin.js +2 -2
- package/dist/record-plugin.js.map +1 -1
- package/dist/repack/lint/Rules.d.ts +1 -2
- package/dist/rest-api-plugin.js +6 -5
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/role-plugin.js +0 -1
- package/dist/role-plugin.js.map +1 -1
- package/dist/schedule-script/scheduled-script-plugin.js +5 -4
- package/dist/schedule-script/scheduled-script-plugin.js.map +1 -1
- package/dist/script-action-plugin.js +0 -2
- package/dist/script-action-plugin.js.map +1 -1
- package/dist/script-include-plugin.js +0 -4
- package/dist/script-include-plugin.js.map +1 -1
- package/dist/server-module-plugin/index.js +2 -3
- package/dist/server-module-plugin/index.js.map +1 -1
- package/dist/service-catalog/catalog-clientscript-plugin.js +0 -2
- package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
- package/dist/service-catalog/catalog-item-plugin.js +0 -2
- package/dist/service-catalog/catalog-item-plugin.js.map +1 -1
- package/dist/service-catalog/catalog-ui-policy-plugin.js +0 -2
- package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
- package/dist/service-catalog/sc-record-producer-plugin.js +0 -2
- package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -1
- package/dist/service-catalog/variable-set-plugin.js +0 -2
- package/dist/service-catalog/variable-set-plugin.js.map +1 -1
- package/dist/service-portal/angular-provider-plugin.js +0 -2
- package/dist/service-portal/angular-provider-plugin.js.map +1 -1
- package/dist/service-portal/dependency-plugin.js +3 -5
- package/dist/service-portal/dependency-plugin.js.map +1 -1
- package/dist/service-portal/header-footer-plugin.js +3 -5
- package/dist/service-portal/header-footer-plugin.js.map +1 -1
- package/dist/service-portal/menu-plugin.js +0 -1
- package/dist/service-portal/menu-plugin.js.map +1 -1
- package/dist/service-portal/page-plugin.js +0 -1
- package/dist/service-portal/page-plugin.js.map +1 -1
- package/dist/service-portal/page-route-map-plugin.js +0 -1
- package/dist/service-portal/page-route-map-plugin.js.map +1 -1
- package/dist/service-portal/portal-plugin.js +0 -2
- package/dist/service-portal/portal-plugin.js.map +1 -1
- package/dist/service-portal/theme-plugin.js +0 -2
- package/dist/service-portal/theme-plugin.js.map +1 -1
- package/dist/service-portal/widget-plugin.js +3 -5
- package/dist/service-portal/widget-plugin.js.map +1 -1
- package/dist/sla-plugin.js +0 -2
- package/dist/sla-plugin.js.map +1 -1
- package/dist/static-content-plugin.js +32 -3
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +102 -11
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-action-plugin.js +26 -17
- package/dist/ui-action-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +159 -17
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/ui-policy-plugin.js +0 -1
- package/dist/ui-policy-plugin.js.map +1 -1
- package/dist/user-preference-plugin.js +0 -2
- package/dist/user-preference-plugin.js.map +1 -1
- package/dist/utils.d.ts +1 -9
- package/dist/utils.js +0 -14
- package/dist/utils.js.map +1 -1
- package/dist/ux-list-menu-config-plugin.js +0 -2
- package/dist/ux-list-menu-config-plugin.js.map +1 -1
- package/dist/view-plugin.js +0 -1
- package/dist/view-plugin.js.map +1 -1
- package/dist/workspace-plugin.js +0 -2
- package/dist/workspace-plugin.js.map +1 -1
- package/package.json +6 -6
- package/src/acl-plugin.ts +1 -4
- package/src/applicability-plugin.ts +0 -2
- package/src/application-menu-plugin.ts +0 -2
- package/src/arrow-function-plugin.ts +0 -1
- package/src/atf/test-plugin.ts +0 -2
- package/src/basic-syntax-plugin.ts +0 -1
- package/src/business-rule-plugin.ts +1 -2
- package/src/call-expression-plugin.ts +0 -1
- package/src/claims-plugin.ts +0 -1
- package/src/client-script-plugin.ts +1 -2
- package/src/column-plugin.ts +29 -9
- package/src/cross-scope-privilege-plugin.ts +1 -2
- package/src/dashboard/dashboard-plugin.ts +0 -2
- package/src/data-plugin.ts +0 -1
- package/src/data-policy-plugin.ts +333 -0
- package/src/email-notification-plugin.ts +8 -4
- package/src/flow/flow-logic/flow-logic-constants.ts +6 -0
- package/src/flow/flow-logic/flow-logic-diagnostics.ts +236 -58
- package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +59 -6
- package/src/flow/flow-logic/flow-logic-plugin.ts +368 -38
- package/src/flow/flow-logic/flow-logic-shapes.ts +25 -0
- package/src/flow/plugins/approval-rules-plugin.ts +0 -1
- package/src/flow/plugins/flow-action-definition-plugin.ts +940 -208
- package/src/flow/plugins/flow-data-pill-plugin.ts +3 -5
- package/src/flow/plugins/flow-definition-plugin.ts +159 -26
- package/src/flow/plugins/flow-diagnostics-plugin.ts +89 -3
- package/src/flow/plugins/flow-instance-plugin.ts +26 -12
- package/src/flow/plugins/flow-trigger-instance-plugin.ts +0 -1
- package/src/flow/plugins/inline-script-plugin.ts +0 -1
- package/src/flow/plugins/step-definition-plugin.ts +0 -2
- package/src/flow/plugins/step-instance-plugin.ts +259 -65
- package/src/flow/plugins/trigger-plugin.ts +0 -2
- package/src/flow/plugins/wfa-datapill-plugin.ts +0 -1
- package/src/flow/utils/datapill-transformer.ts +13 -5
- package/src/flow/utils/flow-constants.ts +19 -1
- package/src/flow/utils/flow-io-to-record.ts +29 -19
- package/src/flow/utils/flow-pill-utils.ts +48 -0
- package/src/flow/utils/flow-stage-processor.ts +831 -0
- package/src/flow/utils/pill-string-parser.ts +29 -47
- package/src/flow/utils/utils.ts +39 -35
- package/src/form-plugin.ts +5 -15
- package/src/html-import-plugin.ts +0 -1
- package/src/import-sets-plugin.ts +0 -2
- package/src/inbound-email-action-plugin.ts +1 -2
- package/src/index.ts +7 -1
- package/src/instance-scan-plugin.ts +0 -7
- package/src/json-plugin.ts +0 -1
- package/src/list-plugin.ts +6 -2
- package/src/now-attach-plugin.ts +0 -1
- package/src/now-config-plugin.ts +0 -1
- package/src/now-id-plugin.ts +0 -1
- package/src/now-include-plugin.ts +0 -1
- package/src/now-ref-plugin.ts +0 -1
- package/src/now-unresolved-plugin.ts +0 -1
- package/src/package-json-plugin.ts +8 -3
- package/src/property-plugin.ts +0 -2
- package/src/record-plugin.ts +3 -3
- package/src/repack/lint/Rules.ts +1 -1
- package/src/rest-api-plugin.ts +7 -6
- package/src/role-plugin.ts +1 -2
- package/src/schedule-script/scheduled-script-plugin.ts +11 -5
- package/src/script-action-plugin.ts +0 -2
- package/src/script-include-plugin.ts +0 -4
- package/src/server-module-plugin/index.ts +2 -3
- package/src/service-catalog/catalog-clientscript-plugin.ts +0 -2
- package/src/service-catalog/catalog-item-plugin.ts +0 -2
- package/src/service-catalog/catalog-ui-policy-plugin.ts +0 -2
- package/src/service-catalog/sc-record-producer-plugin.ts +0 -2
- package/src/service-catalog/variable-set-plugin.ts +0 -2
- package/src/service-portal/angular-provider-plugin.ts +0 -2
- package/src/service-portal/dependency-plugin.ts +0 -2
- package/src/service-portal/header-footer-plugin.ts +0 -2
- package/src/service-portal/menu-plugin.ts +1 -2
- package/src/service-portal/page-plugin.ts +1 -2
- package/src/service-portal/page-route-map-plugin.ts +1 -2
- package/src/service-portal/portal-plugin.ts +0 -2
- package/src/service-portal/theme-plugin.ts +0 -2
- package/src/service-portal/widget-plugin.ts +0 -2
- package/src/sla-plugin.ts +0 -2
- package/src/static-content-plugin.ts +37 -4
- package/src/table-plugin.ts +118 -16
- package/src/ui-action-plugin.ts +30 -17
- package/src/ui-page-plugin.ts +188 -20
- package/src/ui-policy-plugin.ts +1 -2
- package/src/user-preference-plugin.ts +0 -2
- package/src/utils.ts +0 -15
- package/src/ux-list-menu-config-plugin.ts +0 -2
- package/src/view-plugin.ts +0 -1
- package/src/workspace-plugin.ts +0 -2
|
@@ -3,19 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ActionDefinitionPlugin = void 0;
|
|
4
4
|
const sdk_build_core_1 = require("@servicenow/sdk-build-core");
|
|
5
5
|
const flow_io_to_record_1 = require("../utils/flow-io-to-record");
|
|
6
|
+
const built_in_complex_objects_1 = require("../utils/built-in-complex-objects");
|
|
6
7
|
const flow_to_xml_1 = require("../utils/flow-to-xml");
|
|
7
8
|
const flow_constants_1 = require("../utils/flow-constants");
|
|
9
|
+
const flow_pill_utils_1 = require("../utils/flow-pill-utils");
|
|
8
10
|
const column_helper_1 = require("../../column/column-helper");
|
|
9
11
|
const schema_to_flow_object_1 = require("../utils/schema-to-flow-object");
|
|
10
12
|
const flow_instance_plugin_1 = require("./flow-instance-plugin");
|
|
13
|
+
const flow_shapes_1 = require("../utils/flow-shapes");
|
|
11
14
|
const arrow_function_plugin_1 = require("../../arrow-function-plugin");
|
|
12
|
-
const utils_1 = require("../../utils");
|
|
13
15
|
const inline_script_plugin_1 = require("./inline-script-plugin");
|
|
14
16
|
const step_instance_plugin_1 = require("./step-instance-plugin");
|
|
15
17
|
const now_id_plugin_1 = require("../../now-id-plugin");
|
|
16
18
|
const now_include_plugin_1 = require("../../now-include-plugin");
|
|
17
|
-
const
|
|
19
|
+
const utils_1 = require("../utils/utils");
|
|
18
20
|
const pill_string_parser_1 = require("../utils/pill-string-parser");
|
|
21
|
+
const data_pill_shapes_1 = require("../utils/data-pill-shapes");
|
|
19
22
|
const label_cache_parser_1 = require("../utils/label-cache-parser");
|
|
20
23
|
const column_helper_2 = require("../../column/column-helper");
|
|
21
24
|
const pill_shape_helpers_1 = require("../utils/pill-shape-helpers");
|
|
@@ -127,70 +130,52 @@ function resolveAnyPillFromShape(fieldShape, cidMap) {
|
|
|
127
130
|
const pathParts = propertyNames.slice(1);
|
|
128
131
|
return { pill: `{{step[${stepCid}].${pathParts.join('.')}${typeSuffix}}}`, isStep: true };
|
|
129
132
|
}
|
|
130
|
-
|
|
131
|
-
* Strips the |type suffix from a pill string.
|
|
132
|
-
* e.g., "{{step[CID].record.number|string}}" → "{{step[CID].record.number}}"
|
|
133
|
-
* Note: Mirrors stripPillType in step-instance-plugin.ts (kept separate to avoid exporting private functions).
|
|
134
|
-
*/
|
|
135
|
-
function stripPillTypeSuffix(pill) {
|
|
136
|
-
return pill.replace(/\|[^}]+/, '');
|
|
137
|
-
}
|
|
138
|
-
/** Regex for extracting step pill type annotations — same pattern as STEP_PILL_TYPE_REGEX in step-instance-plugin.ts */
|
|
139
|
-
const STEP_PILL_WITH_TYPE_REGEX = /\{\{step\[([^\]]+)\]\.([^|}]+)(?:\|([^}]+))?\}\}/g;
|
|
140
|
-
/** Extracts the step pill type annotation from a pill string and stores it in pillTypeMap for label_cache. */
|
|
141
|
-
function collectStepPillType(pill, pillTypeMap) {
|
|
142
|
-
for (const match of pill.matchAll(STEP_PILL_WITH_TYPE_REGEX)) {
|
|
143
|
-
const [, cid, pillPath, dataType] = match;
|
|
144
|
-
if (cid && pillPath && dataType) {
|
|
145
|
-
pillTypeMap.set(`${cid}::${pillPath}`, dataType);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
133
|
+
// stripPillType, collectPillTypes, and STEP_PILL_TYPE_REGEX are imported from ../utils/flow-pill-utils
|
|
149
134
|
/** Creates a sys_element_mapping record — shared by all cases in resolveUnresolvedStepPills. */
|
|
150
|
-
function createElementMapping(factory, source, field, id,
|
|
135
|
+
function createElementMapping(factory, source, field, id, mappingTable, value) {
|
|
151
136
|
return factory.createRecord({
|
|
152
137
|
source,
|
|
153
138
|
table: 'sys_element_mapping',
|
|
154
139
|
properties: {
|
|
155
140
|
field,
|
|
156
141
|
id,
|
|
157
|
-
table:
|
|
142
|
+
table: mappingTable,
|
|
158
143
|
value,
|
|
159
144
|
},
|
|
160
145
|
});
|
|
161
146
|
}
|
|
162
147
|
/**
|
|
163
|
-
* Resolves a TemplateExpressionShape
|
|
164
|
-
*
|
|
165
|
-
*
|
|
148
|
+
* Resolves ALL pills in a TemplateExpressionShape — both action pills (PillShape) and
|
|
149
|
+
* step pills (wfa.dataPill CallExpressionShape). Returns the full resolved pill string
|
|
150
|
+
* with type suffixes stripped. Plain text spans are preserved verbatim.
|
|
166
151
|
*/
|
|
167
|
-
function
|
|
152
|
+
function resolveAllPillsInTemplate(templateShape, cidMap, pillTypeMap) {
|
|
168
153
|
let result = templateShape.getLiteralText();
|
|
169
|
-
let hasStepPills = false;
|
|
170
154
|
for (const span of templateShape.getSpans()) {
|
|
171
155
|
const expr = span.getExpression();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
collectStepPillType(resolved.pill, pillTypeMap);
|
|
177
|
-
}
|
|
178
|
-
hasStepPills = true;
|
|
156
|
+
if (expr instanceof data_pill_shapes_1.PillShape) {
|
|
157
|
+
const raw = expr.getValue();
|
|
158
|
+
if (pillTypeMap) {
|
|
159
|
+
(0, flow_pill_utils_1.collectPillTypes)(raw, pillTypeMap);
|
|
179
160
|
}
|
|
180
|
-
result +=
|
|
161
|
+
result += (0, flow_pill_utils_1.stripPillType)(raw);
|
|
181
162
|
}
|
|
182
163
|
else {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
164
|
+
const resolved = resolveAnyPillFromShape(expr, cidMap);
|
|
165
|
+
if (resolved) {
|
|
166
|
+
if (resolved.isStep && pillTypeMap) {
|
|
167
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
168
|
+
}
|
|
169
|
+
result += (0, flow_pill_utils_1.stripPillType)(resolved.pill);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const val = String(expr.getValue?.() ?? '');
|
|
173
|
+
result += val.startsWith('{{') ? (0, flow_pill_utils_1.stripPillType)(val) : val;
|
|
174
|
+
}
|
|
187
175
|
}
|
|
188
176
|
result += span.getLiteralText();
|
|
189
177
|
}
|
|
190
|
-
|
|
191
|
-
return undefined;
|
|
192
|
-
}
|
|
193
|
-
return { result, hasStepPills };
|
|
178
|
+
return result;
|
|
194
179
|
}
|
|
195
180
|
async function resolveUnresolvedStepPills(steps, cidMap, pillTypeMap, factory) {
|
|
196
181
|
if (cidMap.size === 0 || steps.length === 0) {
|
|
@@ -203,6 +188,33 @@ async function resolveUnresolvedStepPills(steps, cidMap, pillTypeMap, factory) {
|
|
|
203
188
|
continue;
|
|
204
189
|
}
|
|
205
190
|
const valuesProperties = inputs.properties({ resolve: false });
|
|
191
|
+
// Handle inputVariables — nested object where each entry's `value` may contain step pills.
|
|
192
|
+
// Ext inputs use a different element_mapping table than regular step definition inputs.
|
|
193
|
+
const inputVariablesShape = valuesProperties['inputVariables'];
|
|
194
|
+
if (inputVariablesShape) {
|
|
195
|
+
const inputVarObj = inputVariablesShape.asObject();
|
|
196
|
+
const inputVarProps = inputVarObj.properties({ resolve: false });
|
|
197
|
+
const extInputTableName = `${flow_constants_1.EXT_INPUT_TABLE_PREFIX}${stepInstanceSysId}`;
|
|
198
|
+
for (const [varName, configShapeRaw] of Object.entries(inputVarProps)) {
|
|
199
|
+
const configObj = configShapeRaw.asObject();
|
|
200
|
+
const varValueShape = configObj.properties({ resolve: false })['value'];
|
|
201
|
+
if (!varValueShape) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const resolved = resolveAnyPillFromShape(varValueShape, cidMap);
|
|
205
|
+
if (resolved?.isStep) {
|
|
206
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
207
|
+
newRecords.push(await createElementMapping(factory, stepShape, varName, stepInstanceSysId, extInputTableName, (0, flow_pill_utils_1.stripPillType)(resolved.pill)));
|
|
208
|
+
}
|
|
209
|
+
else if (varValueShape.is(sdk_build_core_1.TemplateExpressionShape)) {
|
|
210
|
+
const resolvedText = resolveAllPillsInTemplate(varValueShape, cidMap, pillTypeMap);
|
|
211
|
+
if (resolvedText.includes('{{step[')) {
|
|
212
|
+
newRecords.push(await createElementMapping(factory, stepShape, varName, stepInstanceSysId, extInputTableName, resolvedText));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const stepDefTableName = `${flow_constants_1.STEP_DEF_INPUT_TABLE_PREFIX}${stepDefinitionSysId}`;
|
|
206
218
|
for (const [key, valueShape] of Object.entries(valuesProperties)) {
|
|
207
219
|
if (key === 'inputVariables' || key === 'outputVariables' || key === 'errorHandlingType') {
|
|
208
220
|
continue;
|
|
@@ -210,15 +222,17 @@ async function resolveUnresolvedStepPills(steps, cidMap, pillTypeMap, factory) {
|
|
|
210
222
|
// Case 1: Simple step pill — wfa.dataPill(stepVar.prop, 'type')
|
|
211
223
|
const resolved = resolveAnyPillFromShape(valueShape, cidMap);
|
|
212
224
|
if (resolved?.isStep) {
|
|
213
|
-
|
|
214
|
-
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId,
|
|
225
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
226
|
+
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId, stepDefTableName, (0, flow_pill_utils_1.stripPillType)(resolved.pill)));
|
|
215
227
|
continue;
|
|
216
228
|
}
|
|
217
229
|
// Case 2: TemplateExpressionShape with step pills
|
|
218
230
|
if (valueShape.is(sdk_build_core_1.TemplateExpressionShape)) {
|
|
219
|
-
const
|
|
220
|
-
if
|
|
221
|
-
|
|
231
|
+
const resolvedText = resolveAllPillsInTemplate(valueShape, cidMap, pillTypeMap);
|
|
232
|
+
// Only emit if step pills were resolved — action-only pills are already
|
|
233
|
+
// handled by SDK auto-processing.
|
|
234
|
+
if (resolvedText.includes('{{step[')) {
|
|
235
|
+
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId, stepDefTableName, resolvedText));
|
|
222
236
|
}
|
|
223
237
|
continue;
|
|
224
238
|
}
|
|
@@ -230,28 +244,109 @@ async function resolveUnresolvedStepPills(steps, cidMap, pillTypeMap, factory) {
|
|
|
230
244
|
for (const [field, fieldShape] of templateObj.entries({ resolve: false })) {
|
|
231
245
|
const fieldResolved = resolveAnyPillFromShape(fieldShape, cidMap);
|
|
232
246
|
if (fieldResolved?.isStep) {
|
|
233
|
-
|
|
234
|
-
entries.push(`${field}=${
|
|
247
|
+
(0, flow_pill_utils_1.collectPillTypes)(fieldResolved.pill, pillTypeMap);
|
|
248
|
+
entries.push(`${field}=${(0, flow_pill_utils_1.stripPillType)(fieldResolved.pill)}`);
|
|
235
249
|
hasStepPills = true;
|
|
236
250
|
}
|
|
237
251
|
else if (fieldShape.is(sdk_build_core_1.TemplateExpressionShape)) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
252
|
+
const resolvedText = resolveAllPillsInTemplate(fieldShape, cidMap, pillTypeMap);
|
|
253
|
+
entries.push(`${field}=${resolvedText}`);
|
|
254
|
+
if (resolvedText.includes('{{step[')) {
|
|
241
255
|
hasStepPills = true;
|
|
242
256
|
}
|
|
243
|
-
else {
|
|
244
|
-
const val = fieldShape.getValue?.();
|
|
245
|
-
entries.push(`${field}=${String(val ?? '')}`);
|
|
246
|
-
}
|
|
247
257
|
}
|
|
248
258
|
else {
|
|
249
259
|
const val = String(fieldShape.getValue?.() ?? '');
|
|
250
|
-
entries.push(`${field}=${val.startsWith('{{') ?
|
|
260
|
+
entries.push(`${field}=${val.startsWith('{{') ? (0, flow_pill_utils_1.stripPillType)(val) : val}`);
|
|
251
261
|
}
|
|
252
262
|
}
|
|
253
263
|
if (hasStepPills) {
|
|
254
|
-
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId,
|
|
264
|
+
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId, stepDefTableName, entries.join('^')));
|
|
265
|
+
}
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
// Case 4: ApprovalDueDateShape — resolve step pill in 'date' field
|
|
269
|
+
// During initial auto-processing, cidMap was empty so the step pill in 'date'
|
|
270
|
+
// couldn't be resolved. Now cidMap is populated, so resolve and create element_mapping.
|
|
271
|
+
if (valueShape.is(flow_shapes_1.ApprovalDueDateShape)) {
|
|
272
|
+
const dueDateShape = valueShape;
|
|
273
|
+
const dateFieldShape = dueDateShape.get('date', false);
|
|
274
|
+
const dateResolved = resolveAnyPillFromShape(dateFieldShape, cidMap);
|
|
275
|
+
if (dateResolved?.isStep) {
|
|
276
|
+
(0, flow_pill_utils_1.collectPillTypes)(dateResolved.pill, pillTypeMap);
|
|
277
|
+
// Build the full JSON with the resolved step pill in the date field.
|
|
278
|
+
// getApprovalDueDate() resolves all properties (turning the unresolvable
|
|
279
|
+
// CallExpressionShape into a Symbol that JSON.stringify drops).
|
|
280
|
+
// Override the date field with the resolved pill string.
|
|
281
|
+
const dueDate = dueDateShape.getApprovalDueDate();
|
|
282
|
+
const correctedShape = new flow_shapes_1.ApprovalDueDateShape({
|
|
283
|
+
source: dueDateShape.getSource(),
|
|
284
|
+
value: { ...dueDate, date: (0, flow_pill_utils_1.stripPillType)(dateResolved.pill) },
|
|
285
|
+
});
|
|
286
|
+
const jsonValue = correctedShape.toString().getValue();
|
|
287
|
+
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId, stepDefTableName, jsonValue));
|
|
288
|
+
}
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
// Case 5: ApprovalRulesShape — resolve step pills in users/groups arrays.
|
|
292
|
+
// Uses the same structural walk as resolveApprovalRulesPills in step-instance-plugin
|
|
293
|
+
// but with resolveAnyPillFromShape (which has access to cidMap).
|
|
294
|
+
if (valueShape.is(flow_shapes_1.ApprovalRulesShape)) {
|
|
295
|
+
const rulesShape = valueShape;
|
|
296
|
+
const rules = rulesShape.getApprovalRules();
|
|
297
|
+
let hasStepPills = false;
|
|
298
|
+
const ruleSetsShape = rulesShape.get('ruleSets', false).ifArray();
|
|
299
|
+
ruleSetsShape?.getElements(false).forEach((ruleSetShape, rsIdx) => {
|
|
300
|
+
const rulesArrayShape = ruleSetShape.ifObject()?.get('rules', false).ifArray();
|
|
301
|
+
rulesArrayShape?.getElements(false).forEach((ruleShape, rIdx) => {
|
|
302
|
+
ruleShape
|
|
303
|
+
.ifArray()
|
|
304
|
+
?.getElements(false)
|
|
305
|
+
.forEach((conditionShape, cIdx) => {
|
|
306
|
+
const conditionObj = conditionShape.ifObject();
|
|
307
|
+
if (!conditionObj) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const condition = rules.ruleSets?.[rsIdx]?.rules?.[rIdx]?.[cIdx];
|
|
311
|
+
if (!condition) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// Resolve step pills in users array
|
|
315
|
+
conditionObj
|
|
316
|
+
.get('users', false)
|
|
317
|
+
.ifArray()
|
|
318
|
+
?.getElements(false)
|
|
319
|
+
.forEach((userShape, uIdx) => {
|
|
320
|
+
const resolved = resolveAnyPillFromShape(userShape, cidMap);
|
|
321
|
+
if (resolved?.isStep && condition.users) {
|
|
322
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
323
|
+
condition.users[uIdx] = (0, flow_pill_utils_1.stripPillType)(resolved.pill);
|
|
324
|
+
hasStepPills = true;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
// Resolve step pills in groups array
|
|
328
|
+
conditionObj
|
|
329
|
+
.get('groups', false)
|
|
330
|
+
.ifArray()
|
|
331
|
+
?.getElements(false)
|
|
332
|
+
.forEach((groupShape, gIdx) => {
|
|
333
|
+
const resolved = resolveAnyPillFromShape(groupShape, cidMap);
|
|
334
|
+
if (resolved?.isStep && condition.groups) {
|
|
335
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
336
|
+
condition.groups[gIdx] = (0, flow_pill_utils_1.stripPillType)(resolved.pill);
|
|
337
|
+
hasStepPills = true;
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
if (hasStepPills) {
|
|
344
|
+
const correctedShape = new flow_shapes_1.ApprovalRulesShape({
|
|
345
|
+
source: rulesShape.getSource(),
|
|
346
|
+
value: rules,
|
|
347
|
+
});
|
|
348
|
+
const jsonValue = correctedShape.toString().getValue();
|
|
349
|
+
newRecords.push(await createElementMapping(factory, stepShape, key, stepInstanceSysId, stepDefTableName, jsonValue));
|
|
255
350
|
}
|
|
256
351
|
}
|
|
257
352
|
}
|
|
@@ -259,51 +354,68 @@ async function resolveUnresolvedStepPills(steps, cidMap, pillTypeMap, factory) {
|
|
|
259
354
|
return newRecords;
|
|
260
355
|
}
|
|
261
356
|
/**
|
|
262
|
-
*
|
|
263
|
-
* Scans
|
|
264
|
-
* and deduplicates by (cid, pillPath).
|
|
265
|
-
*
|
|
266
|
-
* This follows the same post-processing pattern as flow-definition-plugin which extracts
|
|
267
|
-
* pills from already-created records rather than during shape transformation.
|
|
357
|
+
* Collects all pill-bearing text strings from records.
|
|
358
|
+
* Scans sys_element_mapping.value, sys_hub_status_condition.condition and .status fields.
|
|
268
359
|
*/
|
|
269
|
-
function
|
|
270
|
-
const
|
|
271
|
-
const seen = new Set();
|
|
360
|
+
function collectPillTextsFromRecords(records) {
|
|
361
|
+
const texts = [];
|
|
272
362
|
for (const topRec of records) {
|
|
273
|
-
// sys_element_mapping records are nested inside step instance records;
|
|
274
|
-
// flat() expands them so we can scan pill values.
|
|
275
363
|
for (const rec of topRec.flat()) {
|
|
276
|
-
|
|
277
|
-
|
|
364
|
+
const table = rec.getTable();
|
|
365
|
+
if (table === 'sys_element_mapping') {
|
|
366
|
+
const value = rec.get('value')?.asString()?.getValue() ?? '';
|
|
367
|
+
if (value) {
|
|
368
|
+
texts.push(value);
|
|
369
|
+
}
|
|
278
370
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (!cid || !pillPath) {
|
|
284
|
-
continue;
|
|
371
|
+
else if (table === 'sys_hub_status_condition') {
|
|
372
|
+
const condition = rec.get('condition')?.asString()?.getValue() ?? '';
|
|
373
|
+
if (condition) {
|
|
374
|
+
texts.push(condition);
|
|
285
375
|
}
|
|
286
|
-
const
|
|
287
|
-
if (
|
|
288
|
-
|
|
376
|
+
const status = rec.get('status')?.asString()?.getValue() ?? '';
|
|
377
|
+
if (status) {
|
|
378
|
+
texts.push(status);
|
|
289
379
|
}
|
|
290
|
-
seen.add(key);
|
|
291
|
-
// Prefer type from pillTypeMap (collected from wfa.dataPill() args before stripping),
|
|
292
|
-
// fall back to regex capture from element_mapping, then default to 'string'
|
|
293
|
-
const resolvedType = pillTypeMap?.get(key) ?? dataType ?? 'string';
|
|
294
|
-
pills.push({
|
|
295
|
-
cid,
|
|
296
|
-
stepLabel: cidToLabelMap.get(cid) ?? '',
|
|
297
|
-
pillPath,
|
|
298
|
-
dataType: resolvedType,
|
|
299
|
-
});
|
|
300
380
|
}
|
|
301
381
|
}
|
|
302
382
|
}
|
|
383
|
+
return texts;
|
|
384
|
+
}
|
|
385
|
+
function extractStepPillsFromRecords(records, cidToLabelMap, pillTypeMap) {
|
|
386
|
+
const pills = [];
|
|
387
|
+
const seen = new Set();
|
|
388
|
+
for (const text of collectPillTextsFromRecords(records)) {
|
|
389
|
+
const matches = text.matchAll(flow_pill_utils_1.STEP_PILL_TYPE_REGEX);
|
|
390
|
+
for (const match of matches) {
|
|
391
|
+
const [, cid, pillPath, dataType] = match;
|
|
392
|
+
if (!cid || !pillPath) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
// Skip base __step_status__ — already handled in buildActionLabelCache via cidToLabelMap
|
|
396
|
+
if (pillPath === '__step_status__') {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
const key = `${cid}::${pillPath}`;
|
|
400
|
+
if (seen.has(key)) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
seen.add(key);
|
|
404
|
+
// Prefer type from pillTypeMap (collected from wfa.dataPill() args before stripping),
|
|
405
|
+
// fall back to regex capture from element_mapping, then default to 'string'
|
|
406
|
+
const resolvedType = pillTypeMap?.get(key) ?? dataType ?? 'string';
|
|
407
|
+
pills.push({
|
|
408
|
+
cid,
|
|
409
|
+
stepLabel: cidToLabelMap.get(cid) ?? '',
|
|
410
|
+
pillPath,
|
|
411
|
+
dataType: resolvedType,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
303
415
|
return pills;
|
|
304
416
|
}
|
|
305
417
|
/**
|
|
306
|
-
* Extracts action dot-walk pill info from
|
|
418
|
+
* Extracts action dot-walk pill info from records.
|
|
307
419
|
* Scans for {{action.X.Y...}} patterns where the path has 2+ segments (i.e., deeper than top-level input).
|
|
308
420
|
* Deduplicates by full path. Uses pillTypeMap for type resolution.
|
|
309
421
|
*/
|
|
@@ -311,34 +423,28 @@ function extractActionDotWalkPills(records, pillTypeMap) {
|
|
|
311
423
|
const pills = [];
|
|
312
424
|
const seen = new Set();
|
|
313
425
|
const regex = /\{\{action\.([^|}]+)(?:\|([^}]+))?\}\}/g;
|
|
314
|
-
for (const
|
|
315
|
-
for (const
|
|
316
|
-
|
|
426
|
+
for (const text of collectPillTextsFromRecords(records)) {
|
|
427
|
+
for (const match of text.matchAll(regex)) {
|
|
428
|
+
const [, path, dataType] = match;
|
|
429
|
+
if (!path) {
|
|
317
430
|
continue;
|
|
318
431
|
}
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
// Only dot-walk pills (2+ segments) — top-level ones are already in inputsConfig
|
|
327
|
-
if (segments.length < 2) {
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
if (seen.has(path)) {
|
|
331
|
-
continue;
|
|
332
|
-
}
|
|
333
|
-
seen.add(path);
|
|
334
|
-
const resolvedType = pillTypeMap?.get(`action::${path}`) ?? dataType ?? 'string';
|
|
335
|
-
pills.push({
|
|
336
|
-
fullPath: path,
|
|
337
|
-
parentField: segments[0] ?? '',
|
|
338
|
-
columnName: segments[segments.length - 1] ?? '',
|
|
339
|
-
dataType: resolvedType,
|
|
340
|
-
});
|
|
432
|
+
const segments = path.split('.');
|
|
433
|
+
// Only dot-walk pills (2+ segments) — top-level ones are already in inputsConfig
|
|
434
|
+
if (segments.length < 2) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (seen.has(path)) {
|
|
438
|
+
continue;
|
|
341
439
|
}
|
|
440
|
+
seen.add(path);
|
|
441
|
+
const resolvedType = pillTypeMap?.get(`action::${path}`) ?? dataType ?? 'string';
|
|
442
|
+
pills.push({
|
|
443
|
+
fullPath: path,
|
|
444
|
+
parentField: segments[0] ?? '',
|
|
445
|
+
columnName: segments[segments.length - 1] ?? '',
|
|
446
|
+
dataType: resolvedType,
|
|
447
|
+
});
|
|
342
448
|
}
|
|
343
449
|
}
|
|
344
450
|
return pills;
|
|
@@ -574,6 +680,66 @@ function convertActionPillsInInputs(inputsObj, source, diagnostics, labelCacheMa
|
|
|
574
680
|
}
|
|
575
681
|
}
|
|
576
682
|
}
|
|
683
|
+
/**
|
|
684
|
+
* Converts pill strings buried inside ApprovalRulesShape and ApprovalDueDateShape values
|
|
685
|
+
* to wfa.dataPill() shapes. These structured shapes are created by normalizeInputValue()
|
|
686
|
+
* before convertActionPillsInInputs runs, so their nested pill strings are unreachable
|
|
687
|
+
* by the normal string-based pill conversion.
|
|
688
|
+
*/
|
|
689
|
+
function convertPillsInStructuredShapes(inputsObj, source, diagnostics, labelCacheMap) {
|
|
690
|
+
for (const [key, val] of Object.entries(inputsObj)) {
|
|
691
|
+
if (val instanceof flow_shapes_1.ApprovalRulesShape) {
|
|
692
|
+
const rules = val.getApprovalRules();
|
|
693
|
+
let changed = false;
|
|
694
|
+
const newRuleSets = rules.ruleSets?.map((ruleSet) => ({
|
|
695
|
+
...ruleSet,
|
|
696
|
+
rules: ruleSet.rules?.map((rule) => rule.map((condition) => ({
|
|
697
|
+
...condition,
|
|
698
|
+
users: condition.users?.map((user) => {
|
|
699
|
+
const s = String(user);
|
|
700
|
+
if ((0, pill_string_parser_1.detectPillPattern)(s) !== 'none') {
|
|
701
|
+
const shape = convertActionPillToShape(s, source, diagnostics, labelCacheMap);
|
|
702
|
+
if (shape) {
|
|
703
|
+
changed = true;
|
|
704
|
+
return shape;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return user;
|
|
708
|
+
}),
|
|
709
|
+
groups: condition.groups?.map((group) => {
|
|
710
|
+
const s = String(group);
|
|
711
|
+
if ((0, pill_string_parser_1.detectPillPattern)(s) !== 'none') {
|
|
712
|
+
const shape = convertActionPillToShape(s, source, diagnostics, labelCacheMap);
|
|
713
|
+
if (shape) {
|
|
714
|
+
changed = true;
|
|
715
|
+
return shape;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return group;
|
|
719
|
+
}),
|
|
720
|
+
}))),
|
|
721
|
+
}));
|
|
722
|
+
if (changed && newRuleSets) {
|
|
723
|
+
inputsObj[key] = new flow_shapes_1.ApprovalRulesShape({
|
|
724
|
+
source,
|
|
725
|
+
value: { ...rules, ruleSets: newRuleSets },
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
else if (val instanceof flow_shapes_1.ApprovalDueDateShape) {
|
|
730
|
+
const dueDate = val.getApprovalDueDate();
|
|
731
|
+
if (dueDate.date && (0, pill_string_parser_1.detectPillPattern)(dueDate.date) !== 'none') {
|
|
732
|
+
const shape = convertActionPillToShape(dueDate.date, source, diagnostics, labelCacheMap);
|
|
733
|
+
if (shape) {
|
|
734
|
+
inputsObj[key] = new flow_shapes_1.ApprovalDueDateShape({
|
|
735
|
+
source,
|
|
736
|
+
value: { ...dueDate, date: shape },
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
577
743
|
/** Regex to find step[UUID] pills */
|
|
578
744
|
const STEP_PILL_REGEX = /\{\{step\[([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\]\.([^|}]+)(?:\|[^}]*)?\}\}/g;
|
|
579
745
|
/**
|
|
@@ -622,6 +788,84 @@ function convertStepPillsInInputs(inputsObj, source, cidToIdentifierMap, labelCa
|
|
|
622
788
|
inputsObj[key] = new sdk_build_core_1.TemplateValueShape({ source, value: newTemplateValue });
|
|
623
789
|
}
|
|
624
790
|
}
|
|
791
|
+
else if (val instanceof flow_shapes_1.ApprovalDueDateShape) {
|
|
792
|
+
const dueDate = val.getApprovalDueDate();
|
|
793
|
+
if (dueDate.date && typeof dueDate.date === 'string' && (0, pill_string_parser_1.detectPillPattern)(dueDate.date) !== 'none') {
|
|
794
|
+
const shape = convertStepPillString(dueDate.date, source, cidToIdentifierMap, labelCacheMap);
|
|
795
|
+
if (shape) {
|
|
796
|
+
inputsObj[key] = new flow_shapes_1.ApprovalDueDateShape({
|
|
797
|
+
source,
|
|
798
|
+
value: { ...dueDate, date: shape },
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
else if (val instanceof flow_shapes_1.ApprovalRulesShape) {
|
|
804
|
+
const rules = val.getApprovalRules();
|
|
805
|
+
let changed = false;
|
|
806
|
+
const newRuleSets = rules.ruleSets?.map((ruleSet) => ({
|
|
807
|
+
...ruleSet,
|
|
808
|
+
rules: ruleSet.rules?.map((rule) => rule.map((condition) => ({
|
|
809
|
+
...condition,
|
|
810
|
+
users: condition.users?.map((user) => {
|
|
811
|
+
const s = String(user);
|
|
812
|
+
if ((0, pill_string_parser_1.detectPillPattern)(s) !== 'none') {
|
|
813
|
+
const shape = convertStepPillString(s, source, cidToIdentifierMap, labelCacheMap);
|
|
814
|
+
if (shape) {
|
|
815
|
+
changed = true;
|
|
816
|
+
return shape;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return user;
|
|
820
|
+
}),
|
|
821
|
+
groups: condition.groups?.map((group) => {
|
|
822
|
+
const s = String(group);
|
|
823
|
+
if ((0, pill_string_parser_1.detectPillPattern)(s) !== 'none') {
|
|
824
|
+
const shape = convertStepPillString(s, source, cidToIdentifierMap, labelCacheMap);
|
|
825
|
+
if (shape) {
|
|
826
|
+
changed = true;
|
|
827
|
+
return shape;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return group;
|
|
831
|
+
}),
|
|
832
|
+
}))),
|
|
833
|
+
}));
|
|
834
|
+
if (changed && newRuleSets) {
|
|
835
|
+
inputsObj[key] = new flow_shapes_1.ApprovalRulesShape({
|
|
836
|
+
source,
|
|
837
|
+
value: { ...rules, ruleSets: newRuleSets },
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
else if (val && typeof val === 'object' && !Array.isArray(val) && !isShapeInstance(val)) {
|
|
842
|
+
// Recursively process nested plain objects (e.g., inputVariables)
|
|
843
|
+
// This handles script step input variables which have 'value' fields with step pills
|
|
844
|
+
const nestedObj = val;
|
|
845
|
+
for (const nestedVal of Object.values(nestedObj)) {
|
|
846
|
+
if (nestedVal &&
|
|
847
|
+
typeof nestedVal === 'object' &&
|
|
848
|
+
!Array.isArray(nestedVal) &&
|
|
849
|
+
!isShapeInstance(nestedVal)) {
|
|
850
|
+
const innerObj = nestedVal;
|
|
851
|
+
const innerValue = innerObj['value'];
|
|
852
|
+
if (typeof innerValue === 'string') {
|
|
853
|
+
const converted = convertStepPillString(innerValue, source, cidToIdentifierMap, labelCacheMap);
|
|
854
|
+
if (converted) {
|
|
855
|
+
innerObj['value'] = converted;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
else if (innerValue instanceof sdk_build_core_1.TemplateExpressionShape) {
|
|
859
|
+
// Handle case where convertActionPillsInInputs already converted action pills,
|
|
860
|
+
// leaving step pills in the template literal text segments
|
|
861
|
+
const resolved = resolveStepPillsInTemplateExpression(innerValue, source, cidToIdentifierMap, labelCacheMap);
|
|
862
|
+
if (resolved) {
|
|
863
|
+
innerObj['value'] = resolved;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
625
869
|
}
|
|
626
870
|
}
|
|
627
871
|
/**
|
|
@@ -632,9 +876,12 @@ function resolveStepPillMatch(uuid, property, source, cidToIdentifierMap, labelC
|
|
|
632
876
|
if (!identifier) {
|
|
633
877
|
return undefined;
|
|
634
878
|
}
|
|
879
|
+
// Split dot-walk property path into individual segments (e.g., "record.manager.email" → ["record", "manager", "email"])
|
|
880
|
+
// PropertyAccessShape needs each path segment as a separate element for correct code generation
|
|
881
|
+
const pathParts = property.split('.');
|
|
635
882
|
const expression = new sdk_build_core_1.PropertyAccessShape({
|
|
636
883
|
source,
|
|
637
|
-
elements: [identifier,
|
|
884
|
+
elements: [identifier, ...pathParts],
|
|
638
885
|
});
|
|
639
886
|
const pillName = `step[${uuid}].${property}`;
|
|
640
887
|
const dataType = labelCacheMap?.get(pillName) || 'string';
|
|
@@ -889,9 +1136,118 @@ const actionDefRelationships = {
|
|
|
889
1136
|
descendant: true,
|
|
890
1137
|
},
|
|
891
1138
|
};
|
|
1139
|
+
/**
|
|
1140
|
+
* Resolves any shape (string literal, number, template expression, dataPill call)
|
|
1141
|
+
* to its final string representation with pill references resolved.
|
|
1142
|
+
*/
|
|
1143
|
+
function resolveToString(shape, cidMap, pillTypeMap) {
|
|
1144
|
+
if (shape instanceof sdk_build_core_1.TemplateExpressionShape) {
|
|
1145
|
+
return resolveAllPillsInTemplate(shape, cidMap, pillTypeMap);
|
|
1146
|
+
}
|
|
1147
|
+
if (shape instanceof data_pill_shapes_1.PillShape) {
|
|
1148
|
+
const raw = shape.getValue();
|
|
1149
|
+
(0, flow_pill_utils_1.collectPillTypes)(raw, pillTypeMap);
|
|
1150
|
+
return (0, flow_pill_utils_1.stripPillType)(raw);
|
|
1151
|
+
}
|
|
1152
|
+
const resolved = resolveAnyPillFromShape(shape, cidMap);
|
|
1153
|
+
if (resolved) {
|
|
1154
|
+
if (resolved.isStep) {
|
|
1155
|
+
(0, flow_pill_utils_1.collectPillTypes)(resolved.pill, pillTypeMap);
|
|
1156
|
+
}
|
|
1157
|
+
return (0, flow_pill_utils_1.stripPillType)(resolved.pill);
|
|
1158
|
+
}
|
|
1159
|
+
return String(shape.getValue?.() ?? '');
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Builds the complex JSON `status` field for a sys_hub_status_condition record.
|
|
1163
|
+
* The status contains complexObject (runtime values), complexObjectSchema
|
|
1164
|
+
* (FlowDesigner:FDACTIONSTATUS with SimpleMapFacet field descriptors), and type facets.
|
|
1165
|
+
*
|
|
1166
|
+
* When a field value contains datapill references ({{...}}), it goes into the
|
|
1167
|
+
* `mapped` field of the SimpleMapFacet; otherwise static values go into
|
|
1168
|
+
* complexObject.$cv.$v and mapped is "{}".
|
|
1169
|
+
*/
|
|
1170
|
+
function buildStatusConditionJson(codeValue, messageValue) {
|
|
1171
|
+
const hasPillInCode = codeValue.includes('{{');
|
|
1172
|
+
const hasPillInMessage = messageValue.includes('{{');
|
|
1173
|
+
const codeMapped = hasPillInCode ? JSON.stringify({ code: codeValue }) : '{}';
|
|
1174
|
+
const messageMapped = hasPillInMessage ? JSON.stringify({ message: messageValue }) : '{}';
|
|
1175
|
+
const codeCV = hasPillInCode ? '' : codeValue;
|
|
1176
|
+
const messageCV = hasPillInMessage ? '' : messageValue;
|
|
1177
|
+
// Derive the complexObjectSchema from the built-in FDACTIONSTATUS definition
|
|
1178
|
+
// rather than hardcoding it, so it stays in sync with the canonical schema.
|
|
1179
|
+
const fdActionStatus = built_in_complex_objects_1.builtInComplexObjects['FDACTIONSTATUS'];
|
|
1180
|
+
if (!fdActionStatus) {
|
|
1181
|
+
throw new Error('FDACTIONSTATUS not found in builtInComplexObjects');
|
|
1182
|
+
}
|
|
1183
|
+
const baseSchema = JSON.parse(fdActionStatus.data.serialized_content);
|
|
1184
|
+
const fdSchema = baseSchema['FlowDesigner:FDACTIONSTATUS'];
|
|
1185
|
+
// Inject `mapped` into the field facets for code and message
|
|
1186
|
+
for (const [fieldName, mapped] of [
|
|
1187
|
+
['code', codeMapped],
|
|
1188
|
+
['message', messageMapped],
|
|
1189
|
+
]) {
|
|
1190
|
+
const facetKey = `${fieldName}.$field_facets`;
|
|
1191
|
+
const facets = JSON.parse(fdSchema[facetKey].SimpleMapFacet);
|
|
1192
|
+
facets.mapped = mapped;
|
|
1193
|
+
fdSchema[facetKey].SimpleMapFacet = JSON.stringify(facets);
|
|
1194
|
+
}
|
|
1195
|
+
return JSON.stringify({
|
|
1196
|
+
version: '1.0',
|
|
1197
|
+
complexObject: {
|
|
1198
|
+
code: { $cv: { $c: 'java.lang.String', $v: codeCV } },
|
|
1199
|
+
message: { $cv: { $c: 'java.lang.String', $v: messageCV } },
|
|
1200
|
+
},
|
|
1201
|
+
complexObjectSchema: baseSchema,
|
|
1202
|
+
serializationFormat: 'JSON',
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Parses a status JSON blob from a sys_hub_status_condition record and extracts
|
|
1207
|
+
* the code and message values. Datapill references live in the `mapped` field
|
|
1208
|
+
* of the SimpleMapFacet; static values live in complexObject.$cv.$v.
|
|
1209
|
+
*/
|
|
1210
|
+
function parseStatusConditionJson(statusJson, logger) {
|
|
1211
|
+
try {
|
|
1212
|
+
const parsed = JSON.parse(statusJson);
|
|
1213
|
+
const co = parsed?.complexObject ?? {};
|
|
1214
|
+
const schema = parsed?.complexObjectSchema ?? {};
|
|
1215
|
+
const fdSchema = schema['FlowDesigner:FDACTIONSTATUS'] ?? {};
|
|
1216
|
+
// Extract code
|
|
1217
|
+
let code = co?.code?.$cv?.$v ?? '';
|
|
1218
|
+
const codeFacetsRaw = fdSchema['code.$field_facets']?.SimpleMapFacet;
|
|
1219
|
+
if (codeFacetsRaw) {
|
|
1220
|
+
const codeFacets = typeof codeFacetsRaw === 'string' ? JSON.parse(codeFacetsRaw) : codeFacetsRaw;
|
|
1221
|
+
const codeMapped = codeFacets?.mapped;
|
|
1222
|
+
if (codeMapped && codeMapped !== '{}') {
|
|
1223
|
+
const mappedObj = typeof codeMapped === 'string' ? JSON.parse(codeMapped) : codeMapped;
|
|
1224
|
+
if (mappedObj?.code) {
|
|
1225
|
+
code = mappedObj.code;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
// Extract message
|
|
1230
|
+
let message = co?.message?.$cv?.$v ?? '';
|
|
1231
|
+
const msgFacetsRaw = fdSchema['message.$field_facets']?.SimpleMapFacet;
|
|
1232
|
+
if (msgFacetsRaw) {
|
|
1233
|
+
const msgFacets = typeof msgFacetsRaw === 'string' ? JSON.parse(msgFacetsRaw) : msgFacetsRaw;
|
|
1234
|
+
const msgMapped = msgFacets?.mapped;
|
|
1235
|
+
if (msgMapped && msgMapped !== '{}') {
|
|
1236
|
+
const mappedObj = typeof msgMapped === 'string' ? JSON.parse(msgMapped) : msgMapped;
|
|
1237
|
+
if (mappedObj?.message) {
|
|
1238
|
+
message = mappedObj.message;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
return { code, message };
|
|
1243
|
+
}
|
|
1244
|
+
catch (e) {
|
|
1245
|
+
logger?.warn(`parseStatusConditionJson: failed to parse status JSON — ${e}`);
|
|
1246
|
+
return { code: '', message: '' };
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
892
1249
|
exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
893
1250
|
name: 'ActionDefinitionPlugin',
|
|
894
|
-
docs: [(0, utils_1.createSdkDocEntry)('Action', ['sys_hub_action_type_definition'])],
|
|
895
1251
|
records: {
|
|
896
1252
|
sys_hub_action_type_definition: {
|
|
897
1253
|
relationships: {
|
|
@@ -901,6 +1257,10 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
901
1257
|
descendant: true,
|
|
902
1258
|
relationships: {
|
|
903
1259
|
...actionDefRelationships,
|
|
1260
|
+
sys_variable_value: {
|
|
1261
|
+
via: 'document_key',
|
|
1262
|
+
descendant: true,
|
|
1263
|
+
},
|
|
904
1264
|
sys_element_mapping: {
|
|
905
1265
|
via: 'id',
|
|
906
1266
|
descendant: true,
|
|
@@ -934,85 +1294,31 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
934
1294
|
},
|
|
935
1295
|
async toShape(record, { descendants, diagnostics, logger }) {
|
|
936
1296
|
const actionSysId = record.getId().getValue();
|
|
937
|
-
//
|
|
938
|
-
//
|
|
939
|
-
//
|
|
940
|
-
const
|
|
1297
|
+
// Query error evaluation descendants for this action.
|
|
1298
|
+
// sys_hub_action_status_metadata is the parent container;
|
|
1299
|
+
// sys_hub_status_condition holds the individual conditions.
|
|
1300
|
+
const actionStatusMetadata = descendants
|
|
941
1301
|
.query('sys_hub_action_status_metadata')
|
|
942
|
-
.filter((r) => r.get('action_type_id')?.asString()?.getValue() === actionSysId)
|
|
943
|
-
|
|
944
|
-
const
|
|
1302
|
+
.filter((r) => r.get('action_type_id')?.asString()?.getValue() === actionSysId);
|
|
1303
|
+
const actionStatusMetadataIds = actionStatusMetadata.map((r) => r.getId().getValue());
|
|
1304
|
+
const statusConditions = descendants
|
|
945
1305
|
.query('sys_hub_status_condition')
|
|
946
|
-
.
|
|
947
|
-
if (hasErrorEvaluation) {
|
|
948
|
-
const actionName = record.get('name')?.getValue() ?? actionSysId;
|
|
949
|
-
logger.warn(`Action '${actionName}' has error evaluation — falling back to Record API`);
|
|
950
|
-
return { success: false };
|
|
951
|
-
}
|
|
1306
|
+
.filter((r) => actionStatusMetadataIds.includes(r.get('action_status_metadata_id')?.asString()?.getValue() ?? ''));
|
|
952
1307
|
// Filter inputs/outputs to only those belonging to this action definition,
|
|
953
|
-
// excluding snapshot-parented records
|
|
1308
|
+
// excluding snapshot-parented records, and sort by <order> to preserve
|
|
1309
|
+
// the order defined in the XML (instance document order is not guaranteed)
|
|
1310
|
+
const sortByOrder = (a, b) => Number(a.get('order')?.asString()?.getValue() ?? 0) -
|
|
1311
|
+
Number(b.get('order')?.asString()?.getValue() ?? 0);
|
|
954
1312
|
const actionInputs = descendants
|
|
955
1313
|
.query('sys_hub_action_input')
|
|
956
|
-
.filter((r) => r.get('model')?.asString()?.getValue() === actionSysId)
|
|
1314
|
+
.filter((r) => r.get('model')?.asString()?.getValue() === actionSysId)
|
|
1315
|
+
.sort(sortByOrder);
|
|
957
1316
|
const actionOutputs = descendants
|
|
958
1317
|
.query('sys_hub_action_output')
|
|
959
|
-
.filter((r) => r.get('model')?.asString()?.getValue() === actionSysId)
|
|
960
|
-
|
|
961
|
-
// Core actions (in CORE_ACTIONS_SYS_ID_NAME_MAP) are fully supported and should not fall back.
|
|
962
|
-
// System-generated outputs (__action_status__, __dont_treat_as_error__) are excluded —
|
|
963
|
-
// every action has these automatically, they are not custom outputs.
|
|
964
|
-
const isCoreAction = actionSysId in flow_constants_1.CORE_ACTIONS_SYS_ID_NAME_MAP;
|
|
965
|
-
const customOutputs = actionOutputs.filter((r) => {
|
|
966
|
-
const element = r.get('element')?.asString()?.getValue() ?? '';
|
|
967
|
-
return element !== '__action_status__' && element !== '__dont_treat_as_error__';
|
|
968
|
-
});
|
|
969
|
-
if (!isCoreAction && customOutputs.length > 0) {
|
|
970
|
-
const actionName = record.get('name')?.getValue() ?? actionSysId;
|
|
971
|
-
logger.warn(`Custom action '${actionName}' has outputs — falling back to Record API`);
|
|
972
|
-
return { success: false };
|
|
973
|
-
}
|
|
974
|
-
// Build snapshot output value map: element name → assigned value
|
|
975
|
-
// Output values are stored in two places on the snapshot:
|
|
976
|
-
// 1. sys_variable_value records (plain text values)
|
|
977
|
-
// 2. sys_element_mapping records (datapill/template values)
|
|
978
|
-
const snapshotOutputValues = new Map();
|
|
979
|
-
const snapshots = descendants.query('sys_hub_action_type_snapshot');
|
|
980
|
-
if (snapshots.length > 0) {
|
|
981
|
-
const snapshotId = snapshots[0]?.getId()?.getValue();
|
|
982
|
-
// Check sys_element_mapping for datapill values (field=element name, id=snapshot id)
|
|
983
|
-
const elementMappings = descendants
|
|
984
|
-
.query('sys_element_mapping')
|
|
985
|
-
.filter((r) => r.get('id')?.asString()?.getValue() === snapshotId);
|
|
986
|
-
for (const mapping of elementMappings) {
|
|
987
|
-
const fieldName = mapping.get('field')?.asString()?.getValue();
|
|
988
|
-
const value = mapping.get('value')?.ifString()?.getValue();
|
|
989
|
-
if (fieldName && value !== undefined && value !== '') {
|
|
990
|
-
snapshotOutputValues.set(fieldName, value);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
// Check sys_variable_value for plain text values (on snapshot outputs)
|
|
994
|
-
const snapshotOutputs = descendants
|
|
995
|
-
.query('sys_hub_action_output')
|
|
996
|
-
.filter((r) => r.get('model')?.asString()?.getValue() === snapshotId);
|
|
997
|
-
for (const snapshotOutput of snapshotOutputs) {
|
|
998
|
-
const elementName = snapshotOutput.get('element')?.asString()?.getValue();
|
|
999
|
-
if (!elementName || snapshotOutputValues.has(elementName)) {
|
|
1000
|
-
continue;
|
|
1001
|
-
}
|
|
1002
|
-
const snapshotOutputSysId = snapshotOutput.getId().getValue();
|
|
1003
|
-
const varValues = descendants
|
|
1004
|
-
.query('sys_variable_value')
|
|
1005
|
-
.filter((v) => v.get('variable')?.asString()?.getValue() === snapshotOutputSysId);
|
|
1006
|
-
if (varValues.length > 0) {
|
|
1007
|
-
const value = varValues[0]?.get('value')?.ifString()?.getValue();
|
|
1008
|
-
if (value !== undefined && value !== '') {
|
|
1009
|
-
snapshotOutputValues.set(elementName, value);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1318
|
+
.filter((r) => r.get('model')?.asString()?.getValue() === actionSysId)
|
|
1319
|
+
.sort(sortByOrder);
|
|
1014
1320
|
const inputs = (0, flow_io_to_record_1.buildVariableShapes)(actionInputs, descendants);
|
|
1015
|
-
const outputs = (0, flow_io_to_record_1.buildVariableShapes)(actionOutputs, descendants
|
|
1321
|
+
const outputs = (0, flow_io_to_record_1.buildVariableShapes)(actionOutputs, descendants);
|
|
1016
1322
|
// Extract label_cache from action definition for datapill type info
|
|
1017
1323
|
let labelCacheMap;
|
|
1018
1324
|
try {
|
|
@@ -1095,7 +1401,7 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1095
1401
|
}
|
|
1096
1402
|
// Ext input element_mappings have table var__m_sys_hub_step_ext_input_*
|
|
1097
1403
|
// Collect their values but don't add to inputsObj (they go under inputVariables)
|
|
1098
|
-
if (table.startsWith(
|
|
1404
|
+
if (table.startsWith(flow_constants_1.EXT_INPUT_TABLE_PREFIX)) {
|
|
1099
1405
|
extInputMappingValues[rawFieldName] = value;
|
|
1100
1406
|
continue;
|
|
1101
1407
|
}
|
|
@@ -1156,8 +1462,8 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1156
1462
|
// Find value from sys_variable_value or element_mapping (datapill)
|
|
1157
1463
|
// Prioritize pills from sys_element_mapping over static values from sys_variable_value
|
|
1158
1464
|
const varValueRecord = stepVarValues.find((v) => v.get('variable')?.asString()?.getValue() === extInputSysId);
|
|
1159
|
-
const value = extInputMappingValues[elementName]
|
|
1160
|
-
varValueRecord?.get('value')?.asString()?.getValue()
|
|
1465
|
+
const value = extInputMappingValues[elementName] ??
|
|
1466
|
+
varValueRecord?.get('value')?.asString()?.getValue() ??
|
|
1161
1467
|
'';
|
|
1162
1468
|
const inputEntry = { label };
|
|
1163
1469
|
if (value) {
|
|
@@ -1181,17 +1487,17 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1181
1487
|
continue;
|
|
1182
1488
|
}
|
|
1183
1489
|
const label = extOutput.get('label')?.asString()?.getValue() || elementName;
|
|
1184
|
-
const mandatory = extOutput.get('mandatory')?.
|
|
1185
|
-
const internalType = extOutput.get('internal_type')?.
|
|
1490
|
+
const mandatory = extOutput.get('mandatory')?.ifString()?.getValue() === 'true';
|
|
1491
|
+
const internalType = extOutput.get('internal_type')?.ifString()?.getValue() ?? 'string';
|
|
1186
1492
|
// Check attributes for uiType to handle cases where internal_type is generic
|
|
1187
|
-
const attributes = extOutput.get('attributes')?.
|
|
1493
|
+
const attributes = extOutput.get('attributes')?.ifString()?.getValue() ?? '';
|
|
1188
1494
|
const uiType = (0, schema_to_flow_object_1.getAttributeValue)(attributes, 'uiType') ?? internalType;
|
|
1189
1495
|
const columnApiName = column_helper_1.COLUMN_TYPE_TO_API[uiType] ?? 'StringColumn';
|
|
1190
1496
|
const columnProps = { label };
|
|
1191
1497
|
if (mandatory) {
|
|
1192
1498
|
columnProps['mandatory'] = true;
|
|
1193
1499
|
}
|
|
1194
|
-
const maxLength = extOutput.get('max_length')?.
|
|
1500
|
+
const maxLength = extOutput.get('max_length')?.ifString()?.getValue();
|
|
1195
1501
|
if (maxLength) {
|
|
1196
1502
|
columnProps['maxLength'] = Number(maxLength);
|
|
1197
1503
|
}
|
|
@@ -1203,12 +1509,12 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1203
1509
|
if (hint) {
|
|
1204
1510
|
columnProps['hint'] = hint;
|
|
1205
1511
|
}
|
|
1206
|
-
const referenceTable = extOutput.get('reference')?.
|
|
1512
|
+
const referenceTable = extOutput.get('reference')?.ifString()?.getValue();
|
|
1207
1513
|
if (referenceTable &&
|
|
1208
1514
|
(columnApiName === 'ReferenceColumn' || columnApiName === 'ListColumn')) {
|
|
1209
1515
|
columnProps['referenceTable'] = referenceTable;
|
|
1210
1516
|
}
|
|
1211
|
-
const defaultValue = extOutput.get('default_value')?.
|
|
1517
|
+
const defaultValue = extOutput.get('default_value')?.ifString()?.getValue();
|
|
1212
1518
|
if (defaultValue) {
|
|
1213
1519
|
columnProps['default'] = defaultValue;
|
|
1214
1520
|
}
|
|
@@ -1227,6 +1533,9 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1227
1533
|
}
|
|
1228
1534
|
// Convert action input pills ({{action.xxx}}) to wfa.dataPill(params.inputs.xxx, 'type')
|
|
1229
1535
|
convertActionPillsInInputs(inputsObj, stepInstance, diagnostics, labelCacheMap);
|
|
1536
|
+
// Convert pills buried inside ApprovalRulesShape/ApprovalDueDateShape
|
|
1537
|
+
// (these were already parsed by normalizeInputValue before pill conversion)
|
|
1538
|
+
convertPillsInStructuredShapes(inputsObj, stepInstance, diagnostics, labelCacheMap);
|
|
1230
1539
|
// Convert step output pills ({{step[UUID].xxx}}) to wfa.dataPill(varName.xxx, 'type')
|
|
1231
1540
|
// Earlier steps are already in cidToIdentifierMap since steps are processed in order
|
|
1232
1541
|
convertStepPillsInInputs(inputsObj, stepInstance, cidToIdentifierMap, labelCacheMap);
|
|
@@ -1238,7 +1547,7 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1238
1547
|
configProperties['label'] = label;
|
|
1239
1548
|
}
|
|
1240
1549
|
// Built-in/OOB step: emit actionStep.xxx reference
|
|
1241
|
-
const stepIdentifier = (0,
|
|
1550
|
+
const stepIdentifier = (0, utils_1.getBuiltInStepIdentifier)(stepTypeSysId);
|
|
1242
1551
|
// Built-in/OOB step: emit actionStep.xxx identifier reference
|
|
1243
1552
|
const stepDefShape = stepIdentifier
|
|
1244
1553
|
? new sdk_build_core_1.IdentifierShape({ source: stepInstance, name: stepIdentifier })
|
|
@@ -1272,6 +1581,150 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1272
1581
|
}));
|
|
1273
1582
|
}
|
|
1274
1583
|
}
|
|
1584
|
+
// Reconstruct wfa.errorEvaluation([...]) from sys_hub_status_condition records.
|
|
1585
|
+
// This must appear before wfa.assignActionOutputs in the generated Fluent file.
|
|
1586
|
+
if (statusConditions.length > 0) {
|
|
1587
|
+
const sortedConditions = [...statusConditions].sort(sortByOrder);
|
|
1588
|
+
const conditionShapes = [];
|
|
1589
|
+
for (const cond of sortedConditions) {
|
|
1590
|
+
const label = cond.get('label')?.asString()?.getValue() ?? '';
|
|
1591
|
+
const condition = cond.get('condition')?.asString()?.getValue() ?? '';
|
|
1592
|
+
const dontTreatAsError = cond.get('dont_treat_as_error')?.asString()?.getValue() === 'true';
|
|
1593
|
+
const statusJson = cond.get('status')?.asString()?.getValue() ?? '{}';
|
|
1594
|
+
const { code, message } = parseStatusConditionJson(statusJson, logger);
|
|
1595
|
+
// Build status props as plain object, resolve pills, then wrap
|
|
1596
|
+
const statusProps = {};
|
|
1597
|
+
statusProps['code'] = /^\d+$/.test(code) ? Number(code) : code;
|
|
1598
|
+
statusProps['message'] = message;
|
|
1599
|
+
convertActionPillsInInputs(statusProps, cond, diagnostics, labelCacheMap);
|
|
1600
|
+
convertStepPillsInInputs(statusProps, cond, cidToIdentifierMap, labelCacheMap);
|
|
1601
|
+
// Build condition props as plain object, resolve pills on condition only.
|
|
1602
|
+
// label is a display name and must NOT be pill-converted;
|
|
1603
|
+
// status pills are already resolved above via statusProps.
|
|
1604
|
+
const conditionProps = { condition };
|
|
1605
|
+
convertActionPillsInInputs(conditionProps, cond, diagnostics, labelCacheMap);
|
|
1606
|
+
convertStepPillsInInputs(conditionProps, cond, cidToIdentifierMap, labelCacheMap);
|
|
1607
|
+
const condProps = {
|
|
1608
|
+
label,
|
|
1609
|
+
condition: conditionProps['condition'],
|
|
1610
|
+
status: new sdk_build_core_1.ObjectShape({ source: cond, properties: statusProps }),
|
|
1611
|
+
};
|
|
1612
|
+
if (dontTreatAsError) {
|
|
1613
|
+
condProps['dontTreatAsError'] = true;
|
|
1614
|
+
}
|
|
1615
|
+
conditionShapes.push(new sdk_build_core_1.ObjectShape({ source: cond, properties: condProps }));
|
|
1616
|
+
}
|
|
1617
|
+
const statusSource = actionStatusMetadata[0] ?? record;
|
|
1618
|
+
stepShapes.push(new sdk_build_core_1.CallExpressionShape({
|
|
1619
|
+
source: statusSource,
|
|
1620
|
+
callee: flow_constants_1.ERROR_EVALUATION_CALLEE,
|
|
1621
|
+
args: [
|
|
1622
|
+
new sdk_build_core_1.ArrayShape({
|
|
1623
|
+
source: statusSource,
|
|
1624
|
+
elements: conditionShapes,
|
|
1625
|
+
}),
|
|
1626
|
+
],
|
|
1627
|
+
}));
|
|
1628
|
+
}
|
|
1629
|
+
// Reconstruct wfa.assignActionOutputs() from output element_mappings.
|
|
1630
|
+
// Element mappings for output assignments can be keyed to the action def sys_id
|
|
1631
|
+
// (draft actions) or a snapshot sys_id (published actions). Check both.
|
|
1632
|
+
{
|
|
1633
|
+
const candidateIds = new Set([actionSysId]);
|
|
1634
|
+
const snapshots = descendants
|
|
1635
|
+
.query('sys_hub_action_type_snapshot')
|
|
1636
|
+
.filter((s) => s.get('parent_action')?.asString()?.getValue() === actionSysId);
|
|
1637
|
+
for (const snap of snapshots) {
|
|
1638
|
+
candidateIds.add(snap.getId().getValue());
|
|
1639
|
+
}
|
|
1640
|
+
// Find element_mappings for action outputs keyed to any candidate id
|
|
1641
|
+
const outputElementMappings = descendants
|
|
1642
|
+
.query('sys_element_mapping')
|
|
1643
|
+
.filter((m) => candidateIds.has(m.get('id')?.asString()?.getValue() ?? '') &&
|
|
1644
|
+
(m.get('table')?.asString()?.getValue() ?? '').startsWith(flow_constants_1.ACTION_OUTPUT_TABLE_PREFIX));
|
|
1645
|
+
// Build output element name lookup from all output records
|
|
1646
|
+
// (action-parented and snapshot-parented) for sys_variable_value resolution
|
|
1647
|
+
const varSysIdToElement = new Map();
|
|
1648
|
+
const snapshotOutputs = descendants
|
|
1649
|
+
.query('sys_hub_action_output')
|
|
1650
|
+
.filter((r) => candidateIds.has(r.get('model')?.asString()?.getValue() ?? ''));
|
|
1651
|
+
for (const outputRec of [...snapshotOutputs, ...actionOutputs]) {
|
|
1652
|
+
const element = outputRec.get('element')?.asString()?.getValue();
|
|
1653
|
+
if (element) {
|
|
1654
|
+
varSysIdToElement.set(outputRec.getId().getValue(), element);
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
// Gather sys_variable_value records for static output values
|
|
1658
|
+
const outputVarValues = descendants.query('sys_variable_value').filter((v) => {
|
|
1659
|
+
const docKey = v.get('document_key')?.asString()?.getValue() ?? '';
|
|
1660
|
+
return candidateIds.has(docKey);
|
|
1661
|
+
});
|
|
1662
|
+
if (outputElementMappings.length > 0 || outputVarValues.length > 0) {
|
|
1663
|
+
const valuesObj = {};
|
|
1664
|
+
const sourceRecord = snapshots[0] ?? record;
|
|
1665
|
+
// Static values from sys_variable_value
|
|
1666
|
+
for (const varValue of outputVarValues) {
|
|
1667
|
+
const variableSysId = varValue.get('variable')?.asString()?.getValue();
|
|
1668
|
+
const value = varValue.get('value')?.asString()?.getValue();
|
|
1669
|
+
const outputName = variableSysId ? varSysIdToElement.get(variableSysId) : undefined;
|
|
1670
|
+
// Skip internal platform outputs and missing values (null/undefined)
|
|
1671
|
+
if (!outputName || outputName.startsWith('__') || value == null) {
|
|
1672
|
+
continue;
|
|
1673
|
+
}
|
|
1674
|
+
// Skip FlowObject/FlowArray complex object schema serializations.
|
|
1675
|
+
// These sys_variable_value records store the output's type structure
|
|
1676
|
+
// (already declared via FlowObject/FlowArray in Fluent), not user-assigned values.
|
|
1677
|
+
if (value.includes('"complexObjectSchema"') || value.includes('"$COCollectionField"')) {
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
// sys_variable_value can contain pill strings (e.g. {{action.variable|string}})
|
|
1681
|
+
// Strip type suffix (|string, |reference) before pill parsing
|
|
1682
|
+
const pillStripped = value.replace(/\|[a-z_]+\}\}/g, '}}');
|
|
1683
|
+
valuesObj[outputName] = pillStripped;
|
|
1684
|
+
}
|
|
1685
|
+
// Datapill values from sys_element_mapping (overrides var values when both exist)
|
|
1686
|
+
for (const mapping of outputElementMappings) {
|
|
1687
|
+
const outputName = mapping.get('field')?.asString()?.getValue();
|
|
1688
|
+
const pillValue = mapping.get('value')?.asString()?.getValue();
|
|
1689
|
+
// Skip internal outputs, missing values, and empty pill strings.
|
|
1690
|
+
// An empty pill value means "no datapill assignment" — the static value
|
|
1691
|
+
// from sys_variable_value (if any) should be preserved.
|
|
1692
|
+
if (!outputName || !pillValue || outputName.startsWith('__')) {
|
|
1693
|
+
continue;
|
|
1694
|
+
}
|
|
1695
|
+
valuesObj[outputName] = pillValue;
|
|
1696
|
+
}
|
|
1697
|
+
// Two-pass pill resolution (same approach as step inputs):
|
|
1698
|
+
// Pass 1: Convert action pills ({{action.xxx}}) → dataPill shapes
|
|
1699
|
+
convertActionPillsInInputs(valuesObj, sourceRecord, diagnostics, labelCacheMap);
|
|
1700
|
+
// Pass 2: Convert step pills ({{step[UUID].xxx}}) → dataPill shapes
|
|
1701
|
+
convertStepPillsInInputs(valuesObj, sourceRecord, cidToIdentifierMap, labelCacheMap);
|
|
1702
|
+
if (Object.keys(valuesObj).length > 0) {
|
|
1703
|
+
// Use params.outputs reference instead of duplicating the full schema
|
|
1704
|
+
const outputsRef = new sdk_build_core_1.PropertyAccessShape({
|
|
1705
|
+
source: sourceRecord,
|
|
1706
|
+
elements: [
|
|
1707
|
+
new sdk_build_core_1.IdentifierShape({
|
|
1708
|
+
source: sourceRecord,
|
|
1709
|
+
name: ACTION_PILL_PARAM_NAME,
|
|
1710
|
+
}),
|
|
1711
|
+
'outputs',
|
|
1712
|
+
],
|
|
1713
|
+
});
|
|
1714
|
+
stepShapes.push(new sdk_build_core_1.CallExpressionShape({
|
|
1715
|
+
source: sourceRecord,
|
|
1716
|
+
callee: flow_constants_1.ASSIGN_ACTION_OUTPUTS_CALLEE,
|
|
1717
|
+
args: [
|
|
1718
|
+
outputsRef,
|
|
1719
|
+
new sdk_build_core_1.ObjectShape({
|
|
1720
|
+
source: sourceRecord,
|
|
1721
|
+
properties: valuesObj,
|
|
1722
|
+
}),
|
|
1723
|
+
],
|
|
1724
|
+
}));
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1275
1728
|
// Build args: config + optional body with step instances
|
|
1276
1729
|
const actionConfig = record.transform(({ $ }) => ({
|
|
1277
1730
|
$id: $.val(now_id_plugin_1.NowIdShape.from(record)),
|
|
@@ -1280,7 +1733,7 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1280
1733
|
description: $.def(''),
|
|
1281
1734
|
access: $.def('public'),
|
|
1282
1735
|
category: $.def(''),
|
|
1283
|
-
|
|
1736
|
+
protectionPolicy: $.from('sys_policy').def(''),
|
|
1284
1737
|
inputs: $.val(inputs),
|
|
1285
1738
|
outputs: $.val(outputs),
|
|
1286
1739
|
}));
|
|
@@ -1298,7 +1751,7 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1298
1751
|
args,
|
|
1299
1752
|
});
|
|
1300
1753
|
// Try to get the existing identifier from the record source, fallback to slugified name
|
|
1301
|
-
const actionName = (0,
|
|
1754
|
+
const actionName = (0, utils_1.getIdentifierFromRecord)(record) ??
|
|
1302
1755
|
(0, flow_constants_1.slugifyString)(String(record.get('internal_name')?.getValue() || record.get('name')?.getValue()));
|
|
1303
1756
|
return {
|
|
1304
1757
|
success: true,
|
|
@@ -1335,6 +1788,9 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1335
1788
|
sys_hub_status_condition: {
|
|
1336
1789
|
coalesce: ['action_status_metadata_id', 'order'],
|
|
1337
1790
|
},
|
|
1791
|
+
sys_element_mapping: {
|
|
1792
|
+
coalesce: ['id', 'table', 'field'],
|
|
1793
|
+
},
|
|
1338
1794
|
},
|
|
1339
1795
|
shapes: [
|
|
1340
1796
|
{
|
|
@@ -1354,12 +1810,11 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1354
1810
|
explicitId: actionConfiguration.get('$id'),
|
|
1355
1811
|
properties: actionConfiguration.transform(({ $ }) => ({
|
|
1356
1812
|
name: $,
|
|
1357
|
-
internal_name: $.from('name').map((n) => (0, flow_constants_1.slugifyString)(n.getValue())),
|
|
1358
1813
|
annotation: $.def(''),
|
|
1359
1814
|
description: $.def(''),
|
|
1360
1815
|
access: $.def('public'),
|
|
1361
1816
|
category: $.def(''),
|
|
1362
|
-
sys_policy: $.from('
|
|
1817
|
+
sys_policy: $.from('protectionPolicy').def(''),
|
|
1363
1818
|
active: $.val(true),
|
|
1364
1819
|
state: $.val('draft'),
|
|
1365
1820
|
system_level: $.val(false),
|
|
@@ -1397,10 +1852,25 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1397
1852
|
const cidToLabelMap = new Map();
|
|
1398
1853
|
const pillTypeMap = new Map();
|
|
1399
1854
|
const stepInfos = [];
|
|
1855
|
+
let assignActionOutputsShape;
|
|
1856
|
+
let errorEvaluationShape;
|
|
1400
1857
|
let order = 1;
|
|
1401
1858
|
for (const [, v] of (allInstances ?? []).entries()) {
|
|
1402
1859
|
const isVarStatement = v instanceof sdk_build_core_1.VariableStatementShape;
|
|
1403
1860
|
const innerShape = isVarStatement ? v.getInitializer() : v;
|
|
1861
|
+
if (innerShape instanceof sdk_build_core_1.CallExpressionShape &&
|
|
1862
|
+
innerShape.getCallee() === flow_constants_1.ASSIGN_ACTION_OUTPUTS_CALLEE) {
|
|
1863
|
+
assignActionOutputsShape = innerShape;
|
|
1864
|
+
continue;
|
|
1865
|
+
}
|
|
1866
|
+
if (innerShape instanceof sdk_build_core_1.CallExpressionShape &&
|
|
1867
|
+
innerShape.getCallee() === flow_constants_1.ERROR_EVALUATION_CALLEE) {
|
|
1868
|
+
errorEvaluationShape = innerShape;
|
|
1869
|
+
if (assignActionOutputsShape) {
|
|
1870
|
+
diagnostics.error(innerShape, `wfa.errorEvaluation() must appear before wfa.assignActionOutputs() in the action body.`);
|
|
1871
|
+
}
|
|
1872
|
+
continue;
|
|
1873
|
+
}
|
|
1404
1874
|
if (innerShape.getSource() instanceof step_instance_plugin_1.StepInstanceShape) {
|
|
1405
1875
|
const stepShape = innerShape.getSource();
|
|
1406
1876
|
stepShape.setCidMap(cidMap);
|
|
@@ -1440,6 +1910,135 @@ exports.ActionDefinitionPlugin = sdk_build_core_1.Plugin.create({
|
|
|
1440
1910
|
// inputs directly and create correct sys_element_mapping records.
|
|
1441
1911
|
const resolvedStepPillRecords = await resolveUnresolvedStepPills(stepInfos, cidMap, pillTypeMap, factory);
|
|
1442
1912
|
relatedRecords.push(...resolvedStepPillRecords);
|
|
1913
|
+
// Create sys_element_mapping records for assignActionOutputs values.
|
|
1914
|
+
// For draft actions, element_mappings reference the action definition sys_id directly.
|
|
1915
|
+
if (assignActionOutputsShape) {
|
|
1916
|
+
const actionDefId = actionDefinitionRecord.getId().getValue();
|
|
1917
|
+
const valuesArg = assignActionOutputsShape.getArgument(1)?.asObject();
|
|
1918
|
+
// Validate that assigned output names match declared outputs
|
|
1919
|
+
if (valuesArg && !outputsConfig) {
|
|
1920
|
+
diagnostics.error(assignActionOutputsShape, 'assignActionOutputs is used but no outputs are declared in the action config');
|
|
1921
|
+
}
|
|
1922
|
+
if (valuesArg && outputsConfig) {
|
|
1923
|
+
const declaredOutputNames = new Set(outputsConfig.keys());
|
|
1924
|
+
const assignedOutputNames = new Set();
|
|
1925
|
+
for (const [outputName] of valuesArg.entries({ resolve: false })) {
|
|
1926
|
+
assignedOutputNames.add(outputName);
|
|
1927
|
+
if (!declaredOutputNames.has(outputName)) {
|
|
1928
|
+
diagnostics.error(valuesArg.get(outputName), `Unknown output '${outputName}'. Available outputs: ${[...declaredOutputNames].join(', ') || '(none)'}`);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
for (const declaredName of declaredOutputNames) {
|
|
1932
|
+
if (!assignedOutputNames.has(declaredName)) {
|
|
1933
|
+
diagnostics.error(assignActionOutputsShape, `Output '${declaredName}' is declared but not assigned in assignActionOutputs. All declared outputs must be assigned a value.`);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
if (valuesArg) {
|
|
1938
|
+
const entries = valuesArg.entries({ resolve: false });
|
|
1939
|
+
for (const [outputName, valueShape] of entries) {
|
|
1940
|
+
const shape = valueShape;
|
|
1941
|
+
// Validate that the output value is not an empty string
|
|
1942
|
+
if (shape.isString() && shape.getValue() === '') {
|
|
1943
|
+
diagnostics.error(valuesArg.get(outputName), `Output '${outputName}' is assigned an empty string. All action outputs must be assigned a non-empty value.`);
|
|
1944
|
+
}
|
|
1945
|
+
const pillValue = resolveToString(shape, cidMap, pillTypeMap);
|
|
1946
|
+
const elementMapping = await factory.createRecord({
|
|
1947
|
+
source: assignActionOutputsShape,
|
|
1948
|
+
table: 'sys_element_mapping',
|
|
1949
|
+
properties: {
|
|
1950
|
+
field: outputName,
|
|
1951
|
+
id: actionDefId,
|
|
1952
|
+
table: `${flow_constants_1.ACTION_OUTPUT_TABLE_PREFIX}${actionDefId}`,
|
|
1953
|
+
value: pillValue,
|
|
1954
|
+
},
|
|
1955
|
+
});
|
|
1956
|
+
relatedRecords.push(elementMapping);
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
// ── Error Evaluation ─────────────────────────────────────────────
|
|
1961
|
+
// wfa.errorEvaluation([...]) → sys_hub_action_status_metadata + sys_hub_status_condition records
|
|
1962
|
+
if (errorEvaluationShape) {
|
|
1963
|
+
const actionDefId = actionDefinitionRecord.getId().getValue();
|
|
1964
|
+
// Create the single sys_hub_action_status_metadata record for this action
|
|
1965
|
+
const statusMetadataRecord = await factory.createRecord({
|
|
1966
|
+
source: errorEvaluationShape,
|
|
1967
|
+
table: 'sys_hub_action_status_metadata',
|
|
1968
|
+
properties: {
|
|
1969
|
+
action_type_id: actionDefId,
|
|
1970
|
+
},
|
|
1971
|
+
});
|
|
1972
|
+
relatedRecords.push(statusMetadataRecord);
|
|
1973
|
+
const metadataId = statusMetadataRecord.getId().getValue();
|
|
1974
|
+
// Parse the array of conditions (arg 0)
|
|
1975
|
+
const conditionsArg = errorEvaluationShape.getArgument(0);
|
|
1976
|
+
if (conditionsArg?.isArray()) {
|
|
1977
|
+
const elements = conditionsArg.asArray().getElements(false);
|
|
1978
|
+
let condOrder = 1;
|
|
1979
|
+
for (const condElement of elements) {
|
|
1980
|
+
if (!condElement.isObject()) {
|
|
1981
|
+
continue;
|
|
1982
|
+
}
|
|
1983
|
+
const condObj = condElement.asObject();
|
|
1984
|
+
// Extract fields from { label, condition, status, dontTreatAsError }
|
|
1985
|
+
const labelShape = condObj.get('label');
|
|
1986
|
+
const conditionShape = condObj.get('condition');
|
|
1987
|
+
const statusShape = condObj.get('status')?.ifObject()?.asObject();
|
|
1988
|
+
const dontTreatShape = condObj.get('dontTreatAsError');
|
|
1989
|
+
const label = labelShape?.ifString()?.getValue() ?? '';
|
|
1990
|
+
const condition = conditionShape ? resolveToString(conditionShape, cidMap, pillTypeMap) : '';
|
|
1991
|
+
const dontTreatRaw = dontTreatShape?.getValue?.();
|
|
1992
|
+
const dontTreatAsError = dontTreatRaw === true || dontTreatRaw === 'true';
|
|
1993
|
+
// Resolve status code and message (may contain datapills).
|
|
1994
|
+
// Use entries({ resolve: false }) to get raw shapes — without this,
|
|
1995
|
+
// PillShape values get auto-resolved and lose their pill reference.
|
|
1996
|
+
let codeValue = '';
|
|
1997
|
+
let messageValue = '';
|
|
1998
|
+
if (statusShape) {
|
|
1999
|
+
for (const [field, fieldShape] of statusShape.entries({ resolve: false })) {
|
|
2000
|
+
const shape = fieldShape;
|
|
2001
|
+
if (field === 'code') {
|
|
2002
|
+
codeValue = resolveToString(shape, cidMap, pillTypeMap);
|
|
2003
|
+
}
|
|
2004
|
+
else if (field === 'message') {
|
|
2005
|
+
messageValue = resolveToString(shape, cidMap, pillTypeMap);
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
const statusJson = buildStatusConditionJson(codeValue, messageValue);
|
|
2010
|
+
const conditionRecord = await factory.createRecord({
|
|
2011
|
+
source: errorEvaluationShape,
|
|
2012
|
+
table: 'sys_hub_status_condition',
|
|
2013
|
+
properties: {
|
|
2014
|
+
action_status_metadata_id: metadataId,
|
|
2015
|
+
condition,
|
|
2016
|
+
dont_treat_as_error: dontTreatAsError,
|
|
2017
|
+
label,
|
|
2018
|
+
order: condOrder,
|
|
2019
|
+
status: statusJson,
|
|
2020
|
+
},
|
|
2021
|
+
});
|
|
2022
|
+
relatedRecords.push(conditionRecord);
|
|
2023
|
+
condOrder++;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
// Create the __action_status__ element_mapping record.
|
|
2027
|
+
// The platform requires this to connect error evaluation status
|
|
2028
|
+
// conditions to the action's output. Its value is the base
|
|
2029
|
+
// FDACTIONSTATUS JSON with empty code/message mapped fields.
|
|
2030
|
+
const actionStatusMapping = await factory.createRecord({
|
|
2031
|
+
source: errorEvaluationShape,
|
|
2032
|
+
table: 'sys_element_mapping',
|
|
2033
|
+
properties: {
|
|
2034
|
+
field: '__action_status__',
|
|
2035
|
+
id: actionDefId,
|
|
2036
|
+
table: `${flow_constants_1.ACTION_OUTPUT_TABLE_PREFIX}${actionDefId}`,
|
|
2037
|
+
value: buildStatusConditionJson('', ''),
|
|
2038
|
+
},
|
|
2039
|
+
});
|
|
2040
|
+
relatedRecords.push(actionStatusMapping);
|
|
2041
|
+
}
|
|
1443
2042
|
const collectedStepPills = extractStepPillsFromRecords(relatedRecords, cidToLabelMap, pillTypeMap);
|
|
1444
2043
|
const dotWalkPills = extractActionDotWalkPills(relatedRecords, pillTypeMap);
|
|
1445
2044
|
if (inputsConfig) {
|