@servicenow/sdk-build-plugins 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/dist/acl-plugin.js +11 -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/column-to-record.d.ts +10 -3
  15. package/dist/column/column-to-record.js +44 -7
  16. package/dist/column/column-to-record.js.map +1 -1
  17. package/dist/column-plugin.d.ts +3 -1
  18. package/dist/column-plugin.js +12 -12
  19. package/dist/column-plugin.js.map +1 -1
  20. package/dist/dashboard/dashboard-component-property-defaults.d.ts +152 -0
  21. package/dist/dashboard/dashboard-component-property-defaults.js +264 -0
  22. package/dist/dashboard/dashboard-component-property-defaults.js.map +1 -0
  23. package/dist/dashboard/dashboard-component-resolver.d.ts +13 -0
  24. package/dist/dashboard/dashboard-component-resolver.js +69 -0
  25. package/dist/dashboard/dashboard-component-resolver.js.map +1 -0
  26. package/dist/dashboard/dashboard-plugin.d.ts +12 -0
  27. package/dist/dashboard/dashboard-plugin.js +397 -0
  28. package/dist/dashboard/dashboard-plugin.js.map +1 -0
  29. package/dist/data-plugin.d.ts +3 -0
  30. package/dist/data-plugin.js +61 -113
  31. package/dist/data-plugin.js.map +1 -1
  32. package/dist/email-notification-plugin.d.ts +2 -0
  33. package/dist/email-notification-plugin.js +541 -0
  34. package/dist/email-notification-plugin.js.map +1 -0
  35. package/dist/flow/constants/flow-plugin-constants.d.ts +58 -0
  36. package/dist/flow/constants/flow-plugin-constants.js +70 -0
  37. package/dist/flow/constants/flow-plugin-constants.js.map +1 -0
  38. package/dist/flow/flow-logic/flow-logic-constants.d.ts +38 -0
  39. package/dist/flow/flow-logic/flow-logic-constants.js +118 -0
  40. package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -0
  41. package/dist/flow/flow-logic/flow-logic-diagnostics.d.ts +19 -0
  42. package/dist/flow/flow-logic/flow-logic-diagnostics.js +503 -0
  43. package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -0
  44. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +62 -0
  45. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +2092 -0
  46. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -0
  47. package/dist/flow/flow-logic/flow-logic-plugin.d.ts +52 -0
  48. package/dist/flow/flow-logic/flow-logic-plugin.js +283 -0
  49. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -0
  50. package/dist/flow/flow-logic/flow-logic-shapes.d.ts +104 -0
  51. package/dist/flow/flow-logic/flow-logic-shapes.js +201 -0
  52. package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -0
  53. package/dist/flow/plugins/approval-rules-plugin.d.ts +2 -0
  54. package/dist/flow/plugins/approval-rules-plugin.js +49 -0
  55. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -0
  56. package/dist/flow/plugins/flow-action-definition-plugin.d.ts +2 -0
  57. package/dist/flow/plugins/flow-action-definition-plugin.js +286 -0
  58. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -0
  59. package/dist/flow/plugins/flow-data-pill-plugin.d.ts +9 -0
  60. package/dist/flow/plugins/flow-data-pill-plugin.js +212 -0
  61. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -0
  62. package/dist/flow/plugins/flow-definition-plugin.d.ts +2 -0
  63. package/dist/flow/plugins/flow-definition-plugin.js +1668 -0
  64. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -0
  65. package/dist/flow/plugins/flow-diagnostics-plugin.d.ts +26 -0
  66. package/dist/flow/plugins/flow-diagnostics-plugin.js +217 -0
  67. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -0
  68. package/dist/flow/plugins/flow-instance-plugin.d.ts +12 -0
  69. package/dist/flow/plugins/flow-instance-plugin.js +1205 -0
  70. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -0
  71. package/dist/flow/plugins/flow-trigger-instance-plugin.d.ts +2 -0
  72. package/dist/flow/plugins/flow-trigger-instance-plugin.js +338 -0
  73. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -0
  74. package/dist/flow/plugins/inline-script-plugin.d.ts +39 -0
  75. package/dist/flow/plugins/inline-script-plugin.js +80 -0
  76. package/dist/flow/plugins/inline-script-plugin.js.map +1 -0
  77. package/dist/flow/plugins/step-definition-plugin.d.ts +5 -0
  78. package/dist/flow/plugins/step-definition-plugin.js +71 -0
  79. package/dist/flow/plugins/step-definition-plugin.js.map +1 -0
  80. package/dist/flow/plugins/step-instance-plugin.d.ts +31 -0
  81. package/dist/flow/plugins/step-instance-plugin.js +339 -0
  82. package/dist/flow/plugins/step-instance-plugin.js.map +1 -0
  83. package/dist/flow/plugins/trigger-plugin.d.ts +2 -0
  84. package/dist/flow/plugins/trigger-plugin.js +96 -0
  85. package/dist/flow/plugins/trigger-plugin.js.map +1 -0
  86. package/dist/flow/plugins/wfa-datapill-plugin.d.ts +15 -0
  87. package/dist/flow/plugins/wfa-datapill-plugin.js +178 -0
  88. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -0
  89. package/dist/flow/utils/approval-rules-processor.d.ts +13 -0
  90. package/dist/flow/utils/approval-rules-processor.js +267 -0
  91. package/dist/flow/utils/approval-rules-processor.js.map +1 -0
  92. package/dist/flow/utils/built-in-complex-objects.d.ts +19 -0
  93. package/dist/flow/utils/built-in-complex-objects.js +62 -0
  94. package/dist/flow/utils/built-in-complex-objects.js.map +1 -0
  95. package/dist/flow/utils/complex-object-resolver.d.ts +8 -0
  96. package/dist/flow/utils/complex-object-resolver.js +614 -0
  97. package/dist/flow/utils/complex-object-resolver.js.map +1 -0
  98. package/dist/flow/utils/complex-objects.d.ts +36 -0
  99. package/dist/flow/utils/complex-objects.js +481 -0
  100. package/dist/flow/utils/complex-objects.js.map +1 -0
  101. package/dist/flow/utils/data-pill-shapes.d.ts +58 -0
  102. package/dist/flow/utils/data-pill-shapes.js +135 -0
  103. package/dist/flow/utils/data-pill-shapes.js.map +1 -0
  104. package/dist/flow/utils/datapill-transformer.d.ts +110 -0
  105. package/dist/flow/utils/datapill-transformer.js +503 -0
  106. package/dist/flow/utils/datapill-transformer.js.map +1 -0
  107. package/dist/flow/utils/flow-constants.d.ts +72 -0
  108. package/dist/flow/utils/flow-constants.js +230 -0
  109. package/dist/flow/utils/flow-constants.js.map +1 -0
  110. package/dist/flow/utils/flow-io-to-record.d.ts +44 -0
  111. package/dist/flow/utils/flow-io-to-record.js +409 -0
  112. package/dist/flow/utils/flow-io-to-record.js.map +1 -0
  113. package/dist/flow/utils/flow-shapes.d.ts +161 -0
  114. package/dist/flow/utils/flow-shapes.js +255 -0
  115. package/dist/flow/utils/flow-shapes.js.map +1 -0
  116. package/dist/flow/utils/flow-to-xml.d.ts +16 -0
  117. package/dist/flow/utils/flow-to-xml.js +237 -0
  118. package/dist/flow/utils/flow-to-xml.js.map +1 -0
  119. package/dist/flow/utils/flow-variable-processor.d.ts +51 -0
  120. package/dist/flow/utils/flow-variable-processor.js +69 -0
  121. package/dist/flow/utils/flow-variable-processor.js.map +1 -0
  122. package/dist/flow/utils/label-cache-parser.d.ts +7 -0
  123. package/dist/flow/utils/label-cache-parser.js +24 -0
  124. package/dist/flow/utils/label-cache-parser.js.map +1 -0
  125. package/dist/flow/utils/label-cache-processor.d.ts +119 -0
  126. package/dist/flow/utils/label-cache-processor.js +719 -0
  127. package/dist/flow/utils/label-cache-processor.js.map +1 -0
  128. package/dist/flow/utils/pill-string-parser.d.ts +88 -0
  129. package/dist/flow/utils/pill-string-parser.js +306 -0
  130. package/dist/flow/utils/pill-string-parser.js.map +1 -0
  131. package/dist/flow/utils/schema-to-flow-object.d.ts +22 -0
  132. package/dist/flow/utils/schema-to-flow-object.js +318 -0
  133. package/dist/flow/utils/schema-to-flow-object.js.map +1 -0
  134. package/dist/flow/utils/service-catalog.d.ts +47 -0
  135. package/dist/flow/utils/service-catalog.js +137 -0
  136. package/dist/flow/utils/service-catalog.js.map +1 -0
  137. package/dist/flow/utils/utils.d.ts +117 -0
  138. package/dist/flow/utils/utils.js +345 -0
  139. package/dist/flow/utils/utils.js.map +1 -0
  140. package/dist/index.d.ts +20 -1
  141. package/dist/index.js +21 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/list-plugin.js +1 -1
  144. package/dist/list-plugin.js.map +1 -1
  145. package/dist/now-attach-plugin.d.ts +1 -0
  146. package/dist/now-attach-plugin.js +10 -10
  147. package/dist/now-attach-plugin.js.map +1 -1
  148. package/dist/now-ref-plugin.js +1 -1
  149. package/dist/now-ref-plugin.js.map +1 -1
  150. package/dist/record-plugin.d.ts +29 -0
  151. package/dist/record-plugin.js +66 -7
  152. package/dist/record-plugin.js.map +1 -1
  153. package/dist/repack/index.d.ts +2 -0
  154. package/dist/repack/index.js +8 -0
  155. package/dist/repack/index.js.map +1 -1
  156. package/dist/rest-api-plugin.js +54 -44
  157. package/dist/rest-api-plugin.js.map +1 -1
  158. package/dist/server-module-plugin/index.d.ts +10 -0
  159. package/dist/server-module-plugin/index.js +83 -59
  160. package/dist/server-module-plugin/index.js.map +1 -1
  161. package/dist/service-catalog/catalog-clientscript-plugin.d.ts +2 -0
  162. package/dist/service-catalog/catalog-clientscript-plugin.js +117 -0
  163. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -0
  164. package/dist/service-catalog/catalog-item-plugin.d.ts +2 -0
  165. package/dist/service-catalog/catalog-item-plugin.js +115 -0
  166. package/dist/service-catalog/catalog-item-plugin.js.map +1 -0
  167. package/dist/service-catalog/catalog-ui-policy-plugin.d.ts +2 -0
  168. package/dist/service-catalog/catalog-ui-policy-plugin.js +266 -0
  169. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -0
  170. package/dist/service-catalog/index.d.ts +5 -0
  171. package/dist/service-catalog/index.js +22 -0
  172. package/dist/service-catalog/index.js.map +1 -0
  173. package/dist/service-catalog/record-to-shape.d.ts +6 -0
  174. package/dist/service-catalog/record-to-shape.js +93 -0
  175. package/dist/service-catalog/record-to-shape.js.map +1 -0
  176. package/dist/service-catalog/sc-record-producer-plugin.d.ts +2 -0
  177. package/dist/service-catalog/sc-record-producer-plugin.js +140 -0
  178. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -0
  179. package/dist/service-catalog/service-catalog-base.d.ts +311 -0
  180. package/dist/service-catalog/service-catalog-base.js +542 -0
  181. package/dist/service-catalog/service-catalog-base.js.map +1 -0
  182. package/dist/service-catalog/service-catalog-diagnostics.d.ts +45 -0
  183. package/dist/service-catalog/service-catalog-diagnostics.js +172 -0
  184. package/dist/service-catalog/service-catalog-diagnostics.js.map +1 -0
  185. package/dist/service-catalog/shape-to-record.d.ts +8 -0
  186. package/dist/service-catalog/shape-to-record.js +235 -0
  187. package/dist/service-catalog/shape-to-record.js.map +1 -0
  188. package/dist/service-catalog/utils.d.ts +323 -0
  189. package/dist/service-catalog/utils.js +1216 -0
  190. package/dist/service-catalog/utils.js.map +1 -0
  191. package/dist/service-catalog/variable-helper.d.ts +43 -0
  192. package/dist/service-catalog/variable-helper.js +92 -0
  193. package/dist/service-catalog/variable-helper.js.map +1 -0
  194. package/dist/service-catalog/variable-set-plugin.d.ts +2 -0
  195. package/dist/service-catalog/variable-set-plugin.js +175 -0
  196. package/dist/service-catalog/variable-set-plugin.js.map +1 -0
  197. package/dist/service-catalog/variables-transform.d.ts +139 -0
  198. package/dist/service-catalog/variables-transform.js +403 -0
  199. package/dist/service-catalog/variables-transform.js.map +1 -0
  200. package/dist/sla/sla-validators.d.ts +61 -0
  201. package/dist/sla/sla-validators.js +224 -0
  202. package/dist/sla/sla-validators.js.map +1 -0
  203. package/dist/sla-plugin.d.ts +5 -0
  204. package/dist/sla-plugin.js +280 -0
  205. package/dist/sla-plugin.js.map +1 -0
  206. package/dist/static-content-plugin.js +25 -2
  207. package/dist/static-content-plugin.js.map +1 -1
  208. package/dist/table-plugin.js +32 -15
  209. package/dist/table-plugin.js.map +1 -1
  210. package/dist/ui-page-plugin.js +832 -19
  211. package/dist/ui-page-plugin.js.map +1 -1
  212. package/dist/ui-policy-plugin.js +5 -7
  213. package/dist/ui-policy-plugin.js.map +1 -1
  214. package/dist/utils.d.ts +10 -1
  215. package/dist/utils.js +16 -0
  216. package/dist/utils.js.map +1 -1
  217. package/dist/ux-list-menu-config-plugin.d.ts +2 -0
  218. package/dist/ux-list-menu-config-plugin.js +292 -0
  219. package/dist/ux-list-menu-config-plugin.js.map +1 -0
  220. package/dist/workspace-plugin/chrome-tab.d.ts +2 -0
  221. package/dist/workspace-plugin/chrome-tab.js +46 -0
  222. package/dist/workspace-plugin/chrome-tab.js.map +1 -0
  223. package/dist/workspace-plugin/constants.d.ts +52 -0
  224. package/dist/workspace-plugin/constants.js +56 -0
  225. package/dist/workspace-plugin/constants.js.map +1 -0
  226. package/dist/workspace-plugin/fluent-utils.d.ts +9 -0
  227. package/dist/workspace-plugin/fluent-utils.js +60 -0
  228. package/dist/workspace-plugin/fluent-utils.js.map +1 -0
  229. package/dist/workspace-plugin/page.d.ts +8 -0
  230. package/dist/workspace-plugin/page.js +108 -0
  231. package/dist/workspace-plugin/page.js.map +1 -0
  232. package/dist/workspace-plugin/screen.d.ts +1 -0
  233. package/dist/workspace-plugin/screen.js +38 -0
  234. package/dist/workspace-plugin/screen.js.map +1 -0
  235. package/dist/workspace-plugin/templates/index.d.ts +10 -0
  236. package/dist/workspace-plugin/templates/index.js +20 -0
  237. package/dist/workspace-plugin/templates/index.js.map +1 -0
  238. package/dist/workspace-plugin/templates/record-page-composition.d.ts +1 -0
  239. package/dist/workspace-plugin/templates/record-page-composition.js +4043 -0
  240. package/dist/workspace-plugin/templates/record-page-composition.js.map +1 -0
  241. package/dist/workspace-plugin/templates/record-page-data.d.ts +1 -0
  242. package/dist/workspace-plugin/templates/record-page-data.js +527 -0
  243. package/dist/workspace-plugin/templates/record-page-data.js.map +1 -0
  244. package/dist/workspace-plugin/templates/record-page-interalEventMappings.d.ts +1 -0
  245. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js +39 -0
  246. package/dist/workspace-plugin/templates/record-page-interalEventMappings.js.map +1 -0
  247. package/dist/workspace-plugin/templates/record-page-layoutModel.d.ts +1 -0
  248. package/dist/workspace-plugin/templates/record-page-layoutModel.js +55 -0
  249. package/dist/workspace-plugin/templates/record-page-layoutModel.js.map +1 -0
  250. package/dist/workspace-plugin/templates/record-page-properties.d.ts +1 -0
  251. package/dist/workspace-plugin/templates/record-page-properties.js +135 -0
  252. package/dist/workspace-plugin/templates/record-page-properties.js.map +1 -0
  253. package/dist/workspace-plugin/templates/record-page.d.ts +3 -0
  254. package/dist/workspace-plugin/templates/record-page.js +8 -0
  255. package/dist/workspace-plugin/templates/record-page.js.map +1 -0
  256. package/dist/workspace-plugin.d.ts +2 -0
  257. package/dist/workspace-plugin.js +453 -0
  258. package/dist/workspace-plugin.js.map +1 -0
  259. package/package.json +10 -12
  260. package/src/acl-plugin.ts +16 -1
  261. package/src/applicability-plugin.ts +82 -0
  262. package/src/atf/test-plugin.ts +6 -3
  263. package/src/basic-syntax-plugin.ts +10 -1
  264. package/src/business-rule-plugin.ts +2 -1
  265. package/src/call-expression-plugin.ts +2 -130
  266. package/src/column/column-to-record.ts +54 -8
  267. package/src/column-plugin.ts +29 -13
  268. package/src/dashboard/dashboard-component-property-defaults.ts +277 -0
  269. package/src/dashboard/dashboard-component-resolver.ts +69 -0
  270. package/src/dashboard/dashboard-plugin.ts +450 -0
  271. package/src/data-plugin.ts +67 -139
  272. package/src/email-notification-plugin.ts +850 -0
  273. package/src/flow/constants/flow-plugin-constants.ts +79 -0
  274. package/src/flow/flow-logic/flow-logic-constants.ts +120 -0
  275. package/src/flow/flow-logic/flow-logic-diagnostics.ts +591 -0
  276. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +2550 -0
  277. package/src/flow/flow-logic/flow-logic-plugin.ts +337 -0
  278. package/src/flow/flow-logic/flow-logic-shapes.ts +215 -0
  279. package/src/flow/plugins/approval-rules-plugin.ts +48 -0
  280. package/src/flow/plugins/flow-action-definition-plugin.ts +295 -0
  281. package/src/flow/plugins/flow-data-pill-plugin.ts +258 -0
  282. package/src/flow/plugins/flow-definition-plugin.ts +2173 -0
  283. package/src/flow/plugins/flow-diagnostics-plugin.ts +280 -0
  284. package/src/flow/plugins/flow-instance-plugin.ts +1499 -0
  285. package/src/flow/plugins/flow-trigger-instance-plugin.ts +444 -0
  286. package/src/flow/plugins/inline-script-plugin.ts +83 -0
  287. package/src/flow/plugins/step-definition-plugin.ts +67 -0
  288. package/src/flow/plugins/step-instance-plugin.ts +431 -0
  289. package/src/flow/plugins/trigger-plugin.ts +95 -0
  290. package/src/flow/plugins/wfa-datapill-plugin.ts +213 -0
  291. package/src/flow/utils/approval-rules-processor.ts +298 -0
  292. package/src/flow/utils/built-in-complex-objects.ts +81 -0
  293. package/src/flow/utils/complex-object-resolver.ts +875 -0
  294. package/src/flow/utils/complex-objects.ts +656 -0
  295. package/src/flow/utils/data-pill-shapes.ts +165 -0
  296. package/src/flow/utils/datapill-transformer.ts +632 -0
  297. package/src/flow/utils/flow-constants.ts +285 -0
  298. package/src/flow/utils/flow-io-to-record.ts +533 -0
  299. package/src/flow/utils/flow-shapes.ts +296 -0
  300. package/src/flow/utils/flow-to-xml.ts +318 -0
  301. package/src/flow/utils/flow-variable-processor.ts +100 -0
  302. package/src/flow/utils/label-cache-parser.ts +37 -0
  303. package/src/flow/utils/label-cache-processor.ts +870 -0
  304. package/src/flow/utils/pill-string-parser.ts +375 -0
  305. package/src/flow/utils/schema-to-flow-object.ts +385 -0
  306. package/src/flow/utils/service-catalog.ts +174 -0
  307. package/src/flow/utils/utils.ts +395 -0
  308. package/src/index.ts +20 -1
  309. package/src/list-plugin.ts +1 -1
  310. package/src/now-attach-plugin.ts +14 -11
  311. package/src/now-ref-plugin.ts +1 -1
  312. package/src/record-plugin.ts +76 -11
  313. package/src/repack/index.ts +14 -0
  314. package/src/rest-api-plugin.ts +62 -50
  315. package/src/server-module-plugin/index.ts +112 -86
  316. package/src/service-catalog/catalog-clientscript-plugin.ts +140 -0
  317. package/src/service-catalog/catalog-item-plugin.ts +162 -0
  318. package/src/service-catalog/catalog-ui-policy-plugin.ts +324 -0
  319. package/src/service-catalog/index.ts +5 -0
  320. package/src/service-catalog/record-to-shape.ts +109 -0
  321. package/src/service-catalog/sc-record-producer-plugin.ts +201 -0
  322. package/src/service-catalog/service-catalog-base.ts +600 -0
  323. package/src/service-catalog/service-catalog-diagnostics.ts +254 -0
  324. package/src/service-catalog/shape-to-record.ts +279 -0
  325. package/src/service-catalog/utils.ts +1455 -0
  326. package/src/service-catalog/variable-helper.ts +135 -0
  327. package/src/service-catalog/variable-set-plugin.ts +197 -0
  328. package/src/service-catalog/variables-transform.ts +438 -0
  329. package/src/sla/sla-validators.ts +331 -0
  330. package/src/sla-plugin.ts +358 -0
  331. package/src/static-content-plugin.ts +25 -2
  332. package/src/table-plugin.ts +49 -16
  333. package/src/ui-page-plugin.ts +1063 -20
  334. package/src/ui-policy-plugin.ts +5 -9
  335. package/src/utils.ts +24 -1
  336. package/src/ux-list-menu-config-plugin.ts +312 -0
  337. package/src/workspace-plugin/chrome-tab.ts +44 -0
  338. package/src/workspace-plugin/constants.ts +53 -0
  339. package/src/workspace-plugin/fluent-utils.ts +60 -0
  340. package/src/workspace-plugin/page.ts +139 -0
  341. package/src/workspace-plugin/screen.ts +34 -0
  342. package/src/workspace-plugin/templates/index.ts +17 -0
  343. package/src/workspace-plugin/templates/record-page-composition.ts +4051 -0
  344. package/src/workspace-plugin/templates/record-page-data.ts +523 -0
  345. package/src/workspace-plugin/templates/record-page-interalEventMappings.ts +35 -0
  346. package/src/workspace-plugin/templates/record-page-layoutModel.ts +51 -0
  347. package/src/workspace-plugin/templates/record-page-properties.ts +131 -0
  348. package/src/workspace-plugin/templates/record-page.ts +6 -0
  349. package/src/workspace-plugin.ts +574 -0
