@servicenow/sdk-build-plugins 4.2.0 → 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.
Files changed (330) hide show
  1. package/dist/acl-plugin.js +9 -0
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/applicability-plugin.d.ts +2 -0
  4. package/dist/applicability-plugin.js +72 -0
  5. package/dist/applicability-plugin.js.map +1 -0
  6. package/dist/atf/test-plugin.js +5 -2
  7. package/dist/atf/test-plugin.js.map +1 -1
  8. package/dist/basic-syntax-plugin.js +7 -1
  9. package/dist/basic-syntax-plugin.js.map +1 -1
  10. package/dist/business-rule-plugin.js +1 -0
  11. package/dist/business-rule-plugin.js.map +1 -1
  12. package/dist/call-expression-plugin.js +1 -107
  13. package/dist/call-expression-plugin.js.map +1 -1
  14. package/dist/column-plugin.js +1 -1
  15. package/dist/column-plugin.js.map +1 -1
  16. package/dist/dashboard/dashboard-component-property-defaults.d.ts +152 -0
  17. package/dist/dashboard/dashboard-component-property-defaults.js +264 -0
  18. package/dist/dashboard/dashboard-component-property-defaults.js.map +1 -0
  19. package/dist/dashboard/dashboard-component-resolver.d.ts +13 -0
  20. package/dist/dashboard/dashboard-component-resolver.js +69 -0
  21. package/dist/dashboard/dashboard-component-resolver.js.map +1 -0
  22. package/dist/dashboard/dashboard-plugin.d.ts +12 -0
  23. package/dist/dashboard/dashboard-plugin.js +397 -0
  24. package/dist/dashboard/dashboard-plugin.js.map +1 -0
  25. package/dist/data-plugin.d.ts +3 -0
  26. package/dist/data-plugin.js +61 -113
  27. package/dist/data-plugin.js.map +1 -1
  28. package/dist/email-notification-plugin.d.ts +2 -0
  29. package/dist/email-notification-plugin.js +541 -0
  30. package/dist/email-notification-plugin.js.map +1 -0
  31. package/dist/flow/constants/flow-plugin-constants.d.ts +58 -0
  32. package/dist/flow/constants/flow-plugin-constants.js +70 -0
  33. package/dist/flow/constants/flow-plugin-constants.js.map +1 -0
  34. package/dist/flow/flow-logic/flow-logic-constants.d.ts +38 -0
  35. package/dist/flow/flow-logic/flow-logic-constants.js +118 -0
  36. package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -0
  37. package/dist/flow/flow-logic/flow-logic-diagnostics.d.ts +19 -0
  38. package/dist/flow/flow-logic/flow-logic-diagnostics.js +503 -0
  39. package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -0
  40. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +62 -0
  41. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +2092 -0
  42. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -0
  43. package/dist/flow/flow-logic/flow-logic-plugin.d.ts +52 -0
  44. package/dist/flow/flow-logic/flow-logic-plugin.js +283 -0
  45. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -0
  46. package/dist/flow/flow-logic/flow-logic-shapes.d.ts +104 -0
  47. package/dist/flow/flow-logic/flow-logic-shapes.js +201 -0
  48. package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -0
  49. package/dist/flow/plugins/approval-rules-plugin.d.ts +2 -0
  50. package/dist/flow/plugins/approval-rules-plugin.js +49 -0
  51. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -0
  52. package/dist/flow/plugins/flow-action-definition-plugin.d.ts +2 -0
  53. package/dist/flow/plugins/flow-action-definition-plugin.js +286 -0
  54. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -0
  55. package/dist/flow/plugins/flow-data-pill-plugin.d.ts +9 -0
  56. package/dist/flow/plugins/flow-data-pill-plugin.js +212 -0
  57. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -0
  58. package/dist/flow/plugins/flow-definition-plugin.d.ts +2 -0
  59. package/dist/flow/plugins/flow-definition-plugin.js +1668 -0
  60. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -0
  61. package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +26 -0
  62. package/dist/flow/plugins/flow-diagnostics-plugin.js +217 -0
  63. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -0
  64. package/dist/flow/plugins/flow-instance-plugin.d.ts +12 -0
  65. package/dist/flow/plugins/flow-instance-plugin.js +930 -0
  66. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -0
  67. package/dist/flow/plugins/flow-trigger-instance-plugin.d.ts +2 -0
  68. package/dist/flow/plugins/flow-trigger-instance-plugin.js +324 -0
  69. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -0
  70. package/dist/flow/plugins/inline-script-plugin.d.ts +39 -0
  71. package/dist/flow/plugins/inline-script-plugin.js +80 -0
  72. package/dist/flow/plugins/inline-script-plugin.js.map +1 -0
  73. package/dist/flow/plugins/step-definition-plugin.d.ts +5 -0
  74. package/dist/flow/plugins/step-definition-plugin.js +71 -0
  75. package/dist/flow/plugins/step-definition-plugin.js.map +1 -0
  76. package/dist/flow/plugins/step-instance-plugin.d.ts +31 -0
  77. package/dist/flow/plugins/step-instance-plugin.js +339 -0
  78. package/dist/flow/plugins/step-instance-plugin.js.map +1 -0
  79. package/dist/flow/plugins/trigger-plugin.d.ts +2 -0
  80. package/dist/flow/plugins/trigger-plugin.js +96 -0
  81. package/dist/flow/plugins/trigger-plugin.js.map +1 -0
  82. package/dist/flow/plugins/wfa-datapill-plugin.d.ts +15 -0
  83. package/dist/flow/plugins/wfa-datapill-plugin.js +178 -0
  84. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -0
  85. package/dist/flow/utils/approval-rules-processor.d.ts +13 -0
  86. package/dist/flow/utils/approval-rules-processor.js +267 -0
  87. package/dist/flow/utils/approval-rules-processor.js.map +1 -0
  88. package/dist/flow/utils/built-in-complex-objects.d.ts +19 -0
  89. package/dist/flow/utils/built-in-complex-objects.js +62 -0
  90. package/dist/flow/utils/built-in-complex-objects.js.map +1 -0
  91. package/dist/flow/utils/complex-object-resolver.d.ts +8 -0
  92. package/dist/flow/utils/complex-object-resolver.js +614 -0
  93. package/dist/flow/utils/complex-object-resolver.js.map +1 -0
  94. package/dist/flow/utils/complex-objects.d.ts +36 -0
  95. package/dist/flow/utils/complex-objects.js +481 -0
  96. package/dist/flow/utils/complex-objects.js.map +1 -0
  97. package/dist/flow/utils/data-pill-shapes.d.ts +58 -0
  98. package/dist/flow/utils/data-pill-shapes.js +135 -0
  99. package/dist/flow/utils/data-pill-shapes.js.map +1 -0
  100. package/dist/flow/utils/datapill-transformer.d.ts +110 -0
  101. package/dist/flow/utils/datapill-transformer.js +503 -0
  102. package/dist/flow/utils/datapill-transformer.js.map +1 -0
  103. package/dist/flow/utils/flow-constants.d.ts +65 -0
  104. package/dist/flow/utils/flow-constants.js +223 -0
  105. package/dist/flow/utils/flow-constants.js.map +1 -0
  106. package/dist/flow/utils/flow-io-to-record.d.ts +44 -0
  107. package/dist/flow/utils/flow-io-to-record.js +409 -0
  108. package/dist/flow/utils/flow-io-to-record.js.map +1 -0
  109. package/dist/flow/utils/flow-shapes.d.ts +161 -0
  110. package/dist/flow/utils/flow-shapes.js +255 -0
  111. package/dist/flow/utils/flow-shapes.js.map +1 -0
  112. package/dist/flow/utils/flow-to-xml.d.ts +16 -0
  113. package/dist/flow/utils/flow-to-xml.js +237 -0
  114. package/dist/flow/utils/flow-to-xml.js.map +1 -0
  115. package/dist/flow/utils/flow-variable-processor.d.ts +51 -0
  116. package/dist/flow/utils/flow-variable-processor.js +69 -0
  117. package/dist/flow/utils/flow-variable-processor.js.map +1 -0
  118. package/dist/flow/utils/label-cache-parser.d.ts +7 -0
  119. package/dist/flow/utils/label-cache-parser.js +24 -0
  120. package/dist/flow/utils/label-cache-parser.js.map +1 -0
  121. package/dist/flow/utils/label-cache-processor.d.ts +119 -0
  122. package/dist/flow/utils/label-cache-processor.js +719 -0
  123. package/dist/flow/utils/label-cache-processor.js.map +1 -0
  124. package/dist/flow/utils/pill-string-parser.d.ts +88 -0
  125. package/dist/flow/utils/pill-string-parser.js +306 -0
  126. package/dist/flow/utils/pill-string-parser.js.map +1 -0
  127. package/dist/flow/utils/schema-to-flow-object.d.ts +22 -0
  128. package/dist/flow/utils/schema-to-flow-object.js +318 -0
  129. package/dist/flow/utils/schema-to-flow-object.js.map +1 -0
  130. package/dist/flow/utils/utils.d.ts +117 -0
  131. package/dist/flow/utils/utils.js +345 -0
  132. package/dist/flow/utils/utils.js.map +1 -0
  133. package/dist/index.d.ts +20 -1
  134. package/dist/index.js +21 -1
  135. package/dist/index.js.map +1 -1
  136. package/dist/list-plugin.js +1 -1
  137. package/dist/list-plugin.js.map +1 -1
  138. package/dist/now-attach-plugin.d.ts +1 -0
  139. package/dist/now-attach-plugin.js +3 -0
  140. package/dist/now-attach-plugin.js.map +1 -1
  141. package/dist/record-plugin.d.ts +29 -0
  142. package/dist/record-plugin.js +66 -7
  143. package/dist/record-plugin.js.map +1 -1
  144. package/dist/repack/index.d.ts +2 -0
  145. package/dist/repack/index.js +8 -0
  146. package/dist/repack/index.js.map +1 -1
  147. package/dist/rest-api-plugin.js +54 -44
  148. package/dist/rest-api-plugin.js.map +1 -1
  149. package/dist/server-module-plugin/index.js +38 -4
  150. package/dist/server-module-plugin/index.js.map +1 -1
  151. package/dist/service-catalog/catalog-clientscript-plugin.d.ts +2 -0
  152. package/dist/service-catalog/catalog-clientscript-plugin.js +117 -0
  153. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -0
  154. package/dist/service-catalog/catalog-item-plugin.d.ts +2 -0
  155. package/dist/service-catalog/catalog-item-plugin.js +115 -0
  156. package/dist/service-catalog/catalog-item-plugin.js.map +1 -0
  157. package/dist/service-catalog/catalog-ui-policy-plugin.d.ts +2 -0
  158. package/dist/service-catalog/catalog-ui-policy-plugin.js +266 -0
  159. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -0
  160. package/dist/service-catalog/index.d.ts +5 -0
  161. package/dist/service-catalog/index.js +22 -0
  162. package/dist/service-catalog/index.js.map +1 -0
  163. package/dist/service-catalog/record-to-shape.d.ts +6 -0
  164. package/dist/service-catalog/record-to-shape.js +93 -0
  165. package/dist/service-catalog/record-to-shape.js.map +1 -0
  166. package/dist/service-catalog/sc-record-producer-plugin.d.ts +2 -0
  167. package/dist/service-catalog/sc-record-producer-plugin.js +139 -0
  168. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -0
  169. package/dist/service-catalog/service-catalog-base.d.ts +311 -0
  170. package/dist/service-catalog/service-catalog-base.js +542 -0
  171. package/dist/service-catalog/service-catalog-base.js.map +1 -0
  172. package/dist/service-catalog/service-catalog-diagnostics.d.ts +45 -0
  173. package/dist/service-catalog/service-catalog-diagnostics.js +169 -0
  174. package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -0
  175. package/dist/service-catalog/shape-to-record.d.ts +7 -0
  176. package/dist/service-catalog/shape-to-record.js +232 -0
  177. package/dist/service-catalog/shape-to-record.js.map +1 -0
  178. package/dist/service-catalog/utils.d.ts +313 -0
  179. package/dist/service-catalog/utils.js +1144 -0
  180. package/dist/service-catalog/utils.js.map +1 -0
  181. package/dist/service-catalog/variable-helper.d.ts +43 -0
  182. package/dist/service-catalog/variable-helper.js +92 -0
  183. package/dist/service-catalog/variable-helper.js.map +1 -0
  184. package/dist/service-catalog/variable-set-plugin.d.ts +2 -0
  185. package/dist/service-catalog/variable-set-plugin.js +175 -0
  186. package/dist/service-catalog/variable-set-plugin.js.map +1 -0
  187. package/dist/service-catalog/variables-transform.d.ts +139 -0
  188. package/dist/service-catalog/variables-transform.js +403 -0
  189. package/dist/service-catalog/variables-transform.js.map +1 -0
  190. package/dist/sla/sla-validators.d.ts +61 -0
  191. package/dist/sla/sla-validators.js +224 -0
  192. package/dist/sla/sla-validators.js.map +1 -0
  193. package/dist/sla-plugin.d.ts +5 -0
  194. package/dist/sla-plugin.js +280 -0
  195. package/dist/sla-plugin.js.map +1 -0
  196. package/dist/table-plugin.js +16 -2
  197. package/dist/table-plugin.js.map +1 -1
  198. package/dist/ui-policy-plugin.js +5 -7
  199. package/dist/ui-policy-plugin.js.map +1 -1
  200. package/dist/utils.d.ts +10 -1
  201. package/dist/utils.js +16 -0
  202. package/dist/utils.js.map +1 -1
  203. package/dist/ux-list-menu-config-plugin.d.ts +2 -0
  204. package/dist/ux-list-menu-config-plugin.js +292 -0
  205. package/dist/ux-list-menu-config-plugin.js.map +1 -0
  206. package/dist/workspace-plugin/chrome-tab.d.ts +2 -0
  207. package/dist/workspace-plugin/chrome-tab.js +46 -0
  208. package/dist/workspace-plugin/chrome-tab.js.map +1 -0
  209. package/dist/workspace-plugin/constants.d.ts +52 -0
  210. package/dist/workspace-plugin/constants.js +56 -0
  211. package/dist/workspace-plugin/constants.js.map +1 -0
  212. package/dist/workspace-plugin/fluent-utils.d.ts +9 -0
  213. package/dist/workspace-plugin/fluent-utils.js +60 -0
  214. package/dist/workspace-plugin/fluent-utils.js.map +1 -0
  215. package/dist/workspace-plugin/page.d.ts +8 -0
  216. package/dist/workspace-plugin/page.js +108 -0
  217. package/dist/workspace-plugin/page.js.map +1 -0
  218. package/dist/workspace-plugin/screen.d.ts +1 -0
  219. package/dist/workspace-plugin/screen.js +38 -0
  220. package/dist/workspace-plugin/screen.js.map +1 -0
  221. package/dist/workspace-plugin/templates/index.d.ts +10 -0
  222. package/dist/workspace-plugin/templates/index.js +20 -0
  223. package/dist/workspace-plugin/templates/index.js.map +1 -0
  224. package/dist/workspace-plugin/templates/record-page-composition.d.ts +1 -0
  225. package/dist/workspace-plugin/templates/record-page-composition.js +4043 -0
  226. package/dist/workspace-plugin/templates/record-page-composition.js.map +1 -0
  227. package/dist/workspace-plugin/templates/record-page-data.d.ts +1 -0
  228. package/dist/workspace-plugin/templates/record-page-data.js +527 -0
  229. package/dist/workspace-plugin/templates/record-page-data.js.map +1 -0
  230. package/dist/workspace-plugin/templates/record-page-interalEventMappings.d.ts +1 -0
  231. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js +39 -0
  232. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js.map +1 -0
  233. package/dist/workspace-plugin/templates/record-page-layoutModel.d.ts +1 -0
  234. package/dist/workspace-plugin/templates/record-page-layoutModel.js +55 -0
  235. package/dist/workspace-plugin/templates/record-page-layoutModel.js.map +1 -0
  236. package/dist/workspace-plugin/templates/record-page-properties.d.ts +1 -0
  237. package/dist/workspace-plugin/templates/record-page-properties.js +135 -0
  238. package/dist/workspace-plugin/templates/record-page-properties.js.map +1 -0
  239. package/dist/workspace-plugin/templates/record-page.d.ts +3 -0
  240. package/dist/workspace-plugin/templates/record-page.js +8 -0
  241. package/dist/workspace-plugin/templates/record-page.js.map +1 -0
  242. package/dist/workspace-plugin.d.ts +2 -0
  243. package/dist/workspace-plugin.js +453 -0
  244. package/dist/workspace-plugin.js.map +1 -0
  245. package/package.json +10 -12
  246. package/src/acl-plugin.ts +14 -1
  247. package/src/applicability-plugin.ts +82 -0
  248. package/src/atf/test-plugin.ts +6 -3
  249. package/src/basic-syntax-plugin.ts +10 -1
  250. package/src/business-rule-plugin.ts +2 -1
  251. package/src/call-expression-plugin.ts +2 -130
  252. package/src/column-plugin.ts +1 -1
  253. package/src/dashboard/dashboard-component-property-defaults.ts +277 -0
  254. package/src/dashboard/dashboard-component-resolver.ts +69 -0
  255. package/src/dashboard/dashboard-plugin.ts +450 -0
  256. package/src/data-plugin.ts +67 -139
  257. package/src/email-notification-plugin.ts +850 -0
  258. package/src/flow/constants/flow-plugin-constants.ts +79 -0
  259. package/src/flow/flow-logic/flow-logic-constants.ts +120 -0
  260. package/src/flow/flow-logic/flow-logic-diagnostics.ts +591 -0
  261. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +2550 -0
  262. package/src/flow/flow-logic/flow-logic-plugin.ts +337 -0
  263. package/src/flow/flow-logic/flow-logic-shapes.ts +215 -0
  264. package/src/flow/plugins/approval-rules-plugin.ts +48 -0
  265. package/src/flow/plugins/flow-action-definition-plugin.ts +295 -0
  266. package/src/flow/plugins/flow-data-pill-plugin.ts +258 -0
  267. package/src/flow/plugins/flow-definition-plugin.ts +2173 -0
  268. package/src/flow/plugins/flow-diagnostics-plugin.ts +280 -0
  269. package/src/flow/plugins/flow-instance-plugin.ts +1148 -0
  270. package/src/flow/plugins/flow-trigger-instance-plugin.ts +426 -0
  271. package/src/flow/plugins/inline-script-plugin.ts +83 -0
  272. package/src/flow/plugins/step-definition-plugin.ts +67 -0
  273. package/src/flow/plugins/step-instance-plugin.ts +431 -0
  274. package/src/flow/plugins/trigger-plugin.ts +95 -0
  275. package/src/flow/plugins/wfa-datapill-plugin.ts +213 -0
  276. package/src/flow/utils/approval-rules-processor.ts +298 -0
  277. package/src/flow/utils/built-in-complex-objects.ts +81 -0
  278. package/src/flow/utils/complex-object-resolver.ts +875 -0
  279. package/src/flow/utils/complex-objects.ts +656 -0
  280. package/src/flow/utils/data-pill-shapes.ts +165 -0
  281. package/src/flow/utils/datapill-transformer.ts +632 -0
  282. package/src/flow/utils/flow-constants.ts +276 -0
  283. package/src/flow/utils/flow-io-to-record.ts +533 -0
  284. package/src/flow/utils/flow-shapes.ts +296 -0
  285. package/src/flow/utils/flow-to-xml.ts +318 -0
  286. package/src/flow/utils/flow-variable-processor.ts +100 -0
  287. package/src/flow/utils/label-cache-parser.ts +37 -0
  288. package/src/flow/utils/label-cache-processor.ts +870 -0
  289. package/src/flow/utils/pill-string-parser.ts +375 -0
  290. package/src/flow/utils/schema-to-flow-object.ts +385 -0
  291. package/src/flow/utils/utils.ts +395 -0
  292. package/src/index.ts +21 -1
  293. package/src/list-plugin.ts +1 -1
  294. package/src/now-attach-plugin.ts +4 -0
  295. package/src/record-plugin.ts +76 -11
  296. package/src/repack/index.ts +14 -0
  297. package/src/rest-api-plugin.ts +62 -50
  298. package/src/server-module-plugin/index.ts +53 -17
  299. package/src/service-catalog/catalog-clientscript-plugin.ts +140 -0
  300. package/src/service-catalog/catalog-item-plugin.ts +162 -0
  301. package/src/service-catalog/catalog-ui-policy-plugin.ts +324 -0
  302. package/src/service-catalog/index.ts +5 -0
  303. package/src/service-catalog/record-to-shape.ts +109 -0
  304. package/src/service-catalog/sc-record-producer-plugin.ts +201 -0
  305. package/src/service-catalog/service-catalog-base.ts +600 -0
  306. package/src/service-catalog/service-catalog-diagnostics.ts +251 -0
  307. package/src/service-catalog/shape-to-record.ts +275 -0
  308. package/src/service-catalog/utils.ts +1362 -0
  309. package/src/service-catalog/variable-helper.ts +135 -0
  310. package/src/service-catalog/variable-set-plugin.ts +197 -0
  311. package/src/service-catalog/variables-transform.ts +438 -0
  312. package/src/sla/sla-validators.ts +331 -0
  313. package/src/sla-plugin.ts +358 -0
  314. package/src/table-plugin.ts +19 -2
  315. package/src/ui-policy-plugin.ts +5 -9
  316. package/src/utils.ts +24 -1
  317. package/src/ux-list-menu-config-plugin.ts +312 -0
  318. package/src/workspace-plugin/chrome-tab.ts +44 -0
  319. package/src/workspace-plugin/constants.ts +53 -0
  320. package/src/workspace-plugin/fluent-utils.ts +60 -0
  321. package/src/workspace-plugin/page.ts +139 -0
  322. package/src/workspace-plugin/screen.ts +34 -0
  323. package/src/workspace-plugin/templates/index.ts +17 -0
  324. package/src/workspace-plugin/templates/record-page-composition.ts +4051 -0
  325. package/src/workspace-plugin/templates/record-page-data.ts +523 -0
  326. package/src/workspace-plugin/templates/record-page-interalEventMappings.ts +35 -0
  327. package/src/workspace-plugin/templates/record-page-layoutModel.ts +51 -0
  328. package/src/workspace-plugin/templates/record-page-properties.ts +131 -0
  329. package/src/workspace-plugin/templates/record-page.ts +6 -0
  330. package/src/workspace-plugin.ts +574 -0
