@servicenow/sdk-build-plugins 4.6.0 → 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 +3 -4
- 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 +6 -10
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +10 -4
- 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 +120 -49
- 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 +1 -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 +5 -4
- 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 +4 -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 +2 -4
- 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 +2 -4
- 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/service-catalog-base.d.ts +2 -2
- package/dist/service-catalog/service-catalog-base.js +2 -2
- package/dist/service-catalog/service-catalog-base.js.map +1 -1
- package/dist/service-catalog/utils.js +1 -1
- package/dist/service-catalog/utils.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 +303 -66
- 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 +28 -97
- 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 +5 -9
- package/dist/utils.js +38 -11
- 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 +4 -5
- 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 +6 -11
- package/src/basic-syntax-plugin.ts +11 -4
- 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 +163 -76
- 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 +1 -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 +14 -6
- 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 +8 -4
- package/src/server-module-plugin/index.ts +2 -3
- package/src/service-catalog/catalog-clientscript-plugin.ts +2 -4
- package/src/service-catalog/catalog-item-plugin.ts +0 -2
- package/src/service-catalog/catalog-ui-policy-plugin.ts +2 -4
- package/src/service-catalog/sc-record-producer-plugin.ts +0 -2
- package/src/service-catalog/service-catalog-base.ts +2 -2
- package/src/service-catalog/utils.ts +1 -1
- 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 +371 -92
- package/src/ui-action-plugin.ts +30 -17
- package/src/ui-page-plugin.ts +188 -20
- package/src/ui-policy-plugin.ts +33 -130
- package/src/user-preference-plugin.ts +0 -2
- package/src/utils.ts +48 -11
- package/src/ux-list-menu-config-plugin.ts +0 -2
- package/src/view-plugin.ts +0 -1
- package/src/workspace-plugin.ts +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FlowLogicInstanceShape
|
|
1
|
+
import type { FlowLogicInstanceShape } from './flow-logic-shapes'
|
|
2
2
|
import {
|
|
3
3
|
ts,
|
|
4
4
|
PropertyAccessShape,
|
|
@@ -8,11 +8,19 @@ import {
|
|
|
8
8
|
ObjectShape,
|
|
9
9
|
CallExpressionShape,
|
|
10
10
|
type Diagnostics,
|
|
11
|
+
type Shape,
|
|
11
12
|
} from '@servicenow/sdk-build-core'
|
|
12
13
|
import { FLOW_LOGIC } from './flow-logic-constants'
|
|
13
14
|
import { getCallExpressionName } from '../../utils'
|
|
14
15
|
import { findAncestorByCalleeName } from '../utils/utils'
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
isDoInParallelShape,
|
|
18
|
+
isSetFlowVariablesShape,
|
|
19
|
+
isAppendToFlowVariablesShape,
|
|
20
|
+
isAssignSubflowOutputsShape,
|
|
21
|
+
isTryCatchShape,
|
|
22
|
+
} from './flow-logic-plugin-helpers'
|
|
23
|
+
import { ArrowFunctionShape } from '../../arrow-function-plugin'
|
|
16
24
|
import { PillShape } from '../utils/data-pill-shapes'
|
|
17
25
|
import { ARRAY_FLOW_DATA_TYPES, type ArrayFlowDataType } from '@servicenow/sdk-core/runtime/flow'
|
|
18
26
|
import { FDInlineScriptCallShape } from '../plugins/inline-script-plugin'
|
|
@@ -30,8 +38,9 @@ const FLOW_LOGIC_VALIDATORS: { [K in FLOW_LOGIC]: FlowLogicValidator } = {
|
|
|
30
38
|
[FLOW_LOGIC.WAIT_FOR_A_DURATION]: validateWaitForADuration,
|
|
31
39
|
[FLOW_LOGIC.FOR_EACH]: validateForEach,
|
|
32
40
|
[FLOW_LOGIC.DO_IN_PARALLEL]: validateDoInParallel,
|
|
33
|
-
[FLOW_LOGIC.TRY_CATCH]:
|
|
41
|
+
[FLOW_LOGIC.TRY_CATCH]: validateTryCatch,
|
|
34
42
|
[FLOW_LOGIC.SET_FLOW_VARIABLES]: validateSetFlowVariables,
|
|
43
|
+
[FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES]: validateAppendToFlowVariables,
|
|
35
44
|
[FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS]: validateAssignSubflowOutputs,
|
|
36
45
|
}
|
|
37
46
|
|
|
@@ -137,8 +146,8 @@ function findParentFlowLogic(node: ts.Node | undefined): ts.CallExpression | und
|
|
|
137
146
|
|
|
138
147
|
const callName = getCallExpressionName(current)
|
|
139
148
|
|
|
140
|
-
if ([FLOW_LOGIC.IF, FLOW_LOGIC.ELSEIF, FLOW_LOGIC.ELSE,
|
|
141
|
-
if (callName ===
|
|
149
|
+
if ([FLOW_LOGIC.IF, FLOW_LOGIC.ELSEIF, FLOW_LOGIC.ELSE, FLOW_LOGIC.TRY_CATCH, 'MakeADecision'].includes(callName)) {
|
|
150
|
+
if (callName === FLOW_LOGIC.TRY_CATCH) {
|
|
142
151
|
// For TryCatch, GoBackTo should only be in the catch block, not in try block
|
|
143
152
|
if (!isInCatchBlock(node)) {
|
|
144
153
|
return undefined // Invalid placement - not in catch block
|
|
@@ -311,13 +320,36 @@ function validateForEach(expr: FlowLogicInstanceShape): string | undefined {
|
|
|
311
320
|
return undefined
|
|
312
321
|
}
|
|
313
322
|
|
|
323
|
+
// TypeScript enforces argument count, $id, and `() => void` shape of try/catch.
|
|
324
|
+
// The plugin's transform logic requires arrow functions specifically, which TS does not distinguish from other
|
|
325
|
+
// function forms — so check that here.
|
|
326
|
+
function validateTryCatch(expr: FlowLogicInstanceShape): string | undefined {
|
|
327
|
+
if (!isTryCatchShape(expr)) {
|
|
328
|
+
return undefined
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const handlers = expr.getArgument(1)?.if(ObjectShape)
|
|
332
|
+
const tryHandler = handlers?.get('try')
|
|
333
|
+
const catchHandler = handlers?.get('catch')
|
|
334
|
+
|
|
335
|
+
if (!tryHandler?.if(ArrowFunctionShape)) {
|
|
336
|
+
return "TryCatch: 'try' handler must be an arrow function"
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (!catchHandler?.if(ArrowFunctionShape)) {
|
|
340
|
+
return "TryCatch: 'catch' handler must be an arrow function"
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return undefined
|
|
344
|
+
}
|
|
345
|
+
|
|
314
346
|
function validateDoInParallel(expr: FlowLogicInstanceShape): string | undefined {
|
|
315
347
|
if (isDoInParallelShape(expr)) {
|
|
316
|
-
|
|
317
|
-
|
|
348
|
+
// Check for nested `DoInParallel`. `findAncestorByCalleeName` returns the node itself when it matches, so
|
|
349
|
+
// start the search from the parent call expression. Otherwise, every `DoInParallel` would flag itself.
|
|
350
|
+
const parentCall = expr.getOriginalNode()?.getFirstAncestorByKind(ts.SyntaxKind.CallExpression)
|
|
351
|
+
const parentDoInParallel = findAncestorByCalleeName(parentCall, FLOW_LOGIC.DO_IN_PARALLEL)
|
|
318
352
|
|
|
319
|
-
// Check for nested DoInParallel
|
|
320
|
-
const parentDoInParallel = findAncestorByCalleeName(originalNode, FLOW_LOGIC.DO_IN_PARALLEL)
|
|
321
353
|
if (parentDoInParallel) {
|
|
322
354
|
return 'Nested DoInParallel calls are not allowed. DoInParallel cannot be used within another DoInParallel block.'
|
|
323
355
|
}
|
|
@@ -327,83 +359,69 @@ function validateDoInParallel(expr: FlowLogicInstanceShape): string | undefined
|
|
|
327
359
|
}
|
|
328
360
|
|
|
329
361
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
362
|
+
* Shared validator for "variable assignment"-style flow logic shapes (SetFlowVariables and AppendToFlowVariables).
|
|
363
|
+
* Both shapes share the (config, schema, values) argument layout and the same value-type rules; only the type guard,
|
|
364
|
+
* the values' accessor, and the error-message prefix differ. Routing both through one helper prevents the two
|
|
365
|
+
* implementations from drifting independently and ensures any future validation change applies to both call sites at
|
|
366
|
+
* once.
|
|
332
367
|
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
* 6. Variable values: Must be valid types (string, number, boolean, or datapill)
|
|
368
|
+
* Validations performed:
|
|
369
|
+
* 1. Argument count must be exactly 3 (config, schema, values).
|
|
370
|
+
* 2. Config must expose a valid $id (`expr.getSysId()` must not throw).
|
|
371
|
+
* 3. Values argument must be a defined, non-empty object.
|
|
372
|
+
* 4. Every key must be a non-empty string.
|
|
373
|
+
* 5. Every value must be a string / number / boolean / object / array / datapill / inline script.
|
|
340
374
|
*
|
|
341
|
-
*
|
|
342
|
-
* -
|
|
343
|
-
* -
|
|
344
|
-
* -
|
|
345
|
-
*
|
|
346
|
-
* - Arrays: [1, 2, 3] (ArrayShape - for FlowArray types)
|
|
347
|
-
* - Datapills: params.trigger.name, params.complexObject (PropertyAccessShape)
|
|
348
|
-
* - Template expressions: `Hello ${params.trigger.name}` (TemplateExpressionShape)
|
|
349
|
-
*
|
|
350
|
-
* @param expr - The SetFlowVariables flow logic instance shape
|
|
351
|
-
* @returns Error message if validation fails, undefined if valid
|
|
352
|
-
*
|
|
353
|
-
* @example
|
|
354
|
-
* // Valid usage
|
|
355
|
-
* wfa.flowLogic.setFlowVariables(
|
|
356
|
-
* { $id: Now.ID['...'] },
|
|
357
|
-
* params.flowVariables, // ← Schema reference (2nd argument)
|
|
358
|
-
* { user: params.trigger.name, count: 42, active: true }
|
|
359
|
-
* )
|
|
375
|
+
* @param expr - The flow logic instance shape to validate.
|
|
376
|
+
* @param name - API name used as the error-message prefix (e.g., 'SetFlowVariables').
|
|
377
|
+
* @param isShape - Type-guard distinguishing the specific assignment shape.
|
|
378
|
+
* @param getValues - Accessor returning the values ObjectShape from the narrowed shape.
|
|
379
|
+
* @returns Error message if validation fails, undefined otherwise.
|
|
360
380
|
*/
|
|
361
|
-
function
|
|
362
|
-
|
|
381
|
+
function validateVariableAssignmentShape<S extends FlowLogicInstanceShape>(
|
|
382
|
+
expr: FlowLogicInstanceShape,
|
|
383
|
+
name: string,
|
|
384
|
+
isShape: (e: FlowLogicInstanceShape) => e is S,
|
|
385
|
+
getValues: (shape: S) => ObjectShape | undefined
|
|
386
|
+
): string | undefined {
|
|
387
|
+
if (!isShape(expr)) {
|
|
363
388
|
return undefined
|
|
364
389
|
}
|
|
365
390
|
|
|
366
|
-
// Validate argument count
|
|
367
391
|
const args = expr.getArguments()
|
|
368
392
|
if (args.length !== 3) {
|
|
369
|
-
return
|
|
393
|
+
return `${name} requires exactly 3 arguments (config, schema, values), but received ${args.length}`
|
|
370
394
|
}
|
|
371
395
|
|
|
372
|
-
// Validate config argument
|
|
373
396
|
try {
|
|
374
397
|
expr.getSysId()
|
|
375
|
-
} catch
|
|
376
|
-
return
|
|
398
|
+
} catch {
|
|
399
|
+
return `${name}: First argument (config) must be an object with valid $id property`
|
|
377
400
|
}
|
|
378
401
|
|
|
379
|
-
|
|
380
|
-
const valuesArg = expr.getVariablesToSet()
|
|
402
|
+
const valuesArg = getValues(expr)
|
|
381
403
|
if (!valuesArg || valuesArg.isUndefined()) {
|
|
382
|
-
return
|
|
404
|
+
return `${name}: Third argument (values) is required`
|
|
383
405
|
}
|
|
384
406
|
|
|
385
407
|
if (!valuesArg.isObject()) {
|
|
386
|
-
return
|
|
408
|
+
return `${name}: Third argument (values) must be an object`
|
|
387
409
|
}
|
|
388
410
|
|
|
389
|
-
// Validate that values object is not empty
|
|
390
411
|
const entries = Array.from(valuesArg.entries({ resolve: false }))
|
|
391
412
|
if (entries.length === 0) {
|
|
392
|
-
return
|
|
413
|
+
return `${name}: Values object cannot be empty - at least one variable is required`
|
|
393
414
|
}
|
|
394
415
|
|
|
395
|
-
// Validate each value in the object
|
|
396
416
|
for (const [key, valueShape] of entries) {
|
|
397
417
|
if (!key || key.trim() === '') {
|
|
398
|
-
return
|
|
418
|
+
return `${name}: Variable names cannot be empty`
|
|
399
419
|
}
|
|
400
420
|
|
|
401
|
-
// Check if value is valid (string, datapill, template expression, or inline script)
|
|
402
421
|
if (valueShape.isUndefined()) {
|
|
403
|
-
return
|
|
422
|
+
return `${name}: Variable '${key}' has undefined value`
|
|
404
423
|
}
|
|
405
424
|
|
|
406
|
-
// Values can be: strings, numbers, booleans, objects, arrays, datapills, template expressions, or inline scripts
|
|
407
425
|
const isDatapill = valueShape instanceof PropertyAccessShape || valueShape instanceof TemplateExpressionShape
|
|
408
426
|
const isInlineScript = valueShape instanceof FDInlineScriptCallShape
|
|
409
427
|
const isIdentifier = valueShape instanceof IdentifierShape
|
|
@@ -417,17 +435,177 @@ function validateSetFlowVariables(expr: FlowLogicInstanceShape): string | undefi
|
|
|
417
435
|
isInlineScript
|
|
418
436
|
|
|
419
437
|
if (!isValidType) {
|
|
420
|
-
// Provide specific error message for unsupported types
|
|
421
438
|
if (isIdentifier) {
|
|
422
|
-
return
|
|
439
|
+
return `${name}: Variable '${key}' cannot use local variable references. Use direct values (literals) or datapills (e.g., params.someField) instead`
|
|
423
440
|
}
|
|
424
|
-
|
|
441
|
+
|
|
442
|
+
return `${name}: Variable '${key}' has invalid value type. Expected string, number, boolean, object, array, or datapill expression`
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return undefined
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function validateSetFlowVariables(expr: FlowLogicInstanceShape): string | undefined {
|
|
450
|
+
return validateVariableAssignmentShape(expr, 'SetFlowVariables', isSetFlowVariablesShape, (s) =>
|
|
451
|
+
s.getVariablesToSet()
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Validates AppendToFlowVariables flow logic instance.
|
|
457
|
+
*
|
|
458
|
+
* The "target must be array-typed" constraint is enforced at compile time by the API type signature
|
|
459
|
+
* (`KV[K] extends Array<infer E> ? ... : never`). The platform only supports appending to Array.Object flow variables —
|
|
460
|
+
* other array element types (string / integer / boolean / datetime) are runtime no-ops, so this validator emits an
|
|
461
|
+
* error for any target whose flow variable is not declared as `FlowArray({ elementType: FlowObject(...) })`. The
|
|
462
|
+
* remaining argument / structural checks are shared with SetFlowVariables via `validateVariableAssignmentShape`.
|
|
463
|
+
*
|
|
464
|
+
* Additionally, when an array literal is provided as the value for an Array.Object target, every element must itself
|
|
465
|
+
* be an object literal or a datapill expression — primitive literals are not valid array.object elements and the TS
|
|
466
|
+
* `unknown[]` arm of the value union lets them slip past the compile-time check.
|
|
467
|
+
*
|
|
468
|
+
* @param expr - The AppendToFlowVariables flow logic instance shape
|
|
469
|
+
* @returns Error message if validation fails, undefined if valid
|
|
470
|
+
*/
|
|
471
|
+
function validateAppendToFlowVariables(expr: FlowLogicInstanceShape): string | undefined {
|
|
472
|
+
const shapeError = validateVariableAssignmentShape(
|
|
473
|
+
expr,
|
|
474
|
+
'AppendToFlowVariables',
|
|
475
|
+
isAppendToFlowVariablesShape,
|
|
476
|
+
(s) => s.getValuesToAppend()
|
|
477
|
+
)
|
|
478
|
+
if (shapeError) {
|
|
479
|
+
return shapeError
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (!isAppendToFlowVariablesShape(expr)) {
|
|
483
|
+
return undefined
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const parentFlow = findAncestorByCalleeName(expr.getOriginalNode(), 'Flow', 'Subflow')
|
|
487
|
+
if (!parentFlow) {
|
|
488
|
+
// Placement is already validated by the umbrella check; nothing further to assert here.
|
|
489
|
+
return undefined
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const flowVariableInitializers = getFlowVariableInitializers(parentFlow)
|
|
493
|
+
const valuesArg = expr.getValuesToAppend()
|
|
494
|
+
for (const [key, valueShape] of valuesArg.entries({ resolve: false })) {
|
|
495
|
+
const initializer = flowVariableInitializers.get(key)
|
|
496
|
+
// If the variable isn't declared in flowVariables, the TS signature has already rejected the key at compile
|
|
497
|
+
// time — skip rather than double-reporting.
|
|
498
|
+
if (!initializer) {
|
|
499
|
+
continue
|
|
500
|
+
}
|
|
501
|
+
if (!isArrayObjectFlowVariable(initializer)) {
|
|
502
|
+
return `AppendToFlowVariables: Variable '${key}' is not an Array.Object flow variable. AppendToFlowVariables only supports Array.Object targets — declare the variable as FlowArray({ elementType: FlowObject(...) }).`
|
|
503
|
+
}
|
|
504
|
+
const elementError = validateArrayObjectElements(key, valueShape)
|
|
505
|
+
if (elementError) {
|
|
506
|
+
return elementError
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return undefined
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* For an Array.Object target, every element of an array-literal value must be an object literal or a datapill
|
|
515
|
+
* expression. A primitive literal (string / number / boolean) inside the array is silently accepted by TypeScript
|
|
516
|
+
* (via the `unknown[]` arm of the value union) but rejected by the platform at runtime, so we flag it here.
|
|
517
|
+
*
|
|
518
|
+
* Non-array values (single object literal, whole-field template string, whole-field datapill) are accepted as-is —
|
|
519
|
+
* those arms are already covered by the shared `validateVariableAssignmentShape` checks and by the platform's own
|
|
520
|
+
* runtime handling.
|
|
521
|
+
*/
|
|
522
|
+
function validateArrayObjectElements(key: string, valueShape: Shape): string | undefined {
|
|
523
|
+
if (!valueShape.isArray()) {
|
|
524
|
+
return undefined
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const elements = valueShape.asArray().getElements(false)
|
|
528
|
+
for (const [i, element] of elements.entries()) {
|
|
529
|
+
if (isArrayObjectElement(element)) {
|
|
530
|
+
continue
|
|
425
531
|
}
|
|
532
|
+
|
|
533
|
+
return `AppendToFlowVariables: Variable '${key}' has an invalid element at index ${i}. Array.Object variables only accept object literals or datapill expressions as elements — primitive values are not allowed.`
|
|
426
534
|
}
|
|
427
535
|
|
|
428
536
|
return undefined
|
|
429
537
|
}
|
|
430
538
|
|
|
539
|
+
function isArrayObjectElement(element: Shape): boolean {
|
|
540
|
+
if (element instanceof ObjectShape) {
|
|
541
|
+
return true
|
|
542
|
+
}
|
|
543
|
+
if (
|
|
544
|
+
element instanceof PropertyAccessShape ||
|
|
545
|
+
element instanceof TemplateExpressionShape ||
|
|
546
|
+
element instanceof PillShape ||
|
|
547
|
+
element instanceof FDInlineScriptCallShape
|
|
548
|
+
) {
|
|
549
|
+
return true
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// `wfa.dataPill(...)` calls are unwrapped to PillShape by the DataPillPlugin in normal builds. However, raw
|
|
553
|
+
// CallExpressionShape can still arrive here for fixtures that haven't been subclassed yet — accept any call
|
|
554
|
+
// expression whose callee resolves to wfa.dataPill so the order of plugin subclassing does not matter.
|
|
555
|
+
return element instanceof CallExpressionShape && element.getCallee() === 'wfa.dataPill'
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Reads a Flow / Subflow's `flowVariables` config property and returns a map from variable name to its initializer
|
|
560
|
+
* expression. Returns an empty map when `flowVariables` is missing or shaped unexpectedly — those cases are handled by
|
|
561
|
+
* other validators (or by the TypeScript type system) and should not be re-flagged here.
|
|
562
|
+
*/
|
|
563
|
+
function getFlowVariableInitializers(flowOrSubflow: ts.CallExpression): Map<string, ts.Expression> {
|
|
564
|
+
const result = new Map<string, ts.Expression>()
|
|
565
|
+
const configArg = flowOrSubflow.getArguments()[0]
|
|
566
|
+
if (!configArg || !ts.Node.isObjectLiteralExpression(configArg)) {
|
|
567
|
+
return result
|
|
568
|
+
}
|
|
569
|
+
const flowVarsProp = configArg.getProperty('flowVariables')?.asKind(ts.SyntaxKind.PropertyAssignment)
|
|
570
|
+
const flowVarsObject = flowVarsProp?.getInitializer()?.asKind(ts.SyntaxKind.ObjectLiteralExpression)
|
|
571
|
+
if (!flowVarsObject) {
|
|
572
|
+
return result
|
|
573
|
+
}
|
|
574
|
+
for (const prop of flowVarsObject.getProperties()) {
|
|
575
|
+
const propertyAssignment = prop.asKind(ts.SyntaxKind.PropertyAssignment)
|
|
576
|
+
const initializer = propertyAssignment?.getInitializer()
|
|
577
|
+
if (!propertyAssignment || !initializer) {
|
|
578
|
+
continue
|
|
579
|
+
}
|
|
580
|
+
result.set(getPropertyAssignmentName(propertyAssignment), initializer)
|
|
581
|
+
}
|
|
582
|
+
return result
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function getPropertyAssignmentName(node: ts.PropertyAssignment): string {
|
|
586
|
+
const nameNode = node.getNameNode()
|
|
587
|
+
return ts.Node.isStringLiteral(nameNode) || ts.Node.isNoSubstitutionTemplateLiteral(nameNode)
|
|
588
|
+
? nameNode.getLiteralValue()
|
|
589
|
+
: nameNode.getText()
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Returns true when the given flow-variable initializer expression is a `FlowArray({ elementType: FlowObject(...) })`
|
|
594
|
+
* call — the only flow-variable shape that AppendToFlowVariables can target at runtime.
|
|
595
|
+
*/
|
|
596
|
+
function isArrayObjectFlowVariable(initializer: ts.Expression): boolean {
|
|
597
|
+
if (!ts.Node.isCallExpression(initializer) || getCallExpressionName(initializer) !== 'FlowArray') {
|
|
598
|
+
return false
|
|
599
|
+
}
|
|
600
|
+
const flowArrayConfig = initializer.getArguments()[0]?.asKind(ts.SyntaxKind.ObjectLiteralExpression)
|
|
601
|
+
const elementTypeProp = flowArrayConfig?.getProperty('elementType')?.asKind(ts.SyntaxKind.PropertyAssignment)
|
|
602
|
+
const elementTypeInit = elementTypeProp?.getInitializer()
|
|
603
|
+
if (!elementTypeInit || !ts.Node.isCallExpression(elementTypeInit)) {
|
|
604
|
+
return false
|
|
605
|
+
}
|
|
606
|
+
return getCallExpressionName(elementTypeInit) === 'FlowObject'
|
|
607
|
+
}
|
|
608
|
+
|
|
431
609
|
/**
|
|
432
610
|
* Validates AssignSubflowOutputs flow logic instance.
|
|
433
611
|
* Performs comprehensive validation of arguments, types, structure, and placement.
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
TryCatchInstanceShape,
|
|
8
8
|
DoInParallelInstanceShape,
|
|
9
9
|
SetFlowVariablesInstanceShape,
|
|
10
|
+
AppendToFlowVariablesInstanceShape,
|
|
10
11
|
AssignSubflowOutputsInstanceShape,
|
|
11
12
|
} from './flow-logic-shapes'
|
|
12
13
|
import {
|
|
@@ -33,7 +34,7 @@ import {
|
|
|
33
34
|
DURATION_TYPE_PROPS,
|
|
34
35
|
WAIT_FOR_A_DURATION_INPUT_DESCRIPTORS,
|
|
35
36
|
} from './flow-logic-constants'
|
|
36
|
-
import { resolveDataPillShape, sysIdToUuid } from '../utils/utils'
|
|
37
|
+
import { getOrderSuffix, resolveDataPillShape, sysIdToUuid } from '../utils/utils'
|
|
37
38
|
import { ArrowFunctionShape } from '../../arrow-function-plugin'
|
|
38
39
|
import { NowIdShape } from '../../now-id-plugin'
|
|
39
40
|
import { validateFlowLogic, validateSibling } from './flow-logic-diagnostics'
|
|
@@ -222,6 +223,9 @@ export namespace FlowLogicValueProcessor {
|
|
|
222
223
|
[FLOW_LOGIC.SET_FLOW_VARIABLES]: (data) => {
|
|
223
224
|
return prepareSetFlowVariables(data.asObject(), '')
|
|
224
225
|
},
|
|
226
|
+
[FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES]: (data) => {
|
|
227
|
+
return prepareSetFlowVariables(data.asObject(), '')
|
|
228
|
+
},
|
|
225
229
|
[FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS]: (data) => {
|
|
226
230
|
return prepareAssignSubflowOutputs(data.asObject())
|
|
227
231
|
},
|
|
@@ -266,7 +270,7 @@ export namespace FlowLogicValueProcessor {
|
|
|
266
270
|
return {
|
|
267
271
|
outputsToAssign: logicType === FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS ? preparedData : [],
|
|
268
272
|
variables:
|
|
269
|
-
logicType === FLOW_LOGIC.SET_FLOW_VARIABLES
|
|
273
|
+
logicType === FLOW_LOGIC.SET_FLOW_VARIABLES || logicType === FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES
|
|
270
274
|
? prepareSetFlowVariables(data.asObject(), 'variables')
|
|
271
275
|
: [],
|
|
272
276
|
decisionTableInputs: [],
|
|
@@ -655,7 +659,12 @@ export namespace FlowLogicValueProcessor {
|
|
|
655
659
|
[FLOW_LOGIC.FOR_EACH]: parseForEach,
|
|
656
660
|
[FLOW_LOGIC.DO_IN_PARALLEL]: () => ({}),
|
|
657
661
|
[FLOW_LOGIC.TRY_CATCH]: () => ({}),
|
|
662
|
+
// Unreachable: parse() short-circuits for SET_FLOW_VARIABLES, APPEND_TO_FLOW_VARIABLES, and
|
|
663
|
+
// ASSIGN_SUBFLOW_OUTPUTS before this lookup runs — their payloads live in `variables` / `outputsToAssign`, not
|
|
664
|
+
// `inputs`, so they take dedicated branches that delegate to `parseEntriesFromArray`. The entries below exist
|
|
665
|
+
// only to satisfy the `{ [K in FLOW_LOGIC]: ValueParser }` exhaustiveness constraint.
|
|
658
666
|
[FLOW_LOGIC.SET_FLOW_VARIABLES]: () => ({}),
|
|
667
|
+
[FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES]: () => ({}),
|
|
659
668
|
[FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS]: () => ({}),
|
|
660
669
|
}
|
|
661
670
|
|
|
@@ -688,8 +697,9 @@ export namespace FlowLogicValueProcessor {
|
|
|
688
697
|
): FlowLogicParseResult {
|
|
689
698
|
const valuesJson = parseGzippedJson(gZippedString)
|
|
690
699
|
|
|
691
|
-
// Special handling for SET_FLOW_VARIABLES - data is in
|
|
692
|
-
|
|
700
|
+
// Special handling for SET_FLOW_VARIABLES and APPEND_TO_FLOW_VARIABLES - data is in the variable array.
|
|
701
|
+
// Both flow logics share the same wire format; only the platform-side semantics differ (overwrite vs. append).
|
|
702
|
+
if (logicType === FLOW_LOGIC.SET_FLOW_VARIABLES || logicType === FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES) {
|
|
693
703
|
if (valuesJson?.variables?.length) {
|
|
694
704
|
return parseEntriesFromArray(valuesJson.variables, typeMap, labelCacheMap)
|
|
695
705
|
}
|
|
@@ -1642,6 +1652,10 @@ export function isSetFlowVariablesShape(expr: FlowLogicInstanceShape): expr is S
|
|
|
1642
1652
|
return expr.getCallee() === FLOW_LOGIC.SET_FLOW_VARIABLES
|
|
1643
1653
|
}
|
|
1644
1654
|
|
|
1655
|
+
export function isAppendToFlowVariablesShape(expr: FlowLogicInstanceShape): expr is AppendToFlowVariablesInstanceShape {
|
|
1656
|
+
return expr.getCallee() === FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1645
1659
|
export function isAssignSubflowOutputsShape(expr: FlowLogicInstanceShape): expr is AssignSubflowOutputsInstanceShape {
|
|
1646
1660
|
return expr.getCallee() === FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS
|
|
1647
1661
|
}
|
|
@@ -1905,6 +1919,11 @@ async function extractDataFromShape(
|
|
|
1905
1919
|
return await resolveConfigDataPills(variablesToSet, transform, diagnostics)
|
|
1906
1920
|
}
|
|
1907
1921
|
|
|
1922
|
+
if (isAppendToFlowVariablesShape(expr)) {
|
|
1923
|
+
const valuesToAppend = expr.getValuesToAppend()
|
|
1924
|
+
return await resolveConfigDataPills(valuesToAppend, transform, diagnostics)
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1908
1927
|
if (isAssignSubflowOutputsShape(expr)) {
|
|
1909
1928
|
const assignedSubflowOutputs = expr.getAssignedSubflowOutputs()
|
|
1910
1929
|
return await resolveConfigDataPills(assignedSubflowOutputs, transform, diagnostics)
|
|
@@ -1969,6 +1988,12 @@ export async function getFlowLogicInstanceRecord(
|
|
|
1969
1988
|
})
|
|
1970
1989
|
}
|
|
1971
1990
|
|
|
1991
|
+
if (isAppendToFlowVariablesShape(expr)) {
|
|
1992
|
+
instanceRecord = instanceRecord.merge({
|
|
1993
|
+
flow_variables_assigned: expr.getValuesToAppendAsString(),
|
|
1994
|
+
})
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1972
1997
|
instanceRecord = instanceRecord.merge({
|
|
1973
1998
|
values: values,
|
|
1974
1999
|
})
|
|
@@ -2084,6 +2109,7 @@ const FLOW_LOGIC_ARGUMENT_BUILDERS: { [K in FLOW_LOGIC]: FlowLogicArgumentBuilde
|
|
|
2084
2109
|
[FLOW_LOGIC.DO_IN_PARALLEL]: buildBasicArguments,
|
|
2085
2110
|
[FLOW_LOGIC.TRY_CATCH]: buildBasicArguments,
|
|
2086
2111
|
[FLOW_LOGIC.SET_FLOW_VARIABLES]: buildSetFlowVariablesArguments,
|
|
2112
|
+
[FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES]: buildAppendToFlowVariablesArguments,
|
|
2087
2113
|
[FLOW_LOGIC.ASSIGN_SUBFLOW_OUTPUTS]: buildAssignSubflowOutputsArguments,
|
|
2088
2114
|
}
|
|
2089
2115
|
|
|
@@ -2226,6 +2252,31 @@ function buildSetFlowVariablesArguments(
|
|
|
2226
2252
|
)
|
|
2227
2253
|
}
|
|
2228
2254
|
|
|
2255
|
+
/**
|
|
2256
|
+
* Builds arguments for AppendToFlowVariables when converting XML to Fluent.
|
|
2257
|
+
* Mirrors SetFlowVariables — both target the flow's `sys_hub_flow_variable` schema and use the `{{flowVariables}}`
|
|
2258
|
+
* schema reference. The platform-side semantics differ (append vs. overwrite), but the wire format and argument shape
|
|
2259
|
+
* are identical.
|
|
2260
|
+
*
|
|
2261
|
+
* @param record - ServiceNow sys_hub_flow_logic_instance_v2 record
|
|
2262
|
+
* @param _logicBodyShapes - Unused (required by FlowLogicArgumentBuilder interface)
|
|
2263
|
+
* @param database - Database to query for the flow variable schemas
|
|
2264
|
+
* @returns Array of three Shape arguments for AppendToFlowVariables call
|
|
2265
|
+
*/
|
|
2266
|
+
function buildAppendToFlowVariablesArguments(
|
|
2267
|
+
record: Record,
|
|
2268
|
+
_logicBodyShapes: Shape[],
|
|
2269
|
+
database: Database
|
|
2270
|
+
): Shape<unknown>[] {
|
|
2271
|
+
return buildVariableOrOutputArguments(
|
|
2272
|
+
record,
|
|
2273
|
+
database,
|
|
2274
|
+
'sys_hub_flow_variable',
|
|
2275
|
+
FLOW_LOGIC.APPEND_TO_FLOW_VARIABLES,
|
|
2276
|
+
'{{flowVariables}}'
|
|
2277
|
+
)
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2229
2280
|
/**
|
|
2230
2281
|
* Builds arguments for AssignSubflowOutputs when converting XML to Fluent.
|
|
2231
2282
|
* Creates the three arguments required by the AssignSubflowOutputs API:
|
|
@@ -2431,11 +2482,13 @@ function extractForEachParameterName(record: Record): string {
|
|
|
2431
2482
|
}
|
|
2432
2483
|
|
|
2433
2484
|
/**
|
|
2434
|
-
* Gets the fallback parameter name based on order or default.
|
|
2485
|
+
* Gets the fallback parameter name based on order or default. A ForEach inside
|
|
2486
|
+
* a DoInParallel branch carries a composite order like `19➛20`; strip the
|
|
2487
|
+
* separator so the generated identifier is valid JS.
|
|
2435
2488
|
*/
|
|
2436
2489
|
function getFallbackParameterName(record: Record): string {
|
|
2437
2490
|
const order = record.get('order')?.getValue() as string | undefined
|
|
2438
|
-
return order ? `item_${order}` : 'item'
|
|
2491
|
+
return order ? `item_${getOrderSuffix(order)}` : 'item'
|
|
2439
2492
|
}
|
|
2440
2493
|
|
|
2441
2494
|
function buildForEachArguments(record: Record, logicBodyShapes: Shape[]): Shape<unknown>[] {
|