@@ -0,0 +1,870 @@
1
+ // biome-ignore-all lint/suspicious/noExplicitAny: This file processes dynamic JSON structures for label caching
2
+ import type { Record } from '@servicenow/sdk-build-core'
3
+ import { getAttributeValue, parseAttributesToObject } from './schema-to-flow-object'
4
+ import { CallExpressionShape, ObjectShape, UndefinedShape } from '@servicenow/sdk-build-core'
5
+ import { COLUMN_API_TO_TYPE } from '../../column/column-helper'
6
+ import { FLOW_LOGIC_SYS_ID_MAP, FLOW_LOGIC } from '../flow-logic/flow-logic-constants'
7
+ import { isUuidPrefix, parseSinglePill, PILL_REGEX } from './pill-string-parser'
8
+ import { isDataPill } from './complex-object-resolver'
9
+
10
+ /**
11
+ * Label Cache and Data Pill Metadata Utilities
12
+ *
13
+ * This module contains all utilities for:
14
+ * - Processing label cache for flow definitions
15
+ * - Extracting data pill metadata from instances
16
+ * - Resolving labels from complex objects
17
+ * - Generating initial data pill metadata for instances
18
+ */
19
+
20
+ // ============================================================================
21
+ // Helper Functions
22
+ // ============================================================================
23
+
24
+ /**
25
+ * Maps trigger name prefixes (from data pill names) to their display labels
26
+ * This mapping is derived from the actual trigger definitions and their labels
27
+ */
28
+ /**
29
+ * Regex pattern to strip |dataType suffix from datapill expressions
30
+ * Matches: {{pillName|dataType}} and captures pillName to replace with {{pillName}}
31
+ */
32
+ const STRIP_DATATYPE_FROM_PILL_REGEX = /\{\{([^|}]+)\|[^}]+\}\}/g
33
+
34
+ const TRIGGER_NAME_TO_LABEL_MAP: { [key: string]: string } = {
35
+ Created: 'Trigger - Record Created',
36
+ Updated: 'Trigger - Record Updated',
37
+ 'Created or Updated': 'Trigger - Record Created or Updated',
38
+ Daily: 'Trigger - Run Daily',
39
+ Monthly: 'Trigger - Run Monthly',
40
+ Repeat: 'Trigger - Run Repeat',
41
+ 'Run Once': 'Trigger - Run Once',
42
+ Weekly: 'Trigger - Run Weekly',
43
+ 'Inbound Email': 'Trigger - Inbound Email',
44
+ 'Service Catalog': 'Trigger - Service Catalog',
45
+ 'Knowledge Management': 'Trigger - Knowledge Management',
46
+ 'Remote Table Query': 'Trigger - Remote Table Query',
47
+ 'SLA Task': 'Trigger - SLA Task',
48
+ }
49
+
50
+ // ============================================================================
51
+ // Trigger Output and Input Extraction
52
+ // ============================================================================
53
+
54
+ /**
55
+ * Helper function to extract trigger inputs from trigger instance shape
56
+ * Returns a map of input name to value for use in label cache processing
57
+ */
58
+ export function extractTriggerInputs(triggerInstanceShape: CallExpressionShape | undefined): Map<string, unknown> {
59
+ const triggerInputsMap = new Map<string, unknown>()
60
+
61
+ if (!triggerInstanceShape) {
62
+ return triggerInputsMap
63
+ }
64
+
65
+ // Extract trigger inputs from argument(2)
66
+ const triggerInputsObj = triggerInstanceShape.getArgument(2)?.as(ObjectShape)
67
+ if (triggerInputsObj) {
68
+ for (const [inputName, inputValue] of triggerInputsObj.entries()) {
69
+ if (!inputValue) {
70
+ continue
71
+ }
72
+ // Extract the actual value from different shape types
73
+ const value = inputValue.getValue()
74
+ triggerInputsMap.set(inputName, value)
75
+ }
76
+ }
77
+
78
+ return triggerInputsMap
79
+ }
80
+
81
+ /**
82
+ * Helper function to extract trigger output definitions from trigger instance shape
83
+ * Returns a map of output name to { label, type } for use in label cache processing
84
+ */
85
+ export function extractTriggerOutputs(
86
+ triggerInstanceShape: CallExpressionShape | undefined
87
+ ): Map<string, { label: string; type: string }> {
88
+ const triggerOutputShapeMap = new Map<string, { label: string; type: string }>()
89
+
90
+ if (!triggerInstanceShape || triggerInstanceShape instanceof UndefinedShape) {
91
+ return triggerOutputShapeMap
92
+ }
93
+
94
+ const triggerDefArg = triggerInstanceShape.getArgument(0)
95
+ if (!(triggerDefArg instanceof CallExpressionShape)) {
96
+ return triggerOutputShapeMap
97
+ }
98
+
99
+ const triggerConfigArg = triggerDefArg.getArgument(0)
100
+ if (!(triggerConfigArg instanceof ObjectShape)) {
101
+ return triggerOutputShapeMap
102
+ }
103
+
104
+ const outputsObj = triggerConfigArg.get('outputs')
105
+ if (!(outputsObj instanceof ObjectShape)) {
106
+ return triggerOutputShapeMap
107
+ }
108
+
109
+ // Iterate through all output properties and extract column metadata
110
+ for (const [outputName, outputValue] of outputsObj.entries()) {
111
+ if (!outputValue) {
112
+ continue
113
+ }
114
+
115
+ const outputDefCE = outputValue.as(CallExpressionShape)
116
+ const callee = outputDefCE.getCallee()
117
+ if (!callee) {
118
+ continue
119
+ }
120
+
121
+ // Extract column type name (optimized: lastIndexOf instead of split)
122
+ const lastDotIndex = callee.lastIndexOf('.')
123
+ const columnApiName = lastDotIndex >= 0 ? callee.substring(lastDotIndex + 1) : callee
124
+
125
+ // Map to internal type
126
+ const internalType = COLUMN_API_TO_TYPE[columnApiName] || columnApiName
127
+ if (!internalType) {
128
+ continue
129
+ }
130
+
131
+ // Extract label from argument object
132
+ const outputDefArg = outputDefCE.getArgument(0)
133
+ const label = outputDefArg ? outputDefArg.as(ObjectShape).get('label')?.getValue() : undefined
134
+
135
+ triggerOutputShapeMap.set(outputName, {
136
+ label: label ? String(label) : outputName,
137
+ type: internalType,
138
+ })
139
+ }
140
+
141
+ return triggerOutputShapeMap
142
+ }
143
+
144
+ /**
145
+ * Creates a lookup map from records by element name.
146
+ * Used to build maps of flow variables, subflow inputs, etc.
147
+ *
148
+ * @param records - Array of records to filter and map
149
+ * @param tableName - Table name to filter by
150
+ * @returns Map of element names to records
151
+ */
152
+ export function createDefinitionMap(records: Record[], tableName: string): Map<string, Record> {
153
+ const map = new Map<string, Record>()
154
+ records
155
+ .filter((rec) => rec.getTable() === tableName)
156
+ .forEach((record) => {
157
+ const element = record.get('element')?.asString()?.getValue()
158
+ if (element) {
159
+ map.set(element, record)
160
+ }
161
+ })
162
+ return map
163
+ }
164
+
165
+ // ============================================================================
166
+ // Complex Object Label Extraction
167
+ // ============================================================================
168
+
169
+ /**
170
+ * Extracts labels from complex object schema and determines field types.
171
+ * Traverses nested complex object structures to build label paths.
172
+ */
173
+ export function extractLabelsFromComplexObject(
174
+ segments: string[],
175
+ coRecord: Record,
176
+ labelParts: string[]
177
+ ): string | null {
178
+ const serializedContent = coRecord.get('serialized_content')?.ifString()?.getValue()
179
+ if (!serializedContent) {
180
+ return null
181
+ }
182
+
183
+ const schema = JSON.parse(serializedContent)
184
+ const rootKey = Object.keys(schema).find((k) => k.startsWith('FlowDesigner:'))
185
+ if (!rootKey) {
186
+ return null
187
+ }
188
+
189
+ let currentSchema = schema[rootKey]
190
+ let extractedType: string | null = null
191
+
192
+ // If accessing root object itself (segments.length === 2), extract type from root .$type_facets
193
+ if (segments.length === 2) {
194
+ const rootTypeFacets = schema[`${rootKey}.$type_facets`]?.SimpleMapFacet
195
+ if (rootTypeFacets) {
196
+ const rootFacetData = JSON.parse(rootTypeFacets)
197
+ if (rootFacetData.uiType) {
198
+ extractedType = rootFacetData.uiType
199
+ }
200
+ }
201
+ return extractedType
202
+ }
203
+
204
+ for (let i = 2; i < segments.length; i++) {
205
+ const fieldName = segments[i]
206
+ if (!fieldName) {
207
+ continue
208
+ }
209
+
210
+ const facetKey = `${fieldName}.$field_facets`
211
+ const facet = currentSchema[facetKey]?.SimpleMapFacet
212
+
213
+ if (!facet) {
214
+ throw new Error(
215
+ `Missing field facets for '${fieldName}' in complex object schema. ` +
216
+ `Path: ${segments.join('.')}. This indicates the schema is incomplete or the field doesn't exist.`
217
+ )
218
+ }
219
+
220
+ const facetData = JSON.parse(facet)
221
+ labelParts.push(facetData.label || fieldName)
222
+
223
+ if (i === segments.length - 1 && facetData.uiType) {
224
+ extractedType = facetData.uiType
225
+ }
226
+
227
+ if (
228
+ currentSchema[fieldName] &&
229
+ typeof currentSchema[fieldName] === 'object' &&
230
+ !Array.isArray(currentSchema[fieldName])
231
+ ) {
232
+ currentSchema = currentSchema[fieldName]
233
+ }
234
+ }
235
+
236
+ return extractedType
237
+ }
238
+
239
+ /**
240
+ * Parses a data pill string and extracts the prefix and path.
241
+ * Supports all data pill formats: {{prefix.path}}
242
+ *
243
+ * @param pillString - The data pill string (e.g., "{{flow_variable.varName}}", "{{trigger.current.sys_id}}")
244
+ * @returns Object with prefix and path, or null if not a valid pill
245
+ *
246
+ * @example
247
+ * parseDataPill("{{flow_variable.varName}}") // { prefix: 'flow_variable', path: 'varName' }
248
+ * parseDataPill("{{trigger.current.sys_id}}") // { prefix: 'trigger', path: 'current.sys_id' }
249
+ * parseDataPill("{{subflow.output}}") // { prefix: 'subflow', path: 'output' }
250
+ */
251
+ function parseDataPill(pillString: string): { prefix: string; path: string } | null {
252
+ // Use the existing parseSinglePill utility from pill-string-parser
253
+ const parsed = parseSinglePill(pillString, false)
254
+ if (!parsed) {
255
+ return null
256
+ }
257
+ return {
258
+ prefix: parsed.prefix,
259
+ path: parsed.path,
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Extracts table name from a flow variable definition record.
265
+ * Handles both ReferenceColumn (reference_table) and FlowArray (childName) types.
266
+ *
267
+ * @param flowVar - The flow variable definition record
268
+ * @returns Table name or null if not found
269
+ */
270
+ function extractTableNameFromFlowVariable(flowVar: Record): string | null {
271
+ // Try to get table name from reference_table field (for simple reference columns)
272
+ const refTable = flowVar.get('reference_table')?.getValue() as string | undefined
273
+ if (refTable) {
274
+ return refTable
275
+ }
276
+
277
+ // For FlowArray, extract child type from source shape
278
+ const sourceShape = flowVar.getSource()
279
+ if (sourceShape instanceof CallExpressionShape) {
280
+ const firstArg = sourceShape.getArgument(0)
281
+ if (firstArg instanceof ObjectShape) {
282
+ return (firstArg.get('childName')?.getValue() as string) || null
283
+ }
284
+ }
285
+
286
+ return null
287
+ }
288
+
289
+ /**
290
+ * Extracts forEach metadata from a flow logic instance record.
291
+ * This includes the step number and table name (if available) for forEach loops.
292
+ *
293
+ * @param rec - The flow logic instance record
294
+ * @param order - The step order number
295
+ * @param flowVarDefMap - Map of flow variable names to their definition records
296
+ * @returns Object with stepNumber and tableName
297
+ */
298
+ export function extractForEachMetadata(
299
+ rec: Record,
300
+ order: number,
301
+ flowVarDefMap: Map<string, Record>
302
+ ): { stepNumber: number; tableName: string | null } {
303
+ const valuesJson = rec.get('values')?.getValue()
304
+ let tableName: string | null = null
305
+
306
+ // Early return if no values or inputs array
307
+ if (
308
+ !valuesJson ||
309
+ typeof valuesJson !== 'object' ||
310
+ !('inputs' in valuesJson) ||
311
+ !Array.isArray(valuesJson.inputs)
312
+ ) {
313
+ return { stepNumber: order, tableName }
314
+ }
315
+
316
+ // Find the 'items' input in the forEach values
317
+ const itemsInput = valuesJson.inputs.find((inp: { name?: string }) => inp?.name === 'items')
318
+ if (!itemsInput?.value || typeof itemsInput.value !== 'string') {
319
+ return { stepNumber: order, tableName }
320
+ }
321
+
322
+ // Parse the data pill to extract prefix and path
323
+ const parsed = parseDataPill(itemsInput.value)
324
+ if (!parsed) {
325
+ return { stepNumber: order, tableName }
326
+ }
327
+
328
+ // Handle flow_variable pills specifically (can extract table name from flow variable definitions)
329
+ if (parsed.prefix === 'flow_variable') {
330
+ // TODO: Fix this: below parsed.path comes as "flow_variable|dataTypes".
331
+ const varName = parsed.path.split('|')[0] || ''
332
+ const flowVar = flowVarDefMap.get(varName)
333
+ if (flowVar) {
334
+ tableName = extractTableNameFromFlowVariable(flowVar)
335
+ }
336
+ }
337
+
338
+ return { stepNumber: order, tableName }
339
+ }
340
+
341
+ /**
342
+ * Updates the forEach metadata map if the record is a forEach instance.
343
+ * Extracts metadata (step number and table name) and adds it to the map.
344
+ *
345
+ * @param rec - The flow logic instance record to check
346
+ * @param order - The step order number
347
+ * @param flowVarDefMap - Map of flow variable names to their definition records
348
+ * @param forEachMetadataMap - Map containing forEach metadata
349
+ * @returns Updated forEachMetadataMap with new forEach metadata if found
350
+ */
351
+ export function updateForEachMetadata(
352
+ rec: Record,
353
+ order: number,
354
+ flowVarDefMap: Map<string, Record>,
355
+ forEachMetadataMap: Map<string, { stepNumber: number; tableName: string | null }>
356
+ ): Map<string, { stepNumber: number; tableName: string | null }> {
357
+ const logicDefId = rec.get('logic_definition')?.getValue()
358
+ if (logicDefId === FLOW_LOGIC_SYS_ID_MAP[FLOW_LOGIC.FOR_EACH]) {
359
+ const uiId = rec.get('ui_id')?.getValue() as string
360
+ if (uiId) {
361
+ const metadata = extractForEachMetadata(rec, order, flowVarDefMap)
362
+ if (metadata) {
363
+ forEachMetadataMap.set(uiId, metadata)
364
+ }
365
+ }
366
+ }
367
+ return forEachMetadataMap
368
+ }
369
+
370
+ /**
371
+ * Helper function to extract data pills from a string value and update the label cache.
372
+ * Shared logic used by both extractDataPillsFromChildren and extractDataPillsFromValuesArray.
373
+ * @param value - The string value potentially containing data pills
374
+ * @param fieldName - The name of the field containing this value
375
+ * @param stepUuid - UUID of the step where these data pills are used
376
+ * @param labelCacheMap - Existing label cache map to update (modified in place)
377
+ */
378
+ function extractPillsFromValue(
379
+ value: string,
380
+ fieldName: string,
381
+ stepUuid: string,
382
+ labelCacheMap: Map<string, any>
383
+ ): void {
384
+ if (typeof value !== 'string' || !value.includes('{{')) {
385
+ return
386
+ }
387
+
388
+ const matches = value.matchAll(PILL_REGEX)
389
+ for (const match of matches) {
390
+ const pillString = match[0] // e.g., "{{trigger.table_name|string}}" or "{{trigger.current.company|glide_list|meta:user_criteria:company:core_company}}"
391
+ const pillContent = pillString.slice(2, -2) // Remove {{ and }}
392
+ const parts = pillContent.split('|')
393
+
394
+ const dataPillName = parts[0]
395
+ const dataPillType = parts[1]
396
+ const metaPart = parts[2] // e.g., "meta:user_criteria:company:core_company"
397
+
398
+ if (!dataPillName) {
399
+ continue
400
+ }
401
+
402
+ // Parse metadata if present
403
+ let metadata: { parentTableName?: string; columnName?: string; reference?: string } | undefined
404
+ if (metaPart && metaPart.startsWith('meta:')) {
405
+ const metaValues = metaPart.substring(5).split(':') // Remove "meta:" prefix and split
406
+ const parentTableName = metaValues[0]?.trim() || undefined
407
+ const columnName = metaValues[1]?.trim() || undefined
408
+ const reference = metaValues[2]?.trim() || undefined
409
+
410
+ // Only create metadata object if at least one field has a non-empty value
411
+ if (parentTableName || columnName || reference) {
412
+ metadata = {}
413
+ // Only add properties with actual non-empty values
414
+ if (parentTableName && parentTableName.length > 0) {
415
+ metadata.parentTableName = parentTableName
416
+ }
417
+ if (columnName && columnName.length > 0) {
418
+ metadata.columnName = columnName
419
+ }
420
+ if (reference && reference.length > 0) {
421
+ metadata.reference = reference
422
+ }
423
+ }
424
+ }
425
+
426
+ updateLabelCacheForPill(dataPillName, dataPillType, stepUuid, fieldName, labelCacheMap, metadata)
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Updates the label cache map with data pill usage information.
432
+ * Shared logic for tracking pill usage across different step instances.
433
+ * @param pillName - The data pill name (e.g., "trigger.table_name")
434
+ * @param pillType - The data pill type (e.g., "string")
435
+ * @param stepUuid - UUID of the step where this pill is used
436
+ * @param fieldName - The field name where this pill is used
437
+ * @param labelCacheMap - Existing label cache map to update (modified in place)
438
+ * @param metadata - Optional metadata containing parentTableName, columnName, and reference
439
+ */
440
+ function updateLabelCacheForPill(
441
+ pillName: string,
442
+ pillType: string | undefined,
443
+ stepUuid: string,
444
+ fieldName: string,
445
+ labelCacheMap: Map<string, any>,
446
+ metadata?: { parentTableName?: string; columnName?: string; reference?: string }
447
+ ): void {
448
+ if (labelCacheMap.has(pillName)) {
449
+ const existingPill = labelCacheMap.get(pillName)
450
+
451
+ // Update type if we have a better type (non-undefined) and existing is undefined
452
+ if (pillType && !existingPill.type) {
453
+ existingPill.type = pillType
454
+ existingPill.base_type = pillType
455
+ }
456
+
457
+ // Update usedInstances - add this step's UUID and field name
458
+ if (existingPill.usedInstances[stepUuid]) {
459
+ // Step UUID already exists, add field name if not already present
460
+ if (!existingPill.usedInstances[stepUuid].includes(fieldName)) {
461
+ existingPill.usedInstances[stepUuid].push(fieldName)
462
+ }
463
+ } else {
464
+ // New step UUID, create new entry
465
+ existingPill.usedInstances[stepUuid] = [fieldName]
466
+ }
467
+
468
+ // Update metadata fields if provided and not already set
469
+ if (metadata) {
470
+ if (metadata.parentTableName && metadata.parentTableName.length > 0 && !existingPill.parent_table_name) {
471
+ existingPill.parent_table_name = metadata.parentTableName
472
+ }
473
+ if (metadata.columnName && metadata.columnName.length > 0 && !existingPill.column_name) {
474
+ existingPill.column_name = metadata.columnName
475
+ }
476
+ if (metadata.reference && metadata.reference.length > 0 && !existingPill.reference) {
477
+ existingPill.reference = metadata.reference
478
+ }
479
+ }
480
+ } else {
481
+ // New data pill, create entry
482
+ const pillEntry: any = {
483
+ name: pillName,
484
+ label: '', // Will be populated later by resolveDataPillMetadata
485
+ type: pillType,
486
+ base_type: pillType,
487
+ usedInstances: {
488
+ [stepUuid]: [fieldName],
489
+ },
490
+ attributes: {},
491
+ }
492
+
493
+ // Add metadata fields only if they have non-empty values
494
+ if (metadata) {
495
+ if (metadata.parentTableName && metadata.parentTableName.length > 0) {
496
+ pillEntry.parent_table_name = metadata.parentTableName
497
+ }
498
+ if (metadata.columnName && metadata.columnName.length > 0) {
499
+ pillEntry.column_name = metadata.columnName
500
+ }
501
+ if (metadata.reference && metadata.reference.length > 0) {
502
+ pillEntry.reference = metadata.reference
503
+ }
504
+ }
505
+
506
+ labelCacheMap.set(pillName, pillEntry)
507
+ }
508
+ }
509
+
510
+ /**
511
+ * Recursively extracts data pills from children array (used for FlowObject fields)
512
+ * @param children - Array of child field objects
513
+ * @param stepUuid - UUID of the step where these data pills are used
514
+ * @param labelCacheMap - Existing label cache map to update (modified in place)
515
+ */
516
+ function extractDataPillsFromChildren(children: any[], stepUuid: string, labelCacheMap: Map<string, any>): void {
517
+ for (const child of children) {
518
+ if (!child) {
519
+ continue
520
+ }
521
+
522
+ // Add type annotation to datapill strings based on parameter.type before extraction
523
+ // This ensures the label cache can extract and store the correct type
524
+ if (isDataPill(child.value)) {
525
+ const paramType = child.parameter?.type
526
+ if (paramType && paramType !== 'string' && paramType !== 'glide_date_time') {
527
+ // Add type annotation: {{path}} -> {{path|type}}
528
+ const pillContent = child.value.slice(2, -2) // Remove {{ and }}
529
+ // Check if it already has a type annotation
530
+ if (!pillContent.includes('|')) {
531
+ child.value = `{{${pillContent}|${paramType}}}`
532
+ }
533
+ }
534
+ }
535
+
536
+ // Extract datapills from this child's value using shared logic
537
+ extractPillsFromValue(child.value, child.name, stepUuid, labelCacheMap)
538
+
539
+ // Strip |dataType from pills in-place
540
+ if (typeof child.value === 'string') {
541
+ child.value = child.value.replace(STRIP_DATATYPE_FROM_PILL_REGEX, '{{$1}}')
542
+ }
543
+
544
+ // Recursively process nested children (for nested FlowObjects)
545
+ if (child.children && Array.isArray(child.children) && child.children.length > 0) {
546
+ extractDataPillsFromChildren(child.children, stepUuid, labelCacheMap)
547
+ }
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Extracts data pills from a values structure and tracks their usage.
553
+ * Data pills are in the format {{dataPillName}} within string values.
554
+ *
555
+ * Handles three different table types:
556
+ * - sys_hub_action_instance_v2: Array of objects with name/value pairs
557
+ * - sys_hub_flow_logic_instance_v2: Object with keys (inputs, outputsToAssign, etc.) containing arrays
558
+ * - sys_hub_sub_flow_instance_v2: Handled as needed
559
+ *
560
+ * @param valuesData - Values data (array or object depending on table type)
561
+ * @param stepUuid - UUID of the step where these data pills are used
562
+ * @param labelCacheMap - Existing label cache map to update (modified in place)
563
+ * @param tableName - The table name to determine data structure
564
+ * @returns Updated label cache map with data pill usage tracked
565
+ */
566
+ export function extractDataPillsFromValuesArray(
567
+ valuesData: any,
568
+ stepUuid: string,
569
+ labelCacheMap: Map<string, any>
570
+ // tableName?: string
571
+ ): Map<string, any> {
572
+ if (!valuesData) {
573
+ return labelCacheMap
574
+ }
575
+
576
+ // Handle sys_hub_action_instance_v2: Array of objects
577
+ if (Array.isArray(valuesData)) {
578
+ for (const input of valuesData) {
579
+ const inputName = input.name
580
+ const inputValue = input.value
581
+
582
+ // Handle children array for FlowObject fields with datapills
583
+ if (input.children && Array.isArray(input.children) && input.children.length > 0) {
584
+ // For FlowObjects with children, extract from children only (not parent value)
585
+ extractDataPillsFromChildren(input.children, stepUuid, labelCacheMap)
586
+ } else {
587
+ // For regular fields without children, extract from the value using shared logic
588
+ extractPillsFromValue(inputValue, inputName, stepUuid, labelCacheMap)
589
+ }
590
+
591
+ // Strip |dataType from pills in-place
592
+ if (typeof input.value === 'string') {
593
+ input.value = input.value.replace(STRIP_DATATYPE_FROM_PILL_REGEX, '{{$1}}')
594
+ input.displayValue = input.displayValue.replace(STRIP_DATATYPE_FROM_PILL_REGEX, '{{$1}}')
595
+ }
596
+ }
597
+ }
598
+ // Handle sys_hub_flow_logic_instance_v2: Object with keys containing arrays
599
+ else if (typeof valuesData === 'object') {
600
+ // Iterate over all keys (inputs, outputsToAssign, variables, etc.)
601
+ for (const [key, arrayValue] of Object.entries(valuesData)) {
602
+ if (Array.isArray(arrayValue)) {
603
+ // Process each item in the array
604
+ for (const item of arrayValue) {
605
+ if (item && typeof item === 'object') {
606
+ const itemName = item.name || key
607
+ const itemValue = item.value
608
+
609
+ // Handle children array for FlowObject fields with datapills
610
+ if (item.children && Array.isArray(item.children) && item.children.length > 0) {
611
+ // For FlowObjects with children, extract from children only (not parent value)
612
+ extractDataPillsFromChildren(item.children, stepUuid, labelCacheMap)
613
+ } else {
614
+ // For regular fields without children, extract from the value using shared logic
615
+ extractPillsFromValue(itemValue, itemName, stepUuid, labelCacheMap)
616
+ }
617
+
618
+ // Strip |dataType from pills in-place
619
+ if (typeof item.value === 'string') {
620
+ item.value = item.value.replace(STRIP_DATATYPE_FROM_PILL_REGEX, '{{$1}}')
621
+ item.displayValue = item.displayValue.replace(STRIP_DATATYPE_FROM_PILL_REGEX, '{{$1}}')
622
+ }
623
+ }
624
+ }
625
+ }
626
+ }
627
+ }
628
+
629
+ return labelCacheMap
630
+ }
631
+
632
+ /**
633
+ * Resolves data pill metadata including label parts, variable definition, and type information.
634
+ * Handles flow variables, subflow inputs, trigger pills, and forEach item pills.
635
+ */
636
+ export function resolveDataPillMetadata(
637
+ segments: string[],
638
+ flowVarDefMap: Map<string, Record>,
639
+ subflowInputDefMap: Map<string, Record>,
640
+ relatedRecords: Record[],
641
+ triggerData?: { inputs: Map<string, any>; outputs: Map<string, { label: string; type: string }> },
642
+ forEachMetadataMap?: Map<string, { stepNumber: number; tableName: string | null }>
643
+ // parentUiId?: string
644
+ ): {
645
+ labelParts: string[]
646
+ varDef: Record | undefined
647
+ extractedType: string | null
648
+ } {
649
+ const labelParts: string[] = []
650
+ let varDef: Record | undefined
651
+ let extractedType: string | null = null
652
+ const [prefix, varName] = segments
653
+
654
+ const getLabel = (record: Record | undefined) => record?.get('label')?.ifString()?.asString()?.getValue()
655
+
656
+ // Handle forEach item pills (format: "uuid.item.fieldName" or "uuid.item")
657
+ // Check if prefix is a UUID (forEach instance ui_id)
658
+ if (prefix && isUuidPrefix(prefix) && varName === 'item' && forEachMetadataMap) {
659
+ const forEachMetadata = forEachMetadataMap.get(prefix)
660
+ if (forEachMetadata) {
661
+ // Build label: "2 - For Each➛Problem Record➛Number"
662
+ labelParts.push(`${forEachMetadata.stepNumber} - For Each - `)
663
+
664
+ // Add table name or generic "Record"
665
+ if (forEachMetadata.tableName) {
666
+ labelParts.push(`${forEachMetadata.tableName} Record`)
667
+ } else {
668
+ labelParts.push('item')
669
+ }
670
+
671
+ // Add remaining field segments with capitalized names
672
+ if (segments.length > 2) {
673
+ const fieldSegments = segments.slice(2).map((segment) =>
674
+ segment
675
+ .split('_')
676
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
677
+ .join(' ')
678
+ )
679
+ labelParts.push(...fieldSegments)
680
+ }
681
+ }
682
+ }
683
+ // Handle trigger data pills (format: "Created_1.table_name" or "Inbound Email_1.body_text")
684
+ else if (prefix?.endsWith('_1') && varName && triggerData) {
685
+ const triggerOutput = triggerData.outputs.get(varName)
686
+ const triggerName = prefix.slice(0, -2) // Remove "_1" suffix
687
+ const firstLabelPart = TRIGGER_NAME_TO_LABEL_MAP[triggerName] || `Trigger - ${triggerName}`
688
+ labelParts.push(firstLabelPart)
689
+ const tableName = triggerData.inputs.get('table') as string | undefined
690
+
691
+ if (varName === 'current') {
692
+ labelParts.push(`${tableName} Record`)
693
+ const formattedSegments = segments.slice(2).map((segment) =>
694
+ segment
695
+ .split('_')
696
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
697
+ .join(' ')
698
+ )
699
+ labelParts.push(...formattedSegments)
700
+ } else if (triggerOutput) {
701
+ // Map trigger name to its display label, or construct default if not in map
702
+ labelParts.push(varName === 'table_name' && tableName ? `${tableName} Table` : triggerOutput.label)
703
+ extractedType = triggerOutput.type
704
+ }
705
+ } else if (prefix === 'flow_variable' && varName) {
706
+ varDef = flowVarDefMap.get(varName)
707
+ labelParts.push('Flow Variables')
708
+ const defLabel = getLabel(varDef)
709
+ if (defLabel) {
710
+ labelParts.push(defLabel)
711
+ }
712
+
713
+ if (varDef) {
714
+ const attributesStr = varDef.get('attributes')?.ifString()?.getValue() ?? ''
715
+ // const attributes = parseAttributesToObject(attributesStr)
716
+ const coTypeName = getAttributeValue(attributesStr, 'co_type_name')
717
+
718
+ if (coTypeName) {
719
+ const coRecord = relatedRecords.find(
720
+ (rec) =>
721
+ rec.getTable() === 'sys_complex_object' &&
722
+ rec.get('name')?.asString()?.getValue() === coTypeName
723
+ )
724
+
725
+ if (coRecord) {
726
+ extractedType = extractLabelsFromComplexObject(segments, coRecord, labelParts)
727
+ }
728
+ }
729
+ }
730
+ } else if (prefix === 'subflow' && varName) {
731
+ varDef = subflowInputDefMap.get(varName)
732
+ labelParts.push('Input')
733
+ const defLabel = getLabel(varDef)
734
+ if (defLabel) {
735
+ labelParts.push(defLabel)
736
+ }
737
+
738
+ if (varDef) {
739
+ const attributesStr = varDef.get('attributes')?.ifString()?.getValue() ?? ''
740
+ const attributes = parseAttributesToObject(attributesStr)
741
+ const coTypeName = attributes.co_type_name
742
+
743
+ if (coTypeName) {
744
+ const coRecord = relatedRecords.find(
745
+ (rec) =>
746
+ rec.getTable() === 'sys_complex_object' &&
747
+ rec.get('name')?.asString()?.getValue() === coTypeName
748
+ )
749
+
750
+ if (coRecord) {
751
+ extractedType = extractLabelsFromComplexObject(segments, coRecord, labelParts)
752
+ }
753
+ }
754
+ }
755
+ } else {
756
+ // Handle other data pill types (trigger, inputs, outputs, etc.)
757
+ // Add all path segments which will be joined with ➛ in processDataPill
758
+ labelParts.push(...segments)
759
+ }
760
+
761
+ return { labelParts, varDef, extractedType }
762
+ }
763
+
764
+ /**
765
+ * Processes a single data pill and enriches it with label, type, and reference metadata
766
+ */
767
+ function processDataPill(
768
+ varMeta: any,
769
+ flowVarDefMap: Map<string, Record>,
770
+ subflowInputDefMap: Map<string, Record>,
771
+ relatedRecords: Record[],
772
+ triggerData?: { inputs: Map<string, any>; outputs: Map<string, { label: string; type: string }> },
773
+ forEachMetadataMap?: Map<string, { stepNumber: number; tableName: string | null }>
774
+ ): void {
775
+ const varKey = varMeta.name
776
+ // Now the datapill structure is {{datapill.path|datatype}}, hence we need to split below
777
+ const segments = varKey.split('.')
778
+
779
+ const { labelParts, varDef, extractedType } = resolveDataPillMetadata(
780
+ segments,
781
+ flowVarDefMap,
782
+ subflowInputDefMap,
783
+ relatedRecords,
784
+ triggerData,
785
+ forEachMetadataMap
786
+ )
787
+
788
+ if (labelParts.length > 0) {
789
+ varMeta.label = labelParts.join('➛')
790
+ }
791
+
792
+ if (extractedType) {
793
+ varMeta.type = extractedType
794
+ varMeta.base_type = extractedType
795
+ }
796
+
797
+ // Note: parent_table_name, column_name, and reference are already set
798
+ // by updateLabelCacheForPill when parsing the pill string metadata
799
+
800
+ if (varDef && !varMeta.type) {
801
+ const internalType = varDef.get('internal_type')?.ifString()?.asString()?.getValue() || varMeta.column_type
802
+ varMeta.type = internalType
803
+ varMeta.base_type = internalType
804
+ }
805
+
806
+ if (varDef) {
807
+ varMeta.reference_table = varDef.get('reference_table')?.ifString()?.asString()?.getValue() || null
808
+ varMeta.reference_display = varDef.get('reference_display')?.ifString()?.asString()?.getValue() || null
809
+ }
810
+ }
811
+
812
+ /**
813
+ * Extracts and aggregates label cache data from instance record attributes.
814
+ * Returns a new map with enriched data pill metadata.
815
+ */
816
+ export function extractLabelCache(
817
+ flowVarDefMap: Map<string, Record>,
818
+ subflowInputDefMap: Map<string, Record>,
819
+ relatedRecords: Record[],
820
+ existingLabelCacheMap?: Map<string, any>,
821
+ triggerData?: { inputs: Map<string, any>; outputs: Map<string, { label: string; type: string }> },
822
+ forEachMetadataMap?: Map<string, { stepNumber: number; tableName: string | null }>
823
+ ): Map<string, any> {
824
+ const labelCacheMap = new Map(existingLabelCacheMap)
825
+ for (const key of labelCacheMap.keys()) {
826
+ const varMeta = labelCacheMap.get(key)
827
+ if (!varMeta.label) {
828
+ processDataPill(varMeta, flowVarDefMap, subflowInputDefMap, relatedRecords, triggerData, forEachMetadataMap)
829
+ }
830
+ }
831
+ return labelCacheMap
832
+ }
833
+
834
+ // ============================================================================
835
+ // Instance Data Pill Metadata Generation
836
+ // ============================================================================
837
+
838
+ /**
839
+ * Builds data pill metadata attributes for instance records.
840
+ * Used by action and subflow instances to track data pill usage.
841
+ *
842
+ * This metadata is stored in the instance's attributes field and later enriched in
843
+ * the flow definition's label_cache with proper labels, types, and references.
844
+ *
845
+ * @param dataPillMetadata - Map of data pill metadata collected during instance processing
846
+ * @param instanceUiId - The UUID of the instance
847
+ * @returns Array of data pill metadata attributes ready for instance record
848
+ */
849
+
850
+ export function buildDataPillAttributes(dataPillMetadata: Map<string, any>, instanceUiId: string): any[] {
851
+ const dataPillAttributes: any[] = []
852
+ for (const [, pillInfo] of dataPillMetadata.entries()) {
853
+ dataPillAttributes.push({
854
+ name: pillInfo.dataPillPath,
855
+ label: '', // Will be enriched by processDataPill in extractLabelCacheFromAttributes
856
+ reference: null,
857
+ reference_display: null,
858
+ type: 'string',
859
+ base_type: 'string',
860
+ parent_table_name: null,
861
+ column_name: null,
862
+ choices: [],
863
+ usedInstances: {
864
+ [instanceUiId]: [pillInfo.inputFieldName],
865
+ },
866
+ attributes: {},
867
+ })
868
+ }
869
+ return dataPillAttributes
870
+ }