@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.
Files changed (388) hide show
  1. package/dist/acl-plugin.js +22 -4
  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/application-menu-plugin.js +1 -0
  7. package/dist/application-menu-plugin.js.map +1 -1
  8. package/dist/atf/step-configs.d.ts +13 -12
  9. package/dist/atf/step-configs.js.map +1 -1
  10. package/dist/atf/test-plugin.d.ts +1 -1
  11. package/dist/atf/test-plugin.js +13 -7
  12. package/dist/atf/test-plugin.js.map +1 -1
  13. package/dist/basic-syntax-plugin.js +58 -14
  14. package/dist/basic-syntax-plugin.js.map +1 -1
  15. package/dist/business-rule-plugin.js +1 -0
  16. package/dist/business-rule-plugin.js.map +1 -1
  17. package/dist/call-expression-plugin.js +1 -107
  18. package/dist/call-expression-plugin.js.map +1 -1
  19. package/dist/claims-plugin.js +1 -1
  20. package/dist/claims-plugin.js.map +1 -1
  21. package/dist/client-script-plugin.js +5 -17
  22. package/dist/client-script-plugin.js.map +1 -1
  23. package/dist/column/column-helper.d.ts +1 -1
  24. package/dist/column/column-helper.js +46 -2
  25. package/dist/column/column-helper.js.map +1 -1
  26. package/dist/column/column-to-record.js +6 -4
  27. package/dist/column/column-to-record.js.map +1 -1
  28. package/dist/column-plugin.js +107 -28
  29. package/dist/column-plugin.js.map +1 -1
  30. package/dist/dashboard/dashboard-component-property-defaults.d.ts +152 -0
  31. package/dist/dashboard/dashboard-component-property-defaults.js +264 -0
  32. package/dist/dashboard/dashboard-component-property-defaults.js.map +1 -0
  33. package/dist/dashboard/dashboard-component-resolver.d.ts +13 -0
  34. package/dist/dashboard/dashboard-component-resolver.js +69 -0
  35. package/dist/dashboard/dashboard-component-resolver.js.map +1 -0
  36. package/dist/dashboard/dashboard-plugin.d.ts +12 -0
  37. package/dist/dashboard/dashboard-plugin.js +397 -0
  38. package/dist/dashboard/dashboard-plugin.js.map +1 -0
  39. package/dist/data-plugin.d.ts +6 -0
  40. package/dist/data-plugin.js +156 -0
  41. package/dist/data-plugin.js.map +1 -0
  42. package/dist/email-notification-plugin.d.ts +2 -0
  43. package/dist/email-notification-plugin.js +541 -0
  44. package/dist/email-notification-plugin.js.map +1 -0
  45. package/dist/flow/constants/flow-plugin-constants.d.ts +58 -0
  46. package/dist/flow/constants/flow-plugin-constants.js +70 -0
  47. package/dist/flow/constants/flow-plugin-constants.js.map +1 -0
  48. package/dist/flow/flow-logic/flow-logic-constants.d.ts +38 -0
  49. package/dist/flow/flow-logic/flow-logic-constants.js +118 -0
  50. package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -0
  51. package/dist/flow/flow-logic/flow-logic-diagnostics.d.ts +19 -0
  52. package/dist/flow/flow-logic/flow-logic-diagnostics.js +503 -0
  53. package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -0
  54. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +62 -0
  55. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +2092 -0
  56. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -0
  57. package/dist/flow/flow-logic/flow-logic-plugin.d.ts +52 -0
  58. package/dist/flow/flow-logic/flow-logic-plugin.js +283 -0
  59. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -0
  60. package/dist/flow/flow-logic/flow-logic-shapes.d.ts +104 -0
  61. package/dist/flow/flow-logic/flow-logic-shapes.js +201 -0
  62. package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -0
  63. package/dist/flow/plugins/approval-rules-plugin.d.ts +2 -0
  64. package/dist/flow/plugins/approval-rules-plugin.js +49 -0
  65. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -0
  66. package/dist/flow/plugins/flow-action-definition-plugin.d.ts +2 -0
  67. package/dist/flow/plugins/flow-action-definition-plugin.js +286 -0
  68. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -0
  69. package/dist/flow/plugins/flow-data-pill-plugin.d.ts +9 -0
  70. package/dist/flow/plugins/flow-data-pill-plugin.js +212 -0
  71. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -0
  72. package/dist/flow/plugins/flow-definition-plugin.d.ts +2 -0
  73. package/dist/flow/plugins/flow-definition-plugin.js +1668 -0
  74. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -0
  75. package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +26 -0
  76. package/dist/flow/plugins/flow-diagnostics-plugin.js +217 -0
  77. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -0
  78. package/dist/flow/plugins/flow-instance-plugin.d.ts +12 -0
  79. package/dist/flow/plugins/flow-instance-plugin.js +930 -0
  80. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -0
  81. package/dist/flow/plugins/flow-trigger-instance-plugin.d.ts +2 -0
  82. package/dist/flow/plugins/flow-trigger-instance-plugin.js +324 -0
  83. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -0
  84. package/dist/flow/plugins/inline-script-plugin.d.ts +39 -0
  85. package/dist/flow/plugins/inline-script-plugin.js +80 -0
  86. package/dist/flow/plugins/inline-script-plugin.js.map +1 -0
  87. package/dist/flow/plugins/step-definition-plugin.d.ts +5 -0
  88. package/dist/flow/plugins/step-definition-plugin.js +71 -0
  89. package/dist/flow/plugins/step-definition-plugin.js.map +1 -0
  90. package/dist/flow/plugins/step-instance-plugin.d.ts +31 -0
  91. package/dist/flow/plugins/step-instance-plugin.js +339 -0
  92. package/dist/flow/plugins/step-instance-plugin.js.map +1 -0
  93. package/dist/flow/plugins/trigger-plugin.d.ts +2 -0
  94. package/dist/flow/plugins/trigger-plugin.js +96 -0
  95. package/dist/flow/plugins/trigger-plugin.js.map +1 -0
  96. package/dist/flow/plugins/wfa-datapill-plugin.d.ts +15 -0
  97. package/dist/flow/plugins/wfa-datapill-plugin.js +178 -0
  98. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -0
  99. package/dist/flow/utils/approval-rules-processor.d.ts +13 -0
  100. package/dist/flow/utils/approval-rules-processor.js +267 -0
  101. package/dist/flow/utils/approval-rules-processor.js.map +1 -0
  102. package/dist/flow/utils/built-in-complex-objects.d.ts +19 -0
  103. package/dist/flow/utils/built-in-complex-objects.js +62 -0
  104. package/dist/flow/utils/built-in-complex-objects.js.map +1 -0
  105. package/dist/flow/utils/complex-object-resolver.d.ts +8 -0
  106. package/dist/flow/utils/complex-object-resolver.js +614 -0
  107. package/dist/flow/utils/complex-object-resolver.js.map +1 -0
  108. package/dist/flow/utils/complex-objects.d.ts +36 -0
  109. package/dist/flow/utils/complex-objects.js +481 -0
  110. package/dist/flow/utils/complex-objects.js.map +1 -0
  111. package/dist/flow/utils/data-pill-shapes.d.ts +58 -0
  112. package/dist/flow/utils/data-pill-shapes.js +135 -0
  113. package/dist/flow/utils/data-pill-shapes.js.map +1 -0
  114. package/dist/flow/utils/datapill-transformer.d.ts +110 -0
  115. package/dist/flow/utils/datapill-transformer.js +503 -0
  116. package/dist/flow/utils/datapill-transformer.js.map +1 -0
  117. package/dist/flow/utils/flow-constants.d.ts +65 -0
  118. package/dist/flow/utils/flow-constants.js +223 -0
  119. package/dist/flow/utils/flow-constants.js.map +1 -0
  120. package/dist/flow/utils/flow-io-to-record.d.ts +44 -0
  121. package/dist/flow/utils/flow-io-to-record.js +409 -0
  122. package/dist/flow/utils/flow-io-to-record.js.map +1 -0
  123. package/dist/flow/utils/flow-shapes.d.ts +161 -0
  124. package/dist/flow/utils/flow-shapes.js +255 -0
  125. package/dist/flow/utils/flow-shapes.js.map +1 -0
  126. package/dist/flow/utils/flow-to-xml.d.ts +16 -0
  127. package/dist/flow/utils/flow-to-xml.js +237 -0
  128. package/dist/flow/utils/flow-to-xml.js.map +1 -0
  129. package/dist/flow/utils/flow-variable-processor.d.ts +51 -0
  130. package/dist/flow/utils/flow-variable-processor.js +69 -0
  131. package/dist/flow/utils/flow-variable-processor.js.map +1 -0
  132. package/dist/flow/utils/label-cache-parser.d.ts +7 -0
  133. package/dist/flow/utils/label-cache-parser.js +24 -0
  134. package/dist/flow/utils/label-cache-parser.js.map +1 -0
  135. package/dist/flow/utils/label-cache-processor.d.ts +119 -0
  136. package/dist/flow/utils/label-cache-processor.js +719 -0
  137. package/dist/flow/utils/label-cache-processor.js.map +1 -0
  138. package/dist/flow/utils/pill-string-parser.d.ts +88 -0
  139. package/dist/flow/utils/pill-string-parser.js +306 -0
  140. package/dist/flow/utils/pill-string-parser.js.map +1 -0
  141. package/dist/flow/utils/schema-to-flow-object.d.ts +22 -0
  142. package/dist/flow/utils/schema-to-flow-object.js +318 -0
  143. package/dist/flow/utils/schema-to-flow-object.js.map +1 -0
  144. package/dist/flow/utils/utils.d.ts +117 -0
  145. package/dist/flow/utils/utils.js +345 -0
  146. package/dist/flow/utils/utils.js.map +1 -0
  147. package/dist/import-sets-plugin.d.ts +2 -0
  148. package/dist/import-sets-plugin.js +412 -0
  149. package/dist/import-sets-plugin.js.map +1 -0
  150. package/dist/index.d.ts +24 -1
  151. package/dist/index.js +25 -1
  152. package/dist/index.js.map +1 -1
  153. package/dist/json-plugin.d.ts +4 -4
  154. package/dist/json-plugin.js +21 -7
  155. package/dist/json-plugin.js.map +1 -1
  156. package/dist/list-plugin.js +83 -1
  157. package/dist/list-plugin.js.map +1 -1
  158. package/dist/now-attach-plugin.d.ts +36 -0
  159. package/dist/now-attach-plugin.js +320 -0
  160. package/dist/now-attach-plugin.js.map +1 -0
  161. package/dist/now-config-plugin.js +3 -0
  162. package/dist/now-config-plugin.js.map +1 -1
  163. package/dist/now-include-plugin.js +7 -1
  164. package/dist/now-include-plugin.js.map +1 -1
  165. package/dist/package-json-plugin.js +2 -2
  166. package/dist/package-json-plugin.js.map +1 -1
  167. package/dist/record-plugin.d.ts +35 -0
  168. package/dist/record-plugin.js +109 -23
  169. package/dist/record-plugin.js.map +1 -1
  170. package/dist/repack/index.d.ts +2 -0
  171. package/dist/repack/index.js +8 -0
  172. package/dist/repack/index.js.map +1 -1
  173. package/dist/repack/lint/Rules.js.map +1 -1
  174. package/dist/rest-api-plugin.js +81 -74
  175. package/dist/rest-api-plugin.js.map +1 -1
  176. package/dist/role-plugin.js +1 -0
  177. package/dist/role-plugin.js.map +1 -1
  178. package/dist/server-module-plugin/index.js +53 -6
  179. package/dist/server-module-plugin/index.js.map +1 -1
  180. package/dist/service-catalog/catalog-clientscript-plugin.d.ts +2 -0
  181. package/dist/service-catalog/catalog-clientscript-plugin.js +117 -0
  182. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -0
  183. package/dist/service-catalog/catalog-item-plugin.d.ts +2 -0
  184. package/dist/service-catalog/catalog-item-plugin.js +115 -0
  185. package/dist/service-catalog/catalog-item-plugin.js.map +1 -0
  186. package/dist/service-catalog/catalog-ui-policy-plugin.d.ts +2 -0
  187. package/dist/service-catalog/catalog-ui-policy-plugin.js +266 -0
  188. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -0
  189. package/dist/service-catalog/index.d.ts +5 -0
  190. package/dist/service-catalog/index.js +22 -0
  191. package/dist/service-catalog/index.js.map +1 -0
  192. package/dist/service-catalog/record-to-shape.d.ts +6 -0
  193. package/dist/service-catalog/record-to-shape.js +93 -0
  194. package/dist/service-catalog/record-to-shape.js.map +1 -0
  195. package/dist/service-catalog/sc-record-producer-plugin.d.ts +2 -0
  196. package/dist/service-catalog/sc-record-producer-plugin.js +139 -0
  197. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -0
  198. package/dist/service-catalog/service-catalog-base.d.ts +311 -0
  199. package/dist/service-catalog/service-catalog-base.js +542 -0
  200. package/dist/service-catalog/service-catalog-base.js.map +1 -0
  201. package/dist/service-catalog/service-catalog-diagnostics.d.ts +45 -0
  202. package/dist/service-catalog/service-catalog-diagnostics.js +169 -0
  203. package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -0
  204. package/dist/service-catalog/shape-to-record.d.ts +7 -0
  205. package/dist/service-catalog/shape-to-record.js +232 -0
  206. package/dist/service-catalog/shape-to-record.js.map +1 -0
  207. package/dist/service-catalog/utils.d.ts +313 -0
  208. package/dist/service-catalog/utils.js +1144 -0
  209. package/dist/service-catalog/utils.js.map +1 -0
  210. package/dist/service-catalog/variable-helper.d.ts +43 -0
  211. package/dist/service-catalog/variable-helper.js +92 -0
  212. package/dist/service-catalog/variable-helper.js.map +1 -0
  213. package/dist/service-catalog/variable-set-plugin.d.ts +2 -0
  214. package/dist/service-catalog/variable-set-plugin.js +175 -0
  215. package/dist/service-catalog/variable-set-plugin.js.map +1 -0
  216. package/dist/service-catalog/variables-transform.d.ts +139 -0
  217. package/dist/service-catalog/variables-transform.js +403 -0
  218. package/dist/service-catalog/variables-transform.js.map +1 -0
  219. package/dist/service-portal/widget-plugin.js +4 -1
  220. package/dist/service-portal/widget-plugin.js.map +1 -1
  221. package/dist/sla/sla-validators.d.ts +61 -0
  222. package/dist/sla/sla-validators.js +224 -0
  223. package/dist/sla/sla-validators.js.map +1 -0
  224. package/dist/sla-plugin.d.ts +5 -0
  225. package/dist/sla-plugin.js +280 -0
  226. package/dist/sla-plugin.js.map +1 -0
  227. package/dist/static-content-plugin.d.ts +1 -0
  228. package/dist/static-content-plugin.js +4 -3
  229. package/dist/static-content-plugin.js.map +1 -1
  230. package/dist/table-plugin.js +49 -4
  231. package/dist/table-plugin.js.map +1 -1
  232. package/dist/ui-page-plugin.js +2 -1
  233. package/dist/ui-page-plugin.js.map +1 -1
  234. package/dist/ui-policy-plugin.d.ts +2 -0
  235. package/dist/ui-policy-plugin.js +405 -0
  236. package/dist/ui-policy-plugin.js.map +1 -0
  237. package/dist/utils.d.ts +19 -1
  238. package/dist/utils.js +40 -0
  239. package/dist/utils.js.map +1 -1
  240. package/dist/ux-list-menu-config-plugin.d.ts +2 -0
  241. package/dist/ux-list-menu-config-plugin.js +292 -0
  242. package/dist/ux-list-menu-config-plugin.js.map +1 -0
  243. package/dist/view-plugin.js +1 -1
  244. package/dist/view-plugin.js.map +1 -1
  245. package/dist/workspace-plugin/chrome-tab.d.ts +2 -0
  246. package/dist/workspace-plugin/chrome-tab.js +46 -0
  247. package/dist/workspace-plugin/chrome-tab.js.map +1 -0
  248. package/dist/workspace-plugin/constants.d.ts +52 -0
  249. package/dist/workspace-plugin/constants.js +56 -0
  250. package/dist/workspace-plugin/constants.js.map +1 -0
  251. package/dist/workspace-plugin/fluent-utils.d.ts +9 -0
  252. package/dist/workspace-plugin/fluent-utils.js +60 -0
  253. package/dist/workspace-plugin/fluent-utils.js.map +1 -0
  254. package/dist/workspace-plugin/page.d.ts +8 -0
  255. package/dist/workspace-plugin/page.js +108 -0
  256. package/dist/workspace-plugin/page.js.map +1 -0
  257. package/dist/workspace-plugin/screen.d.ts +1 -0
  258. package/dist/workspace-plugin/screen.js +38 -0
  259. package/dist/workspace-plugin/screen.js.map +1 -0
  260. package/dist/workspace-plugin/templates/index.d.ts +10 -0
  261. package/dist/workspace-plugin/templates/index.js +20 -0
  262. package/dist/workspace-plugin/templates/index.js.map +1 -0
  263. package/dist/workspace-plugin/templates/record-page-composition.d.ts +1 -0
  264. package/dist/workspace-plugin/templates/record-page-composition.js +4043 -0
  265. package/dist/workspace-plugin/templates/record-page-composition.js.map +1 -0
  266. package/dist/workspace-plugin/templates/record-page-data.d.ts +1 -0
  267. package/dist/workspace-plugin/templates/record-page-data.js +527 -0
  268. package/dist/workspace-plugin/templates/record-page-data.js.map +1 -0
  269. package/dist/workspace-plugin/templates/record-page-interalEventMappings.d.ts +1 -0
  270. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js +39 -0
  271. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js.map +1 -0
  272. package/dist/workspace-plugin/templates/record-page-layoutModel.d.ts +1 -0
  273. package/dist/workspace-plugin/templates/record-page-layoutModel.js +55 -0
  274. package/dist/workspace-plugin/templates/record-page-layoutModel.js.map +1 -0
  275. package/dist/workspace-plugin/templates/record-page-properties.d.ts +1 -0
  276. package/dist/workspace-plugin/templates/record-page-properties.js +135 -0
  277. package/dist/workspace-plugin/templates/record-page-properties.js.map +1 -0
  278. package/dist/workspace-plugin/templates/record-page.d.ts +3 -0
  279. package/dist/workspace-plugin/templates/record-page.js +8 -0
  280. package/dist/workspace-plugin/templates/record-page.js.map +1 -0
  281. package/dist/workspace-plugin.d.ts +2 -0
  282. package/dist/workspace-plugin.js +453 -0
  283. package/dist/workspace-plugin.js.map +1 -0
  284. package/package.json +10 -12
  285. package/src/_types/eslint-plugin-es-x.d.ts +17 -0
  286. package/src/_types/md5.js.d.ts +8 -0
  287. package/src/acl-plugin.ts +33 -10
  288. package/src/applicability-plugin.ts +82 -0
  289. package/src/application-menu-plugin.ts +1 -0
  290. package/src/atf/step-configs.ts +14 -12
  291. package/src/atf/test-plugin.ts +46 -24
  292. package/src/basic-syntax-plugin.ts +71 -14
  293. package/src/business-rule-plugin.ts +9 -5
  294. package/src/call-expression-plugin.ts +2 -130
  295. package/src/claims-plugin.ts +1 -1
  296. package/src/client-script-plugin.ts +8 -22
  297. package/src/column/column-helper.ts +65 -3
  298. package/src/column/column-to-record.ts +6 -4
  299. package/src/column-plugin.ts +142 -40
  300. package/src/dashboard/dashboard-component-property-defaults.ts +277 -0
  301. package/src/dashboard/dashboard-component-resolver.ts +69 -0
  302. package/src/dashboard/dashboard-plugin.ts +450 -0
  303. package/src/data-plugin.ts +194 -0
  304. package/src/email-notification-plugin.ts +850 -0
  305. package/src/flow/constants/flow-plugin-constants.ts +79 -0
  306. package/src/flow/flow-logic/flow-logic-constants.ts +120 -0
  307. package/src/flow/flow-logic/flow-logic-diagnostics.ts +591 -0
  308. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +2550 -0
  309. package/src/flow/flow-logic/flow-logic-plugin.ts +337 -0
  310. package/src/flow/flow-logic/flow-logic-shapes.ts +215 -0
  311. package/src/flow/plugins/approval-rules-plugin.ts +48 -0
  312. package/src/flow/plugins/flow-action-definition-plugin.ts +295 -0
  313. package/src/flow/plugins/flow-data-pill-plugin.ts +258 -0
  314. package/src/flow/plugins/flow-definition-plugin.ts +2173 -0
  315. package/src/flow/plugins/flow-diagnostics-plugin.ts +280 -0
  316. package/src/flow/plugins/flow-instance-plugin.ts +1148 -0
  317. package/src/flow/plugins/flow-trigger-instance-plugin.ts +426 -0
  318. package/src/flow/plugins/inline-script-plugin.ts +83 -0
  319. package/src/flow/plugins/step-definition-plugin.ts +67 -0
  320. package/src/flow/plugins/step-instance-plugin.ts +431 -0
  321. package/src/flow/plugins/trigger-plugin.ts +95 -0
  322. package/src/flow/plugins/wfa-datapill-plugin.ts +213 -0
  323. package/src/flow/utils/approval-rules-processor.ts +298 -0
  324. package/src/flow/utils/built-in-complex-objects.ts +81 -0
  325. package/src/flow/utils/complex-object-resolver.ts +875 -0
  326. package/src/flow/utils/complex-objects.ts +656 -0
  327. package/src/flow/utils/data-pill-shapes.ts +165 -0
  328. package/src/flow/utils/datapill-transformer.ts +632 -0
  329. package/src/flow/utils/flow-constants.ts +276 -0
  330. package/src/flow/utils/flow-io-to-record.ts +533 -0
  331. package/src/flow/utils/flow-shapes.ts +296 -0
  332. package/src/flow/utils/flow-to-xml.ts +318 -0
  333. package/src/flow/utils/flow-variable-processor.ts +100 -0
  334. package/src/flow/utils/label-cache-parser.ts +37 -0
  335. package/src/flow/utils/label-cache-processor.ts +870 -0
  336. package/src/flow/utils/pill-string-parser.ts +375 -0
  337. package/src/flow/utils/schema-to-flow-object.ts +385 -0
  338. package/src/flow/utils/utils.ts +395 -0
  339. package/src/import-sets-plugin.ts +542 -0
  340. package/src/index.ts +25 -1
  341. package/src/json-plugin.ts +31 -12
  342. package/src/list-plugin.ts +91 -1
  343. package/src/now-attach-plugin.ts +403 -0
  344. package/src/now-config-plugin.ts +6 -2
  345. package/src/now-include-plugin.ts +8 -1
  346. package/src/package-json-plugin.ts +3 -3
  347. package/src/record-plugin.ts +126 -30
  348. package/src/repack/index.ts +14 -0
  349. package/src/repack/lint/Rules.ts +1 -10
  350. package/src/rest-api-plugin.ts +106 -100
  351. package/src/role-plugin.ts +1 -0
  352. package/src/server-module-plugin/index.ts +74 -22
  353. package/src/service-catalog/catalog-clientscript-plugin.ts +140 -0
  354. package/src/service-catalog/catalog-item-plugin.ts +162 -0
  355. package/src/service-catalog/catalog-ui-policy-plugin.ts +324 -0
  356. package/src/service-catalog/index.ts +5 -0
  357. package/src/service-catalog/record-to-shape.ts +109 -0
  358. package/src/service-catalog/sc-record-producer-plugin.ts +201 -0
  359. package/src/service-catalog/service-catalog-base.ts +600 -0
  360. package/src/service-catalog/service-catalog-diagnostics.ts +251 -0
  361. package/src/service-catalog/shape-to-record.ts +275 -0
  362. package/src/service-catalog/utils.ts +1362 -0
  363. package/src/service-catalog/variable-helper.ts +135 -0
  364. package/src/service-catalog/variable-set-plugin.ts +197 -0
  365. package/src/service-catalog/variables-transform.ts +438 -0
  366. package/src/service-portal/widget-plugin.ts +4 -1
  367. package/src/sla/sla-validators.ts +331 -0
  368. package/src/sla-plugin.ts +358 -0
  369. package/src/static-content-plugin.ts +2 -2
  370. package/src/table-plugin.ts +66 -9
  371. package/src/ui-page-plugin.ts +2 -1
  372. package/src/ui-policy-plugin.ts +505 -0
  373. package/src/utils.ts +50 -1
  374. package/src/ux-list-menu-config-plugin.ts +312 -0
  375. package/src/view-plugin.ts +1 -1
  376. package/src/workspace-plugin/chrome-tab.ts +44 -0
  377. package/src/workspace-plugin/constants.ts +53 -0
  378. package/src/workspace-plugin/fluent-utils.ts +60 -0
  379. package/src/workspace-plugin/page.ts +139 -0
  380. package/src/workspace-plugin/screen.ts +34 -0
  381. package/src/workspace-plugin/templates/index.ts +17 -0
  382. package/src/workspace-plugin/templates/record-page-composition.ts +4051 -0
  383. package/src/workspace-plugin/templates/record-page-data.ts +523 -0
  384. package/src/workspace-plugin/templates/record-page-interalEventMappings.ts +35 -0
  385. package/src/workspace-plugin/templates/record-page-layoutModel.ts +51 -0
  386. package/src/workspace-plugin/templates/record-page-properties.ts +131 -0
  387. package/src/workspace-plugin/templates/record-page.ts +6 -0
  388. package/src/workspace-plugin.ts +574 -0
