@servicenow/sdk-build-plugins 4.1.1 → 4.3.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 +22 -4
- 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/application-menu-plugin.js +1 -0
- package/dist/application-menu-plugin.js.map +1 -1
- package/dist/atf/step-configs.d.ts +13 -12
- package/dist/atf/step-configs.js.map +1 -1
- package/dist/atf/test-plugin.d.ts +1 -1
- package/dist/atf/test-plugin.js +13 -7
- package/dist/atf/test-plugin.js.map +1 -1
- package/dist/basic-syntax-plugin.js +58 -14
- 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/claims-plugin.js +1 -1
- package/dist/claims-plugin.js.map +1 -1
- package/dist/client-script-plugin.js +5 -17
- package/dist/client-script-plugin.js.map +1 -1
- package/dist/column/column-helper.d.ts +1 -1
- package/dist/column/column-helper.js +46 -2
- package/dist/column/column-helper.js.map +1 -1
- package/dist/column/column-to-record.js +6 -4
- package/dist/column/column-to-record.js.map +1 -1
- package/dist/column-plugin.js +107 -28
- 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 +6 -0
- package/dist/data-plugin.js +156 -0
- package/dist/data-plugin.js.map +1 -0
- 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 +930 -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 +324 -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 +65 -0
- package/dist/flow/utils/flow-constants.js +223 -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/utils.d.ts +117 -0
- package/dist/flow/utils/utils.js +345 -0
- package/dist/flow/utils/utils.js.map +1 -0
- package/dist/import-sets-plugin.d.ts +2 -0
- package/dist/import-sets-plugin.js +412 -0
- package/dist/import-sets-plugin.js.map +1 -0
- package/dist/index.d.ts +24 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/json-plugin.d.ts +4 -4
- package/dist/json-plugin.js +21 -7
- package/dist/json-plugin.js.map +1 -1
- package/dist/list-plugin.js +83 -1
- package/dist/list-plugin.js.map +1 -1
- package/dist/now-attach-plugin.d.ts +36 -0
- package/dist/now-attach-plugin.js +320 -0
- package/dist/now-attach-plugin.js.map +1 -0
- package/dist/now-config-plugin.js +3 -0
- package/dist/now-config-plugin.js.map +1 -1
- package/dist/now-include-plugin.js +7 -1
- package/dist/now-include-plugin.js.map +1 -1
- package/dist/package-json-plugin.js +2 -2
- package/dist/package-json-plugin.js.map +1 -1
- package/dist/record-plugin.d.ts +35 -0
- package/dist/record-plugin.js +109 -23
- 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/repack/lint/Rules.js.map +1 -1
- package/dist/rest-api-plugin.js +81 -74
- package/dist/rest-api-plugin.js.map +1 -1
- package/dist/role-plugin.js +1 -0
- package/dist/role-plugin.js.map +1 -1
- package/dist/server-module-plugin/index.js +53 -6
- 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 +139 -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 +169 -0
- package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -0
- package/dist/service-catalog/shape-to-record.d.ts +7 -0
- package/dist/service-catalog/shape-to-record.js +232 -0
- package/dist/service-catalog/shape-to-record.js.map +1 -0
- package/dist/service-catalog/utils.d.ts +313 -0
- package/dist/service-catalog/utils.js +1144 -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/service-portal/widget-plugin.js +4 -1
- package/dist/service-portal/widget-plugin.js.map +1 -1
- 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.d.ts +1 -0
- package/dist/static-content-plugin.js +4 -3
- package/dist/static-content-plugin.js.map +1 -1
- package/dist/table-plugin.js +49 -4
- package/dist/table-plugin.js.map +1 -1
- package/dist/ui-page-plugin.js +2 -1
- package/dist/ui-page-plugin.js.map +1 -1
- package/dist/ui-policy-plugin.d.ts +2 -0
- package/dist/ui-policy-plugin.js +405 -0
- package/dist/ui-policy-plugin.js.map +1 -0
- package/dist/utils.d.ts +19 -1
- package/dist/utils.js +40 -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/view-plugin.js +1 -1
- package/dist/view-plugin.js.map +1 -1
- 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/_types/eslint-plugin-es-x.d.ts +17 -0
- package/src/_types/md5.js.d.ts +8 -0
- package/src/acl-plugin.ts +33 -10
- package/src/applicability-plugin.ts +82 -0
- package/src/application-menu-plugin.ts +1 -0
- package/src/atf/step-configs.ts +14 -12
- package/src/atf/test-plugin.ts +46 -24
- package/src/basic-syntax-plugin.ts +71 -14
- package/src/business-rule-plugin.ts +9 -5
- package/src/call-expression-plugin.ts +2 -130
- package/src/claims-plugin.ts +1 -1
- package/src/client-script-plugin.ts +8 -22
- package/src/column/column-helper.ts +65 -3
- package/src/column/column-to-record.ts +6 -4
- package/src/column-plugin.ts +142 -40
- 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 +194 -0
- 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 +1148 -0
- package/src/flow/plugins/flow-trigger-instance-plugin.ts +426 -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 +276 -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/utils.ts +395 -0
- package/src/import-sets-plugin.ts +542 -0
- package/src/index.ts +25 -1
- package/src/json-plugin.ts +31 -12
- package/src/list-plugin.ts +91 -1
- package/src/now-attach-plugin.ts +403 -0
- package/src/now-config-plugin.ts +6 -2
- package/src/now-include-plugin.ts +8 -1
- package/src/package-json-plugin.ts +3 -3
- package/src/record-plugin.ts +126 -30
- package/src/repack/index.ts +14 -0
- package/src/repack/lint/Rules.ts +1 -10
- package/src/rest-api-plugin.ts +106 -100
- package/src/role-plugin.ts +1 -0
- package/src/server-module-plugin/index.ts +74 -22
- 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 +251 -0
- package/src/service-catalog/shape-to-record.ts +275 -0
- package/src/service-catalog/utils.ts +1362 -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/service-portal/widget-plugin.ts +4 -1
- package/src/sla/sla-validators.ts +331 -0
- package/src/sla-plugin.ts +358 -0
- package/src/static-content-plugin.ts +2 -2
- package/src/table-plugin.ts +66 -9
- package/src/ui-page-plugin.ts +2 -1
- package/src/ui-policy-plugin.ts +505 -0
- package/src/utils.ts +50 -1
- package/src/ux-list-menu-config-plugin.ts +312 -0
- package/src/view-plugin.ts +1 -1
- 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,505 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Compiler,
|
|
3
|
+
type Diagnostics,
|
|
4
|
+
CallExpressionShape,
|
|
5
|
+
Plugin,
|
|
6
|
+
isSNScope,
|
|
7
|
+
isGUID,
|
|
8
|
+
type Record,
|
|
9
|
+
type Shape,
|
|
10
|
+
} from '@servicenow/sdk-build-core'
|
|
11
|
+
import { validateClientSideScript } from './utils'
|
|
12
|
+
import { NowIdShape } from './now-id-plugin'
|
|
13
|
+
|
|
14
|
+
// Define table names as constants since they're not exported from the core tables
|
|
15
|
+
const SYS_UI_POLICY = 'sys_ui_policy'
|
|
16
|
+
const SYS_UI_POLICY_ACTION = 'sys_ui_policy_action'
|
|
17
|
+
const SYS_UI_POLICY_RL_ACTION = 'sys_ui_policy_rl_action'
|
|
18
|
+
const DEFAULT_SCRIPT = 'function onCondition() {\n\n}'
|
|
19
|
+
|
|
20
|
+
// UI Type constant for string-to-number mapping
|
|
21
|
+
const UiTypeMapping = { desktop: 0, 'mobile-or-service-portal': 1, all: 10 }
|
|
22
|
+
const getUITypeFromId = (id: number): string => {
|
|
23
|
+
const entry = Object.entries(UiTypeMapping).find(([_, v]) => v === id)
|
|
24
|
+
if (!entry) {
|
|
25
|
+
throw Error(`Invalid UI Type encountered: ${id}, check XML data before transforming again.`)
|
|
26
|
+
}
|
|
27
|
+
return entry[0]
|
|
28
|
+
}
|
|
29
|
+
const getUITypeId = (value: keyof typeof UiTypeMapping): number => {
|
|
30
|
+
const entry = UiTypeMapping[value]
|
|
31
|
+
if (entry === undefined) {
|
|
32
|
+
throw Error(`Invalid ui_type found: ${value}`)
|
|
33
|
+
}
|
|
34
|
+
return entry
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Converts ServiceNow string format ('true'/'false'/'ignore') to boolean | 'ignore'
|
|
39
|
+
* Used when reading from database (toShape)
|
|
40
|
+
*/
|
|
41
|
+
const stringToBoolean = (value?: string): boolean | 'ignore' | undefined => {
|
|
42
|
+
switch (value) {
|
|
43
|
+
case 'true':
|
|
44
|
+
return true
|
|
45
|
+
case 'false':
|
|
46
|
+
return false
|
|
47
|
+
case 'ignore':
|
|
48
|
+
return 'ignore'
|
|
49
|
+
default:
|
|
50
|
+
return undefined
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Converts boolean | 'ignore' to ServiceNow string format ('true'/'false'/'ignore')
|
|
56
|
+
* Used when writing to database (toRecord)
|
|
57
|
+
*/
|
|
58
|
+
const booleanToString = (value: Shape): string => {
|
|
59
|
+
if (value?.isBoolean()) {
|
|
60
|
+
return value.getValue() ? 'true' : 'false'
|
|
61
|
+
}
|
|
62
|
+
return 'ignore'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Checks if a value is a valid action property (boolean or 'ignore')
|
|
67
|
+
* Used for validation in toRecord
|
|
68
|
+
*/
|
|
69
|
+
const isValidActionValue = (value: Shape): boolean => {
|
|
70
|
+
return value?.isBoolean() || (value?.isString() && value.getValue() === 'ignore')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Helper to determine if a script should be included in generated Fluent code
|
|
74
|
+
const isValidScript = (scriptValue: Shape) =>
|
|
75
|
+
scriptValue?.isString() && scriptValue.getValue() !== '' && scriptValue.getValue() !== DEFAULT_SCRIPT
|
|
76
|
+
|
|
77
|
+
// Helper function to validate a script property for import/require statements
|
|
78
|
+
const validateScriptProperty = (
|
|
79
|
+
scriptProperty: Shape | undefined,
|
|
80
|
+
compiler: Compiler,
|
|
81
|
+
diagnostics: Diagnostics
|
|
82
|
+
): void => {
|
|
83
|
+
if (scriptProperty?.isString()) {
|
|
84
|
+
const scriptContent = scriptProperty.getValue()
|
|
85
|
+
if (scriptContent && !validateClientSideScript(scriptContent, compiler)) {
|
|
86
|
+
diagnostics.error(
|
|
87
|
+
scriptProperty,
|
|
88
|
+
'UI Policy scripts cannot import or require modules. Scripts run client-side in the browser.'
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const UiPolicyPlugin = Plugin.create({
|
|
95
|
+
name: 'UiPolicyPlugin',
|
|
96
|
+
records: {
|
|
97
|
+
[SYS_UI_POLICY]: {
|
|
98
|
+
coalesce: ['table', 'short_description'],
|
|
99
|
+
relationships: {
|
|
100
|
+
[SYS_UI_POLICY_ACTION]: {
|
|
101
|
+
via: 'ui_policy',
|
|
102
|
+
descendant: true,
|
|
103
|
+
},
|
|
104
|
+
[SYS_UI_POLICY_RL_ACTION]: {
|
|
105
|
+
via: 'ui_policy',
|
|
106
|
+
descendant: true,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
toShape(record, { descendants }) {
|
|
110
|
+
const actions = descendants
|
|
111
|
+
.query(SYS_UI_POLICY_ACTION)
|
|
112
|
+
.map((action) => {
|
|
113
|
+
const fieldValue = action.get('field')?.ifString()?.getValue()
|
|
114
|
+
if (!fieldValue) {
|
|
115
|
+
return null // Skip actions without a field
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const actionObj: {
|
|
119
|
+
field: string
|
|
120
|
+
visible?: boolean | 'ignore'
|
|
121
|
+
readOnly?: boolean | 'ignore'
|
|
122
|
+
mandatory?: boolean | 'ignore'
|
|
123
|
+
cleared?: boolean
|
|
124
|
+
table?: string
|
|
125
|
+
value?: string
|
|
126
|
+
fieldMessage?: string
|
|
127
|
+
fieldMessageType?: string
|
|
128
|
+
valueAction?: string
|
|
129
|
+
} = {
|
|
130
|
+
field: fieldValue,
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Convert ServiceNow string format to boolean | 'ignore'
|
|
134
|
+
const visible = stringToBoolean(action.get('visible')?.ifString()?.getValue())
|
|
135
|
+
const disabled = stringToBoolean(action.get('disabled')?.ifString()?.getValue())
|
|
136
|
+
const mandatory = stringToBoolean(action.get('mandatory')?.ifString()?.getValue())
|
|
137
|
+
|
|
138
|
+
// Only include visible if it's not 'ignore'
|
|
139
|
+
if (visible !== undefined && visible !== 'ignore') {
|
|
140
|
+
actionObj.visible = visible
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Convert 'disabled' to 'readOnly'
|
|
144
|
+
// Only include 'readOnly' if it's not 'ignore'
|
|
145
|
+
if (disabled !== undefined && disabled !== 'ignore') {
|
|
146
|
+
actionObj.readOnly = disabled
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Only include mandatory if it's not 'ignore'
|
|
150
|
+
if (mandatory !== undefined && mandatory !== 'ignore') {
|
|
151
|
+
actionObj.mandatory = mandatory
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const cleared = action.get('cleared')?.ifBoolean()?.getValue()
|
|
155
|
+
if (cleared) {
|
|
156
|
+
actionObj.cleared = cleared
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Add new optional fields - only if they have meaningful values
|
|
160
|
+
const table = action.get('table')?.ifString()?.getValue()
|
|
161
|
+
const parentTable = record.get('table')?.ifString()?.getValue()
|
|
162
|
+
// Only include table if it's different from the parent policy's table
|
|
163
|
+
if (table && table !== parentTable) {
|
|
164
|
+
actionObj.table = table
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const value = action.get('value')?.ifString()?.getValue()
|
|
168
|
+
if (value) {
|
|
169
|
+
actionObj.value = value
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const fieldMessage = action.get('field_message')?.ifString()?.getValue()
|
|
173
|
+
if (fieldMessage) {
|
|
174
|
+
actionObj.fieldMessage = fieldMessage
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const fieldMessageType = action.get('field_message_type')?.ifString()?.getValue()
|
|
178
|
+
// Only include if it's not the default value 'none'
|
|
179
|
+
if (fieldMessageType && fieldMessageType !== 'none') {
|
|
180
|
+
actionObj.fieldMessageType = fieldMessageType
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const valueAction = action.get('value_action')?.ifString()?.getValue()
|
|
184
|
+
// Only include if it's not the default value 'ignore'
|
|
185
|
+
if (valueAction && valueAction !== 'ignore') {
|
|
186
|
+
actionObj.valueAction = valueAction
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Skip actions that have no meaningful properties (all are 'ignore')
|
|
190
|
+
if (Object.keys(actionObj).length === 1) {
|
|
191
|
+
return null // Only 'field' property exists, skip this action
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return actionObj
|
|
195
|
+
})
|
|
196
|
+
.filter((action) => action !== null) // Remove null actions
|
|
197
|
+
|
|
198
|
+
// Process related list actions
|
|
199
|
+
const relatedListActions = descendants
|
|
200
|
+
.query(SYS_UI_POLICY_RL_ACTION)
|
|
201
|
+
.map((rlAction) => {
|
|
202
|
+
const rlActionObj: {
|
|
203
|
+
list?: string
|
|
204
|
+
visible?: boolean | 'ignore'
|
|
205
|
+
} = {}
|
|
206
|
+
|
|
207
|
+
const listValue = rlAction.get('list')?.ifString()?.getValue()
|
|
208
|
+
if (listValue) {
|
|
209
|
+
// Strip REL: prefix if present (transform ServiceNow → Fluent)
|
|
210
|
+
// Users write plain GUIDs or table.field format in Fluent code
|
|
211
|
+
if (listValue.startsWith('REL:')) {
|
|
212
|
+
rlActionObj.list = listValue.substring(4) // Remove 'REL:' prefix
|
|
213
|
+
} else {
|
|
214
|
+
rlActionObj.list = listValue
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Convert ServiceNow string format to boolean | 'ignore'
|
|
219
|
+
const visible = stringToBoolean(rlAction.get('visible')?.ifString()?.getValue())
|
|
220
|
+
if (visible !== undefined && visible !== 'ignore') {
|
|
221
|
+
rlActionObj.visible = visible
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Skip if no meaningful properties (only $id exists)
|
|
225
|
+
if (Object.keys(rlActionObj).length === 0) {
|
|
226
|
+
return null
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return rlActionObj
|
|
230
|
+
})
|
|
231
|
+
.filter((rlAction) => rlAction !== null) // Remove null actions
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
success: true,
|
|
235
|
+
value: new CallExpressionShape({
|
|
236
|
+
source: record,
|
|
237
|
+
callee: 'UiPolicy',
|
|
238
|
+
args: [
|
|
239
|
+
record.transform(({ $ }) => {
|
|
240
|
+
const scriptTrueValue = record.get('script_true')
|
|
241
|
+
const scriptFalseValue = record.get('script_false')
|
|
242
|
+
const runScriptsValue = record.get('run_scripts')?.toBoolean().getValue() ?? false
|
|
243
|
+
const uiTypeValue = record.get('ui_type')
|
|
244
|
+
const includeScriptTrue = runScriptsValue || isValidScript(scriptTrueValue)
|
|
245
|
+
const includeScriptFalse = runScriptsValue || isValidScript(scriptFalseValue)
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
$id: $.val(NowIdShape.from(record)),
|
|
249
|
+
table: $.from('table').def(''),
|
|
250
|
+
shortDescription: $.from('short_description'),
|
|
251
|
+
active: $.toBoolean().def(true),
|
|
252
|
+
global: $.toBoolean().def(true),
|
|
253
|
+
onLoad: $.from('on_load').toBoolean().def(true),
|
|
254
|
+
reverseIfFalse: $.from('reverse_if_false').toBoolean().def(true),
|
|
255
|
+
inherit: $.toBoolean().def(false),
|
|
256
|
+
isolateScript: $.from('isolate_script').toBoolean().def(false),
|
|
257
|
+
conditions: $.def(''),
|
|
258
|
+
runScripts: $.from('run_scripts').toBoolean().def(false),
|
|
259
|
+
|
|
260
|
+
scriptTrue: $.val(
|
|
261
|
+
includeScriptTrue ? (scriptTrueValue?.getValue() ?? DEFAULT_SCRIPT) : undefined
|
|
262
|
+
),
|
|
263
|
+
scriptFalse: $.val(
|
|
264
|
+
includeScriptFalse
|
|
265
|
+
? (scriptFalseValue?.getValue() ?? DEFAULT_SCRIPT)
|
|
266
|
+
: undefined
|
|
267
|
+
),
|
|
268
|
+
// uiType is REQUIRED when runScripts is true, should be omitted when false
|
|
269
|
+
uiType: $.val(
|
|
270
|
+
runScriptsValue
|
|
271
|
+
? getUITypeFromId(uiTypeValue?.toNumber().getValue() ?? 0)
|
|
272
|
+
: undefined
|
|
273
|
+
),
|
|
274
|
+
description: $.from('description').def(''),
|
|
275
|
+
modelId: $.from('model_id').def(''),
|
|
276
|
+
modelTable: $.from('model_table').def(''),
|
|
277
|
+
order: $.from('order').toNumber().def(100),
|
|
278
|
+
setValues: $.from('set_values').def(''),
|
|
279
|
+
view: $.from('view').def(''),
|
|
280
|
+
actions: $.val(actions.length > 0 ? actions : undefined),
|
|
281
|
+
relatedListActions: $.val(
|
|
282
|
+
relatedListActions.length > 0 ? relatedListActions : undefined
|
|
283
|
+
),
|
|
284
|
+
}
|
|
285
|
+
}),
|
|
286
|
+
],
|
|
287
|
+
}),
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
[SYS_UI_POLICY_ACTION]: {
|
|
292
|
+
coalesce: ['ui_policy', 'field'],
|
|
293
|
+
},
|
|
294
|
+
[SYS_UI_POLICY_RL_ACTION]: {
|
|
295
|
+
coalesce: ['ui_policy', 'list'],
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
shapes: [
|
|
299
|
+
{
|
|
300
|
+
shape: CallExpressionShape,
|
|
301
|
+
fileTypes: ['fluent'],
|
|
302
|
+
async toRecord(callExpression, { config, factory, diagnostics, compiler }) {
|
|
303
|
+
if (callExpression.getCallee()?.toString() !== 'UiPolicy') {
|
|
304
|
+
return { success: false }
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const arg = callExpression.getArgument(0)
|
|
308
|
+
if (!arg?.isObject()) {
|
|
309
|
+
return { success: false }
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const shortDescription = arg.get('shortDescription')
|
|
313
|
+
if (shortDescription?.isString() && shortDescription.getValue().trim() === '') {
|
|
314
|
+
diagnostics.error(shortDescription, 'shortDescription cannot be empty or contain only whitespace')
|
|
315
|
+
return { success: false }
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Validate table scope prefix for scoped apps
|
|
319
|
+
const tableValue = arg.get('table')
|
|
320
|
+
if (tableValue?.isString() && config?.scope) {
|
|
321
|
+
const tableName = tableValue.getValue()
|
|
322
|
+
const scopeName = config.scope
|
|
323
|
+
|
|
324
|
+
if (!tableName.startsWith(`${scopeName}_`) && !isSNScope(scopeName) && scopeName !== 'global') {
|
|
325
|
+
diagnostics.error(
|
|
326
|
+
arg.get('table'),
|
|
327
|
+
`'table' property should start with scope prefix '${scopeName}_'. UI Policies in scoped apps can only be created for tables within the same scope.`
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Validate scripts for import statements
|
|
333
|
+
const scriptTrue = arg.get('scriptTrue')
|
|
334
|
+
const scriptFalse = arg.get('scriptFalse')
|
|
335
|
+
validateScriptProperty(scriptTrue, compiler, diagnostics)
|
|
336
|
+
validateScriptProperty(scriptFalse, compiler, diagnostics)
|
|
337
|
+
const runScripts = arg.get('runScripts')
|
|
338
|
+
if (runScripts.isUndefined() || runScripts.ifBoolean()?.equals(false)) {
|
|
339
|
+
;[scriptTrue, scriptFalse]
|
|
340
|
+
.filter((shape) => shape.isDefined() && !shape.equals(DEFAULT_SCRIPT))
|
|
341
|
+
.forEach((shape) =>
|
|
342
|
+
diagnostics.info(shape, `This script will not execute unless runScripts is set to true`)
|
|
343
|
+
)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Convert uiType value to ID (TypeScript enforces valid values at compile time)
|
|
347
|
+
const uiTypeValue = arg.get('uiType')
|
|
348
|
+
const uiTypeId = uiTypeValue?.isString()
|
|
349
|
+
? getUITypeId(uiTypeValue.getValue() as keyof typeof UiTypeMapping)
|
|
350
|
+
: UiTypeMapping.desktop // default
|
|
351
|
+
|
|
352
|
+
// Create the UI Policy record
|
|
353
|
+
const policyRecord = await factory.createRecord({
|
|
354
|
+
source: callExpression,
|
|
355
|
+
table: SYS_UI_POLICY,
|
|
356
|
+
explicitId: arg.get('$id'),
|
|
357
|
+
properties: arg.transform(({ $ }) => ({
|
|
358
|
+
table: $.from('table').def(''),
|
|
359
|
+
short_description: $.from('shortDescription'),
|
|
360
|
+
active: $.from('active').def(true),
|
|
361
|
+
global: $.from('global').def(true),
|
|
362
|
+
on_load: $.from('onLoad').def(true),
|
|
363
|
+
reverse_if_false: $.from('reverseIfFalse').def(true),
|
|
364
|
+
inherit: $.from('inherit').def(false),
|
|
365
|
+
isolate_script: $.from('isolateScript').def(false),
|
|
366
|
+
conditions: $.from('conditions').def(''),
|
|
367
|
+
run_scripts: $.from('runScripts').def(false),
|
|
368
|
+
script_true: $.from('scriptTrue').toCdata().def(DEFAULT_SCRIPT),
|
|
369
|
+
script_false: $.from('scriptFalse').toCdata().def(DEFAULT_SCRIPT),
|
|
370
|
+
description: $.from('description').def(''),
|
|
371
|
+
model_id: $.from('modelId').def(''),
|
|
372
|
+
model_table: $.from('modelTable').def(''),
|
|
373
|
+
order: $.from('order').toNumber().def(100),
|
|
374
|
+
set_values: $.from('setValues').def(''),
|
|
375
|
+
ui_type: $.val(uiTypeId),
|
|
376
|
+
view: $.from('view').def(''),
|
|
377
|
+
})),
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
// Process actions if they exist
|
|
381
|
+
const actions = arg.get('actions')
|
|
382
|
+
const actionRecords: Record[] = []
|
|
383
|
+
|
|
384
|
+
if (actions?.isArray()) {
|
|
385
|
+
const elements = actions.getElements()
|
|
386
|
+
|
|
387
|
+
// Process each action in the array
|
|
388
|
+
for (let i = 0; i < elements.length; i++) {
|
|
389
|
+
const action = elements[i]
|
|
390
|
+
if (!action?.isObject()) {
|
|
391
|
+
continue
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const field = action.get('field')
|
|
395
|
+
|
|
396
|
+
// Validate at least one action property exists
|
|
397
|
+
const hasVisibleProp = isValidActionValue(action.get('visible'))
|
|
398
|
+
const hasReadOnlyProp = isValidActionValue(action.get('readOnly'))
|
|
399
|
+
const hasMandatoryProp = isValidActionValue(action.get('mandatory'))
|
|
400
|
+
const hasClearedProp = action.get('cleared')?.isBoolean() || false
|
|
401
|
+
|
|
402
|
+
if (!hasVisibleProp && !hasReadOnlyProp && !hasMandatoryProp && !hasClearedProp) {
|
|
403
|
+
diagnostics.error(
|
|
404
|
+
action,
|
|
405
|
+
`Action at index ${i} must specify at least one of: visible, readOnly, mandatory, or cleared`
|
|
406
|
+
)
|
|
407
|
+
continue
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const actionRecord = await factory.createRecord({
|
|
411
|
+
source: action, // Use the action as source instead of callExpression
|
|
412
|
+
table: SYS_UI_POLICY_ACTION,
|
|
413
|
+
properties: action.transform(({ $ }) => ({
|
|
414
|
+
ui_policy: $.val(policyRecord.getId()),
|
|
415
|
+
table: $.from('table').def(arg.get('table')?.getValue() || ''),
|
|
416
|
+
field: $.val(field.getValue()),
|
|
417
|
+
visible: $.val(booleanToString(action.get('visible'))),
|
|
418
|
+
disabled: $.val(booleanToString(action.get('readOnly'))),
|
|
419
|
+
mandatory: $.val(booleanToString(action.get('mandatory'))),
|
|
420
|
+
cleared: $.from('cleared').toBoolean().def(false),
|
|
421
|
+
field_message: $.from('fieldMessage').def(''),
|
|
422
|
+
field_message_type: $.from('fieldMessageType').def('none'),
|
|
423
|
+
value: $.from('value').def(''),
|
|
424
|
+
value_action: $.from('valueAction').def('ignore'),
|
|
425
|
+
})),
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
actionRecords.push(actionRecord)
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Create related list action records (optional) - AST approach
|
|
433
|
+
const relatedListActionRecords: Record[] = []
|
|
434
|
+
const relatedListActions = arg.get('relatedListActions')
|
|
435
|
+
if (relatedListActions?.isArray()) {
|
|
436
|
+
const rlElements = relatedListActions.getElements()
|
|
437
|
+
|
|
438
|
+
// Process each related list action in the array (similar to actions)
|
|
439
|
+
for (let i = 0; i < rlElements.length; i++) {
|
|
440
|
+
const rlAction = rlElements[i]
|
|
441
|
+
if (!rlAction?.isObject()) {
|
|
442
|
+
continue
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Validate and process the list property
|
|
446
|
+
const list = rlAction.get('list')
|
|
447
|
+
let listValue = ''
|
|
448
|
+
|
|
449
|
+
if (list) {
|
|
450
|
+
if (list.isRecord()) {
|
|
451
|
+
listValue = `REL:${list.getId().getValue()}`
|
|
452
|
+
} else if (list.isString()) {
|
|
453
|
+
const listStr = list.getValue()
|
|
454
|
+
|
|
455
|
+
if (isGUID(listStr)) {
|
|
456
|
+
listValue = `REL:${listStr}`
|
|
457
|
+
} else if (listStr.includes('.')) {
|
|
458
|
+
const [table, field] = listStr.split('.')
|
|
459
|
+
if (!table || !field || listStr.split('.').length !== 2) {
|
|
460
|
+
diagnostics.error(
|
|
461
|
+
list,
|
|
462
|
+
`Related list action at index ${i}: 'list' property must be in 'table.field' format (e.g., 'incident.caller_id')`
|
|
463
|
+
)
|
|
464
|
+
continue
|
|
465
|
+
}
|
|
466
|
+
listValue = listStr
|
|
467
|
+
} else {
|
|
468
|
+
diagnostics.error(
|
|
469
|
+
list,
|
|
470
|
+
`Related list action at index ${i}: 'list' property must be either a Record<'sys_relationship'>, a GUID, or in 'table.field' format (e.g., 'incident.caller_id')`
|
|
471
|
+
)
|
|
472
|
+
continue
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// At least one property must be specified (visible or list)
|
|
478
|
+
const hasVisibleProp = isValidActionValue(rlAction.get('visible'))
|
|
479
|
+
if (!hasVisibleProp && !listValue) {
|
|
480
|
+
diagnostics.error(
|
|
481
|
+
rlAction,
|
|
482
|
+
`Related list action at index ${i} must specify at least one of: list or visible`
|
|
483
|
+
)
|
|
484
|
+
continue
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const rlActionRecord = await factory.createRecord({
|
|
488
|
+
source: rlAction,
|
|
489
|
+
table: SYS_UI_POLICY_RL_ACTION,
|
|
490
|
+
properties: rlAction.transform(({ $ }) => ({
|
|
491
|
+
list: $.val(listValue),
|
|
492
|
+
ui_policy: $.val(policyRecord.getId()),
|
|
493
|
+
visible: $.val(booleanToString(rlAction.get('visible'))),
|
|
494
|
+
})),
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
relatedListActionRecords.push(rlActionRecord)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return { success: true, value: policyRecord.with(...actionRecords, ...relatedListActionRecords) }
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
})
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ts,
|
|
3
|
+
type Shape,
|
|
4
|
+
type ObjectShape,
|
|
5
|
+
type Diagnostics,
|
|
6
|
+
type Compiler,
|
|
7
|
+
type PluginApiDoc,
|
|
8
|
+
} from '@servicenow/sdk-build-core'
|
|
2
9
|
|
|
3
10
|
export function toReference(shape: Shape) {
|
|
4
11
|
return shape.ifRecord()?.getId() ?? shape.ifString()?.getValue() ?? ''
|
|
@@ -67,3 +74,45 @@ export function generateDeprecatedDiagnostics(object: ObjectShape, diagnostics:
|
|
|
67
74
|
}
|
|
68
75
|
})
|
|
69
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Helper function to check if a call expression is a require statement
|
|
80
|
+
*/
|
|
81
|
+
function isRequire(callExpression: ts.CallExpression): boolean {
|
|
82
|
+
const expression = callExpression.getExpression()
|
|
83
|
+
return ts.Node.isIdentifier(expression) && expression.getText() === 'require'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validates that client-side scripts (Client Scripts and UI Policy scripts) don't contain
|
|
88
|
+
* import or require statements. These scripts run in the browser and cannot use module imports.
|
|
89
|
+
*
|
|
90
|
+
* @param script - The script content to validate
|
|
91
|
+
* @param compiler - The TypeScript compiler instance
|
|
92
|
+
* @returns true if the script is valid (no imports/requires), false otherwise
|
|
93
|
+
*/
|
|
94
|
+
export function validateClientSideScript(script: string, compiler: Compiler): boolean {
|
|
95
|
+
const source = compiler.createSourceFile('tmp-script.ts', script)
|
|
96
|
+
const hasImports = source.getDescendantsOfKind(ts.SyntaxKind.ImportDeclaration).length > 0
|
|
97
|
+
const hasRequires = source.getDescendantsOfKind(ts.SyntaxKind.CallExpression).some(isRequire)
|
|
98
|
+
const isValid = !(hasImports || hasRequires)
|
|
99
|
+
compiler.removeSourceFile(source)
|
|
100
|
+
|
|
101
|
+
return isValid
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Creates a documentation entry for first-party SDK plugins.
|
|
106
|
+
* Using this helper ensures apiName and docPath are always in sync.
|
|
107
|
+
*
|
|
108
|
+
* @param apiName - The API name (e.g., 'BusinessRule', 'Acl')
|
|
109
|
+
* @param tags - Keywords for categorization (typically includes the ServiceNow table name)
|
|
110
|
+
* @returns A complete PluginApiDoc entry
|
|
111
|
+
*/
|
|
112
|
+
export function createSdkDocEntry(apiName: string, tags: string[]): PluginApiDoc {
|
|
113
|
+
return {
|
|
114
|
+
apiName,
|
|
115
|
+
docPath: `@servicenow/sdk/docs/${apiName}/${apiName}.md`,
|
|
116
|
+
tags,
|
|
117
|
+
}
|
|
118
|
+
}
|