@@ -0,0 +1,251 @@
1
+ import type { Diagnostics, ObjectShape } from '@servicenow/sdk-build-core'
2
+
3
+ /**
4
+ * Validates that at most one of executionPlan, flow, or workflow is defined.
5
+ * These fields are mutually exclusive in the FulfillmentProcess type.
6
+ * Returns true if valid, false if a diagnostic was emitted.
7
+ */
8
+ export function validateFulfillmentProcessExclusivity(arg: ObjectShape, diagnostics: Diagnostics): boolean {
9
+ const fields = ['executionPlan', 'flow', 'workflow'] as const
10
+ const defined = fields.filter((f) => arg.get(f).isDefined() && !arg.get(f).ifString()?.isEmpty())
11
+
12
+ if (defined.length > 1) {
13
+ diagnostics.error(
14
+ arg,
15
+ `Only one of executionPlan, flow, or workflow can be specified. Found: ${defined.join(', ')}. Remove the extra fields so that only one fulfillment method is configured.`
16
+ )
17
+ return false
18
+ }
19
+ return true
20
+ }
21
+
22
+ /**
23
+ * Validates that categories are only provided when catalogs are also provided.
24
+ * Returns true if valid, false if a diagnostic was emitted.
25
+ */
26
+ export function validateCategoriesRequireCatalogs(arg: ObjectShape, diagnostics: Diagnostics): boolean {
27
+ const hasCategories =
28
+ arg.get('categories').isDefined() && (arg.get('categories').ifArray()?.getElements()?.length ?? 0) > 0
29
+ const hasCatalogs =
30
+ arg.get('catalogs').isDefined() && (arg.get('catalogs').ifArray()?.getElements()?.length ?? 0) > 0
31
+
32
+ if (hasCategories && !hasCatalogs) {
33
+ diagnostics.error(
34
+ arg.get('categories'),
35
+ `'categories' requires 'catalogs' to also be specified. Categories can only be selected after the Catalogs field is populated.`
36
+ )
37
+ return false
38
+ }
39
+ return true
40
+ }
41
+
42
+ /**
43
+ * Validates that catalogItem and variableSet are not both provided.
44
+ * When appliesTo is 'set', variableSet should be provided; when 'item', catalogItem should be provided.
45
+ * Returns true if valid, false if a diagnostic was emitted.
46
+ */
47
+ export function validateCatalogItemVariableSetExclusivity(
48
+ arg: ObjectShape,
49
+ diagnostics: Diagnostics,
50
+ context: string
51
+ ): boolean {
52
+ const hasCatalogItem = arg.get('catalogItem').isDefined() && !arg.get('catalogItem').ifString()?.isEmpty()
53
+ const hasVariableSet = arg.get('variableSet').isDefined() && !arg.get('variableSet').ifString()?.isEmpty()
54
+
55
+ if (hasCatalogItem && hasVariableSet) {
56
+ diagnostics.error(
57
+ arg,
58
+ `${context}: 'catalogItem' and 'variableSet' are mutually exclusive. Specify only one. When appliesTo is 'set', use variableSet; when 'item', use catalogItem.`
59
+ )
60
+ return false
61
+ }
62
+
63
+ const appliesTo = arg.get('appliesTo')?.ifString()?.getValue()
64
+ if (appliesTo === 'set' && hasCatalogItem) {
65
+ diagnostics.error(
66
+ arg.get('catalogItem'),
67
+ `${context}: 'catalogItem' should not be specified when appliesTo is 'set'. Use 'variableSet' instead.`
68
+ )
69
+ return false
70
+ }
71
+ if (appliesTo === 'item' && hasVariableSet) {
72
+ diagnostics.error(
73
+ arg.get('variableSet'),
74
+ `${context}: 'variableSet' should not be specified when appliesTo is 'item'. Use 'catalogItem' instead.`
75
+ )
76
+ return false
77
+ }
78
+
79
+ return true
80
+ }
81
+
82
+ /**
83
+ * Validates that variableMessage is provided when variableMessageType is set in a UI policy action.
84
+ * Returns true if valid, false if a diagnostic was emitted.
85
+ */
86
+ export function validateUiPolicyActionMessage(actionObj: ObjectShape, diagnostics: Diagnostics): boolean {
87
+ const hasMessageType =
88
+ actionObj.get('variableMessageType').isDefined() && !actionObj.get('variableMessageType').ifString()?.isEmpty()
89
+ const hasMessage =
90
+ actionObj.get('variableMessage').isDefined() && !actionObj.get('variableMessage').ifString()?.isEmpty()
91
+
92
+ if (hasMessageType && !hasMessage) {
93
+ diagnostics.error(
94
+ actionObj.get('variableMessageType'),
95
+ `'variableMessage' is required when 'variableMessageType' is specified. Provide a message to display on the field.`
96
+ )
97
+ return false
98
+ }
99
+
100
+ if (hasMessage && !hasMessageType) {
101
+ diagnostics.error(
102
+ actionObj.get('variableMessage'),
103
+ `'variableMessageType' is required when 'variableMessage' is specified. Provide a message type (info, warning, or error).`
104
+ )
105
+ return false
106
+ }
107
+
108
+ return true
109
+ }
110
+
111
+ /**
112
+ * Validates that 'field' is provided when 'mapToField' is true in a variable config.
113
+ * Returns true if valid, false if a diagnostic was emitted.
114
+ */
115
+ export function validateMapToFieldRequiresField(config: ObjectShape, diagnostics: Diagnostics): boolean {
116
+ const mapToField = config.get('mapToField')
117
+ const isMapToFieldTrue = mapToField.isDefined() && mapToField.ifBoolean()?.getValue() === true
118
+ const hasField = config.get('field').isDefined() && !config.get('field').ifString()?.isEmpty()
119
+
120
+ if (isMapToFieldTrue && !hasField) {
121
+ diagnostics.error(mapToField, `'field' is required when 'mapToField' is true. Specify the field to map to.`)
122
+ return false
123
+ }
124
+
125
+ return true
126
+ }
127
+
128
+ /**
129
+ * Validates that mandatory is not true when hidden or readOnly is true, and vice versa.
130
+ * Returns true if valid, false if a diagnostic was emitted.
131
+ */
132
+ export function validateMandatoryReadOnlyHidden(config: ObjectShape, diagnostics: Diagnostics): boolean {
133
+ const isMandatory = config.get('mandatory').isDefined() && config.get('mandatory').ifBoolean()?.getValue() === true
134
+ const isReadOnly = config.get('readOnly').isDefined() && config.get('readOnly').ifBoolean()?.getValue() === true
135
+ const isHidden = config.get('hidden').isDefined() && config.get('hidden').ifBoolean()?.getValue() === true
136
+
137
+ if (isMandatory && isReadOnly) {
138
+ diagnostics.error(
139
+ config.get('mandatory'),
140
+ `'mandatory' cannot be true when 'readOnly' is true. A field cannot be both required and read-only.`
141
+ )
142
+ return false
143
+ }
144
+
145
+ if (isMandatory && isHidden) {
146
+ diagnostics.error(
147
+ config.get('mandatory'),
148
+ `'mandatory' cannot be true when 'hidden' is true. A field cannot be both required and hidden.`
149
+ )
150
+ return false
151
+ }
152
+
153
+ return true
154
+ }
155
+
156
+ /**
157
+ * Validates lookup variable configuration: table-based and choice-based properties are mutually exclusive,
158
+ * and price fields are not allowed when uniqueValuesOnly is true.
159
+ * Returns true if valid, false if a diagnostic was emitted.
160
+ */
161
+ export function validateLookupSourceExclusivity(config: ObjectShape, diagnostics: Diagnostics): boolean {
162
+ const lookupSource = config.get('lookupSource')
163
+ const lookupSourceValue = lookupSource?.ifString()?.getValue()
164
+ const hasLookupSource = lookupSource.isDefined() && !lookupSource.ifString()?.isEmpty()
165
+ const hasLookupFromTable =
166
+ config.get('lookupFromTable').isDefined() && !config.get('lookupFromTable').ifString()?.isEmpty()
167
+ const hasLookupValueField =
168
+ config.get('lookupValueField').isDefined() && !config.get('lookupValueField').ifString()?.isEmpty()
169
+
170
+ const isChoicesSource = hasLookupSource && lookupSourceValue === 'choices'
171
+
172
+ if (isChoicesSource) {
173
+ if (hasLookupFromTable) {
174
+ diagnostics.error(
175
+ config.get('lookupFromTable'),
176
+ `'lookupFromTable' should not be specified when 'lookupSource' is 'choices'.`
177
+ )
178
+ return false
179
+ }
180
+
181
+ if (hasLookupValueField) {
182
+ diagnostics.error(
183
+ config.get('lookupValueField'),
184
+ `'lookupValueField' should not be specified when 'lookupSource' is 'choices'.`
185
+ )
186
+ return false
187
+ }
188
+
189
+ return true
190
+ }
191
+
192
+ const requiredNode = lookupSource.isDefined() ? lookupSource : config
193
+
194
+ if (!hasLookupFromTable) {
195
+ diagnostics.error(requiredNode, `'lookupFromTable' is required when 'lookupSource' is not 'choices'.`)
196
+ return false
197
+ }
198
+
199
+ if (!hasLookupValueField) {
200
+ diagnostics.error(requiredNode, `'lookupValueField' is required when 'lookupSource' is not 'choices'.`)
201
+ return false
202
+ }
203
+
204
+ return true
205
+ }
206
+
207
+ /**
208
+ * Validates reference qualifier fields are mutually exclusive and consistent with useReferenceQualifier.
209
+ * referenceQualCondition, dynamicRefQual, and referenceQual are mutually exclusive.
210
+ * Returns true if valid, false if a diagnostic was emitted.
211
+ */
212
+ export function validateReferenceQualifierExclusivity(
213
+ config: ObjectShape,
214
+ diagnostics: Diagnostics,
215
+ context: string
216
+ ): boolean {
217
+ const hasRefQualCondition =
218
+ config.get('referenceQualCondition').isDefined() && !config.get('referenceQualCondition').ifString()?.isEmpty()
219
+ const hasDynamicRefQual =
220
+ config.get('dynamicRefQual').isDefined() && !config.get('dynamicRefQual').ifString()?.isEmpty()
221
+ const hasRefQual = config.get('referenceQual').isDefined() && !config.get('referenceQual').ifString()?.isEmpty()
222
+
223
+ const useRefQualShape = config.get('useReferenceQualifier')
224
+ const useRefQual = useRefQualShape?.ifString()?.getValue()
225
+
226
+ if ((useRefQual === 'simple' || useRefQualShape.ifString()?.isEmpty()) && !hasRefQualCondition) {
227
+ diagnostics.error(
228
+ useRefQualShape,
229
+ `${context}: 'referenceQualCondition' is required when 'useReferenceQualifier' is 'simple'.`
230
+ )
231
+ return false
232
+ }
233
+
234
+ if (useRefQual === 'dynamic' && !hasDynamicRefQual) {
235
+ diagnostics.error(
236
+ useRefQualShape,
237
+ `${context}: 'dynamicRefQual' is required when 'useReferenceQualifier' is 'dynamic'.`
238
+ )
239
+ return false
240
+ }
241
+
242
+ if (useRefQual === 'advanced' && !hasRefQual) {
243
+ diagnostics.error(
244
+ useRefQualShape,
245
+ `${context}: 'referenceQual' is required when 'useReferenceQualifier' is 'advanced'.`
246
+ )
247
+ return false
248
+ }
249
+
250
+ return true
251
+ }
@@ -0,0 +1,275 @@
1
+ import {
2
+ CallExpressionShape,
3
+ type Record,
4
+ type Factory,
5
+ type ObjectShape,
6
+ type Diagnostics,
7
+ } from '@servicenow/sdk-build-core'
8
+ import { getVariableTypeFromName } from './variable-helper'
9
+ import { VariableTypeName } from './variable-helper'
10
+ import { convertRolesToString, getVisibilityId } from './utils'
11
+ import {
12
+ validateMapToFieldRequiresField,
13
+ validateMandatoryReadOnlyHidden,
14
+ validateLookupSourceExclusivity,
15
+ validateReferenceQualifierExclusivity,
16
+ } from './service-catalog-diagnostics'
17
+
18
+ export async function buildVariableRecords(options: {
19
+ factory: Factory
20
+ diagnostics: Diagnostics
21
+ variablesConfig: ObjectShape
22
+ parent: Record
23
+ }): Promise<Record[]> {
24
+ const { variablesConfig, factory, parent, diagnostics } = options
25
+ const records: Record[] = []
26
+ let catItemRecord: Record
27
+ let variableSetRecord: Record
28
+ if (parent?.getTable() === 'sc_cat_item' || parent?.getTable() === 'sc_cat_item_producer') {
29
+ catItemRecord = parent
30
+ }
31
+ if (parent?.getTable() === 'item_option_new_set') {
32
+ variableSetRecord = parent
33
+ }
34
+
35
+ // Convert entries to array to use for-of loop
36
+ const entries = Array.from(variablesConfig.entries())
37
+
38
+ // Use for-of loop with await instead of forEach
39
+ for (const [k, v] of entries) {
40
+ const callExpr = v.as(CallExpressionShape)
41
+ const calleeName = callExpr.getCallee()
42
+ const variable = callExpr.getArgument(0)
43
+ if (!variable.isObject() || !variable.asObject().isDefined()) {
44
+ continue
45
+ }
46
+ const config = variable.asObject()
47
+
48
+ // Validate mapToField/field consistency (applies to all non-minimal variables)
49
+ if (
50
+ calleeName !== VariableTypeName.BREAK &&
51
+ calleeName !== VariableTypeName.CONTAINER_END &&
52
+ calleeName !== VariableTypeName.CONTAINER_SPLIT
53
+ ) {
54
+ validateMapToFieldRequiresField(config, diagnostics)
55
+ }
56
+
57
+ // Validate mandatory/readOnly/hidden consistency (applies to interactive variables)
58
+ if (
59
+ calleeName !== VariableTypeName.BREAK &&
60
+ calleeName !== VariableTypeName.CONTAINER_END &&
61
+ calleeName !== VariableTypeName.CONTAINER_SPLIT &&
62
+ calleeName !== VariableTypeName.CONTAINER_START &&
63
+ calleeName !== VariableTypeName.LABEL &&
64
+ calleeName !== VariableTypeName.RICH_TEXT_LABEL &&
65
+ calleeName !== VariableTypeName.CUSTOM &&
66
+ calleeName !== VariableTypeName.CUSTOM_WITH_LABEL &&
67
+ calleeName !== VariableTypeName.UI_PAGE
68
+ ) {
69
+ validateMandatoryReadOnlyHidden(config, diagnostics)
70
+ }
71
+
72
+ // Validate lookup source exclusivity (applies to lookup variables)
73
+ if (
74
+ calleeName === VariableTypeName.LOOKUP_SELECT_BOX ||
75
+ calleeName === VariableTypeName.LOOKUP_MULTIPLE_CHOICE
76
+ ) {
77
+ validateLookupSourceExclusivity(config, diagnostics)
78
+ }
79
+
80
+ // Validate reference qualifier exclusivity (applies to reference and requested-for variables)
81
+ if (calleeName === VariableTypeName.REFERENCE) {
82
+ validateReferenceQualifierExclusivity(config, diagnostics, 'ReferenceVariable')
83
+ }
84
+ if (calleeName === VariableTypeName.REQUESTED_FOR) {
85
+ validateReferenceQualifierExclusivity(config, diagnostics, 'RequestedForVariable')
86
+ }
87
+
88
+ const useEncryption =
89
+ calleeName === VariableTypeName.MASKED ? (config.get('useEncryption')?.getValue() ?? true) : false
90
+ const varType = getVariableTypeFromName(calleeName)
91
+
92
+ const referenceTable =
93
+ calleeName === VariableTypeName.REQUESTED_FOR ? 'sys_user' : config.get('referenceTable')?.getValue()
94
+
95
+ const useReferenceQualifier =
96
+ calleeName === VariableTypeName.LIST_COLLECTOR ||
97
+ calleeName === VariableTypeName.LOOKUP_SELECT_BOX ||
98
+ calleeName === VariableTypeName.LOOKUP_MULTIPLE_CHOICE
99
+ ? 'advanced'
100
+ : 'simple'
101
+
102
+ const props = callExpr
103
+ .getArgument(0)
104
+ .asObject()
105
+ .transform(({ $ }) => ({
106
+ name: $.val(k),
107
+ type: $.val(varType).def(6),
108
+ question_text: $.from('question').def(''),
109
+ order: $.def(0),
110
+ active: $.from('active').toBoolean().def(true),
111
+ mandatory: $.from('mandatory').toBoolean().def(false),
112
+ read_only: $.from('readOnly').toBoolean().def(false),
113
+ hidden: $.from('hidden').toBoolean().def(false),
114
+ disable_initial_slot_fill: $.from('disableInitialSlotFill').toBoolean().def(false),
115
+ conversational_label: $.from('conversationalLabel').def(''),
116
+ layout: $.from('layout').def('normal'),
117
+ tooltip: $.from('tooltip').def(''),
118
+ example_text: $.from('exampleText').def(''),
119
+ show_help: $.from('showHelp').toBoolean().def(false),
120
+ help_tag: $.from('helpTag').def('More information'),
121
+ help_text: $.from('helpText').def(''),
122
+ instructions: $.from('instructions').def('').toCdata(),
123
+ variable_width: $.from('width').def(''),
124
+ attributes: $.from('attributes').def(''),
125
+ default_value: $.from('defaultValue').def(''),
126
+ read_roles: $.from('readRoles').map(convertRolesToString).def([]),
127
+ write_roles: $.from('writeRoles').map(convertRolesToString).def([]),
128
+ create_roles: $.from('createRoles').map(convertRolesToString).def([]),
129
+ delete_roles: $.from('deleteRoles').map(convertRolesToString).def([]),
130
+ cat_item: $.val(catItemRecord).def(''),
131
+ variable_set: $.val(variableSetRecord).def(''),
132
+ reference: $.val(referenceTable).def(''),
133
+ visible_standalone: $.from('visibleStandalone').toBoolean().def(true),
134
+ visible_summary: $.from('visibleSummary').toBoolean().def(true),
135
+ visible_guide: $.from('visibleGuide').toBoolean().def(true),
136
+ visible_bundle: $.from('visibleBundle').toBoolean().def(true),
137
+ not_available_conversation: $.from('removeFromConversationalInterfaces').toBoolean().def(false),
138
+ display_title: $.from('displayTitle').toBoolean().def(false),
139
+ macro: $.from('macro').def(''),
140
+ summary_macro: $.from('summaryMacro').def(''),
141
+ sp_widget: $.from('widget').def(''),
142
+ macroponent: $.from('macroponent').def(''),
143
+ topic_block: $.from('topicBlock').def(''),
144
+ list_table: $.from('listTable').def(''),
145
+ reference_qual: $.from('referenceQual').def(''),
146
+ lookup_source: $.from('lookupSource').def(''),
147
+ lookup_table: $.from('lookupFromTable').def(''),
148
+ lookup_value: $.from('lookupValueField').def(''),
149
+ lookup_label: $.from('lookupLabelFields')
150
+ .def([])
151
+ .map((fields) => (Array.isArray(fields) ? fields.join(',') : fields))
152
+ .def(''),
153
+ lookup_price: $.from('lookupPriceField').def(''),
154
+ rec_lookup_price: $.from('lookupRecurringPriceField').def(''),
155
+ choice_table: $.from('choiceTable').def(''),
156
+ choice_field: $.from('choiceField').def(''),
157
+ lookup_dependent_question: $.from('choicesDependOn').def(''),
158
+ choice_direction: $.from('choiceDirection').def('down'),
159
+ include_none: $.from('includeNone').toBoolean().def(false),
160
+ lookup_unique: $.from('uniqueValuesOnly').toBoolean().def(false),
161
+ mask_use_confirmation: $.from('useConfirmation').toBoolean().def(false),
162
+ mask_use_encryption: $.val(useEncryption).toBoolean().def(false),
163
+ do_not_select_first: $.from('doNotSelectFirstChoice').toBoolean().def(false),
164
+ scale_min: $.from('scaleMin').def(0),
165
+ scale_max: $.from('scaleMax').def(5),
166
+ use_reference_qualifier: $.from('useReferenceQualifier').def(useReferenceQualifier),
167
+ reference_qual_condition: $.from('referenceQualCondition').def(''),
168
+ dynamic_ref_qual: $.from('dynamicRefQual').def(''),
169
+ enable_also_request_for: $.from('enableAlsoRequestFor').toBoolean().def(false),
170
+ rich_text: $.from('richText').toCdata().def(''),
171
+ validate_regex: $.from('validateRegex').def(''),
172
+ ui_page: $.from('uiPage').def(''),
173
+ default_html_value: $.from('defaultHTML').toCdata().def(''),
174
+ map_to_field: $.from('mapToField').toBoolean().def(false),
175
+ field: $.from('field').def(''),
176
+ delivery_plan: $.from('deliveryPlan').def(''),
177
+ visibility: $.from('visibility')
178
+ .map((v) => (v.isString() ? getVisibilityId(v.getValue()) : undefined))
179
+ .def(1),
180
+ roles_to_use_also_request_for: $.from('rolesToUseAlsoRequestFor').map(convertRolesToString).def([]),
181
+ category: $.from('category').def(''),
182
+ pricing_implications: $.from('pricingImplications').toBoolean().def(false),
183
+ show_help_on_load: $.from('alwaysExpand').toBoolean().def(false),
184
+ use_dynamic_default: $.from('useDynamicDefault').toBoolean().def(false),
185
+ // save_script: $.from('saveScript').toCdata().def(DEFAULT_SAVE_SCRIPT),
186
+ read_script: $.from('readScript').toCdata().def(''),
187
+ post_insert_script: $.from('postInsertScript').toCdata().def(''),
188
+ unique: $.def(false),
189
+ global: $.toBoolean().def(false),
190
+ description: $.toCdata().def(''),
191
+ dynamic_value_dot_walk_path: $.from('dotWalkPath').def(''),
192
+ dynamic_value_field: $.from('dependentQuestion').def(''),
193
+ }))
194
+
195
+ const varRecord = await factory.createRecord({
196
+ source: callExpr,
197
+ table: 'item_option_new',
198
+ properties: props,
199
+ })
200
+ const varPricingDetails = config.get('pricingDetails').ifArray()?.getElements() ?? []
201
+ const varPricingDetailsRecords: Record[] = []
202
+ for (const pricingDetail of varPricingDetails) {
203
+ const pricingDetailObj = pricingDetail.asObject()
204
+ varPricingDetailsRecords.push(
205
+ await factory.createRecord({
206
+ source: callExpr,
207
+ table: 'fx_price',
208
+ properties: {
209
+ id: varRecord.getId().getValue(),
210
+ field: pricingDetailObj.get('field').getValue(),
211
+ amount: pricingDetailObj.get('amount').getValue(),
212
+ currency: pricingDetailObj.get('currencyType').getValue(),
213
+ type: 'calculated',
214
+ table: 'item_option_new',
215
+ },
216
+ })
217
+ )
218
+ }
219
+ if (
220
+ (calleeName === VariableTypeName.MULTIPLE_CHOICE || calleeName === VariableTypeName.SELECT_BOX) &&
221
+ config.get('choices').isDefined()
222
+ ) {
223
+ const choices = config.get('choices').asObject()
224
+ const entries = Array.from(choices.entries())
225
+ const choiceRecords: Record[] = []
226
+
227
+ // Use a regular for loop instead of forEach to handle async operations
228
+ for (const [key, value] of entries) {
229
+ const choiceObj = value.asObject()
230
+ const choiceProps = choiceObj.transform(({ $ }) => ({
231
+ value: $.val(key),
232
+ text: $.from('label').def(key),
233
+ inactive: $.from('inactive').toBoolean().def(false),
234
+ order: $.from('sequence').def(0),
235
+ question: $.val(varRecord).def(''),
236
+ }))
237
+
238
+ const choiceRecord = await factory.createRecord({
239
+ source: callExpr,
240
+ table: 'question_choice',
241
+ properties: choiceProps,
242
+ })
243
+
244
+ const pricingDetails = choiceObj.get('pricingDetails').ifArray()?.getElements() ?? []
245
+ const pricingDetailsRecords: Record[] = []
246
+ for (const pricingDetail of pricingDetails) {
247
+ const pricingDetailObj = pricingDetail.asObject()
248
+ pricingDetailsRecords.push(
249
+ await factory.createRecord({
250
+ source: callExpr,
251
+ table: 'fx_price',
252
+ properties: {
253
+ id: choiceRecord.getId().getValue(),
254
+ amount: pricingDetailObj.get('amount')?.getValue(),
255
+ currency: pricingDetailObj.get('currencyType')?.getValue(),
256
+ type: 'calculated',
257
+ field: pricingDetailObj.get('field')?.getValue(),
258
+ table: 'question_choice',
259
+ },
260
+ })
261
+ )
262
+ }
263
+ choiceRecords.push(choiceRecord.with(...pricingDetailsRecords))
264
+ }
265
+
266
+ // Now that all choiceRecords are created, add them to the varRecord
267
+ records.push(varRecord.with(...choiceRecords))
268
+ } else {
269
+ records.push(varRecord)
270
+ }
271
+ records.push(...varPricingDetailsRecords)
272
+ }
273
+
274
+ return records
275
+ }