@@ -0,0 +1,1148 @@
1
+ import {
2
+ CallExpressionShape,
3
+ DurationShape,
4
+ type Factory,
5
+ IdentifierShape,
6
+ type Logger,
7
+ ObjectShape,
8
+ Plugin,
9
+ PropertyAccessShape,
10
+ Record,
11
+ type RecordContext,
12
+ type Result,
13
+ Shape,
14
+ type Source,
15
+ StringShape,
16
+ TemplateExpressionShape,
17
+ TemplateValueShape,
18
+ TimeShape,
19
+ type Transform,
20
+ ts,
21
+ VariableStatementShape,
22
+ } from '@servicenow/sdk-build-core'
23
+ import { NowIdShape } from '../../now-id-plugin'
24
+ import { gunzipSync } from 'node:zlib'
25
+ import { resolveComplexInput as _resolveComplexInput } from '../utils/complex-object-resolver'
26
+ import {
27
+ getCoreActionIdentifier,
28
+ getDirectVariableIdentifier,
29
+ getIdentifierFromShape,
30
+ resolveDataPillShape,
31
+ sysIdToUuid,
32
+ } from '../utils/utils'
33
+ import { getAttributeValue } from '../utils/schema-to-flow-object'
34
+ import {
35
+ ActionSubflowInstanceShape,
36
+ ApprovalRulesShape,
37
+ ApprovalDueDateShape,
38
+ InlineScriptShape,
39
+ } from '../utils/flow-shapes'
40
+ import { FDInlineScriptCallShape } from './inline-script-plugin'
41
+
42
+ import {
43
+ ACTION_DEF_COLUMN_NAME,
44
+ ACTION_INSTANCE_API_NAME,
45
+ APPROVAL_RULES_DATA_TYPE_VALUE,
46
+ APPROVAL_DUE_DATE_DATA_TYPE_VALUE,
47
+ DURATION_DATA_TYPE_VALUE,
48
+ SUBFLOW_INSTANCE_API_NAME,
49
+ TEMPLATE_DATA_TYPE_VALUE,
50
+ TIME_DATA_TYPE_VALUE,
51
+ UNSUPPORTED_DATA_TYPES,
52
+ UTC_TIMEZONE_VALUE,
53
+ APPROVAL_DUE_DATE_INPUT_FIELD_ACTIONS,
54
+ ACTION_TYPE_KEY_NAME,
55
+ } from '../utils/flow-constants'
56
+ import type { ApprovalDueDateType, ApprovalRulesType } from '@servicenow/sdk-core/runtime/flow'
57
+ import type { Duration } from '@servicenow/sdk-core/runtime/db'
58
+
59
+ /**
60
+ * Helper function to check if a field is hidden based on visible or visible_in_fd attributes
61
+ * @param attributes The attributes string from the field definition
62
+ * @returns true if the field has visible='false' or visible_in_fd='false'
63
+ */
64
+ function isHiddenField(attributes: string | undefined): boolean {
65
+ if (!attributes) {
66
+ return false
67
+ }
68
+ const visibleAttr = getAttributeValue(attributes, 'visible')
69
+ const visibleInFdAttr = getAttributeValue(attributes, 'visible_in_fd')
70
+ return visibleAttr === 'false' || visibleInFdAttr === 'false'
71
+ }
72
+
73
+ /**
74
+ * Parses a complex object format where values are nested under $cv.$v
75
+ * @param obj The complex object to parse
76
+ * @returns A simplified object with direct values
77
+ */
78
+ function parseComplexObjectValues(obj: unknown): unknown {
79
+ /**
80
+ * Recursively parse a value that may contain Flow Designer complex-object wrappers.
81
+ * Handles:
82
+ * • Primitive values – returned as-is
83
+ * • Objects with `$cv` – unwrap to `$cv.$v`
84
+ * • Objects with `$COCollectionField` – treat as an array and recurse
85
+ * • Arrays – recurse over each element
86
+ * • Plain objects – recurse over each property
87
+ */
88
+ const parseValue = (val: unknown): unknown => {
89
+ if (val === null || val === undefined) {
90
+ return val
91
+ }
92
+
93
+ // Arrays – recurse element-wise
94
+ if (Array.isArray(val)) {
95
+ return val.map(parseValue)
96
+ }
97
+
98
+ // Objects
99
+ if (typeof val === 'object') {
100
+ const obj = val as globalThis.Record<string, unknown>
101
+ // Direct complex-value wrapper
102
+ if ('$cv' in obj) {
103
+ const cv = obj['$cv'] as globalThis.Record<string, unknown> | undefined
104
+ return parseValue(cv?.['$v'])
105
+ }
106
+
107
+ // Flow Designer collection array wrapper
108
+ if ('$COCollectionField' in obj) {
109
+ return parseValue(obj['$COCollectionField'])
110
+ }
111
+
112
+ // Plain object – recurse on each property
113
+ const out: { [k: string]: unknown } = {}
114
+ for (const [k, v] of Object.entries(val)) {
115
+ out[k] = parseValue(v)
116
+ }
117
+ return out
118
+ }
119
+
120
+ // Primitive
121
+ return val
122
+ }
123
+
124
+ return parseValue(obj)
125
+ }
126
+
127
+ /**
128
+ * Normalize raw input value based on uiType.
129
+ * - Attempts to JSON.parse strings.
130
+ * - Resolves FlowDesigner complexObject structures via parseComplexObjectValues.
131
+ * - For array uiTypes, ensures the result is an array (falling back to raw).
132
+ * - For glide_time, parses the time string and returns a TimeShape object.
133
+ * - For glide_duration, parses the duration string and returns a DurationShape object.
134
+ * - For template_value, parses the time string and returns a TemplateValueShape object.
135
+ */
136
+ export function normalizeInputValue(value: string, uiType?: string, source?: Source, logger?: Logger): unknown {
137
+ // Handle glide_time type specially - parse the time string and return TimeShape
138
+ if (source) {
139
+ try {
140
+ if (uiType === TIME_DATA_TYPE_VALUE) {
141
+ // Create a StringShape from the value and use TimeShape.from() to parse it.
142
+ // Uses UTC timezone value to show in fluent flow to be in sync with Flow designer UI
143
+ return TimeShape.from(source, Shape.from(source, value).asString(), UTC_TIMEZONE_VALUE)
144
+ } else if (uiType === DURATION_DATA_TYPE_VALUE) {
145
+ // Create a StringShape from the value and use DurationShape.from() to parse it
146
+ return DurationShape.from(source, Shape.from(source, value).asString())
147
+ } else if (uiType === TEMPLATE_DATA_TYPE_VALUE) {
148
+ // Create a StringShape from the value and use TemplateValueShape.from() to parse it
149
+ return TemplateValueShape.from(source, Shape.from(source, value).asString())
150
+ } else if (uiType === APPROVAL_RULES_DATA_TYPE_VALUE) {
151
+ // Create a StringShape from the value and use ApprovalRulesShape.from() to parse it
152
+ return ApprovalRulesShape.from(source, Shape.from(source, value).asString())
153
+ } else if (uiType === APPROVAL_DUE_DATE_DATA_TYPE_VALUE) {
154
+ // Check if source is a Record before accessing action_type
155
+ if (source instanceof Record) {
156
+ const actionType = source.get(ACTION_TYPE_KEY_NAME)?.ifDefined()?.asString()?.getValue()
157
+ if (APPROVAL_DUE_DATE_INPUT_FIELD_ACTIONS.includes(actionType as string)) {
158
+ // Create a StringShape from the value and use ApprovalDueDateShape.from() to parse it
159
+ return ApprovalDueDateShape.from(source, Shape.from(source, value).asString())
160
+ }
161
+ }
162
+ }
163
+ } catch (e) {
164
+ // If parsing fails, fall through to normal handling
165
+ logger?.error(
166
+ `Failed to parse value ${value} for ${uiType} in record ${source}: ${e instanceof Error ? e.message : e}`
167
+ )
168
+ return value
169
+ }
170
+ }
171
+
172
+ let parsed: unknown = value
173
+ try {
174
+ if (uiType !== 'string') {
175
+ parsed = JSON.parse(value)
176
+ }
177
+ } catch {
178
+ // handle internal string types
179
+ if (uiType === 'glide_list') {
180
+ // comma separated sys_ids – return [] if empty
181
+ return value && value.trim() !== '' ? value.split(',') : []
182
+ }
183
+ return value // any string literal value (other than a valid stringified JSON)
184
+ }
185
+
186
+ if (parsed && typeof parsed === 'object' && 'complexObject' in parsed) {
187
+ return parseComplexObjectValues(parsed.complexObject)
188
+ }
189
+
190
+ if (uiType?.startsWith('array')) {
191
+ return Array.isArray(parsed) ? parsed : value
192
+ }
193
+
194
+ /**
195
+ * Handle internal non-string types for primitive data types
196
+ * Ex. Instances store boolean values as '1' or '0' instead of true or false. But we show it as true/false in UI/fluent
197
+ */
198
+ if (uiType === 'boolean') {
199
+ parsed = Boolean(parsed) // 1 or true = true, 0 or false = false
200
+ }
201
+
202
+ return parsed
203
+ }
204
+
205
+ function buildInstanceToShape({
206
+ defColumn, // e.g. "action_type" | "subflow"
207
+ inputsTableName, // e.g. "sys_hub_action_input" | "sys_hub_flow_input"
208
+ zippedColumn, // e.g. "values" | "subflow_inputs"
209
+ callee, // "wfa.action" | "wfa.subflow"
210
+ }: {
211
+ defColumn: string
212
+ inputsTableName: string
213
+ zippedColumn: string
214
+ callee: typeof ACTION_INSTANCE_API_NAME | typeof SUBFLOW_INSTANCE_API_NAME
215
+ }) {
216
+ return function toShape(record: Record, { database, logger }: RecordContext): Result<Shape> {
217
+ // Resolve the instance definition - either from the source shape or from the database record
218
+ const source = record.getSource()
219
+ const instanceDef =
220
+ source instanceof ActionSubflowInstanceShape
221
+ ? source.getInstanceDefinition()
222
+ : record.get(defColumn)?.ifDefined()?.asString()
223
+
224
+ const definitionInputs =
225
+ instanceDef instanceof Record
226
+ ? instanceDef.flat().filter((v) => v.getTable() === inputsTableName)
227
+ : undefined
228
+
229
+ const zippedInputs = record.get(zippedColumn)?.ifString()?.getValue() ?? ''
230
+
231
+ // ── Identifier discovery ────────────────────────────────────────────────
232
+ let identifierShapeOrSysId: Shape | undefined = instanceDef
233
+ if (instanceDef instanceof Record) {
234
+ // check for core actions in existing fluent code, if so below condition will keep the existing identifier.
235
+ // Otherwise action.core.log will be replaced with the log.
236
+ const sysId = instanceDef.getId().getValue()
237
+ const coreActionIdentifier = getCoreActionIdentifier(sysId)
238
+ if (coreActionIdentifier) {
239
+ identifierShapeOrSysId = new IdentifierShape({
240
+ source: record,
241
+ name: coreActionIdentifier,
242
+ })
243
+ } else {
244
+ const original = instanceDef.getOriginalSource()
245
+ if (ts.Node.isNode(original)) {
246
+ const varDecl = original.getFirstAncestorByKind(ts.SyntaxKind.VariableDeclaration)
247
+ const idNode = varDecl?.getNameNode()
248
+ if (idNode) {
249
+ identifierShapeOrSysId = new IdentifierShape({
250
+ source: idNode,
251
+ name: idNode.getText(),
252
+ })
253
+ }
254
+ }
255
+ }
256
+ } else {
257
+ // When definition is not a Record, try to resolve from database by sys_id
258
+ if (defColumn === ACTION_DEF_COLUMN_NAME) {
259
+ const sysId = instanceDef?.ifString()?.getValue()
260
+ if (!sysId) {
261
+ return { success: false }
262
+ }
263
+
264
+ const coreActionIdentifier = getCoreActionIdentifier(sysId)
265
+ if (callee === ACTION_INSTANCE_API_NAME && !coreActionIdentifier) {
266
+ logger.warn(`Custom actions are not supported, action = ${sysId}`)
267
+ return { success: false }
268
+ }
269
+
270
+ const action = database
271
+ .query('sys_hub_action_type_definition')
272
+ .find((v) => v.getId().getValue() === sysId)
273
+
274
+ const actionSource = action?.getSource()
275
+ if (actionSource instanceof CallExpressionShape) {
276
+ const identifierName = getIdentifierFromShape(actionSource)
277
+ if (identifierName) {
278
+ identifierShapeOrSysId = new IdentifierShape({
279
+ source: actionSource.getOriginalSource(),
280
+ name: identifierName,
281
+ })
282
+ }
283
+ } else if (coreActionIdentifier) {
284
+ //Special case handling for core actions
285
+ identifierShapeOrSysId = new IdentifierShape({ source: record, name: coreActionIdentifier })
286
+ }
287
+ } else if (defColumn === 'subflow') {
288
+ const sysId = instanceDef?.getValue()
289
+ const subflow = database.query('sys_hub_flow').find((v) => v.getId().getValue() === sysId)
290
+
291
+ const actionSource = subflow?.getSource()
292
+ if (actionSource instanceof CallExpressionShape) {
293
+ const identifierName = getIdentifierFromShape(actionSource)
294
+ if (identifierName) {
295
+ identifierShapeOrSysId = new IdentifierShape({
296
+ source: actionSource.getOriginalSource(),
297
+ name: identifierName,
298
+ })
299
+ }
300
+ }
301
+ }
302
+ }
303
+
304
+ let inputsShape = buildInputsShapeFromZipped({
305
+ zippedInputs,
306
+ definitionInputs,
307
+ record,
308
+ logger,
309
+ })
310
+ if (inputsShape === undefined) {
311
+ return { success: false as const }
312
+ }
313
+ const waitForCompletion =
314
+ record.get('wait_for_completion')?.getValue() === true ||
315
+ record.get('wait_for_completion')?.getValue() === 'true'
316
+ if (waitForCompletion) {
317
+ inputsShape = inputsShape
318
+ ? inputsShape.merge({ waitForCompletion })
319
+ : Shape.from(record, { waitForCompletion }).asObject()
320
+ }
321
+
322
+ const configArg = new ObjectShape({
323
+ source: record,
324
+ properties: record.transform(({ $ }) => ({
325
+ $id: $.val(NowIdShape.from(record)),
326
+ annotation: $.from('comment').def(''),
327
+ uuid: $.from('ui_id').def(''),
328
+ })),
329
+ })
330
+
331
+ // Create the CallExpressionShape for the action/subflow instance
332
+ const callExpression = new CallExpressionShape({
333
+ source: record,
334
+ callee,
335
+ args: [identifierShapeOrSysId, configArg, inputsShape],
336
+ })
337
+
338
+ // Generate variable name from existing source or fallback to callee + ID
339
+ const order = record.get('order')?.getValue()
340
+ let identifierPrefix = ''
341
+ if (callee.toLowerCase() === ACTION_INSTANCE_API_NAME) {
342
+ identifierPrefix = 'action'
343
+ } else if (callee.toLowerCase() === SUBFLOW_INSTANCE_API_NAME) {
344
+ identifierPrefix = 'subflow'
345
+ }
346
+ // Use getDirectVariableIdentifier to only check direct parent VariableDeclaration
347
+ // This prevents actions inside Subflows from inheriting the parent Subflow's variable name
348
+ const variableName =
349
+ getDirectVariableIdentifier(record.getOriginalSource()) ?? `${identifierPrefix}Instance_${order}` // _${instanceId.slice(0, 8)}`
350
+
351
+ // Wrap in VariableStatementShape with isExported: false
352
+ return {
353
+ success: true,
354
+ value: new VariableStatementShape({
355
+ source: record,
356
+ variableName,
357
+ initializer: callExpression,
358
+ isExported: false,
359
+ }),
360
+ }
361
+ }
362
+ }
363
+
364
+ export const FlowInstancePlugin = Plugin.create({
365
+ name: 'FlowInstancePlugin',
366
+ records: {
367
+ sys_hub_action_instance_v2: {
368
+ toShape: buildInstanceToShape({
369
+ defColumn: ACTION_DEF_COLUMN_NAME,
370
+ inputsTableName: 'sys_hub_action_input',
371
+ zippedColumn: 'values',
372
+ callee: ACTION_INSTANCE_API_NAME,
373
+ }),
374
+ },
375
+ sys_hub_sub_flow_instance_v2: {
376
+ toShape: buildInstanceToShape({
377
+ defColumn: 'subflow',
378
+ inputsTableName: 'sys_hub_flow_input',
379
+ zippedColumn: 'subflow_inputs',
380
+ callee: SUBFLOW_INSTANCE_API_NAME,
381
+ }),
382
+ },
383
+ },
384
+ shapes: [
385
+ {
386
+ // Look for FDInstanceShape and return instance records as needed for Flow plugin
387
+ shape: ActionSubflowInstanceShape,
388
+ fileTypes: ['fluent'],
389
+ async toRecord(callExpression, { factory, transform, diagnostics, logger }) {
390
+ const instanceType = callExpression.getInstanceType()
391
+
392
+ // Shortcut for unsupported instance types
393
+ if (instanceType !== ACTION_INSTANCE_API_NAME && instanceType !== SUBFLOW_INSTANCE_API_NAME) {
394
+ return { success: false }
395
+ }
396
+
397
+ const instanceParentDef = callExpression.getInstanceDefinition()
398
+ const instanceSysId = callExpression.getSysId()
399
+ const instanceInputs = callExpression.getInstanceProps()
400
+ const instanceAnnotation = callExpression.getAnnotation()?.getValue()
401
+ const instanceUUID = callExpression.getInstanceUUID()?.getValue()
402
+
403
+ if (!instanceInputs || !instanceSysId || !instanceParentDef) {
404
+ diagnostics.error(
405
+ callExpression,
406
+ `Failed to extract inputs, sysId, or definition from ${instanceType}`
407
+ )
408
+ return { success: false }
409
+ }
410
+
411
+ let instanceRecord: Record | undefined
412
+
413
+ if (instanceType === ACTION_INSTANCE_API_NAME) {
414
+ instanceRecord = await buildActionInstance({
415
+ actionDef: instanceParentDef,
416
+ inputs: instanceInputs,
417
+ sysId: instanceSysId,
418
+ annotation: instanceAnnotation,
419
+ uuid: instanceUUID,
420
+ factory,
421
+ source: callExpression,
422
+ transform,
423
+ logger,
424
+ })
425
+ } else if (instanceType === SUBFLOW_INSTANCE_API_NAME) {
426
+ instanceRecord = await buildSubflowInstance({
427
+ subflowDef: instanceParentDef,
428
+ inputs: instanceInputs,
429
+ sysId: instanceSysId,
430
+ annotation: instanceAnnotation,
431
+ uuid: instanceUUID,
432
+ factory,
433
+ source: callExpression,
434
+ transform,
435
+ })
436
+ }
437
+
438
+ return instanceRecord ? { success: true, value: instanceRecord } : { success: false }
439
+ },
440
+ },
441
+ ],
442
+ })
443
+
444
+ // -------------------------
445
+ // Shared helpers
446
+ // -------------------------
447
+
448
+ /**
449
+ * Builds an FDInlineScriptCallShape from XML inline script data.
450
+ *
451
+ * **Inline Script Detection:**
452
+ * Detects inputs with `scriptActive: true` and extracts the script content from
453
+ * the `script[fieldName].script` property. Creates an FDInlineScriptCallShape that represents
454
+ * `wfa.inlineScript('script content')` in Fluent code.
455
+ *
456
+ * @param fieldName - The name of the input field
457
+ * @param scriptActive - Whether this field contains an active script
458
+ * @param script - The script object containing script content keyed by field name
459
+ * @param source - The source Record for creating the shape
460
+ * @returns FDInlineScriptCallShape if this is an inline script, undefined otherwise
461
+ */
462
+ function buildInlineScriptShapeFromXml(
463
+ fieldName: string,
464
+ scriptActive: boolean | undefined,
465
+ script: { [key: string]: { scriptActive: boolean; script: string } } | undefined,
466
+ source: Record
467
+ ): FDInlineScriptCallShape | undefined {
468
+ if (scriptActive === true && script && script[fieldName]?.script) {
469
+ const scriptContent = script[fieldName].script
470
+
471
+ return new FDInlineScriptCallShape({
472
+ source,
473
+ scriptContent,
474
+ })
475
+ }
476
+
477
+ return undefined
478
+ }
479
+
480
+ /**
481
+ * Build an ObjectShape representing instance inputs from a base64-zipped JSON payload.
482
+ * This is used by both subflow and action instances.
483
+ * Supports bi-directional conversion for inline scripts (XML ↔ Fluent).
484
+ */
485
+ function buildInputsShapeFromZipped({
486
+ zippedInputs,
487
+ definitionInputs,
488
+ record,
489
+ logger,
490
+ }: {
491
+ zippedInputs: string
492
+ definitionInputs: Record[] | undefined
493
+ record: Record
494
+ logger: Logger
495
+ }): ObjectShape | undefined {
496
+ if (!zippedInputs) {
497
+ return undefined
498
+ }
499
+
500
+ const props: { [key: string]: unknown } = {}
501
+
502
+ try {
503
+ const unzipped = gunzipSync(Buffer.from(zippedInputs, 'base64')).toString()
504
+ const values: Array<{
505
+ name: string
506
+ value: unknown
507
+ scriptActive?: boolean
508
+ script?: { [key: string]: { scriptActive: boolean; script: string } }
509
+ parameter: { type: string; attributes: { [key: string]: unknown } }
510
+ }> = JSON.parse(unzipped)
511
+
512
+ for (const { name, value, scriptActive, script, parameter } of values) {
513
+ const attributes = definitionInputs
514
+ ?.find((v) => v.get('element').asString()?.getValue() === name)
515
+ ?.get('attributes')
516
+ ?.ifString()
517
+ ?.getValue()
518
+ const uiType = attributes ? getAttributeValue(attributes, 'uiType') : undefined
519
+ // Skip hidden fields during transformation
520
+ // Convert parameter.attributes object to string format (key=value,key=value)
521
+ const paramAttributesStr = parameter?.attributes
522
+ ? Object.entries(parameter.attributes)
523
+ .map(([key, value]) => `${key}=${value}`)
524
+ .join(',')
525
+ : undefined
526
+ if (isHiddenField(attributes) || isHiddenField(paramAttributesStr)) {
527
+ continue
528
+ }
529
+
530
+ try {
531
+ if (UNSUPPORTED_DATA_TYPES.includes(parameter?.type)) {
532
+ logger.warn(`input ${name} has unsupported data type ${parameter?.type}`)
533
+ return undefined
534
+ }
535
+
536
+ // Check if this is an inline script and convert to wfa.inlineScript() format
537
+ const inlineScriptShape = buildInlineScriptShapeFromXml(name, scriptActive, script, record)
538
+
539
+ if (inlineScriptShape) {
540
+ props[name] = inlineScriptShape
541
+ } else {
542
+ // Use displayValue for proper type conversion (e.g., boolean: '1' → true)
543
+ props[name] = normalizeInputValue(value as string, uiType ?? parameter.type, record, logger)
544
+ }
545
+ } catch (e) {
546
+ const recordInfo = `${record.getTable()}.${record.getId().getValue()}`
547
+ logger.warn(
548
+ `Failed to parse value for ${name} in record ${recordInfo}: ${e instanceof Error ? e.message : e}`
549
+ )
550
+ props[name] = value
551
+ }
552
+ }
553
+
554
+ return new ObjectShape({ source: record, properties: props })
555
+ } catch (error) {
556
+ logger.error(`Malformed/unsupported input payload in subflow_inputs: ${error}`)
557
+ return undefined
558
+ }
559
+ }
560
+
561
+ // -------------------------
562
+ // Helper builders
563
+ // -------------------------
564
+
565
+ async function buildActionInstance({
566
+ actionDef,
567
+ inputs,
568
+ sysId,
569
+ annotation,
570
+ uuid,
571
+ factory,
572
+ source,
573
+ transform,
574
+ logger,
575
+ }: {
576
+ actionDef: Record | StringShape | undefined
577
+ inputs: ObjectShape
578
+ sysId: NowIdShape
579
+ annotation: string | undefined
580
+ uuid: string | undefined
581
+ factory: Factory
582
+ source: Source
583
+ transform: Transform
584
+ logger: Logger
585
+ }): Promise<Record | undefined> {
586
+ const values = actionDef ? await prepareActionInstanceValueJson(inputs, actionDef, transform, logger) : undefined
587
+ const actionDefRecord = actionDef instanceof Record ? actionDef : undefined
588
+ const instanceProps = inputs.transform(({ $ }) => ({
589
+ active: $.val(true),
590
+ // if actionDef is not a Record (sysId fallback cases), actionDef?.getValue() should get get the string value (sysId) as is
591
+ action_type: $.val(actionDefRecord?.getId()?.getValue() || actionDef?.getValue() || ''),
592
+ action_type_parent: $.val(actionDefRecord?.getId()?.getValue() || actionDef?.getValue() || ''),
593
+ comment: $.val(annotation || actionDefRecord?.get('comment')?.getValue() || ''),
594
+ display_text: $.val(''),
595
+ generation_source: $.val(''),
596
+ sys_class_name: $.val('sys_hub_action_instance_v2'),
597
+ updation_source: $.val(''),
598
+ values: $.val(values),
599
+ parent_ui_id: $.val(''),
600
+ }))
601
+
602
+ if (!instanceProps) {
603
+ return undefined
604
+ }
605
+ const record = await factory.createRecord({
606
+ source,
607
+ explicitId: sysId,
608
+ table: 'sys_hub_action_instance_v2',
609
+ properties: instanceProps,
610
+ })
611
+
612
+ // UUID can come from either instance uuid property (for fd ui authored actions) or generated from sysid (for fluent authored actions).
613
+ const instanceUUID = uuid ? uuid : sysIdToUuid(record.getId().getValue())
614
+ return record.merge({ ui_id: instanceUUID })
615
+ }
616
+
617
+ async function buildSubflowInstance({
618
+ subflowDef,
619
+ inputs,
620
+ sysId,
621
+ annotation,
622
+ factory,
623
+ uuid,
624
+ source,
625
+ transform,
626
+ }: {
627
+ subflowDef: Record | StringShape | undefined
628
+ inputs: ObjectShape
629
+ sysId: NowIdShape
630
+ annotation: string | undefined
631
+ factory: Factory
632
+ uuid: string | undefined
633
+ source: Source
634
+ transform: Transform
635
+ }): Promise<Record | undefined> {
636
+ const values = subflowDef ? await prepareSubflowInstanceValueJson(inputs, subflowDef, transform) : undefined
637
+
638
+ const subflowDefRecord = subflowDef instanceof Record ? subflowDef : undefined
639
+ const instanceProps = inputs.transform(({ $ }) => ({
640
+ order: $.val(1 as number),
641
+ flow: $.val(''),
642
+ attributes: $.val(''),
643
+ comment: $.val(annotation || subflowDefRecord?.get('comment')?.getValue() || ''),
644
+ display_text: $.val(''),
645
+ generation_source: $.val(''),
646
+ subflow: $.val(subflowDefRecord?.getId()?.getValue() || subflowDef?.getValue() || ''),
647
+ subflow_inputs: $.val(values),
648
+ wait_for_completion: $.from('waitForCompletion').def(false),
649
+ sys_class_name: $.val('sys_hub_sub_flow_instance_v2'),
650
+ parent_ui_id: $.def(''),
651
+ }))
652
+
653
+ if (!instanceProps) {
654
+ return undefined
655
+ }
656
+ const record = await factory.createRecord({
657
+ source,
658
+ explicitId: sysId,
659
+ table: 'sys_hub_sub_flow_instance_v2',
660
+ properties: instanceProps,
661
+ })
662
+
663
+ // UUID can come from either instance uuid property (for fd ui authored subflows) or generated from sysid (for fluent authored subflows).
664
+ const instanceUUID = uuid ? uuid : sysIdToUuid(record.getId().getValue())
665
+ return record.merge({ ui_id: instanceUUID })
666
+ }
667
+
668
+ /**
669
+ * Checks for inline script patterns in the input properties and resolves them
670
+ * to their appropriate format (either script format or primitive value).
671
+ *
672
+ * Supports inline scripts via wfa.inlineScript('script') (detected as CallExpressionShape/FDInlineScriptCallShape).
673
+ *
674
+ * Architecture note:
675
+ * This function detects inline scripts based on context - only template literals and Now.include()
676
+ * calls used as Action/Subflow inputs are treated as inline scripts. This avoids incorrectly
677
+ * converting template literals used elsewhere in the codebase (logging, formatting, etc.).
678
+ *
679
+ * Similar to data pills processing, this function:
680
+ * - Uses .entries({ resolve: false }) to preserve shape types
681
+ * - Checks if each shape is a TemplateExpressionShape or Now.include() call
682
+ * - Returns special serialization format for inline scripts
683
+ * - Falls back to regular getValue() for non-script shapes
684
+ *
685
+ * @param instanceInputs - The ObjectShape containing input properties
686
+ * @param transform - Transform context for shape conversion
687
+ * @returns Array of [name, value] tuples where inline scripts are serialized appropriately
688
+ */
689
+ async function checkAndResolveInlineScripts(
690
+ instanceInputs: ObjectShape,
691
+ _transform: Transform
692
+ ): Promise<Array<[string, unknown]>> {
693
+ const entries = instanceInputs.entries({ resolve: false })
694
+ const results: [string, unknown][] = []
695
+
696
+ for (const [key, shape] of entries) {
697
+ // Handle wfa.inlineScript() calls - they should already be FDInlineScriptCallShape after plugin processing
698
+ if (shape instanceof FDInlineScriptCallShape) {
699
+ const scriptContent = shape.getValue()
700
+ if (typeof scriptContent === 'string') {
701
+ // Wrap the script content in a TemplateExpressionShape
702
+ const templateShape = new TemplateExpressionShape({
703
+ source: shape,
704
+ literalText: scriptContent,
705
+ })
706
+ // Create InlineScriptShape for Flow Designer serialization
707
+ const inlineScript = new InlineScriptShape({
708
+ source: templateShape,
709
+ scriptContent,
710
+ })
711
+ const scriptValue = inlineScript.toFlowDesignerJson(key)
712
+ results.push([key, scriptValue])
713
+ }
714
+ }
715
+ }
716
+
717
+ return results
718
+ }
719
+
720
+ /**
721
+ * Resolves complex object input values for subflow/action instance preparation.
722
+ * @param name - Input field name
723
+ * @param value - Raw input value
724
+ * @param parentDef - Record containing input and complex object definitions
725
+ * @param inputTableName - Table name to look up input definitions (e.g. 'sys_hub_flow_input' or 'sys_hub_action_input')
726
+ */
727
+ // Deprecated: kept for backward-compat but delegates to shared resolver
728
+ function resolveComplexInput(
729
+ name: string,
730
+ value: unknown,
731
+ parentDef: Record,
732
+ inputTableName: string,
733
+ logger?: Logger
734
+ ): { value: unknown; internalType: unknown } {
735
+ return _resolveComplexInput(name, value, parentDef, inputTableName, undefined, logger)
736
+ }
737
+
738
+ /**
739
+ * Checks if a given value is a serialized inline script object.
740
+ * This is used to identify inputs that have already been processed into the final
741
+ * Flow Designer JSON format for scripts.
742
+ *
743
+ * @param value - The value to check.
744
+ * @returns `true` if the value is a script object, `false` otherwise.
745
+ */
746
+ function isInlineScriptValue(value: unknown): boolean {
747
+ return typeof value === 'object' && value !== null && (value as { scriptActive?: boolean }).scriptActive === true
748
+ }
749
+
750
+ /**
751
+ * Processes an input value from objShape and returns the appropriate result object.
752
+ * Handles inline scripts by returning them as-is, or creates a standard input object.
753
+ *
754
+ * @param inputName - The name of the input field
755
+ * @param objShape - The ObjectShape containing all input values
756
+ * @param options - Optional processing options
757
+ * @param options.type - The parameter type to use (defaults to 'string' if not provided)
758
+ * @param options.actionDefRecord - Action definition record for complex input resolution
759
+ * @param options.inputTableName - Table name for input definitions (e.g., 'sys_hub_action_input')
760
+ * @returns The processed input object
761
+ */
762
+ function processInputValue(
763
+ inputName: string,
764
+ objShape: ObjectShape,
765
+ options?: {
766
+ type?: unknown
767
+ actionDefRecord?: Record
768
+ inputTableName?: string
769
+ logger?: Logger
770
+ }
771
+ ): unknown {
772
+ const value = objShape.get(inputName)
773
+ const primitiveValue = value.getValue()
774
+
775
+ // If it's an inline script object, return it as-is
776
+ if (isInlineScriptValue(primitiveValue)) {
777
+ return primitiveValue
778
+ }
779
+
780
+ let finalValue: unknown = primitiveValue
781
+ let finalType: unknown = options?.type ?? 'string'
782
+
783
+ // If action definition is provided, resolve complex input
784
+ if (options?.actionDefRecord && options?.inputTableName) {
785
+ const resolvedValue = resolveComplexInput(
786
+ inputName,
787
+ primitiveValue,
788
+ options.actionDefRecord,
789
+ options.inputTableName,
790
+ options?.logger
791
+ )
792
+ finalValue = resolvedValue.value
793
+ finalType = resolvedValue.internalType
794
+ }
795
+
796
+ // Return standard input object
797
+ return {
798
+ name: inputName,
799
+ value: finalValue,
800
+ displayValue: finalValue,
801
+ scriptActive: false,
802
+ parameter: {
803
+ type: finalType,
804
+ },
805
+ }
806
+ }
807
+
808
+ /**
809
+ * Processes a definition input that was not provided by the user.
810
+ * Handles hidden fields and default values by creating appropriate input objects.
811
+ *
812
+ * @param inputDef - The input definition record from the action/subflow definition
813
+ * @param inputName - The name of the input field
814
+ * @returns The processed input object if the field is hidden or has a default value, undefined otherwise
815
+ */
816
+ function processDefaultOrHiddenInput(inputDef: Record, inputName: string): unknown | undefined {
817
+ // Get attributes and check if hidden
818
+ const attributes = inputDef.get('attributes')?.ifString()?.getValue()
819
+ const visibleAttr = attributes ? getAttributeValue(attributes, 'visible') : undefined
820
+ const visibleInFdAttr = attributes ? getAttributeValue(attributes, 'visible_in_fd') : undefined
821
+ const isHidden = visibleAttr === 'false' || visibleInFdAttr === 'false'
822
+
823
+ // Get default value and internal type
824
+ const defaultValue = inputDef.get('default_value')?.getValue()
825
+ const hasDefaultValue = defaultValue !== undefined && defaultValue !== null && defaultValue !== ''
826
+ const internalType = inputDef.get('internal_type')?.asString()?.getValue() || 'string'
827
+
828
+ // For hidden fields or fields with default values, add them to result
829
+ if (isHidden || hasDefaultValue) {
830
+ const valueToUse = hasDefaultValue ? defaultValue : ''
831
+ const paramAttributes: { visible?: boolean; visible_in_fd?: boolean } = {}
832
+ if (visibleAttr === 'false') {
833
+ paramAttributes.visible = false
834
+ }
835
+ if (visibleInFdAttr === 'false') {
836
+ paramAttributes.visible_in_fd = false
837
+ }
838
+ return {
839
+ name: inputName,
840
+ value: valueToUse,
841
+ displayValue: valueToUse,
842
+ scriptActive: false,
843
+ parameter: {
844
+ type: internalType,
845
+ ...(Object.keys(paramAttributes).length > 0 && { attributes: paramAttributes }),
846
+ },
847
+ }
848
+ }
849
+ return undefined
850
+ }
851
+
852
+ async function prepareActionInstanceValueJson(
853
+ instanceInputs: ObjectShape | undefined,
854
+ actionDef: Record | StringShape,
855
+ transform: Transform,
856
+ logger: Logger
857
+ ) {
858
+ const actionDefRecord = actionDef.isRecord() ? actionDef.as(Record) : undefined
859
+ if (!instanceInputs) {
860
+ return []
861
+ }
862
+ const isActionDefString = actionDef instanceof StringShape
863
+ // Check for datapills and resolve them
864
+ const dataPillResults = await checkAndResolveDataPills(instanceInputs, transform)
865
+
866
+ // Check for inline script tags and resolve them (only returns scripts)
867
+ const inlineScriptResults = await checkAndResolveInlineScripts(instanceInputs, transform)
868
+ const inlineScriptMap = new Map(inlineScriptResults)
869
+
870
+ // Merge: use inline scripts where they exist, otherwise use datapill results
871
+ // Note: Inline script can be applied to only top level properties; No need to handle nested objects
872
+ const mergedResults = dataPillResults.map(([key, value]) => {
873
+ return inlineScriptMap.has(key) ? [key, inlineScriptMap.get(key)] : [key, value]
874
+ })
875
+
876
+ const objShape = new ObjectShape({
877
+ source: instanceInputs.getSource(),
878
+ properties: Object.fromEntries(mergedResults),
879
+ })
880
+
881
+ const result: unknown[] = []
882
+
883
+ // When isActionDefString is true, there's no action definition in fluent
884
+ // We expect arbitrary inputs and should process all provided inputs directly
885
+ if (actionDefRecord) {
886
+ // When action definition record is present, process only definition inputs
887
+ const definitionInputs = actionDefRecord.flat().filter((v) => v.getTable() === 'sys_hub_action_input')
888
+ const providedInputNames = new Set(objShape.keys())
889
+
890
+ for (const inputDef of definitionInputs) {
891
+ const inputName = inputDef.get('element')?.asString()?.getValue()
892
+ if (!inputName) {
893
+ continue
894
+ }
895
+ // If input is provided in objShape(ie provided by user), process it
896
+ if (providedInputNames.has(inputName)) {
897
+ const processedValue = processInputValue(inputName, objShape, {
898
+ actionDefRecord,
899
+ inputTableName: 'sys_hub_action_input',
900
+ logger,
901
+ })
902
+ result.push(processedValue)
903
+ } else {
904
+ // Process default or hidden input
905
+ const processedValue = processDefaultOrHiddenInput(inputDef, inputName)
906
+ if (processedValue) {
907
+ result.push(processedValue)
908
+ }
909
+ }
910
+ }
911
+ } else if (isActionDefString) {
912
+ for (const inputName of objShape.keys()) {
913
+ const processedValue = processInputValue(inputName, objShape, { type: 'string' })
914
+ result.push(processedValue)
915
+ }
916
+ }
917
+
918
+ return result
919
+ }
920
+
921
+ async function prepareSubflowInstanceValueJson(
922
+ instanceInputs: ObjectShape,
923
+ subflowDef: Record | StringShape,
924
+ transform: Transform
925
+ ) {
926
+ // Check for datapills and resolve them
927
+ const dataPillResults = await checkAndResolveDataPills(instanceInputs, transform)
928
+
929
+ // Check for inline script tags and resolve them (only returns scripts)
930
+ const inlineScriptResults = await checkAndResolveInlineScripts(instanceInputs, transform)
931
+ const inlineScriptMap = new Map(inlineScriptResults)
932
+
933
+ // Merge: use inline scripts where they exist, otherwise use datapill results
934
+ const mergedResults = dataPillResults.map(([key, value]) => {
935
+ return inlineScriptMap.has(key) ? [key, inlineScriptMap.get(key)] : [key, value]
936
+ })
937
+
938
+ const objShape = new ObjectShape({
939
+ source: instanceInputs.getSource(),
940
+ properties: Object.fromEntries(mergedResults),
941
+ })
942
+
943
+ return objShape
944
+ .keys()
945
+ .filter((key) => key !== 'waitForCompletion')
946
+ .map((key) => {
947
+ const value = objShape.get(key)
948
+ const primitiveValue = value.getValue()
949
+
950
+ // If checkAndResolveInlineScripts already returned a script object, return it as-is
951
+ if (isInlineScriptValue(primitiveValue)) {
952
+ return primitiveValue
953
+ }
954
+
955
+ let resolvedValue: { value: unknown; internalType: unknown; children?: unknown[] } = {
956
+ value: primitiveValue,
957
+ internalType: undefined,
958
+ }
959
+ if (subflowDef.isRecord()) {
960
+ resolvedValue = resolveComplexInput(key, primitiveValue, subflowDef.as(Record), 'sys_hub_flow_input')
961
+ }
962
+
963
+ const result: globalThis.Record<string, unknown> = {
964
+ name: key,
965
+ value: resolvedValue.value,
966
+ displayValue: resolvedValue.value,
967
+ parameter: {
968
+ type: resolvedValue.internalType,
969
+ }, // populate later if needed
970
+ }
971
+
972
+ // Add children array if present (for FlowObject with datapills)
973
+ if (resolvedValue.children && resolvedValue.children.length > 0) {
974
+ result['children'] = resolvedValue.children
975
+ }
976
+
977
+ return result
978
+ })
979
+ }
980
+
981
+ /**
982
+ * Type guard to check if a shape is a data pill shape that needs resolution.
983
+ * Data pill shapes include PropertyAccessShape, TemplateExpressionShape, and IdentifierShape.
984
+ * @param shape - The shape to check
985
+ * @returns true if the shape is a data pill shape, false otherwise
986
+ */
987
+ function isDataPillShape(shape: Shape): shape is PropertyAccessShape | TemplateExpressionShape | IdentifierShape {
988
+ return (
989
+ shape instanceof PropertyAccessShape ||
990
+ shape instanceof TemplateExpressionShape ||
991
+ shape instanceof IdentifierShape
992
+ )
993
+ }
994
+
995
+ /**
996
+ * Recursively resolves data pills in nested object structures.
997
+ * Handles objects with nested data pills and constructs the resolved object back.
998
+ * Special shapes like TemplateValueShape and ApprovalRulesShape are also processed recursively
999
+ * since they can contain data pills in their nested structures.
1000
+ * @param shape - The ObjectShape to process
1001
+ * @param transform - The transform instance
1002
+ * @returns Resolved object with all nested data pills resolved
1003
+ */
1004
+ async function resolveObjectShapeRecursively(shape: ObjectShape, transform: Transform): Promise<unknown> {
1005
+ const entries = shape.entries({ resolve: false })
1006
+ const resolvedObject: { [key: string]: unknown } = {}
1007
+
1008
+ for (const [key, valueShape] of entries) {
1009
+ if (isDataPillShape(valueShape)) {
1010
+ // Resolve data pill shapes
1011
+ resolvedObject[key] = await resolveDataPillShape(valueShape, transform)
1012
+ } else if (valueShape.isObject()) {
1013
+ // Recursively resolve all ObjectShapes including special types
1014
+ // TemplateValueShape and ApprovalRulesShape can contain data pills in their nested structures
1015
+ // DurationShape only contains primitive numbers, but handling it recursively is harmless
1016
+ resolvedObject[key] = await resolveObjectShapeRecursively(valueShape.asObject(), transform)
1017
+ } else if (valueShape.isArray()) {
1018
+ // Handle array: recursively resolve each element
1019
+ const arrayShape = valueShape.asArray()
1020
+ const elements = arrayShape.getElements(false)
1021
+ const resolvedArray: unknown[] = []
1022
+
1023
+ for (const element of elements) {
1024
+ if (isDataPillShape(element)) {
1025
+ resolvedArray.push(await resolveDataPillShape(element, transform))
1026
+ } else if (element.isObject()) {
1027
+ resolvedArray.push(await resolveObjectShapeRecursively(element.asObject(), transform))
1028
+ } else if (element.isArray()) {
1029
+ // Recursively handle nested arrays by creating a temporary ObjectShape wrapper
1030
+ const tempShape = new ObjectShape({
1031
+ source: element.getSource(),
1032
+ properties: { temp: element },
1033
+ })
1034
+ const resolved = await resolveObjectShapeRecursively(tempShape, transform)
1035
+ resolvedArray.push((resolved as { temp: unknown }).temp)
1036
+ } else {
1037
+ resolvedArray.push(element.getValue())
1038
+ }
1039
+ }
1040
+
1041
+ resolvedObject[key] = resolvedArray
1042
+ } else {
1043
+ // For all other shapes (primitives), get the value directly
1044
+ resolvedObject[key] = valueShape.getValue()
1045
+ }
1046
+ }
1047
+
1048
+ return resolvedObject
1049
+ }
1050
+
1051
+ /**
1052
+ * Wraps special shape types (ApprovalRulesShape, TemplateValueShape, DurationShape) with their string representations.
1053
+ * @param shape - The original shape
1054
+ * @param resolvedValue - The resolved value
1055
+ * @param source - The source for creating new shapes
1056
+ * @returns The appropriately wrapped value or the original resolved value
1057
+ */
1058
+ function wrapSpecialShape(shape: Shape, resolvedValue: unknown, source: Source): unknown {
1059
+ if (shape.is(ApprovalRulesShape)) {
1060
+ return new ApprovalRulesShape({
1061
+ source,
1062
+ value: resolvedValue as ApprovalRulesType,
1063
+ }).toString()
1064
+ } else if (shape.is(TemplateValueShape)) {
1065
+ return new TemplateValueShape({
1066
+ source,
1067
+ value: resolvedValue as globalThis.Record<string, unknown>,
1068
+ }).toString()
1069
+ } else if (shape.is(DurationShape)) {
1070
+ return new DurationShape({
1071
+ source,
1072
+ value: resolvedValue as Duration,
1073
+ }).toString()
1074
+ } else if (shape.is(ApprovalDueDateShape)) {
1075
+ return new ApprovalDueDateShape({
1076
+ source,
1077
+ value: resolvedValue as ApprovalDueDateType,
1078
+ }).toString()
1079
+ }
1080
+ return resolvedValue
1081
+ }
1082
+
1083
+ /**
1084
+ * Checks for datapills and resolves them in instance inputs.
1085
+ * Similar to resolveObjectShapeRecursively but returns key-value pairs and handles special shapes.
1086
+ * @param instanceInputs - The instance inputs object shape
1087
+ * @param transform - The transform instance
1088
+ * @returns Array of [key, value] pairs with resolved datapills
1089
+ */
1090
+ async function checkAndResolveDataPills(instanceInputs: ObjectShape, transform: Transform) {
1091
+ const entries = instanceInputs.entries({ resolve: false })
1092
+ const results: [string, unknown][] = []
1093
+
1094
+ for (const [key, shape] of entries) {
1095
+ if (shape && isDataPillShape(shape)) {
1096
+ const resolvedValue = await resolveDataPillShape(shape, transform)
1097
+ results.push([key, resolvedValue])
1098
+ } else if (shape.is(DurationShape)) {
1099
+ // Handle DurationShape specially - convert to string representation
1100
+ // DurationShape.getValue() returns a symbol, so we need to get the duration value differently
1101
+ const durationShape = shape.as(DurationShape)
1102
+ const durationValue = durationShape.getDuration()
1103
+ const wrappedValue = wrapSpecialShape(shape, durationValue, instanceInputs.getSource())
1104
+ results.push([key, wrappedValue])
1105
+ } else if (shape.isObject() || shape.is(TemplateValueShape)) {
1106
+ const objShape = shape.is(TemplateValueShape) ? shape.getTemplateValue() : shape.asObject()
1107
+ // Recursively resolve object shapes
1108
+ const resolvedValue = await resolveObjectShapeRecursively(objShape, transform)
1109
+ // Preserve special shapes like TemplateValue by passing the original shape
1110
+ const wrappedValue = wrapSpecialShape(shape, resolvedValue, instanceInputs.getSource())
1111
+ results.push([key, wrappedValue])
1112
+ } else if (shape.isArray()) {
1113
+ // Resolve arrays using the shared recursive logic
1114
+ const resolvedArray = await resolveArrayElements(shape.asArray(), transform)
1115
+ results.push([key, resolvedArray])
1116
+ } else {
1117
+ results.push([key, shape.getValue()])
1118
+ }
1119
+ }
1120
+ return results
1121
+ }
1122
+
1123
+ /**
1124
+ * Resolves all elements in an array shape, handling datapills, objects, and nested arrays.
1125
+ * Shared logic extracted from both resolveObjectShapeRecursively and checkAndResolveDataPills.
1126
+ * @param arrayShape - The array shape to resolve
1127
+ * @param transform - The transform instance
1128
+ * @returns Resolved array with all datapills resolved
1129
+ */
1130
+ async function resolveArrayElements(arrayShape: Shape, transform: Transform): Promise<unknown[]> {
1131
+ const elements = arrayShape.asArray().getElements(false)
1132
+ const resolvedArray: unknown[] = []
1133
+
1134
+ for (const element of elements) {
1135
+ if (isDataPillShape(element)) {
1136
+ resolvedArray.push(await resolveDataPillShape(element, transform))
1137
+ } else if (element.isObject()) {
1138
+ resolvedArray.push(await resolveObjectShapeRecursively(element.asObject(), transform))
1139
+ } else if (element.isArray()) {
1140
+ // Recursively handle nested arrays
1141
+ resolvedArray.push(await resolveArrayElements(element, transform))
1142
+ } else {
1143
+ resolvedArray.push(element.getValue())
1144
+ }
1145
+ }
1146
+
1147
+ return resolvedArray
1148
+ }