@servicenow/sdk-build-plugins 4.2.0 → 4.4.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 +11 -0
- package/dist/acl-plugin.js.map +1 -1
- package/dist/applicability-plugin.d.ts +2 -0
- package/dist/applicability-plugin.js +72 -0
- package/dist/applicability-plugin.js.map +1 -0
- package/dist/atf/test-plugin.js +5 -2
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +7 -1
- package/dist/basic-syntax-plugin.js.map +1 -1
- package/dist/business-rule-plugin.js +1 -0
- package/dist/business-rule-plugin.js.map +1 -1
- package/dist/call-expression-plugin.js +1 -107
- package/dist/call-expression-plugin.js.map +1 -1
- package/dist/column/column-to-record.d.ts +10 -3
- package/dist/column/column-to-record.js +44 -7
- package/dist/column/column-to-record.js.map +1 -1
- package/dist/column-plugin.d.ts +3 -1
- package/dist/column-plugin.js +12 -12
- package/dist/column-plugin.js.map +1 -1
- package/dist/dashboard/dashboard-component-property-defaults.d.ts +152 -0
- package/dist/dashboard/dashboard-component-property-defaults.js +264 -0
- package/dist/dashboard/dashboard-component-property-defaults.js.map +1 -0
- package/dist/dashboard/dashboard-component-resolver.d.ts +13 -0
- package/dist/dashboard/dashboard-component-resolver.js +69 -0
- package/dist/dashboard/dashboard-component-resolver.js.map +1 -0
- package/dist/dashboard/dashboard-plugin.d.ts +12 -0
- package/dist/dashboard/dashboard-plugin.js +397 -0
- package/dist/dashboard/dashboard-plugin.js.map +1 -0
- package/dist/data-plugin.d.ts +3 -0
- package/dist/data-plugin.js +61 -113
- package/dist/data-plugin.js.map +1 -1
- package/dist/email-notification-plugin.d.ts +2 -0
- package/dist/email-notification-plugin.js +541 -0
- package/dist/email-notification-plugin.js.map +1 -0
- package/dist/flow/constants/flow-plugin-constants.d.ts +58 -0
- package/dist/flow/constants/flow-plugin-constants.js +70 -0
- package/dist/flow/constants/flow-plugin-constants.js.map +1 -0
- package/dist/flow/flow-logic/flow-logic-constants.d.ts +38 -0
- package/dist/flow/flow-logic/flow-logic-constants.js +118 -0
- package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -0
- package/dist/flow/flow-logic/flow-logic-diagnostics.d.ts +19 -0
- package/dist/flow/flow-logic/flow-logic-diagnostics.js +503 -0
- package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -0
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +62 -0
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +2092 -0
- package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -0
- package/dist/flow/flow-logic/flow-logic-plugin.d.ts +52 -0
- package/dist/flow/flow-logic/flow-logic-plugin.js +283 -0
- package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -0
- package/dist/flow/flow-logic/flow-logic-shapes.d.ts +104 -0
- package/dist/flow/flow-logic/flow-logic-shapes.js +201 -0
- package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -0
- package/dist/flow/plugins/approval-rules-plugin.d.ts +2 -0
- package/dist/flow/plugins/approval-rules-plugin.js +49 -0
- package/dist/flow/plugins/approval-rules-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-action-definition-plugin.d.ts +2 -0
- package/dist/flow/plugins/flow-action-definition-plugin.js +286 -0
- package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-data-pill-plugin.d.ts +9 -0
- package/dist/flow/plugins/flow-data-pill-plugin.js +212 -0
- package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-definition-plugin.d.ts +2 -0
- package/dist/flow/plugins/flow-definition-plugin.js +1668 -0
- package/dist/flow/plugins/flow-definition-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +26 -0
- package/dist/flow/plugins/flow-diagnostics-plugin.js +217 -0
- package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-instance-plugin.d.ts +12 -0
- package/dist/flow/plugins/flow-instance-plugin.js +1205 -0
- package/dist/flow/plugins/flow-instance-plugin.js.map +1 -0
- package/dist/flow/plugins/flow-trigger-instance-plugin.d.ts +2 -0
- package/dist/flow/plugins/flow-trigger-instance-plugin.js +338 -0
- package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -0
- package/dist/flow/plugins/inline-script-plugin.d.ts +39 -0
- package/dist/flow/plugins/inline-script-plugin.js +80 -0
- package/dist/flow/plugins/inline-script-plugin.js.map +1 -0
- package/dist/flow/plugins/step-definition-plugin.d.ts +5 -0
- package/dist/flow/plugins/step-definition-plugin.js +71 -0
- package/dist/flow/plugins/step-definition-plugin.js.map +1 -0
- package/dist/flow/plugins/step-instance-plugin.d.ts +31 -0
- package/dist/flow/plugins/step-instance-plugin.js +339 -0
- package/dist/flow/plugins/step-instance-plugin.js.map +1 -0
- package/dist/flow/plugins/trigger-plugin.d.ts +2 -0
- package/dist/flow/plugins/trigger-plugin.js +96 -0
- package/dist/flow/plugins/trigger-plugin.js.map +1 -0
- package/dist/flow/plugins/wfa-datapill-plugin.d.ts +15 -0
- package/dist/flow/plugins/wfa-datapill-plugin.js +178 -0
- package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -0
- package/dist/flow/utils/approval-rules-processor.d.ts +13 -0
- package/dist/flow/utils/approval-rules-processor.js +267 -0
- package/dist/flow/utils/approval-rules-processor.js.map +1 -0
- package/dist/flow/utils/built-in-complex-objects.d.ts +19 -0
- package/dist/flow/utils/built-in-complex-objects.js +62 -0
- package/dist/flow/utils/built-in-complex-objects.js.map +1 -0
- package/dist/flow/utils/complex-object-resolver.d.ts +8 -0
- package/dist/flow/utils/complex-object-resolver.js +614 -0
- package/dist/flow/utils/complex-object-resolver.js.map +1 -0
- package/dist/flow/utils/complex-objects.d.ts +36 -0
- package/dist/flow/utils/complex-objects.js +481 -0
- package/dist/flow/utils/complex-objects.js.map +1 -0
- package/dist/flow/utils/data-pill-shapes.d.ts +58 -0
- package/dist/flow/utils/data-pill-shapes.js +135 -0
- package/dist/flow/utils/data-pill-shapes.js.map +1 -0
- package/dist/flow/utils/datapill-transformer.d.ts +110 -0
- package/dist/flow/utils/datapill-transformer.js +503 -0
- package/dist/flow/utils/datapill-transformer.js.map +1 -0
- package/dist/flow/utils/flow-constants.d.ts +72 -0
- package/dist/flow/utils/flow-constants.js +230 -0
- package/dist/flow/utils/flow-constants.js.map +1 -0
- package/dist/flow/utils/flow-io-to-record.d.ts +44 -0
- package/dist/flow/utils/flow-io-to-record.js +409 -0
- package/dist/flow/utils/flow-io-to-record.js.map +1 -0
- package/dist/flow/utils/flow-shapes.d.ts +161 -0
- package/dist/flow/utils/flow-shapes.js +255 -0
- package/dist/flow/utils/flow-shapes.js.map +1 -0
- package/dist/flow/utils/flow-to-xml.d.ts +16 -0
- package/dist/flow/utils/flow-to-xml.js +237 -0
- package/dist/flow/utils/flow-to-xml.js.map +1 -0
- package/dist/flow/utils/flow-variable-processor.d.ts +51 -0
- package/dist/flow/utils/flow-variable-processor.js +69 -0
- package/dist/flow/utils/flow-variable-processor.js.map +1 -0
- package/dist/flow/utils/label-cache-parser.d.ts +7 -0
- package/dist/flow/utils/label-cache-parser.js +24 -0
- package/dist/flow/utils/label-cache-parser.js.map +1 -0
- package/dist/flow/utils/label-cache-processor.d.ts +119 -0
- package/dist/flow/utils/label-cache-processor.js +719 -0
- package/dist/flow/utils/label-cache-processor.js.map +1 -0
- package/dist/flow/utils/pill-string-parser.d.ts +88 -0
- package/dist/flow/utils/pill-string-parser.js +306 -0
- package/dist/flow/utils/pill-string-parser.js.map +1 -0
- package/dist/flow/utils/schema-to-flow-object.d.ts +22 -0
- package/dist/flow/utils/schema-to-flow-object.js +318 -0
- package/dist/flow/utils/schema-to-flow-object.js.map +1 -0
- package/dist/flow/utils/service-catalog.d.ts +47 -0
- package/dist/flow/utils/service-catalog.js +137 -0
- package/dist/flow/utils/service-catalog.js.map +1 -0
- package/dist/flow/utils/utils.d.ts +117 -0
- package/dist/flow/utils/utils.js +345 -0
- package/dist/flow/utils/utils.js.map +1 -0
- package/dist/index.d.ts +20 -1
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/dist/list-plugin.js +1 -1
- package/dist/list-plugin.js.map +1 -1
- package/dist/now-attach-plugin.d.ts +1 -0
- package/dist/now-attach-plugin.js +10 -10
- package/dist/now-attach-plugin.js.map +1 -1
- package/dist/now-ref-plugin.js +1 -1
- package/dist/now-ref-plugin.js.map +1 -1
- package/dist/record-plugin.d.ts +29 -0
- package/dist/record-plugin.js +66 -7
- package/dist/record-plugin.js.map +1 -1
- package/dist/repack/index.d.ts +2 -0
- package/dist/repack/index.js +8 -0
- package/dist/repack/index.js.map +1 -1
- package/dist/rest-api-plugin.js +54 -44
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/server-module-plugin/index.d.ts +10 -0
- package/dist/server-module-plugin/index.js +83 -59
- package/dist/server-module-plugin/index.js.map +1 -1
- package/dist/service-catalog/catalog-clientscript-plugin.d.ts +2 -0
- package/dist/service-catalog/catalog-clientscript-plugin.js +117 -0
- package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -0
- package/dist/service-catalog/catalog-item-plugin.d.ts +2 -0
- package/dist/service-catalog/catalog-item-plugin.js +115 -0
- package/dist/service-catalog/catalog-item-plugin.js.map +1 -0
- package/dist/service-catalog/catalog-ui-policy-plugin.d.ts +2 -0
- package/dist/service-catalog/catalog-ui-policy-plugin.js +266 -0
- package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -0
- package/dist/service-catalog/index.d.ts +5 -0
- package/dist/service-catalog/index.js +22 -0
- package/dist/service-catalog/index.js.map +1 -0
- package/dist/service-catalog/record-to-shape.d.ts +6 -0
- package/dist/service-catalog/record-to-shape.js +93 -0
- package/dist/service-catalog/record-to-shape.js.map +1 -0
- package/dist/service-catalog/sc-record-producer-plugin.d.ts +2 -0
- package/dist/service-catalog/sc-record-producer-plugin.js +140 -0
- package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -0
- package/dist/service-catalog/service-catalog-base.d.ts +311 -0
- package/dist/service-catalog/service-catalog-base.js +542 -0
- package/dist/service-catalog/service-catalog-base.js.map +1 -0
- package/dist/service-catalog/service-catalog-diagnostics.d.ts +45 -0
- package/dist/service-catalog/service-catalog-diagnostics.js +172 -0
- package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -0
- package/dist/service-catalog/shape-to-record.d.ts +8 -0
- package/dist/service-catalog/shape-to-record.js +235 -0
- package/dist/service-catalog/shape-to-record.js.map +1 -0
- package/dist/service-catalog/utils.d.ts +323 -0
- package/dist/service-catalog/utils.js +1216 -0
- package/dist/service-catalog/utils.js.map +1 -0
- package/dist/service-catalog/variable-helper.d.ts +43 -0
- package/dist/service-catalog/variable-helper.js +92 -0
- package/dist/service-catalog/variable-helper.js.map +1 -0
- package/dist/service-catalog/variable-set-plugin.d.ts +2 -0
- package/dist/service-catalog/variable-set-plugin.js +175 -0
- package/dist/service-catalog/variable-set-plugin.js.map +1 -0
- package/dist/service-catalog/variables-transform.d.ts +139 -0
- package/dist/service-catalog/variables-transform.js +403 -0
- package/dist/service-catalog/variables-transform.js.map +1 -0
- package/dist/sla/sla-validators.d.ts +61 -0
- package/dist/sla/sla-validators.js +224 -0
- package/dist/sla/sla-validators.js.map +1 -0
- package/dist/sla-plugin.d.ts +5 -0
- package/dist/sla-plugin.js +280 -0
- package/dist/sla-plugin.js.map +1 -0
- package/dist/static-content-plugin.js +25 -2
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +32 -15
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +832 -19
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/ui-policy-plugin.js +5 -7
- package/dist/ui-policy-plugin.js.map +1 -1
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +16 -0
- package/dist/utils.js.map +1 -1
- package/dist/ux-list-menu-config-plugin.d.ts +2 -0
- package/dist/ux-list-menu-config-plugin.js +292 -0
- package/dist/ux-list-menu-config-plugin.js.map +1 -0
- package/dist/workspace-plugin/chrome-tab.d.ts +2 -0
- package/dist/workspace-plugin/chrome-tab.js +46 -0
- package/dist/workspace-plugin/chrome-tab.js.map +1 -0
- package/dist/workspace-plugin/constants.d.ts +52 -0
- package/dist/workspace-plugin/constants.js +56 -0
- package/dist/workspace-plugin/constants.js.map +1 -0
- package/dist/workspace-plugin/fluent-utils.d.ts +9 -0
- package/dist/workspace-plugin/fluent-utils.js +60 -0
- package/dist/workspace-plugin/fluent-utils.js.map +1 -0
- package/dist/workspace-plugin/page.d.ts +8 -0
- package/dist/workspace-plugin/page.js +108 -0
- package/dist/workspace-plugin/page.js.map +1 -0
- package/dist/workspace-plugin/screen.d.ts +1 -0
- package/dist/workspace-plugin/screen.js +38 -0
- package/dist/workspace-plugin/screen.js.map +1 -0
- package/dist/workspace-plugin/templates/index.d.ts +10 -0
- package/dist/workspace-plugin/templates/index.js +20 -0
- package/dist/workspace-plugin/templates/index.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page-composition.d.ts +1 -0
- package/dist/workspace-plugin/templates/record-page-composition.js +4043 -0
- package/dist/workspace-plugin/templates/record-page-composition.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page-data.d.ts +1 -0
- package/dist/workspace-plugin/templates/record-page-data.js +527 -0
- package/dist/workspace-plugin/templates/record-page-data.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page-interalEventMappings.d.ts +1 -0
- package/dist/workspace-plugin/templates/record-page-interalEventMappings.js +39 -0
- package/dist/workspace-plugin/templates/record-page-interalEventMappings.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page-layoutModel.d.ts +1 -0
- package/dist/workspace-plugin/templates/record-page-layoutModel.js +55 -0
- package/dist/workspace-plugin/templates/record-page-layoutModel.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page-properties.d.ts +1 -0
- package/dist/workspace-plugin/templates/record-page-properties.js +135 -0
- package/dist/workspace-plugin/templates/record-page-properties.js.map +1 -0
- package/dist/workspace-plugin/templates/record-page.d.ts +3 -0
- package/dist/workspace-plugin/templates/record-page.js +8 -0
- package/dist/workspace-plugin/templates/record-page.js.map +1 -0
- package/dist/workspace-plugin.d.ts +2 -0
- package/dist/workspace-plugin.js +453 -0
- package/dist/workspace-plugin.js.map +1 -0
- package/package.json +10 -12
- package/src/acl-plugin.ts +16 -1
- package/src/applicability-plugin.ts +82 -0
- package/src/atf/test-plugin.ts +6 -3
- package/src/basic-syntax-plugin.ts +10 -1
- package/src/business-rule-plugin.ts +2 -1
- package/src/call-expression-plugin.ts +2 -130
- package/src/column/column-to-record.ts +54 -8
- package/src/column-plugin.ts +29 -13
- package/src/dashboard/dashboard-component-property-defaults.ts +277 -0
- package/src/dashboard/dashboard-component-resolver.ts +69 -0
- package/src/dashboard/dashboard-plugin.ts +450 -0
- package/src/data-plugin.ts +67 -139
- package/src/email-notification-plugin.ts +850 -0
- package/src/flow/constants/flow-plugin-constants.ts +79 -0
- package/src/flow/flow-logic/flow-logic-constants.ts +120 -0
- package/src/flow/flow-logic/flow-logic-diagnostics.ts +591 -0
- package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +2550 -0
- package/src/flow/flow-logic/flow-logic-plugin.ts +337 -0
- package/src/flow/flow-logic/flow-logic-shapes.ts +215 -0
- package/src/flow/plugins/approval-rules-plugin.ts +48 -0
- package/src/flow/plugins/flow-action-definition-plugin.ts +295 -0
- package/src/flow/plugins/flow-data-pill-plugin.ts +258 -0
- package/src/flow/plugins/flow-definition-plugin.ts +2173 -0
- package/src/flow/plugins/flow-diagnostics-plugin.ts +280 -0
- package/src/flow/plugins/flow-instance-plugin.ts +1499 -0
- package/src/flow/plugins/flow-trigger-instance-plugin.ts +444 -0
- package/src/flow/plugins/inline-script-plugin.ts +83 -0
- package/src/flow/plugins/step-definition-plugin.ts +67 -0
- package/src/flow/plugins/step-instance-plugin.ts +431 -0
- package/src/flow/plugins/trigger-plugin.ts +95 -0
- package/src/flow/plugins/wfa-datapill-plugin.ts +213 -0
- package/src/flow/utils/approval-rules-processor.ts +298 -0
- package/src/flow/utils/built-in-complex-objects.ts +81 -0
- package/src/flow/utils/complex-object-resolver.ts +875 -0
- package/src/flow/utils/complex-objects.ts +656 -0
- package/src/flow/utils/data-pill-shapes.ts +165 -0
- package/src/flow/utils/datapill-transformer.ts +632 -0
- package/src/flow/utils/flow-constants.ts +285 -0
- package/src/flow/utils/flow-io-to-record.ts +533 -0
- package/src/flow/utils/flow-shapes.ts +296 -0
- package/src/flow/utils/flow-to-xml.ts +318 -0
- package/src/flow/utils/flow-variable-processor.ts +100 -0
- package/src/flow/utils/label-cache-parser.ts +37 -0
- package/src/flow/utils/label-cache-processor.ts +870 -0
- package/src/flow/utils/pill-string-parser.ts +375 -0
- package/src/flow/utils/schema-to-flow-object.ts +385 -0
- package/src/flow/utils/service-catalog.ts +174 -0
- package/src/flow/utils/utils.ts +395 -0
- package/src/index.ts +20 -1
- package/src/list-plugin.ts +1 -1
- package/src/now-attach-plugin.ts +14 -11
- package/src/now-ref-plugin.ts +1 -1
- package/src/record-plugin.ts +76 -11
- package/src/repack/index.ts +14 -0
- package/src/rest-api-plugin.ts +62 -50
- package/src/server-module-plugin/index.ts +112 -86
- package/src/service-catalog/catalog-clientscript-plugin.ts +140 -0
- package/src/service-catalog/catalog-item-plugin.ts +162 -0
- package/src/service-catalog/catalog-ui-policy-plugin.ts +324 -0
- package/src/service-catalog/index.ts +5 -0
- package/src/service-catalog/record-to-shape.ts +109 -0
- package/src/service-catalog/sc-record-producer-plugin.ts +201 -0
- package/src/service-catalog/service-catalog-base.ts +600 -0
- package/src/service-catalog/service-catalog-diagnostics.ts +254 -0
- package/src/service-catalog/shape-to-record.ts +279 -0
- package/src/service-catalog/utils.ts +1455 -0
- package/src/service-catalog/variable-helper.ts +135 -0
- package/src/service-catalog/variable-set-plugin.ts +197 -0
- package/src/service-catalog/variables-transform.ts +438 -0
- package/src/sla/sla-validators.ts +331 -0
- package/src/sla-plugin.ts +358 -0
- package/src/static-content-plugin.ts +25 -2
- package/src/table-plugin.ts +49 -16
- package/src/ui-page-plugin.ts +1063 -20
- package/src/ui-policy-plugin.ts +5 -9
- package/src/utils.ts +24 -1
- package/src/ux-list-menu-config-plugin.ts +312 -0
- package/src/workspace-plugin/chrome-tab.ts +44 -0
- package/src/workspace-plugin/constants.ts +53 -0
- package/src/workspace-plugin/fluent-utils.ts +60 -0
- package/src/workspace-plugin/page.ts +139 -0
- package/src/workspace-plugin/screen.ts +34 -0
- package/src/workspace-plugin/templates/index.ts +17 -0
- package/src/workspace-plugin/templates/record-page-composition.ts +4051 -0
- package/src/workspace-plugin/templates/record-page-data.ts +523 -0
- package/src/workspace-plugin/templates/record-page-interalEventMappings.ts +35 -0
- package/src/workspace-plugin/templates/record-page-layoutModel.ts +51 -0
- package/src/workspace-plugin/templates/record-page-properties.ts +131 -0
- package/src/workspace-plugin/templates/record-page.ts +6 -0
- package/src/workspace-plugin.ts +574 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CallExpressionShape,
|
|
3
|
+
type Source,
|
|
4
|
+
ObjectShape,
|
|
5
|
+
Record,
|
|
6
|
+
StringShape,
|
|
7
|
+
TemplateExpressionShape,
|
|
8
|
+
Shape,
|
|
9
|
+
} from '@servicenow/sdk-build-core'
|
|
10
|
+
import { NowIdShape } from '../../now-id-plugin'
|
|
11
|
+
import type { ApprovalRulesType, ApprovalDueDateType } from '@servicenow/sdk-core/runtime/flow'
|
|
12
|
+
import { approvalRulesJsonToString, approvalRulesStringToJson } from './approval-rules-processor'
|
|
13
|
+
import { APPROVAL_RULES_API_NAME, APPROVAL_DUE_DATE_API_NAME } from './flow-constants'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Abstract base class for all flow definition instances.
|
|
17
|
+
* Extends CallExpressionShape to provide common functionality for flow constructs.
|
|
18
|
+
*/
|
|
19
|
+
export abstract class FDInstanceShape extends CallExpressionShape {
|
|
20
|
+
constructor(source: Source, callee: string, args: unknown[]) {
|
|
21
|
+
super({ source, callee, args })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getInstanceType(): string {
|
|
25
|
+
return this.getCallee()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
abstract getSysId(): NowIdShape | undefined
|
|
29
|
+
abstract getAnnotation(): StringShape | undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Shape class for Action and Subflow instances.
|
|
34
|
+
* Handles the pattern: Action(definition, config, props)
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* Action(createIncident, { $id: Now.ID['incident_0'], annotation: 'Create incident' }, { shortDescription: 'Issue' })
|
|
38
|
+
* Subflow(mySubflow, { $id: Now.ID['subflow_0'], annotation: 'Process data' }, { input: 'value' })
|
|
39
|
+
*/
|
|
40
|
+
export class ActionSubflowInstanceShape extends FDInstanceShape {
|
|
41
|
+
constructor({
|
|
42
|
+
source,
|
|
43
|
+
instanceDefinition,
|
|
44
|
+
instanceProps,
|
|
45
|
+
instanceType,
|
|
46
|
+
configObject,
|
|
47
|
+
}: {
|
|
48
|
+
source: Source
|
|
49
|
+
instanceDefinition: Record | StringShape | undefined
|
|
50
|
+
instanceProps: ObjectShape | undefined
|
|
51
|
+
instanceType: string
|
|
52
|
+
configObject: ObjectShape
|
|
53
|
+
}) {
|
|
54
|
+
const configObj = configObject
|
|
55
|
+
super(source, instanceType, [instanceDefinition, configObj, instanceProps])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getInstanceDefinition(): Record | StringShape | undefined {
|
|
59
|
+
const arg0 = this.getArgument(0)
|
|
60
|
+
if (arg0.isString()) {
|
|
61
|
+
return arg0.as(StringShape)
|
|
62
|
+
}
|
|
63
|
+
return arg0.as(Record)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getInstanceProps(): ObjectShape | undefined {
|
|
67
|
+
return this.getArgument(2).as(ObjectShape)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getSysId(): NowIdShape | undefined {
|
|
71
|
+
const configObj = this.getArgument(1).as(ObjectShape)
|
|
72
|
+
return configObj.get('$id')?.as(NowIdShape)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getAnnotation(): StringShape | undefined {
|
|
76
|
+
const configObj = this.getArgument(1).as(ObjectShape)
|
|
77
|
+
const annotation = configObj.get('annotation')
|
|
78
|
+
return annotation?.isString() ? annotation.asString() : undefined
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getInstanceUUID(): StringShape | undefined {
|
|
82
|
+
const configObj = this.getArgument(1).as(ObjectShape)
|
|
83
|
+
const uuid = configObj.get('uuid')
|
|
84
|
+
return uuid?.isString() ? uuid.asString() : undefined
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Represents an inline script for ServiceNow Flow Designer actions and subflows.
|
|
90
|
+
*
|
|
91
|
+
* Inline scripts allow users to write JavaScript code directly in Flow action/subflow inputs
|
|
92
|
+
* without creating separate Script Includes or Business Rules. This shape wraps the script
|
|
93
|
+
* content and provides serialization to Flow Designer's JSON format.
|
|
94
|
+
*
|
|
95
|
+
* **Supported Formats:**
|
|
96
|
+
* - Template literals without substitutions: \`code\`
|
|
97
|
+
* - External files via Now.include: Now.include('./script.js')
|
|
98
|
+
*
|
|
99
|
+
* **Usage Example:**
|
|
100
|
+
* ```typescript
|
|
101
|
+
* Action(myAction, Now.ID['action_id'], {
|
|
102
|
+
* workNotes: `
|
|
103
|
+
* var number = fd_data.trigger.current.number;
|
|
104
|
+
* return 'Incident ' + number + ' created';
|
|
105
|
+
* `
|
|
106
|
+
* })
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* **Architecture:**
|
|
110
|
+
* This shape is NOT created via a global plugin. Instead, detection happens contextually
|
|
111
|
+
* in FlowInstancePlugin.checkAndResolveInlineScripts() to ensure only template literals
|
|
112
|
+
* used as Action/Subflow inputs are converted to inline scripts. This prevents incorrectly
|
|
113
|
+
* converting template literals used elsewhere (logging, formatting, etc.).
|
|
114
|
+
*
|
|
115
|
+
* @extends TemplateExpressionShape
|
|
116
|
+
*/
|
|
117
|
+
export class InlineScriptShape extends TemplateExpressionShape {
|
|
118
|
+
private readonly scriptContent: string
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates an InlineScriptShape instance.
|
|
122
|
+
*
|
|
123
|
+
* @param source - The original TemplateExpressionShape from the AST
|
|
124
|
+
* @param scriptContent - The JavaScript code to execute (without backticks)
|
|
125
|
+
*/
|
|
126
|
+
constructor({ source, scriptContent }: { source: TemplateExpressionShape; scriptContent: string }) {
|
|
127
|
+
super({ source, literalText: scriptContent })
|
|
128
|
+
this.scriptContent = scriptContent
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Returns the raw script content without template literal backticks.
|
|
133
|
+
*
|
|
134
|
+
* @returns The JavaScript code as a string
|
|
135
|
+
*/
|
|
136
|
+
getScriptContent(): string {
|
|
137
|
+
return this.scriptContent
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Serializes this inline script to ServiceNow Flow Designer JSON format.
|
|
142
|
+
*
|
|
143
|
+
* The output structure includes:
|
|
144
|
+
* - `scriptActive: true` - Indicates this field contains a script
|
|
145
|
+
* - `script` object - Contains the actual script content keyed by field name
|
|
146
|
+
* - Empty `value` and `displayValue` - Required by Flow Designer schema
|
|
147
|
+
*
|
|
148
|
+
* @param fieldName - The name of the action/subflow input field
|
|
149
|
+
* @returns Flow Designer JSON structure for inline scripts
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* inlineScript.toFlowDesignerJson('workNotes')
|
|
154
|
+
* // Returns:
|
|
155
|
+
* // {
|
|
156
|
+
* // name: 'workNotes',
|
|
157
|
+
* // scriptActive: true,
|
|
158
|
+
* // script: { workNotes: { scriptActive: true, script: '...' } },
|
|
159
|
+
* // value: '', displayValue: '', children: []
|
|
160
|
+
* // }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
toFlowDesignerJson(fieldName: string) {
|
|
164
|
+
return {
|
|
165
|
+
name: fieldName,
|
|
166
|
+
value: '',
|
|
167
|
+
displayValue: '',
|
|
168
|
+
children: [],
|
|
169
|
+
scriptActive: true,
|
|
170
|
+
script: {
|
|
171
|
+
[fieldName]: {
|
|
172
|
+
scriptActive: true,
|
|
173
|
+
script: this.scriptContent,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Shape representing ApprovalRules
|
|
182
|
+
* Used with ApprovalRules() helper - Stores approval rules for Flow Designer
|
|
183
|
+
*/
|
|
184
|
+
export class ApprovalRulesShape extends ObjectShape {
|
|
185
|
+
constructor({ source, value }: { source: Source; value: globalThis.Record<string, unknown> }) {
|
|
186
|
+
super({ source, properties: value })
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
getApprovalRules(): ApprovalRulesType {
|
|
190
|
+
return super.getValue()
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Returns code representation as ApprovalRules() helper call.
|
|
195
|
+
* @example 'wfa.approvalRules({"conditionType":"OR","ruleSets":[{"action":"Approves","conditionType":"AND","rules":[[{"rule_type":"Any","users":["_params.trigger.current.assigned_to"],"groups":[],"manual":false}]]},{"action":"Rejects","conditionType":"AND","rules":[[{"rule_type":"Any","users":[],"groups":[],"manual":true}]]}]})'
|
|
196
|
+
*/
|
|
197
|
+
override getCode(): string {
|
|
198
|
+
return `${APPROVAL_RULES_API_NAME}(${super.getCode()})`
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Returns a StringShape of the Approval Rules JSON
|
|
202
|
+
*/
|
|
203
|
+
override toString(): StringShape {
|
|
204
|
+
const approvalRulesString = approvalRulesJsonToString(this.getApprovalRules())
|
|
205
|
+
return Shape.from(this.getSource(), approvalRulesString).toString()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
static override from(source: Source, text: StringShape): ApprovalRulesShape {
|
|
209
|
+
return new ApprovalRulesShape({
|
|
210
|
+
source,
|
|
211
|
+
value: approvalRulesStringToJson(text.getValue()),
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Shape representing ApprovalDueDate
|
|
218
|
+
* Used with ApprovalDueDate() helper - Stores approval due date configuration for Flow Designer
|
|
219
|
+
*/
|
|
220
|
+
export class ApprovalDueDateShape extends ObjectShape {
|
|
221
|
+
constructor({ source, value }: { source: Source; value: globalThis.Record<string, unknown> }) {
|
|
222
|
+
super({ source, properties: value })
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
getApprovalDueDate(): ApprovalDueDateType {
|
|
226
|
+
return super.getValue() as ApprovalDueDateType
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Returns code representation as ApprovalDueDate() helper call.
|
|
231
|
+
* @example 'wfa.approvalDueDate({"action":"none","date_type":"actual","date":"{}","duration":1,"duration_type":"days","schedule":""})'
|
|
232
|
+
*/
|
|
233
|
+
override getCode(): string {
|
|
234
|
+
return `${APPROVAL_DUE_DATE_API_NAME}(${super.getCode()})`
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Returns a StringShape of the Approval Due Date string
|
|
239
|
+
*/
|
|
240
|
+
override toString(): StringShape {
|
|
241
|
+
const approvalDueDateValue = this.getApprovalDueDate()
|
|
242
|
+
|
|
243
|
+
const formattedApprovalDueDate = {
|
|
244
|
+
action: 'none',
|
|
245
|
+
date_type: 'actual',
|
|
246
|
+
date: '{}',
|
|
247
|
+
duration: 1,
|
|
248
|
+
duration_type: 'days',
|
|
249
|
+
schedule: '',
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//Convert the Due Date to the format expected by Flow Designer and populate with default values
|
|
253
|
+
if (approvalDueDateValue) {
|
|
254
|
+
formattedApprovalDueDate.action = approvalDueDateValue.action || 'none'
|
|
255
|
+
formattedApprovalDueDate.date_type = approvalDueDateValue.dateType || 'actual'
|
|
256
|
+
formattedApprovalDueDate.date = approvalDueDateValue.date || '{}'
|
|
257
|
+
formattedApprovalDueDate.duration = approvalDueDateValue.duration || 1
|
|
258
|
+
formattedApprovalDueDate.duration_type = approvalDueDateValue.durationType || 'days'
|
|
259
|
+
|
|
260
|
+
formattedApprovalDueDate.schedule = approvalDueDateValue.daysSchedule || ''
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return Shape.from(this.getSource(), JSON.stringify(formattedApprovalDueDate)).toString()
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
static override from(source: Source, text: StringShape): ApprovalDueDateShape {
|
|
267
|
+
const approvalDueDateValue: ApprovalDueDateType = {
|
|
268
|
+
action: 'none',
|
|
269
|
+
dateType: 'actual',
|
|
270
|
+
date: '{}',
|
|
271
|
+
duration: 1,
|
|
272
|
+
durationType: 'days',
|
|
273
|
+
daysSchedule: '',
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
const parsedValue = JSON.parse(text.getValue())
|
|
277
|
+
|
|
278
|
+
//Convert the Due Date to the format expected by Fluent and populate with default values
|
|
279
|
+
if (parsedValue) {
|
|
280
|
+
approvalDueDateValue.action = parsedValue.action || 'none'
|
|
281
|
+
approvalDueDateValue.dateType = parsedValue.date_type || 'actual'
|
|
282
|
+
approvalDueDateValue.date = parsedValue.date || '{}'
|
|
283
|
+
approvalDueDateValue.duration = Number(parsedValue.duration) || 1
|
|
284
|
+
approvalDueDateValue.durationType = parsedValue.duration_type || 'days'
|
|
285
|
+
approvalDueDateValue.daysSchedule = parsedValue.schedule || ''
|
|
286
|
+
}
|
|
287
|
+
} catch {
|
|
288
|
+
// Failed to parse - will use default values
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return new ApprovalDueDateShape({
|
|
292
|
+
source,
|
|
293
|
+
value: approvalDueDateValue,
|
|
294
|
+
})
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import {
|
|
2
|
+
recordXml,
|
|
3
|
+
type Record,
|
|
4
|
+
type Action,
|
|
5
|
+
unloadBuilder,
|
|
6
|
+
type Database,
|
|
7
|
+
type Relationships,
|
|
8
|
+
} from '@servicenow/sdk-build-core'
|
|
9
|
+
import type { Element } from 'xml-js'
|
|
10
|
+
import { FlowDefinitionPlugin } from '../plugins/flow-definition-plugin'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Tables to exclude from delete_multiple generation.
|
|
14
|
+
* These tables either don't need cleanup or have special handling.
|
|
15
|
+
*/
|
|
16
|
+
const EXCLUDED_TABLES = new Set([
|
|
17
|
+
'sys_flow_record_trigger',
|
|
18
|
+
'sys_flow_timer_trigger',
|
|
19
|
+
'sys_hub_flow_snapshot',
|
|
20
|
+
'sys_choice',
|
|
21
|
+
'sys_documentation',
|
|
22
|
+
'sys_complex_object',
|
|
23
|
+
'sys_element_mapping',
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tables that need cascading delete_multiple entries per instance.
|
|
28
|
+
* For example, sys_hub_alias_mapping needs a delete_multiple for each action/subflow instance.
|
|
29
|
+
*/
|
|
30
|
+
const CASCADING_DELETE_CONFIG: globalThis.Record<string, { table: string; field: string }[]> = {
|
|
31
|
+
sys_hub_action_instance_v2: [{ table: 'sys_hub_alias_mapping', field: 'source_id' }],
|
|
32
|
+
sys_hub_sub_flow_instance_v2: [{ table: 'sys_hub_alias_mapping', field: 'source_id' }],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type DeleteMultipleConfig = {
|
|
36
|
+
parentField: string
|
|
37
|
+
parentType: 'flow' | 'descendant'
|
|
38
|
+
parentTable?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function generateXML(
|
|
42
|
+
record: Record,
|
|
43
|
+
{ config, database }: { config: { scope: string; scopeId: string }; database: Database }
|
|
44
|
+
) {
|
|
45
|
+
const relationships = FlowDefinitionPlugin.getRelationships()[record.getTable()] ?? {}
|
|
46
|
+
const updateName = `${record.getTable()}_${record.getId().getValue()}`
|
|
47
|
+
const recordBuilder = unloadBuilder(config)
|
|
48
|
+
const table = record.getTable()
|
|
49
|
+
const flowId = record.getId().getValue()
|
|
50
|
+
const builder = recordBuilder.record(record, updateName)
|
|
51
|
+
record
|
|
52
|
+
.entries()
|
|
53
|
+
.sort(([a], [b]) => a.localeCompare(b)) // Sort keys to make outputs more deterministic
|
|
54
|
+
.forEach(([prop, shape]) => builder.field(prop, shape, {}))
|
|
55
|
+
|
|
56
|
+
// Get descendants using plugin's getDescendants method and group by table
|
|
57
|
+
const descendants = FlowDefinitionPlugin.getDescendants(record, database)
|
|
58
|
+
const recordMap = descendants.reduce(
|
|
59
|
+
(acc, rec) => {
|
|
60
|
+
const t = rec.getTable()
|
|
61
|
+
if (!acc[t]) {
|
|
62
|
+
acc[t] = []
|
|
63
|
+
}
|
|
64
|
+
acc[t].push(rec)
|
|
65
|
+
return acc
|
|
66
|
+
},
|
|
67
|
+
{} as globalThis.Record<string, Record[]>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
// Build delete_multiple config dynamically from relationships
|
|
71
|
+
const deleteMultipleConfig = buildDeleteMultipleConfig(relationships)
|
|
72
|
+
|
|
73
|
+
// Generate delete_multiple and INSERT_OR_UPDATE entries for each descendant table
|
|
74
|
+
for (const [tableName, records] of Object.entries(recordMap)) {
|
|
75
|
+
// Skip sys_choice as it has special handling
|
|
76
|
+
if (tableName === 'sys_choice') {
|
|
77
|
+
generateNestedXML(records, recordBuilder.recordUpdateElements, config, true)
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Generate delete_multiple entry for this table
|
|
82
|
+
generateDeleteMultiple(
|
|
83
|
+
tableName,
|
|
84
|
+
flowId,
|
|
85
|
+
records,
|
|
86
|
+
recordMap,
|
|
87
|
+
recordBuilder.recordUpdateElements,
|
|
88
|
+
deleteMultipleConfig
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
// Generate INSERT_OR_UPDATE entries for the records
|
|
92
|
+
generateNestedXML(records, recordBuilder.recordUpdateElements, config, false)
|
|
93
|
+
|
|
94
|
+
// Generate cascading delete_multiple entries (e.g., alias_mapping per action instance)
|
|
95
|
+
generateCascadingDeleteMultiple(tableName, records, recordBuilder.recordUpdateElements)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
value: {
|
|
101
|
+
source: record,
|
|
102
|
+
name: `${table}_${flowId}.xml`,
|
|
103
|
+
category: record.getInstallCategory(),
|
|
104
|
+
content: recordBuilder.end(),
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function generateNestedXML(
|
|
110
|
+
records: Record[],
|
|
111
|
+
rootElements: Element[],
|
|
112
|
+
config: { scope: string; scopeId: string },
|
|
113
|
+
choiceRecords: boolean = false
|
|
114
|
+
) {
|
|
115
|
+
if (choiceRecords) {
|
|
116
|
+
// group records by field/element and table/name
|
|
117
|
+
const groupedRecords = records.reduce(
|
|
118
|
+
(acc, record) => {
|
|
119
|
+
const field = record.get('element')?.asString()?.getValue()
|
|
120
|
+
const name = record.get('name')?.asString()?.getValue()
|
|
121
|
+
|
|
122
|
+
if (!field || !name) {
|
|
123
|
+
return acc
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const key = `${name}:${field}`
|
|
127
|
+
|
|
128
|
+
if (!acc[key]) {
|
|
129
|
+
acc[key] = []
|
|
130
|
+
}
|
|
131
|
+
acc[key].push(record)
|
|
132
|
+
|
|
133
|
+
return acc
|
|
134
|
+
},
|
|
135
|
+
{} as globalThis.Record<string, Record[]>
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
for (const [key, records] of Object.entries(groupedRecords)) {
|
|
139
|
+
const [name, field] = key.split(':')
|
|
140
|
+
|
|
141
|
+
const choiceElements: Element[] = []
|
|
142
|
+
const choiceElement: Element = {
|
|
143
|
+
type: 'element',
|
|
144
|
+
name: 'sys_choice',
|
|
145
|
+
attributes: { field, table: name },
|
|
146
|
+
elements: choiceElements,
|
|
147
|
+
}
|
|
148
|
+
rootElements.push(choiceElement)
|
|
149
|
+
|
|
150
|
+
generateNestedXML(records, choiceElements, config)
|
|
151
|
+
}
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
for (const record of records) {
|
|
156
|
+
const table = record.getTable()
|
|
157
|
+
const guid = record.getId().getValue()
|
|
158
|
+
generateRecordXML(record, rootElements, table, guid, record.getAction(), config)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function generateRecordXML(
|
|
163
|
+
record: Record,
|
|
164
|
+
rootElements: Element[],
|
|
165
|
+
table: string,
|
|
166
|
+
guid: string,
|
|
167
|
+
action: Action = 'INSERT_OR_UPDATE',
|
|
168
|
+
config: { scope: string; scopeId: string }
|
|
169
|
+
) {
|
|
170
|
+
const builder = recordXml(rootElements, table, guid, { attr: { action } })
|
|
171
|
+
builder.addSysScope(config.scope, config.scopeId)
|
|
172
|
+
record
|
|
173
|
+
.entries()
|
|
174
|
+
.sort(([a], [b]) => a.localeCompare(b)) // Sort keys to make outputs more deterministic
|
|
175
|
+
.forEach(([prop, shape]) => builder.field(prop, shape, {}))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Build delete_multiple configuration dynamically from plugin relationships.
|
|
180
|
+
* Traverses the relationship tree and extracts parent fields for each descendant table.
|
|
181
|
+
*/
|
|
182
|
+
function buildDeleteMultipleConfig(
|
|
183
|
+
relationships: Relationships,
|
|
184
|
+
parentTable?: string
|
|
185
|
+
): globalThis.Record<string, DeleteMultipleConfig> {
|
|
186
|
+
const config: globalThis.Record<string, DeleteMultipleConfig> = {}
|
|
187
|
+
|
|
188
|
+
for (const [tableName, relationship] of Object.entries(relationships)) {
|
|
189
|
+
// Skip excluded tables
|
|
190
|
+
if (EXCLUDED_TABLES.has(tableName)) {
|
|
191
|
+
continue
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Only process descendant relationships with string 'via' field
|
|
195
|
+
if (!relationship.descendant || typeof relationship.via !== 'string') {
|
|
196
|
+
continue
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Skip inverse relationships (parent references child, not child references parent)
|
|
200
|
+
if (relationship.inverse) {
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Add config for this table
|
|
205
|
+
if (parentTable) {
|
|
206
|
+
// Nested relationship - references another descendant table
|
|
207
|
+
config[tableName] = {
|
|
208
|
+
parentField: relationship.via,
|
|
209
|
+
parentType: 'descendant',
|
|
210
|
+
parentTable,
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
// Direct relationship - references the flow
|
|
214
|
+
config[tableName] = {
|
|
215
|
+
parentField: relationship.via,
|
|
216
|
+
parentType: 'flow',
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Recursively process nested relationships
|
|
221
|
+
if (relationship.relationships) {
|
|
222
|
+
const nestedConfig = buildDeleteMultipleConfig(relationship.relationships, tableName)
|
|
223
|
+
Object.assign(config, nestedConfig)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return config
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Generate a delete_multiple XML element for a descendant table.
|
|
232
|
+
* The query follows the pattern: parentField=parentId^sys_idNOT IN<comma_separated_ids>
|
|
233
|
+
*/
|
|
234
|
+
function generateDeleteMultiple(
|
|
235
|
+
tableName: string,
|
|
236
|
+
flowId: string,
|
|
237
|
+
records: Record[],
|
|
238
|
+
recordMap: globalThis.Record<string, Record[]>,
|
|
239
|
+
rootElements: Element[],
|
|
240
|
+
deleteMultipleConfig: globalThis.Record<string, DeleteMultipleConfig>
|
|
241
|
+
) {
|
|
242
|
+
const config = deleteMultipleConfig[tableName]
|
|
243
|
+
if (!config) {
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let query: string
|
|
248
|
+
|
|
249
|
+
if (config.parentType === 'flow') {
|
|
250
|
+
// Direct reference to flow
|
|
251
|
+
const recordIds = records.map((r) => r.getId().getValue()).join(',')
|
|
252
|
+
if (recordIds) {
|
|
253
|
+
query = `${config.parentField}=${flowId}^sys_idNOT IN${recordIds}`
|
|
254
|
+
} else {
|
|
255
|
+
query = `${config.parentField}=${flowId}`
|
|
256
|
+
}
|
|
257
|
+
} else if (config.parentType === 'descendant' && config.parentTable) {
|
|
258
|
+
// Reference to another descendant table
|
|
259
|
+
const parentRecords = recordMap[config.parentTable] || []
|
|
260
|
+
if (parentRecords.length === 0) {
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Generate delete_multiple for each parent record
|
|
265
|
+
for (const parentRecord of parentRecords) {
|
|
266
|
+
const parentId = parentRecord.getId().getValue()
|
|
267
|
+
const childRecords = records.filter((r) => {
|
|
268
|
+
const refValue = r.get(config.parentField)?.getValue()
|
|
269
|
+
return refValue === parentId
|
|
270
|
+
})
|
|
271
|
+
const childIds = childRecords.map((r) => r.getId().getValue()).join(',')
|
|
272
|
+
|
|
273
|
+
const childQuery = childIds
|
|
274
|
+
? `${config.parentField}=${parentId}^sys_idNOT IN${childIds}`
|
|
275
|
+
: `${config.parentField}=${parentId}`
|
|
276
|
+
|
|
277
|
+
rootElements.push({
|
|
278
|
+
type: 'element',
|
|
279
|
+
name: tableName,
|
|
280
|
+
attributes: { action: 'delete_multiple', query: childQuery },
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
return
|
|
284
|
+
} else {
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
rootElements.push({
|
|
289
|
+
type: 'element',
|
|
290
|
+
name: tableName,
|
|
291
|
+
attributes: { action: 'delete_multiple', query },
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Generate cascading delete_multiple entries for tables that need per-instance cleanup.
|
|
297
|
+
* For example, sys_hub_alias_mapping needs a delete_multiple for each action/subflow instance.
|
|
298
|
+
*/
|
|
299
|
+
function generateCascadingDeleteMultiple(tableName: string, records: Record[], rootElements: Element[]) {
|
|
300
|
+
const cascadeEntries = CASCADING_DELETE_CONFIG[tableName]
|
|
301
|
+
if (!cascadeEntries) {
|
|
302
|
+
return
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
for (const { table, field } of cascadeEntries) {
|
|
306
|
+
// Generate a delete_multiple for each instance record
|
|
307
|
+
for (const record of records) {
|
|
308
|
+
const instanceId = record.getId().getValue()
|
|
309
|
+
const query = `${field}=${instanceId}`
|
|
310
|
+
|
|
311
|
+
rootElements.push({
|
|
312
|
+
type: 'element',
|
|
313
|
+
name: table,
|
|
314
|
+
attributes: { action: 'delete_multiple', query },
|
|
315
|
+
})
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|