@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,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLA Plugin Validation Functions
|
|
3
|
+
*
|
|
4
|
+
* This module contains validation functions that enforce conditional field requirements
|
|
5
|
+
* for SLA definitions. Fields may be mandatory, optional, or restricted depending on
|
|
6
|
+
* the values of control fields.
|
|
7
|
+
*
|
|
8
|
+
* @see ./SLA-VALIDATION-BEHAVIORS.md for detailed documentation of all 11 validation behaviors
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Diagnostics, ObjectShape } from '@servicenow/sdk-build-core'
|
|
12
|
+
|
|
13
|
+
export const DEFAULT_WHEN_TO_RESUME = 'on_condition'
|
|
14
|
+
export const DEFAULT_WHEN_TO_CANCEL = 'on_condition'
|
|
15
|
+
export const DEFAULT_TIMEZONE_SOURCE = 'task.caller_id.time_zone'
|
|
16
|
+
export const DEFAULT_RETROACTIVE_PAUSE = true
|
|
17
|
+
export const DEFAULT_NO_SCHEDULE_ID = '38fa64edc0a8016400f4a5724b0434b8'
|
|
18
|
+
|
|
19
|
+
export const ERROR_MESSAGES = {
|
|
20
|
+
MANDATORY_FIELD: (field: string, reason: string) => `Field '${field}' is required ${reason}`,
|
|
21
|
+
|
|
22
|
+
RESTRICTED_FIELD: (field: string, reason: string) =>
|
|
23
|
+
`Field '${field}' cannot be specified ${reason}. Remove this field from your SLA definition.`,
|
|
24
|
+
|
|
25
|
+
RESTRICTED_WITH_DEFAULT: (field: string, reason: string, defaultValue: unknown) =>
|
|
26
|
+
`Field '${field}' cannot be specified ${reason}. The default value '${defaultValue}' will be used automatically.`,
|
|
27
|
+
|
|
28
|
+
WARNING_FIELD_PERSISTENCE: (field: string, reason: string) =>
|
|
29
|
+
`Field '${field}' is restricted ${reason}. If this value came from an existing SLA definition, it will be preserved but cannot be modified. If you're creating a new SLA, remove this field.`,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validates user-specified duration fields (Behavior 1)
|
|
34
|
+
*/
|
|
35
|
+
export function validateUserSpecifiedDuration(config: ObjectShape, diagnostics: Diagnostics) {
|
|
36
|
+
const duration = config.get('duration')
|
|
37
|
+
|
|
38
|
+
// Duration is mandatory when durationType is empty/"User specified"
|
|
39
|
+
if (!duration || duration.isUndefined()) {
|
|
40
|
+
diagnostics.error(
|
|
41
|
+
config,
|
|
42
|
+
ERROR_MESSAGES.MANDATORY_FIELD('duration', 'when durationType is empty (user specified duration)')
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
// Note: Schedule validation is handled in validateSlaDefinitionSchedule based on scheduleSource
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validates relative duration restrictions (Behavior 2)
|
|
50
|
+
*/
|
|
51
|
+
export function validateRelativeDuration(
|
|
52
|
+
config: ObjectShape,
|
|
53
|
+
conditions: ObjectShape | undefined,
|
|
54
|
+
diagnostics: Diagnostics
|
|
55
|
+
) {
|
|
56
|
+
// When durationType is a relative duration, duration, conditions.pause, conditions.resume, and whenTo.resume
|
|
57
|
+
// are restricted fields. Existing values from XML are preserved (pass-through).
|
|
58
|
+
// We issue a warning to inform the user these fields are managed by the relative duration.
|
|
59
|
+
const duration = config.get('duration')
|
|
60
|
+
const pauseCondition = conditions?.get('pause')
|
|
61
|
+
const resumeCondition = conditions?.get('resume')
|
|
62
|
+
const whenTo = config.get('whenTo')?.ifDefined()?.asObject()
|
|
63
|
+
const whenToResume = whenTo?.get('resume')
|
|
64
|
+
|
|
65
|
+
// duration field is ignored when using relative duration
|
|
66
|
+
if (duration && !duration.isUndefined()) {
|
|
67
|
+
diagnostics.hint(
|
|
68
|
+
duration,
|
|
69
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('duration', 'when durationType is a relative duration')
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (pauseCondition && !pauseCondition.isUndefined()) {
|
|
74
|
+
diagnostics.hint(
|
|
75
|
+
pauseCondition,
|
|
76
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('conditions.pause', 'when durationType is a relative duration')
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (resumeCondition && !resumeCondition.isUndefined()) {
|
|
81
|
+
diagnostics.hint(
|
|
82
|
+
resumeCondition,
|
|
83
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('conditions.resume', 'when durationType is a relative duration')
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (whenToResume && !whenToResume.isUndefined()) {
|
|
88
|
+
diagnostics.hint(
|
|
89
|
+
whenToResume,
|
|
90
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('whenTo.resume', 'when durationType is a relative duration')
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Validates retroactive start requirements (Behaviors 6 & 8)
|
|
97
|
+
*/
|
|
98
|
+
export function validateRetroactiveStart(
|
|
99
|
+
retroactive: ObjectShape,
|
|
100
|
+
isUserSpecifiedDuration: boolean,
|
|
101
|
+
diagnostics: Diagnostics
|
|
102
|
+
) {
|
|
103
|
+
const setStartTo = retroactive.get('setStartTo')
|
|
104
|
+
const retroactivePause = retroactive.get('pause')
|
|
105
|
+
|
|
106
|
+
// setStartTo is mandatory when retroactive.start is true
|
|
107
|
+
const setStartToValue = setStartTo?.ifString()?.getValue()
|
|
108
|
+
if (!setStartToValue) {
|
|
109
|
+
diagnostics.error(
|
|
110
|
+
retroactive,
|
|
111
|
+
ERROR_MESSAGES.MANDATORY_FIELD('retroactive.setStartTo', 'when retroactive.start is true')
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Behavior 8: retroactive.start + relative duration restricts retroactive.pause
|
|
116
|
+
// Existing values from XML are preserved (pass-through) with a warning.
|
|
117
|
+
if (!isUserSpecifiedDuration && retroactivePause && !retroactivePause.isUndefined()) {
|
|
118
|
+
diagnostics.hint(
|
|
119
|
+
retroactivePause,
|
|
120
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE(
|
|
121
|
+
'retroactive.pause',
|
|
122
|
+
'when retroactive.start is true and durationType is a relative duration'
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Validates that retroactive.pause and retroactive.setStartTo are not set when retroactive.start is false (Behavior 7)
|
|
130
|
+
*/
|
|
131
|
+
export function validateRetroactiveFieldsWithoutStart(retroactive: ObjectShape | undefined, diagnostics: Diagnostics) {
|
|
132
|
+
if (!retroactive) {
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const setStartTo = retroactive.get('setStartTo')
|
|
137
|
+
const retroactivePause = retroactive.get('pause')
|
|
138
|
+
|
|
139
|
+
// setStartTo requires retroactive.start to be true (warning for existing values)
|
|
140
|
+
if (setStartTo && !setStartTo.isUndefined()) {
|
|
141
|
+
const value = setStartTo.ifString()?.getValue()
|
|
142
|
+
if (value) {
|
|
143
|
+
diagnostics.hint(
|
|
144
|
+
setStartTo,
|
|
145
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('retroactive.setStartTo', 'unless retroactive.start is true')
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// retroactive.pause requires retroactive.start to be true (warning for existing values)
|
|
151
|
+
if (retroactivePause && !retroactivePause.isUndefined()) {
|
|
152
|
+
const value = retroactivePause.ifBoolean()?.getValue()
|
|
153
|
+
if (value !== undefined) {
|
|
154
|
+
diagnostics.hint(
|
|
155
|
+
retroactivePause,
|
|
156
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('retroactive.pause', 'unless retroactive.start is true')
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Validates no_schedule restrictions (Behavior 4)
|
|
164
|
+
*/
|
|
165
|
+
export function validateNoScheduleRestrictions(config: ObjectShape, diagnostics: Diagnostics) {
|
|
166
|
+
const schedule = config.get('schedule')
|
|
167
|
+
const timezoneSource = config.get('timezoneSource')
|
|
168
|
+
const timezone = config.get('timezone')
|
|
169
|
+
const scheduleSourceField = config.get('scheduleSourceField')
|
|
170
|
+
|
|
171
|
+
// Schedule field: warn if provided, since default is forced
|
|
172
|
+
if (schedule && !schedule.isUndefined()) {
|
|
173
|
+
const value = schedule.ifString()?.getValue()
|
|
174
|
+
if (value) {
|
|
175
|
+
diagnostics.hint(
|
|
176
|
+
schedule,
|
|
177
|
+
ERROR_MESSAGES.RESTRICTED_WITH_DEFAULT(
|
|
178
|
+
'schedule',
|
|
179
|
+
'when scheduleSource is "no_schedule"',
|
|
180
|
+
DEFAULT_NO_SCHEDULE_ID
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// timezoneSource: existing values are preserved with a warning
|
|
187
|
+
if (timezoneSource && !timezoneSource.isUndefined()) {
|
|
188
|
+
const value = timezoneSource.ifString()?.getValue()
|
|
189
|
+
if (value && value !== DEFAULT_TIMEZONE_SOURCE) {
|
|
190
|
+
diagnostics.hint(
|
|
191
|
+
timezoneSource,
|
|
192
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('timezoneSource', 'when scheduleSource is "no_schedule"')
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// timezone: existing values are preserved with a warning
|
|
198
|
+
if (timezone && !timezone.isUndefined()) {
|
|
199
|
+
const value = timezone.ifString()?.getValue()
|
|
200
|
+
if (value) {
|
|
201
|
+
diagnostics.hint(
|
|
202
|
+
timezone,
|
|
203
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('timezone', 'when scheduleSource is "no_schedule"')
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// scheduleSourceField: warn since it doesn't apply to no_schedule
|
|
209
|
+
if (scheduleSourceField && !scheduleSourceField.isUndefined()) {
|
|
210
|
+
const value = scheduleSourceField.ifString()?.getValue()
|
|
211
|
+
if (value) {
|
|
212
|
+
diagnostics.hint(
|
|
213
|
+
scheduleSourceField,
|
|
214
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('scheduleSourceField', 'when scheduleSource is "no_schedule"')
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Validates task_field schedule requirements (Behavior 5)
|
|
222
|
+
*/
|
|
223
|
+
export function validateTaskFieldSchedule(config: ObjectShape, diagnostics: Diagnostics) {
|
|
224
|
+
const schedule = config.get('schedule')
|
|
225
|
+
const scheduleSourceField = config.get('scheduleSourceField')
|
|
226
|
+
const duration = config.get('duration')
|
|
227
|
+
|
|
228
|
+
// schedule: warn since it doesn't apply when using task_field
|
|
229
|
+
if (schedule && !schedule.isUndefined()) {
|
|
230
|
+
const value = schedule.ifString()?.getValue()
|
|
231
|
+
if (value) {
|
|
232
|
+
diagnostics.hint(
|
|
233
|
+
schedule,
|
|
234
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('schedule', 'when scheduleSource is "task_field"')
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// duration: warn since it doesn't apply when using task_field
|
|
240
|
+
if (duration && !duration.isUndefined()) {
|
|
241
|
+
diagnostics.hint(
|
|
242
|
+
duration,
|
|
243
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('duration', 'when scheduleSource is "task_field"')
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!scheduleSourceField || scheduleSourceField.isUndefined()) {
|
|
248
|
+
diagnostics.error(
|
|
249
|
+
config,
|
|
250
|
+
ERROR_MESSAGES.MANDATORY_FIELD('scheduleSourceField', 'when scheduleSource is "task_field"')
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Validates sla_definition schedule requirements (Behavior 3)
|
|
257
|
+
*/
|
|
258
|
+
export function validateSlaDefinitionSchedule(config: ObjectShape, diagnostics: Diagnostics) {
|
|
259
|
+
const schedule = config.get('schedule')
|
|
260
|
+
const scheduleValue = schedule?.ifString()?.getValue()
|
|
261
|
+
|
|
262
|
+
// Check for undefined, null, or empty string
|
|
263
|
+
if (!schedule || schedule.isUndefined() || !scheduleValue) {
|
|
264
|
+
diagnostics.error(config, ERROR_MESSAGES.MANDATORY_FIELD('schedule', 'when scheduleSource is "sla_definition"'))
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Validates timezone source restrictions (Behavior 9)
|
|
270
|
+
*/
|
|
271
|
+
export function validateTimezoneSource(
|
|
272
|
+
config: ObjectShape,
|
|
273
|
+
timezoneSource: string | undefined,
|
|
274
|
+
diagnostics: Diagnostics
|
|
275
|
+
) {
|
|
276
|
+
const timezone = config.get('timezone')
|
|
277
|
+
|
|
278
|
+
// Only allow timezone field when timezoneSource is 'sla.timezone'
|
|
279
|
+
// Existing values from XML are preserved (pass-through) with a warning.
|
|
280
|
+
if (timezoneSource !== 'sla.timezone' && timezone && !timezone.isUndefined()) {
|
|
281
|
+
const currentValue = timezone.ifString()?.getValue()
|
|
282
|
+
if (currentValue) {
|
|
283
|
+
diagnostics.hint(
|
|
284
|
+
timezone,
|
|
285
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('timezone', 'unless timezoneSource is "sla.timezone"')
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Validates no_match resume restrictions (Behavior 10)
|
|
293
|
+
*/
|
|
294
|
+
export function validateNoMatchResume(conditions: ObjectShape | undefined, diagnostics: Diagnostics) {
|
|
295
|
+
const resumeCondition = conditions?.get('resume')
|
|
296
|
+
|
|
297
|
+
// When whenToResume is "no_match", conditions.resume is restricted.
|
|
298
|
+
// Existing values from XML are preserved (pass-through) with a warning.
|
|
299
|
+
if (resumeCondition && !resumeCondition.isUndefined()) {
|
|
300
|
+
const currentValue = resumeCondition.ifString()?.getValue()
|
|
301
|
+
if (currentValue) {
|
|
302
|
+
diagnostics.hint(
|
|
303
|
+
resumeCondition,
|
|
304
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('conditions.resume', 'when whenToResume is "no_match"')
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Validates cancel condition restrictions (Behavior 11)
|
|
312
|
+
*/
|
|
313
|
+
export function validateCancelCondition(
|
|
314
|
+
whenToCancel: string | undefined,
|
|
315
|
+
conditions: ObjectShape | undefined,
|
|
316
|
+
diagnostics: Diagnostics
|
|
317
|
+
) {
|
|
318
|
+
const cancelCondition = conditions?.get('cancel')
|
|
319
|
+
|
|
320
|
+
// Only allow conditions.cancel when whenToCancel is 'on_condition'
|
|
321
|
+
// Existing values from XML are preserved (pass-through) with a warning.
|
|
322
|
+
if (whenToCancel !== 'on_condition' && cancelCondition && !cancelCondition.isUndefined()) {
|
|
323
|
+
const currentValue = cancelCondition.ifString()?.getValue()
|
|
324
|
+
if (currentValue) {
|
|
325
|
+
diagnostics.hint(
|
|
326
|
+
cancelCondition,
|
|
327
|
+
ERROR_MESSAGES.WARNING_FIELD_PERSISTENCE('conditions.cancel', 'unless whenToCancel is "on_condition"')
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { CallExpressionShape, Plugin, DurationShape } from '@servicenow/sdk-build-core'
|
|
2
|
+
import { NowIdShape } from './now-id-plugin'
|
|
3
|
+
import {
|
|
4
|
+
validateUserSpecifiedDuration,
|
|
5
|
+
validateRelativeDuration,
|
|
6
|
+
validateRetroactiveStart,
|
|
7
|
+
validateRetroactiveFieldsWithoutStart,
|
|
8
|
+
validateNoScheduleRestrictions,
|
|
9
|
+
validateTaskFieldSchedule,
|
|
10
|
+
validateSlaDefinitionSchedule,
|
|
11
|
+
validateTimezoneSource,
|
|
12
|
+
validateNoMatchResume,
|
|
13
|
+
validateCancelCondition,
|
|
14
|
+
DEFAULT_WHEN_TO_RESUME,
|
|
15
|
+
DEFAULT_WHEN_TO_CANCEL,
|
|
16
|
+
DEFAULT_TIMEZONE_SOURCE,
|
|
17
|
+
DEFAULT_RETROACTIVE_PAUSE,
|
|
18
|
+
DEFAULT_NO_SCHEDULE_ID,
|
|
19
|
+
} from './sla/sla-validators'
|
|
20
|
+
|
|
21
|
+
const DEFAULT_SLA_FLOW = '828f267973333300e289235f04f6a7a3'
|
|
22
|
+
const DEFAULT_COLLECTION = 'incident'
|
|
23
|
+
const DEFAULT_TYPE = 'SLA'
|
|
24
|
+
const DEFAULT_ACTIVE = true
|
|
25
|
+
const DEFAULT_ADV_CONDITION_TYPE = 'none'
|
|
26
|
+
const DEFAULT_SCHEDULE_SOURCE = 'sla_definition'
|
|
27
|
+
const DEFAULT_RELATIVE_DURATION_WORKS_ON = 'Task record'
|
|
28
|
+
const DEFAULT_RESET_ACTION = 'cancel'
|
|
29
|
+
const DEFAULT_RETROACTIVE = false
|
|
30
|
+
const DEFAULT_ENABLE_LOGGING = false
|
|
31
|
+
const DEFAULT_SYS_DOMAIN_PATH = '/'
|
|
32
|
+
const DEFAULT_DURATION_ON_PLATFORM = '1970-01-01 00:00:00'
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* See ./sla/sla-validators.ts for validation behavior documentation.
|
|
36
|
+
*/
|
|
37
|
+
export const SLAPlugin = Plugin.create({
|
|
38
|
+
name: 'SLAPlugin',
|
|
39
|
+
|
|
40
|
+
records: {
|
|
41
|
+
contract_sla: {
|
|
42
|
+
async toShape(record) {
|
|
43
|
+
return {
|
|
44
|
+
success: true,
|
|
45
|
+
value: new CallExpressionShape({
|
|
46
|
+
source: record,
|
|
47
|
+
callee: 'Sla',
|
|
48
|
+
args: [
|
|
49
|
+
record.transform(({ $ }) => ({
|
|
50
|
+
$id: $.val(NowIdShape.from(record)),
|
|
51
|
+
name: $.map((v) => v.ifString()?.ifNotEmpty()?.getValue()),
|
|
52
|
+
table: $.from('collection'),
|
|
53
|
+
duration: $.from('duration').map((v) => {
|
|
54
|
+
const stringShape = v.ifString()?.ifNotEmpty()
|
|
55
|
+
if (!stringShape) {
|
|
56
|
+
return DurationShape.zero(record)
|
|
57
|
+
}
|
|
58
|
+
const value = stringShape.getValue()
|
|
59
|
+
if (value === DEFAULT_DURATION_ON_PLATFORM) {
|
|
60
|
+
return DurationShape.zero(record)
|
|
61
|
+
}
|
|
62
|
+
return DurationShape.from(record, stringShape)
|
|
63
|
+
}),
|
|
64
|
+
// Return empty string when scheduleSource is 'no_schedule'
|
|
65
|
+
schedule: $.from('schedule', 'schedule_source').map((schedule, schedule_source) => {
|
|
66
|
+
const scheduleSourceValue = schedule_source.ifString()?.getValue()
|
|
67
|
+
if (scheduleSourceValue === 'no_schedule') {
|
|
68
|
+
return ''
|
|
69
|
+
}
|
|
70
|
+
return schedule.ifString()?.ifNotEmpty()?.getValue() ?? ''
|
|
71
|
+
}),
|
|
72
|
+
|
|
73
|
+
type: $.def(DEFAULT_TYPE),
|
|
74
|
+
active: $.toBoolean().def(DEFAULT_ACTIVE),
|
|
75
|
+
advancedConditionType: $.from('adv_condition_type').def(DEFAULT_ADV_CONDITION_TYPE),
|
|
76
|
+
|
|
77
|
+
// Duration & Schedule
|
|
78
|
+
durationType: $.from('duration_type').def(''),
|
|
79
|
+
scheduleSource: $.from('schedule_source').def(DEFAULT_SCHEDULE_SOURCE),
|
|
80
|
+
scheduleSourceField: $.from('schedule_source_field').def(''),
|
|
81
|
+
relativeDurationWorksOn: $.from('relative_duration_works_on').def(
|
|
82
|
+
DEFAULT_RELATIVE_DURATION_WORKS_ON
|
|
83
|
+
),
|
|
84
|
+
|
|
85
|
+
// Conditions
|
|
86
|
+
conditions: $.from(
|
|
87
|
+
'start_condition',
|
|
88
|
+
'stop_condition',
|
|
89
|
+
'pause_condition',
|
|
90
|
+
'resume_condition',
|
|
91
|
+
'reset_condition',
|
|
92
|
+
'cancel_condition'
|
|
93
|
+
).map(
|
|
94
|
+
(
|
|
95
|
+
start_condition,
|
|
96
|
+
stop_condition,
|
|
97
|
+
pause_condition,
|
|
98
|
+
resume_condition,
|
|
99
|
+
reset_condition,
|
|
100
|
+
cancel_condition
|
|
101
|
+
) => {
|
|
102
|
+
const conditions: Record<string, string> = {}
|
|
103
|
+
|
|
104
|
+
const startStr = start_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
105
|
+
if (startStr) {
|
|
106
|
+
conditions['start'] = startStr
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const stopStr = stop_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
110
|
+
if (stopStr) {
|
|
111
|
+
conditions['stop'] = stopStr
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const pauseStr = pause_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
115
|
+
if (pauseStr) {
|
|
116
|
+
conditions['pause'] = pauseStr
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const resumeStr = resume_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
120
|
+
if (resumeStr) {
|
|
121
|
+
conditions['resume'] = resumeStr
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const resetStr = reset_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
125
|
+
if (resetStr) {
|
|
126
|
+
conditions['reset'] = resetStr
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const cancelStr = cancel_condition.ifString()?.ifNotEmpty()?.getValue()
|
|
130
|
+
if (cancelStr) {
|
|
131
|
+
conditions['cancel'] = cancelStr
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Object.keys(conditions).length > 0 ? conditions : undefined
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
|
|
138
|
+
// Condition Behavior
|
|
139
|
+
conditionType: $.from('condition_class').def(''),
|
|
140
|
+
resetAction: $.from('reset_action').def(DEFAULT_RESET_ACTION),
|
|
141
|
+
whenTo: $.from('when_to_resume', 'when_to_cancel').map(
|
|
142
|
+
(when_to_resume, when_to_cancel) => {
|
|
143
|
+
const resumeValue = when_to_resume.ifString()?.getValue()
|
|
144
|
+
const cancelValue = when_to_cancel.ifString()?.getValue()
|
|
145
|
+
return {
|
|
146
|
+
resume: resumeValue || DEFAULT_WHEN_TO_RESUME,
|
|
147
|
+
cancel: cancelValue || DEFAULT_WHEN_TO_CANCEL,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
|
|
152
|
+
// Retroactive
|
|
153
|
+
retroactive: $.from('retroactive', 'retroactive_pause', 'set_start_to').map(
|
|
154
|
+
(retroactive, retroactive_pause, set_start_to) => {
|
|
155
|
+
const startValue = retroactive.ifBoolean()?.getValue() ?? DEFAULT_RETROACTIVE
|
|
156
|
+
const pauseValue = retroactive_pause.ifBoolean()?.getValue()
|
|
157
|
+
const setStartToValue = set_start_to.ifString()?.ifNotEmpty()?.getValue()
|
|
158
|
+
|
|
159
|
+
const result: { start: boolean; pause?: boolean; setStartTo?: string } = {
|
|
160
|
+
start: startValue,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Only include pause when start is true (per Behavior 6/7)
|
|
164
|
+
if (startValue) {
|
|
165
|
+
result.pause = pauseValue ?? DEFAULT_RETROACTIVE_PAUSE
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Only include setStartTo if it has a valid value
|
|
169
|
+
if (setStartToValue) {
|
|
170
|
+
result.setStartTo = setStartToValue
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result
|
|
174
|
+
}
|
|
175
|
+
),
|
|
176
|
+
|
|
177
|
+
// References
|
|
178
|
+
overrides: $.from('sys_overrides').def(''),
|
|
179
|
+
workflow: $.def(''),
|
|
180
|
+
flow: $.def(''),
|
|
181
|
+
vendor: $.def(''),
|
|
182
|
+
|
|
183
|
+
// Time Zones
|
|
184
|
+
timezone: $.def(''),
|
|
185
|
+
timezoneSource: $.from('timezone_source').def(DEFAULT_TIMEZONE_SOURCE),
|
|
186
|
+
|
|
187
|
+
// Metadata
|
|
188
|
+
enableLogging: $.from('enable_logging').toBoolean().def(DEFAULT_ENABLE_LOGGING),
|
|
189
|
+
target: $.def(''),
|
|
190
|
+
|
|
191
|
+
// Domain
|
|
192
|
+
domainPath: $.from('sys_domain_path').def(DEFAULT_SYS_DOMAIN_PATH),
|
|
193
|
+
})),
|
|
194
|
+
],
|
|
195
|
+
}),
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
shapes: [
|
|
202
|
+
{
|
|
203
|
+
shape: CallExpressionShape,
|
|
204
|
+
fileTypes: ['fluent'],
|
|
205
|
+
async toRecord(callExpression, { factory, diagnostics }) {
|
|
206
|
+
if (callExpression.getCallee() !== 'Sla') {
|
|
207
|
+
return { success: false }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const config = callExpression.getArgument(0).asObject()
|
|
211
|
+
|
|
212
|
+
// Extract Control Fields
|
|
213
|
+
const durationType = config.get('durationType')
|
|
214
|
+
const durationTypeValue = durationType?.ifString()?.getValue()
|
|
215
|
+
const isUserSpecifiedOrEmptyDuration = !durationTypeValue || durationTypeValue === ''
|
|
216
|
+
|
|
217
|
+
const scheduleSource = config.get('scheduleSource')
|
|
218
|
+
const scheduleSourceValue = scheduleSource?.ifString()?.getValue() || DEFAULT_SCHEDULE_SOURCE
|
|
219
|
+
|
|
220
|
+
const retroactive = config.get('retroactive')?.ifDefined()?.asObject()
|
|
221
|
+
const retroactiveStartValue = retroactive?.get('start')?.ifBoolean()?.getValue() || false
|
|
222
|
+
|
|
223
|
+
const whenTo = config.get('whenTo')?.ifDefined()?.asObject()
|
|
224
|
+
const whenToResumeValue = whenTo?.get('resume')?.ifString()?.getValue() || DEFAULT_WHEN_TO_RESUME
|
|
225
|
+
const whenToCancelValue = whenTo?.get('cancel')?.ifString()?.getValue() || DEFAULT_WHEN_TO_CANCEL
|
|
226
|
+
|
|
227
|
+
const timezoneSource = config.get('timezoneSource')
|
|
228
|
+
const timezoneSourceValue = timezoneSource?.ifString()?.getValue() || DEFAULT_TIMEZONE_SOURCE
|
|
229
|
+
|
|
230
|
+
// Extract conditions object
|
|
231
|
+
const conditions = config.get('conditions').ifDefined()?.asObject()
|
|
232
|
+
|
|
233
|
+
if (isUserSpecifiedOrEmptyDuration) {
|
|
234
|
+
// Behavior 1: User specified duration
|
|
235
|
+
// Validate duration field uses Duration() helper (only when duration is expected)
|
|
236
|
+
const duration = config.get('duration')
|
|
237
|
+
if (duration && duration.isDefined()) {
|
|
238
|
+
if (!(duration instanceof CallExpressionShape) || duration.getCallee() !== 'Duration') {
|
|
239
|
+
diagnostics.error(duration, "SLA 'duration' field must use the Duration() helper function")
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
validateUserSpecifiedDuration(config, diagnostics)
|
|
243
|
+
} else {
|
|
244
|
+
// Behavior 2: Relative duration
|
|
245
|
+
validateRelativeDuration(config, conditions, diagnostics)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Schedule Source Validations
|
|
249
|
+
if (scheduleSourceValue === 'no_schedule') {
|
|
250
|
+
// Behavior 5: No schedule
|
|
251
|
+
validateNoScheduleRestrictions(config, diagnostics)
|
|
252
|
+
} else if (scheduleSourceValue === 'task_field') {
|
|
253
|
+
// Behavior 6: Task field schedule
|
|
254
|
+
validateTaskFieldSchedule(config, diagnostics)
|
|
255
|
+
} else if (scheduleSourceValue === 'sla_definition') {
|
|
256
|
+
// Behavior 7: SLA definition schedule (default)
|
|
257
|
+
validateSlaDefinitionSchedule(config, diagnostics)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Condition Field Validations
|
|
261
|
+
// Behavior 8: Timezone source
|
|
262
|
+
validateTimezoneSource(config, timezoneSourceValue, diagnostics)
|
|
263
|
+
|
|
264
|
+
// Behavior 9: When to resume = "no_match"
|
|
265
|
+
if (whenToResumeValue === 'no_match') {
|
|
266
|
+
validateNoMatchResume(conditions, diagnostics)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Behavior 10: When to cancel validation
|
|
270
|
+
validateCancelCondition(whenToCancelValue, conditions, diagnostics)
|
|
271
|
+
|
|
272
|
+
// Retroactive Validations
|
|
273
|
+
if (retroactiveStartValue && retroactive) {
|
|
274
|
+
// Behaviors 6 & 8: Retroactive start validations
|
|
275
|
+
validateRetroactiveStart(retroactive, isUserSpecifiedOrEmptyDuration, diagnostics)
|
|
276
|
+
} else {
|
|
277
|
+
// Behavior 7: Validate that retroactive-dependent fields are not set when retroactive.start is false
|
|
278
|
+
validateRetroactiveFieldsWithoutStart(retroactive, diagnostics)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
success: true,
|
|
283
|
+
value: await factory.createRecord({
|
|
284
|
+
source: callExpression,
|
|
285
|
+
table: 'contract_sla',
|
|
286
|
+
explicitId: config.get('$id'),
|
|
287
|
+
properties: config.transform(({ $ }) => ({
|
|
288
|
+
// Core
|
|
289
|
+
name: $.map((v) => v.ifString()?.ifNotEmpty()?.getValue()),
|
|
290
|
+
collection: $.from('table').def(DEFAULT_COLLECTION),
|
|
291
|
+
type: $.def(DEFAULT_TYPE),
|
|
292
|
+
active: $.def(DEFAULT_ACTIVE),
|
|
293
|
+
adv_condition_type: $.from('advancedConditionType').def(DEFAULT_ADV_CONDITION_TYPE),
|
|
294
|
+
|
|
295
|
+
// Duration & Schedule
|
|
296
|
+
duration: $.map((v) => v.toString()),
|
|
297
|
+
duration_type: $.from('durationType').toString(),
|
|
298
|
+
// Conditional schedule: force default when no_schedule
|
|
299
|
+
schedule: $.map((v) => {
|
|
300
|
+
if (scheduleSourceValue === 'no_schedule') {
|
|
301
|
+
return DEFAULT_NO_SCHEDULE_ID
|
|
302
|
+
}
|
|
303
|
+
return v.ifString()?.ifNotEmpty()?.getValue()
|
|
304
|
+
}),
|
|
305
|
+
schedule_source: $.from('scheduleSource').def(DEFAULT_SCHEDULE_SOURCE),
|
|
306
|
+
schedule_source_field: $.from('scheduleSourceField'),
|
|
307
|
+
relative_duration_works_on: $.from('relativeDurationWorksOn').def(
|
|
308
|
+
DEFAULT_RELATIVE_DURATION_WORKS_ON
|
|
309
|
+
),
|
|
310
|
+
|
|
311
|
+
// Conditions
|
|
312
|
+
start_condition: $.val(conditions?.get('start')),
|
|
313
|
+
reset_condition: $.val(conditions?.get('reset')),
|
|
314
|
+
stop_condition: $.val(conditions?.get('stop')),
|
|
315
|
+
cancel_condition: $.val(conditions?.get('cancel')),
|
|
316
|
+
pause_condition: $.val(conditions?.get('pause')),
|
|
317
|
+
resume_condition: $.val(conditions?.get('resume')),
|
|
318
|
+
|
|
319
|
+
// Condition Behavior
|
|
320
|
+
condition_class: $.from('conditionType').toString(),
|
|
321
|
+
reset_action: $.from('resetAction').def(DEFAULT_RESET_ACTION),
|
|
322
|
+
when_to_resume: $.val(whenTo?.get('resume')).def(DEFAULT_WHEN_TO_RESUME),
|
|
323
|
+
when_to_cancel: $.val(whenTo?.get('cancel')).def(DEFAULT_WHEN_TO_CANCEL),
|
|
324
|
+
|
|
325
|
+
// Retroactive
|
|
326
|
+
retroactive: $.val(retroactive?.get('start')).def(DEFAULT_RETROACTIVE),
|
|
327
|
+
retroactive_pause: $.map(() => {
|
|
328
|
+
const value = retroactive?.get('pause')?.ifBoolean()?.getValue()
|
|
329
|
+
if (value !== undefined) {
|
|
330
|
+
return value
|
|
331
|
+
}
|
|
332
|
+
return isUserSpecifiedOrEmptyDuration ? DEFAULT_RETROACTIVE_PAUSE : undefined
|
|
333
|
+
}),
|
|
334
|
+
set_start_to: $.val(retroactive?.get('setStartTo')),
|
|
335
|
+
|
|
336
|
+
// References
|
|
337
|
+
sys_overrides: $.from('overrides'),
|
|
338
|
+
workflow: $,
|
|
339
|
+
flow: $.from('flow').def(DEFAULT_SLA_FLOW),
|
|
340
|
+
vendor: $,
|
|
341
|
+
|
|
342
|
+
// Time Zones
|
|
343
|
+
timezone: $,
|
|
344
|
+
timezone_source: $.from('timezoneSource').def(DEFAULT_TIMEZONE_SOURCE),
|
|
345
|
+
|
|
346
|
+
// Metadata
|
|
347
|
+
enable_logging: $.from('enableLogging').def(DEFAULT_ENABLE_LOGGING),
|
|
348
|
+
target: $,
|
|
349
|
+
|
|
350
|
+
// Domain
|
|
351
|
+
sys_domain_path: $.from('domainPath').def(DEFAULT_SYS_DOMAIN_PATH),
|
|
352
|
+
})),
|
|
353
|
+
}),
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
})
|