@servicenow/sdk-build-plugins 4.6.1 → 4.7.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 (279) hide show
  1. package/dist/acl-plugin.js +0 -3
  2. package/dist/acl-plugin.js.map +1 -1
  3. package/dist/applicability-plugin.js +0 -2
  4. package/dist/applicability-plugin.js.map +1 -1
  5. package/dist/application-menu-plugin.js +0 -2
  6. package/dist/application-menu-plugin.js.map +1 -1
  7. package/dist/arrow-function-plugin.js +0 -1
  8. package/dist/arrow-function-plugin.js.map +1 -1
  9. package/dist/atf/test-plugin.js +0 -2
  10. package/dist/atf/test-plugin.js.map +1 -1
  11. package/dist/basic-syntax-plugin.js +0 -1
  12. package/dist/basic-syntax-plugin.js.map +1 -1
  13. package/dist/business-rule-plugin.js +0 -1
  14. package/dist/business-rule-plugin.js.map +1 -1
  15. package/dist/call-expression-plugin.js +0 -1
  16. package/dist/call-expression-plugin.js.map +1 -1
  17. package/dist/claims-plugin.js +0 -1
  18. package/dist/claims-plugin.js.map +1 -1
  19. package/dist/client-script-plugin.js +0 -1
  20. package/dist/client-script-plugin.js.map +1 -1
  21. package/dist/column-plugin.js +24 -7
  22. package/dist/column-plugin.js.map +1 -1
  23. package/dist/cross-scope-privilege-plugin.js +0 -1
  24. package/dist/cross-scope-privilege-plugin.js.map +1 -1
  25. package/dist/dashboard/dashboard-plugin.js +0 -2
  26. package/dist/dashboard/dashboard-plugin.js.map +1 -1
  27. package/dist/data-plugin.js +0 -1
  28. package/dist/data-plugin.js.map +1 -1
  29. package/dist/data-policy-plugin.d.ts +2 -0
  30. package/dist/data-policy-plugin.js +276 -0
  31. package/dist/data-policy-plugin.js.map +1 -0
  32. package/dist/email-notification-plugin.js +2 -3
  33. package/dist/email-notification-plugin.js.map +1 -1
  34. package/dist/flow/flow-logic/flow-logic-constants.d.ts +2 -0
  35. package/dist/flow/flow-logic/flow-logic-constants.js +6 -1
  36. package/dist/flow/flow-logic/flow-logic-constants.js.map +1 -1
  37. package/dist/flow/flow-logic/flow-logic-diagnostics.js +192 -56
  38. package/dist/flow/flow-logic/flow-logic-diagnostics.js.map +1 -1
  39. package/dist/flow/flow-logic/flow-logic-plugin-helpers.d.ts +2 -1
  40. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js +44 -5
  41. package/dist/flow/flow-logic/flow-logic-plugin-helpers.js.map +1 -1
  42. package/dist/flow/flow-logic/flow-logic-plugin.js +279 -29
  43. package/dist/flow/flow-logic/flow-logic-plugin.js.map +1 -1
  44. package/dist/flow/flow-logic/flow-logic-shapes.d.ts +15 -0
  45. package/dist/flow/flow-logic/flow-logic-shapes.js +25 -1
  46. package/dist/flow/flow-logic/flow-logic-shapes.js.map +1 -1
  47. package/dist/flow/plugins/approval-rules-plugin.js +0 -1
  48. package/dist/flow/plugins/approval-rules-plugin.js.map +1 -1
  49. package/dist/flow/plugins/flow-action-definition-plugin.js +804 -205
  50. package/dist/flow/plugins/flow-action-definition-plugin.js.map +1 -1
  51. package/dist/flow/plugins/flow-data-pill-plugin.js +3 -5
  52. package/dist/flow/plugins/flow-data-pill-plugin.js.map +1 -1
  53. package/dist/flow/plugins/flow-definition-plugin.js +84 -17
  54. package/dist/flow/plugins/flow-definition-plugin.js.map +1 -1
  55. package/dist/flow/plugins/flow-diagnostics-plugin.js +65 -3
  56. package/dist/flow/plugins/flow-diagnostics-plugin.js.map +1 -1
  57. package/dist/flow/plugins/flow-instance-plugin.js +13 -5
  58. package/dist/flow/plugins/flow-instance-plugin.js.map +1 -1
  59. package/dist/flow/plugins/flow-trigger-instance-plugin.js +0 -1
  60. package/dist/flow/plugins/flow-trigger-instance-plugin.js.map +1 -1
  61. package/dist/flow/plugins/inline-script-plugin.js +0 -1
  62. package/dist/flow/plugins/inline-script-plugin.js.map +1 -1
  63. package/dist/flow/plugins/step-definition-plugin.js +0 -2
  64. package/dist/flow/plugins/step-definition-plugin.js.map +1 -1
  65. package/dist/flow/plugins/step-instance-plugin.js +216 -77
  66. package/dist/flow/plugins/step-instance-plugin.js.map +1 -1
  67. package/dist/flow/plugins/trigger-plugin.js +0 -2
  68. package/dist/flow/plugins/trigger-plugin.js.map +1 -1
  69. package/dist/flow/plugins/wfa-datapill-plugin.js +0 -1
  70. package/dist/flow/plugins/wfa-datapill-plugin.js.map +1 -1
  71. package/dist/flow/utils/datapill-transformer.js +9 -5
  72. package/dist/flow/utils/datapill-transformer.js.map +1 -1
  73. package/dist/flow/utils/flow-constants.d.ts +12 -0
  74. package/dist/flow/utils/flow-constants.js +17 -3
  75. package/dist/flow/utils/flow-constants.js.map +1 -1
  76. package/dist/flow/utils/flow-io-to-record.d.ts +1 -1
  77. package/dist/flow/utils/flow-io-to-record.js +21 -13
  78. package/dist/flow/utils/flow-io-to-record.js.map +1 -1
  79. package/dist/flow/utils/flow-pill-utils.d.ts +26 -0
  80. package/dist/flow/utils/flow-pill-utils.js +50 -0
  81. package/dist/flow/utils/flow-pill-utils.js.map +1 -0
  82. package/dist/flow/utils/flow-stage-processor.d.ts +138 -0
  83. package/dist/flow/utils/flow-stage-processor.js +665 -0
  84. package/dist/flow/utils/flow-stage-processor.js.map +1 -0
  85. package/dist/flow/utils/pill-string-parser.js +28 -43
  86. package/dist/flow/utils/pill-string-parser.js.map +1 -1
  87. package/dist/flow/utils/utils.d.ts +11 -6
  88. package/dist/flow/utils/utils.js +37 -28
  89. package/dist/flow/utils/utils.js.map +1 -1
  90. package/dist/form-plugin.js +4 -14
  91. package/dist/form-plugin.js.map +1 -1
  92. package/dist/html-import-plugin.js +0 -1
  93. package/dist/html-import-plugin.js.map +1 -1
  94. package/dist/import-sets-plugin.js +0 -2
  95. package/dist/import-sets-plugin.js.map +1 -1
  96. package/dist/inbound-email-action-plugin.js +0 -1
  97. package/dist/inbound-email-action-plugin.js.map +1 -1
  98. package/dist/index.d.ts +2 -1
  99. package/dist/index.js +5 -1
  100. package/dist/index.js.map +1 -1
  101. package/dist/instance-scan-plugin.js +0 -7
  102. package/dist/instance-scan-plugin.js.map +1 -1
  103. package/dist/json-plugin.js +0 -1
  104. package/dist/json-plugin.js.map +1 -1
  105. package/dist/list-plugin.js +4 -1
  106. package/dist/list-plugin.js.map +1 -1
  107. package/dist/now-attach-plugin.js +0 -1
  108. package/dist/now-attach-plugin.js.map +1 -1
  109. package/dist/now-config-plugin.js +0 -1
  110. package/dist/now-config-plugin.js.map +1 -1
  111. package/dist/now-id-plugin.js +0 -1
  112. package/dist/now-id-plugin.js.map +1 -1
  113. package/dist/now-include-plugin.js +0 -1
  114. package/dist/now-include-plugin.js.map +1 -1
  115. package/dist/now-ref-plugin.js +0 -1
  116. package/dist/now-ref-plugin.js.map +1 -1
  117. package/dist/now-unresolved-plugin.js +0 -1
  118. package/dist/now-unresolved-plugin.js.map +1 -1
  119. package/dist/package-json-plugin.js +3 -2
  120. package/dist/package-json-plugin.js.map +1 -1
  121. package/dist/property-plugin.js +0 -2
  122. package/dist/property-plugin.js.map +1 -1
  123. package/dist/record-plugin.d.ts +2 -0
  124. package/dist/record-plugin.js +2 -2
  125. package/dist/record-plugin.js.map +1 -1
  126. package/dist/repack/lint/Rules.d.ts +1 -2
  127. package/dist/rest-api-plugin.js +6 -5
  128. package/dist/rest-api-plugin.js.map +1 -1
  129. package/dist/role-plugin.js +0 -1
  130. package/dist/role-plugin.js.map +1 -1
  131. package/dist/schedule-script/scheduled-script-plugin.js +5 -4
  132. package/dist/schedule-script/scheduled-script-plugin.js.map +1 -1
  133. package/dist/script-action-plugin.js +0 -2
  134. package/dist/script-action-plugin.js.map +1 -1
  135. package/dist/script-include-plugin.js +0 -4
  136. package/dist/script-include-plugin.js.map +1 -1
  137. package/dist/server-module-plugin/index.js +2 -3
  138. package/dist/server-module-plugin/index.js.map +1 -1
  139. package/dist/service-catalog/catalog-clientscript-plugin.js +0 -2
  140. package/dist/service-catalog/catalog-clientscript-plugin.js.map +1 -1
  141. package/dist/service-catalog/catalog-item-plugin.js +0 -2
  142. package/dist/service-catalog/catalog-item-plugin.js.map +1 -1
  143. package/dist/service-catalog/catalog-ui-policy-plugin.js +0 -2
  144. package/dist/service-catalog/catalog-ui-policy-plugin.js.map +1 -1
  145. package/dist/service-catalog/sc-record-producer-plugin.js +0 -2
  146. package/dist/service-catalog/sc-record-producer-plugin.js.map +1 -1
  147. package/dist/service-catalog/variable-set-plugin.js +0 -2
  148. package/dist/service-catalog/variable-set-plugin.js.map +1 -1
  149. package/dist/service-portal/angular-provider-plugin.js +0 -2
  150. package/dist/service-portal/angular-provider-plugin.js.map +1 -1
  151. package/dist/service-portal/dependency-plugin.js +3 -5
  152. package/dist/service-portal/dependency-plugin.js.map +1 -1
  153. package/dist/service-portal/header-footer-plugin.js +3 -5
  154. package/dist/service-portal/header-footer-plugin.js.map +1 -1
  155. package/dist/service-portal/menu-plugin.js +0 -1
  156. package/dist/service-portal/menu-plugin.js.map +1 -1
  157. package/dist/service-portal/page-plugin.js +0 -1
  158. package/dist/service-portal/page-plugin.js.map +1 -1
  159. package/dist/service-portal/page-route-map-plugin.js +0 -1
  160. package/dist/service-portal/page-route-map-plugin.js.map +1 -1
  161. package/dist/service-portal/portal-plugin.js +0 -2
  162. package/dist/service-portal/portal-plugin.js.map +1 -1
  163. package/dist/service-portal/theme-plugin.js +0 -2
  164. package/dist/service-portal/theme-plugin.js.map +1 -1
  165. package/dist/service-portal/widget-plugin.js +3 -5
  166. package/dist/service-portal/widget-plugin.js.map +1 -1
  167. package/dist/sla-plugin.js +0 -2
  168. package/dist/sla-plugin.js.map +1 -1
  169. package/dist/static-content-plugin.js +32 -3
  170. package/dist/static-content-plugin.js.map +1 -1
  171. package/dist/table-plugin.js +102 -11
  172. package/dist/table-plugin.js.map +1 -1
  173. package/dist/ui-action-plugin.js +26 -17
  174. package/dist/ui-action-plugin.js.map +1 -1
  175. package/dist/ui-page-plugin.js +159 -17
  176. package/dist/ui-page-plugin.js.map +1 -1
  177. package/dist/ui-policy-plugin.js +0 -1
  178. package/dist/ui-policy-plugin.js.map +1 -1
  179. package/dist/user-preference-plugin.js +0 -2
  180. package/dist/user-preference-plugin.js.map +1 -1
  181. package/dist/utils.d.ts +1 -9
  182. package/dist/utils.js +0 -14
  183. package/dist/utils.js.map +1 -1
  184. package/dist/ux-list-menu-config-plugin.js +0 -2
  185. package/dist/ux-list-menu-config-plugin.js.map +1 -1
  186. package/dist/view-plugin.js +0 -1
  187. package/dist/view-plugin.js.map +1 -1
  188. package/dist/workspace-plugin.js +0 -2
  189. package/dist/workspace-plugin.js.map +1 -1
  190. package/package.json +6 -6
  191. package/src/acl-plugin.ts +1 -4
  192. package/src/applicability-plugin.ts +0 -2
  193. package/src/application-menu-plugin.ts +0 -2
  194. package/src/arrow-function-plugin.ts +0 -1
  195. package/src/atf/test-plugin.ts +0 -2
  196. package/src/basic-syntax-plugin.ts +0 -1
  197. package/src/business-rule-plugin.ts +1 -2
  198. package/src/call-expression-plugin.ts +0 -1
  199. package/src/claims-plugin.ts +0 -1
  200. package/src/client-script-plugin.ts +1 -2
  201. package/src/column-plugin.ts +29 -9
  202. package/src/cross-scope-privilege-plugin.ts +1 -2
  203. package/src/dashboard/dashboard-plugin.ts +0 -2
  204. package/src/data-plugin.ts +0 -1
  205. package/src/data-policy-plugin.ts +333 -0
  206. package/src/email-notification-plugin.ts +8 -4
  207. package/src/flow/flow-logic/flow-logic-constants.ts +6 -0
  208. package/src/flow/flow-logic/flow-logic-diagnostics.ts +236 -58
  209. package/src/flow/flow-logic/flow-logic-plugin-helpers.ts +59 -6
  210. package/src/flow/flow-logic/flow-logic-plugin.ts +368 -38
  211. package/src/flow/flow-logic/flow-logic-shapes.ts +25 -0
  212. package/src/flow/plugins/approval-rules-plugin.ts +0 -1
  213. package/src/flow/plugins/flow-action-definition-plugin.ts +940 -208
  214. package/src/flow/plugins/flow-data-pill-plugin.ts +3 -5
  215. package/src/flow/plugins/flow-definition-plugin.ts +159 -26
  216. package/src/flow/plugins/flow-diagnostics-plugin.ts +89 -3
  217. package/src/flow/plugins/flow-instance-plugin.ts +26 -12
  218. package/src/flow/plugins/flow-trigger-instance-plugin.ts +0 -1
  219. package/src/flow/plugins/inline-script-plugin.ts +0 -1
  220. package/src/flow/plugins/step-definition-plugin.ts +0 -2
  221. package/src/flow/plugins/step-instance-plugin.ts +259 -65
  222. package/src/flow/plugins/trigger-plugin.ts +0 -2
  223. package/src/flow/plugins/wfa-datapill-plugin.ts +0 -1
  224. package/src/flow/utils/datapill-transformer.ts +13 -5
  225. package/src/flow/utils/flow-constants.ts +19 -1
  226. package/src/flow/utils/flow-io-to-record.ts +29 -19
  227. package/src/flow/utils/flow-pill-utils.ts +48 -0
  228. package/src/flow/utils/flow-stage-processor.ts +831 -0
  229. package/src/flow/utils/pill-string-parser.ts +29 -47
  230. package/src/flow/utils/utils.ts +39 -35
  231. package/src/form-plugin.ts +5 -15
  232. package/src/html-import-plugin.ts +0 -1
  233. package/src/import-sets-plugin.ts +0 -2
  234. package/src/inbound-email-action-plugin.ts +1 -2
  235. package/src/index.ts +7 -1
  236. package/src/instance-scan-plugin.ts +0 -7
  237. package/src/json-plugin.ts +0 -1
  238. package/src/list-plugin.ts +6 -2
  239. package/src/now-attach-plugin.ts +0 -1
  240. package/src/now-config-plugin.ts +0 -1
  241. package/src/now-id-plugin.ts +0 -1
  242. package/src/now-include-plugin.ts +0 -1
  243. package/src/now-ref-plugin.ts +0 -1
  244. package/src/now-unresolved-plugin.ts +0 -1
  245. package/src/package-json-plugin.ts +8 -3
  246. package/src/property-plugin.ts +0 -2
  247. package/src/record-plugin.ts +3 -3
  248. package/src/repack/lint/Rules.ts +1 -1
  249. package/src/rest-api-plugin.ts +7 -6
  250. package/src/role-plugin.ts +1 -2
  251. package/src/schedule-script/scheduled-script-plugin.ts +11 -5
  252. package/src/script-action-plugin.ts +0 -2
  253. package/src/script-include-plugin.ts +0 -4
  254. package/src/server-module-plugin/index.ts +2 -3
  255. package/src/service-catalog/catalog-clientscript-plugin.ts +0 -2
  256. package/src/service-catalog/catalog-item-plugin.ts +0 -2
  257. package/src/service-catalog/catalog-ui-policy-plugin.ts +0 -2
  258. package/src/service-catalog/sc-record-producer-plugin.ts +0 -2
  259. package/src/service-catalog/variable-set-plugin.ts +0 -2
  260. package/src/service-portal/angular-provider-plugin.ts +0 -2
  261. package/src/service-portal/dependency-plugin.ts +0 -2
  262. package/src/service-portal/header-footer-plugin.ts +0 -2
  263. package/src/service-portal/menu-plugin.ts +1 -2
  264. package/src/service-portal/page-plugin.ts +1 -2
  265. package/src/service-portal/page-route-map-plugin.ts +1 -2
  266. package/src/service-portal/portal-plugin.ts +0 -2
  267. package/src/service-portal/theme-plugin.ts +0 -2
  268. package/src/service-portal/widget-plugin.ts +0 -2
  269. package/src/sla-plugin.ts +0 -2
  270. package/src/static-content-plugin.ts +37 -4
  271. package/src/table-plugin.ts +118 -16
  272. package/src/ui-action-plugin.ts +30 -17
  273. package/src/ui-page-plugin.ts +188 -20
  274. package/src/ui-policy-plugin.ts +1 -2
  275. package/src/user-preference-plugin.ts +0 -2
  276. package/src/utils.ts +0 -15
  277. package/src/ux-list-menu-config-plugin.ts +0 -2
  278. package/src/view-plugin.ts +0 -1
  279. package/src/workspace-plugin.ts +0 -2
@@ -0,0 +1,665 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stageDurationToString = stageDurationToString;
4
+ exports.processHeaderStages = processHeaderStages;
5
+ exports.createSubflowStageRecords = createSubflowStageRecords;
6
+ exports.extractStageKey = extractStageKey;
7
+ exports.unwrapCall = unwrapCall;
8
+ exports.collectSubflowDefName = collectSubflowDefName;
9
+ exports.resolveNestedStagesInline = resolveNestedStagesInline;
10
+ exports.resolveNestedStagesForTryCatch = resolveNestedStagesForTryCatch;
11
+ exports.finalizeStageRecords = finalizeStageRecords;
12
+ exports.toSafeIdentifier = toSafeIdentifier;
13
+ exports.buildStageShapes = buildStageShapes;
14
+ exports.buildStageInsertionMap = buildStageInsertionMap;
15
+ exports.createStageCallShape = createStageCallShape;
16
+ exports.insertNestedStageShapes = insertNestedStageShapes;
17
+ const sdk_build_core_1 = require("@servicenow/sdk-build-core");
18
+ const arrow_function_plugin_1 = require("../../arrow-function-plugin");
19
+ const now_id_plugin_1 = require("../../now-id-plugin");
20
+ const flow_constants_1 = require("./flow-constants");
21
+ const flow_logic_constants_1 = require("../flow-logic/flow-logic-constants");
22
+ const utils_1 = require("./utils");
23
+ // ---------------------------------------------------------------------------
24
+ // Duration conversion (Fluent → XML)
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Converts a `Duration({...})` CallExpressionShape from the Fluent API into the
28
+ * `YYYY-MM-DD HH:MM:SS` string stored in `sys_hub_flow_stage.duration`.
29
+ *
30
+ * `Duration()` is an identity function — ObjectShape.get() resolves it with
31
+ * resolve=true by default, but CallExpressionShape.resolve() returns itself
32
+ * (can't evaluate the body). We therefore read with resolve=false to get the
33
+ * raw CallExpressionShape, then delegate to DurationShape for formatting.
34
+ * Falls back to zero duration when absent or not a Duration() call.
35
+ */
36
+ function stageDurationToString(stageConfig) {
37
+ const raw = stageConfig.get('duration', false);
38
+ const ce = raw.if(sdk_build_core_1.CallExpressionShape) ? raw.as(sdk_build_core_1.CallExpressionShape) : undefined;
39
+ if (ce && ce.getCallee() === sdk_build_core_1.DATA_HELPER_NAMES.DURATION) {
40
+ return new sdk_build_core_1.DurationShape({
41
+ source: raw.getSource(),
42
+ value: ce.getArgument(0).asObject(),
43
+ })
44
+ .toString()
45
+ .getValue();
46
+ }
47
+ return flow_constants_1.STAGE_DEFAULT_DURATION;
48
+ }
49
+ // camelCase API key → snake_case DB key for FlowStageStates fields
50
+ const STATE_KEY_MAP = {
51
+ pending: 'pending',
52
+ inProgress: 'in_progress',
53
+ complete: 'complete',
54
+ error: 'error',
55
+ skipped: 'skipped',
56
+ };
57
+ const DEFAULT_STATES = {
58
+ in_progress: 'In progress',
59
+ complete: 'Completed',
60
+ error: 'Error',
61
+ pending: 'Pending - has not started',
62
+ skipped: 'Skipped',
63
+ };
64
+ // ---------------------------------------------------------------------------
65
+ // Phase 1 — Header stage pre-creation
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Reads the `stages: {}` config object from the Flow/Subflow first argument
69
+ * and creates `sys_hub_flow_stage` records for each declared stage.
70
+ *
71
+ * Records are created WITHOUT `component_indexes` — those are computed by
72
+ * `finalizeStageRecords` after the body loop has determined which actions
73
+ * each stage covers.
74
+ *
75
+ * `stage_id` is derived from the record's own coalesce-based sys_id (which the
76
+ * factory makes stable from `flow + value`), so it is deterministic across
77
+ * builds without requiring a separate hash.
78
+ *
79
+ * @returns Map keyed by the stages object property name (e.g. `'triage'`).
80
+ */
81
+ async function processHeaderStages(flowConfiguration, flowDefinitionRecord, factory) {
82
+ const headerStageRecords = new Map();
83
+ if (!flowConfiguration.has('stages')) {
84
+ return headerStageRecords;
85
+ }
86
+ const stagesObj = flowConfiguration.get('stages').asObject();
87
+ for (const [key, stageVal] of stagesObj.entries()) {
88
+ const stageCE = stageVal.if(sdk_build_core_1.CallExpressionShape) ? stageVal.as(sdk_build_core_1.CallExpressionShape) : undefined;
89
+ if (!stageCE) {
90
+ continue;
91
+ }
92
+ const stageConfig = stageCE.getArgument(0).asObject();
93
+ const stageValue = stageConfig.get('value').ifString()?.getValue() ?? '';
94
+ const statesArg = stageConfig.get('states').ifObject()?.asObject();
95
+ let statesJson;
96
+ if (statesArg) {
97
+ statesJson = {};
98
+ for (const [apiKey, dbKey] of Object.entries(STATE_KEY_MAP)) {
99
+ const val = statesArg.get(apiKey).ifString()?.getValue();
100
+ if (val) {
101
+ statesJson[dbKey] = val;
102
+ }
103
+ }
104
+ }
105
+ else {
106
+ statesJson = { ...DEFAULT_STATES };
107
+ }
108
+ const stageRecord = await factory.createRecord({
109
+ source: stageCE,
110
+ table: flow_constants_1.FLOW_STAGE_TABLE,
111
+ properties: {
112
+ flow: flowDefinitionRecord.getId().getValue(),
113
+ label: stageConfig.get('label').ifString()?.getValue() ?? '',
114
+ value: stageValue,
115
+ duration: stageDurationToString(stageConfig),
116
+ always_show: stageConfig.get('alwaysShow').ifBoolean()?.getValue() ?? false,
117
+ states: JSON.stringify(statesJson),
118
+ type: 'standard',
119
+ ancestor_array_position: 0,
120
+ ancestor_component_id: '',
121
+ ancestor_stage_id: '',
122
+ ancestral_if_else_logic: '',
123
+ },
124
+ });
125
+ // stage_id reuses the record's coalesce-based sys_id — stable across builds
126
+ // because sys_hub_flow_stage coalesces on ['flow', 'value'].
127
+ headerStageRecords.set(key, stageRecord.merge({ stage_id: (0, utils_1.sysIdToUuid)(String(stageRecord.getId().getValue())) }));
128
+ }
129
+ return headerStageRecords;
130
+ }
131
+ // ---------------------------------------------------------------------------
132
+ // Phase 2 — Subflow stage creation
133
+ // ---------------------------------------------------------------------------
134
+ /**
135
+ * Scans `relatedRecords` for subflow instances with `show_stages=true` and
136
+ * creates a separate `sys_hub_flow_stage` record with `type:'subflow'` for each.
137
+ *
138
+ * These differ from developer-declared stages:
139
+ * - `type` = `'subflow'` (not `'standard'`)
140
+ * - `value` = the subflow instance's `ui_id` (UUID)
141
+ * - `label` = the subflow definition's name (resolved via `subflowDefNames` map)
142
+ * - `component_indexes`= empty — the platform links via `value` (the UUID)
143
+ *
144
+ * @param pendingStagesLength Number of developer-declared stages — subflow stages
145
+ * are ordered after them.
146
+ * @param subflowDefNames Map of subflow definition sys_id → name, built by the
147
+ * caller from the original shapes.
148
+ */
149
+ async function createSubflowStageRecords(relatedRecords, pendingStagesLength, flowDefinitionRecord, factory, subflowDefNames) {
150
+ const subflowStageRecords = [];
151
+ let subflowStageOrder = pendingStagesLength;
152
+ for (const rec of relatedRecords) {
153
+ if (rec.getTable() !== 'sys_hub_sub_flow_instance_v2') {
154
+ continue;
155
+ }
156
+ const showStages = rec.get('show_stages')?.getValue();
157
+ if (showStages !== true && showStages !== 'true') {
158
+ continue;
159
+ }
160
+ const uiId = String(rec.get('ui_id')?.getValue() ?? '');
161
+ if (!uiId) {
162
+ continue;
163
+ }
164
+ const defSysId = String(rec.get('subflow')?.getValue() ?? '');
165
+ const label = subflowDefNames.get(defSysId) ?? '';
166
+ const stageRecord = await factory.createRecord({
167
+ source: flowDefinitionRecord,
168
+ table: flow_constants_1.FLOW_STAGE_TABLE,
169
+ properties: {
170
+ flow: flowDefinitionRecord.getId().getValue(),
171
+ type: 'subflow',
172
+ value: uiId,
173
+ label,
174
+ always_show: false,
175
+ states: '{}',
176
+ component_indexes: '',
177
+ order: subflowStageOrder,
178
+ ancestor_array_position: 0,
179
+ ancestor_component_id: '',
180
+ ancestor_stage_id: '',
181
+ ancestral_if_else_logic: '',
182
+ duration: flow_constants_1.STAGE_DEFAULT_DURATION,
183
+ },
184
+ });
185
+ // stage_id reuses the record's coalesce-based sys_id — stable because
186
+ // sys_hub_flow_stage coalesces on ['flow', 'value'] and value = uiId.
187
+ subflowStageRecords.push(stageRecord.merge({ stage_id: (0, utils_1.sysIdToUuid)(String(stageRecord.getId().getValue())) }));
188
+ subflowStageOrder++;
189
+ }
190
+ return subflowStageRecords;
191
+ }
192
+ // ---------------------------------------------------------------------------
193
+ // Body scanning — collect stage markers & subflow definition names
194
+ // ---------------------------------------------------------------------------
195
+ /**
196
+ * Extracts the stage key from a `wfa.stage(params.stages.<key>)` call.
197
+ * Returns `undefined` when the argument is not a PropertyAccessShape.
198
+ */
199
+ function extractStageKey(callExpr) {
200
+ const arg = callExpr.getArgument(0, false);
201
+ if (!arg.if(sdk_build_core_1.PropertyAccessShape)) {
202
+ return undefined;
203
+ }
204
+ return arg.as(sdk_build_core_1.PropertyAccessShape).getLastElement().getName();
205
+ }
206
+ /**
207
+ * Extracts the NowIdKey (`$id` value) from the config object of an instance call.
208
+ * Checks argument positions 0 and 1 (actions use position 1, flow logic uses 0).
209
+ */
210
+ function extractNowIdKey(callExpr) {
211
+ for (const idx of [0, 1]) {
212
+ try {
213
+ const a = callExpr.getArgument(idx);
214
+ if (a?.if(sdk_build_core_1.ObjectShape)) {
215
+ const $id = a.as(sdk_build_core_1.ObjectShape).get('$id');
216
+ if ($id?.if(now_id_plugin_1.NowIdShape)) {
217
+ return String($id.as(now_id_plugin_1.NowIdShape).getValue());
218
+ }
219
+ }
220
+ }
221
+ catch {
222
+ /* skip */
223
+ }
224
+ }
225
+ return undefined;
226
+ }
227
+ /** Unwrap a statement to the underlying CallExpressionShape if applicable. */
228
+ function unwrapCall(stmt) {
229
+ const inner = stmt instanceof sdk_build_core_1.VariableStatementShape ? stmt.getInitializer() : stmt;
230
+ return inner instanceof sdk_build_core_1.CallExpressionShape ? inner : undefined;
231
+ }
232
+ /**
233
+ * Collects subflow definition name from a `wfa.subflow(defRecord, ...)` call
234
+ * and stores it in the provided map.
235
+ */
236
+ function collectSubflowDefName(callExpr, subflowDefNames) {
237
+ const defArg = callExpr.getArgument(0);
238
+ if (defArg?.isRecord()) {
239
+ const defRecord = defArg.as(sdk_build_core_1.Record);
240
+ const defSysId = String(defRecord.getId().getValue());
241
+ if (!subflowDefNames.has(defSysId)) {
242
+ subflowDefNames.set(defSysId, String(defRecord.get('name')?.getValue() ?? ''));
243
+ }
244
+ }
245
+ }
246
+ /**
247
+ * Resolves nested stage indexes inline during the main instance loop.
248
+ *
249
+ * Called when a flow logic instance (if/elseIf/else) is encountered.
250
+ * Builds a local NowIdKey → order map from the flat records (whose orders
251
+ * are known: `baseOrder + index`), then recursively scans the body for
252
+ * `wfa.stage()` calls and pushes resolved entries directly into `pendingStages`.
253
+ *
254
+ * Also collects subflow definition names from nested `wfa.subflow()` calls.
255
+ */
256
+ function resolveNestedStagesInline(callExpr, flatRecords, baseOrder, headerStageRecords, pendingStages, subflowDefNames, diagnostics) {
257
+ const bodyArg = callExpr.getArgument(1, false);
258
+ if (!bodyArg.if(arrow_function_plugin_1.ArrowFunctionShape)) {
259
+ return;
260
+ }
261
+ // Build NowIdKey → order map for these flat records
262
+ const orderByNowIdKey = new Map();
263
+ flatRecords.forEach((rec, idx) => {
264
+ const nk = String(rec.getId().getNowIdKey() ?? '');
265
+ if (nk) {
266
+ orderByNowIdKey.set(nk, baseOrder + idx);
267
+ }
268
+ });
269
+ resolveStagesInBody(bodyArg.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
270
+ }
271
+ /**
272
+ * Resolves nested stages inside a `tryCatch(config, { try, catch })` call.
273
+ * Scans both the `try` and `catch` arrow function bodies for `wfa.stage()` calls.
274
+ */
275
+ function resolveNestedStagesForTryCatch(callExpr, flatRecords, baseOrder, headerStageRecords, pendingStages, subflowDefNames, diagnostics) {
276
+ const handlersArg = callExpr.getArgument(1, false);
277
+ if (!handlersArg.if(sdk_build_core_1.ObjectShape)) {
278
+ return;
279
+ }
280
+ // Build NowIdKey → order map for these flat records
281
+ const orderByNowIdKey = new Map();
282
+ flatRecords.forEach((rec, idx) => {
283
+ const nk = String(rec.getId().getNowIdKey() ?? '');
284
+ if (nk) {
285
+ orderByNowIdKey.set(nk, baseOrder + idx);
286
+ }
287
+ });
288
+ const handlers = handlersArg.as(sdk_build_core_1.ObjectShape);
289
+ const tryHandler = handlers.get('try', false);
290
+ const catchHandler = handlers.get('catch', false);
291
+ if (tryHandler.if(arrow_function_plugin_1.ArrowFunctionShape)) {
292
+ resolveStagesInBody(tryHandler.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
293
+ }
294
+ if (catchHandler.if(arrow_function_plugin_1.ArrowFunctionShape)) {
295
+ resolveStagesInBody(catchHandler.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
296
+ }
297
+ }
298
+ /**
299
+ * Recursively scans an arrow-function body for:
300
+ * - `wfa.stage()` calls: resolves the order of the *next* non-stage instance
301
+ * from `orderByNowIdKey` and pushes directly to `pendingStages`.
302
+ * - `wfa.subflow()` calls: collects the definition name for showSubflowStage labels.
303
+ */
304
+ function resolveStagesInBody(body, headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics) {
305
+ const stmts = body.getStatements();
306
+ for (let i = 0; i < stmts.length; i++) {
307
+ const inner = unwrapCall(stmts[i]);
308
+ if (!inner) {
309
+ continue;
310
+ }
311
+ const callee = inner.getCallee();
312
+ // Recurse into flow logic bodies (if / elseIf / else)
313
+ if (callee === flow_logic_constants_1.FLOW_LOGIC.IF || callee === flow_logic_constants_1.FLOW_LOGIC.ELSEIF || callee === flow_logic_constants_1.FLOW_LOGIC.ELSE) {
314
+ const bodyArg = inner.getArgument(1, false);
315
+ if (bodyArg.if(arrow_function_plugin_1.ArrowFunctionShape)) {
316
+ resolveStagesInBody(bodyArg.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
317
+ }
318
+ continue;
319
+ }
320
+ // Recurse into tryCatch try/catch handler bodies
321
+ if (callee === flow_logic_constants_1.FLOW_LOGIC.TRY_CATCH) {
322
+ const handlersArg = inner.getArgument(1, false);
323
+ if (handlersArg.if(sdk_build_core_1.ObjectShape)) {
324
+ const handlers = handlersArg.as(sdk_build_core_1.ObjectShape);
325
+ const tryHandler = handlers.get('try', false);
326
+ const catchHandler = handlers.get('catch', false);
327
+ if (tryHandler.if(arrow_function_plugin_1.ArrowFunctionShape)) {
328
+ resolveStagesInBody(tryHandler.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
329
+ }
330
+ if (catchHandler.if(arrow_function_plugin_1.ArrowFunctionShape)) {
331
+ resolveStagesInBody(catchHandler.as(arrow_function_plugin_1.ArrowFunctionShape), headerStageRecords, orderByNowIdKey, pendingStages, subflowDefNames, diagnostics);
332
+ }
333
+ }
334
+ continue;
335
+ }
336
+ // Collect subflow definition names from nested bodies
337
+ if (callee === flow_constants_1.SUBFLOW_INSTANCE_API_NAME) {
338
+ collectSubflowDefName(inner, subflowDefNames);
339
+ }
340
+ if (callee !== flow_constants_1.STAGE_API_NAME) {
341
+ continue;
342
+ }
343
+ // Extract the stage key and resolve the order of the next non-stage instance
344
+ const key = extractStageKey(inner);
345
+ if (!key) {
346
+ diagnostics.error(inner, 'wfa.stage() argument must be a stage reference like params.stages.<key>.');
347
+ continue;
348
+ }
349
+ if (!headerStageRecords.has(key)) {
350
+ diagnostics.error(inner, `wfa.stage() references stage '${key}' which is not declared in the stages config.`);
351
+ continue;
352
+ }
353
+ for (let j = i + 1; j < stmts.length; j++) {
354
+ const next = unwrapCall(stmts[j]);
355
+ if (!next || next.getCallee() === flow_constants_1.STAGE_API_NAME) {
356
+ continue;
357
+ }
358
+ const nowIdKey = extractNowIdKey(next);
359
+ if (nowIdKey) {
360
+ const recOrder = orderByNowIdKey.get(nowIdKey);
361
+ if (recOrder != null) {
362
+ pendingStages.push({ startActionIndex: recOrder - 1, key });
363
+ }
364
+ }
365
+ break;
366
+ }
367
+ }
368
+ }
369
+ // ---------------------------------------------------------------------------
370
+ // Header stage finalisation
371
+ // ---------------------------------------------------------------------------
372
+ /**
373
+ * Computes `component_indexes` for each developer-declared stage and merges it
374
+ * onto the pre-created header record.
375
+ *
376
+ * Matching is by **key name**: the `key` stored in each `pendingStage` entry is
377
+ * looked up in `headerStageRecords`. This is correct even when the order of
378
+ * `wfa.stage()` calls in the body differs from the declaration order in the
379
+ * stages config header.
380
+ *
381
+ * A stage may appear multiple times in `pendingStages` (e.g. inside both an
382
+ * `if` and an `elseIf` body). All indexes for the same key are collected and
383
+ * joined with `,` into a single `component_indexes` value on one record.
384
+ *
385
+ * @returns Array of finalised stage records ready to be added to `relatedRecords`.
386
+ */
387
+ function finalizeStageRecords(pendingStages, headerStageRecords) {
388
+ // Group indexes by stage key, preserving encounter order for `order`.
389
+ const indexesByKey = new Map();
390
+ const keyOrder = [];
391
+ for (const entry of pendingStages) {
392
+ if (!entry) {
393
+ continue;
394
+ }
395
+ const existing = indexesByKey.get(entry.key);
396
+ if (existing) {
397
+ existing.push(entry.startActionIndex);
398
+ }
399
+ else {
400
+ indexesByKey.set(entry.key, [entry.startActionIndex]);
401
+ keyOrder.push(entry.key);
402
+ }
403
+ }
404
+ const finalised = [];
405
+ for (let i = 0; i < keyOrder.length; i++) {
406
+ const key = keyOrder[i];
407
+ const indexes = indexesByKey.get(key);
408
+ const headerRecord = headerStageRecords.get(key);
409
+ if (headerRecord) {
410
+ finalised.push(headerRecord.merge({ component_indexes: indexes.join(','), order: i }));
411
+ }
412
+ }
413
+ // Emit declared-but-never-activated stages with empty component_indexes.
414
+ // These are stages declared in the header config that have no wfa.stage()
415
+ // call anywhere in the flow body (e.g. a stage only activated inside a
416
+ // subflow). The platform still needs the sys_hub_flow_stage record so the
417
+ // stage tracker can display it.
418
+ const activatedKeys = new Set(keyOrder);
419
+ let nextOrder = keyOrder.length;
420
+ for (const [key, record] of headerStageRecords) {
421
+ if (!activatedKeys.has(key)) {
422
+ finalised.push(record.merge({ component_indexes: '', order: nextOrder++ }));
423
+ }
424
+ }
425
+ return finalised;
426
+ }
427
+ // ---------------------------------------------------------------------------
428
+ // toShape helpers — reconstruct stages from DB records back to Fluent shapes
429
+ // ---------------------------------------------------------------------------
430
+ // snake_case DB key → camelCase API key (reverse of STATE_KEY_MAP)
431
+ const REVERSE_STATE_KEY_MAP = {
432
+ pending: 'pending',
433
+ in_progress: 'inProgress',
434
+ complete: 'complete',
435
+ error: 'error',
436
+ skipped: 'skipped',
437
+ };
438
+ /**
439
+ * Converts a stage `value` string (which may contain spaces, dots, underscores
440
+ * etc.) into a valid camelCase JavaScript identifier suitable for use as an
441
+ * object property key and in `params.stages.<key>` property-access expressions.
442
+ *
443
+ * Examples:
444
+ * "Request Cancelled" → "requestCancelled"
445
+ * "Dept. Head Approval" → "deptHeadApproval"
446
+ * "CIO Approval" → "cioApproval"
447
+ * "manager_approval" → "managerApproval"
448
+ * "triage" → "triage"
449
+ */
450
+ function toSafeIdentifier(value) {
451
+ const parts = value.split(/[^a-zA-Z0-9]+/).filter(Boolean);
452
+ if (parts.length === 0) {
453
+ return value;
454
+ }
455
+ const result = parts
456
+ .map((part, index) => {
457
+ const lower = part.toLowerCase();
458
+ if (index === 0) {
459
+ return lower;
460
+ }
461
+ return lower.charAt(0).toUpperCase() + lower.slice(1);
462
+ })
463
+ .join('');
464
+ // Prefix with underscore if starts with a digit
465
+ return /^\d/.test(result) ? `_${result}` : result;
466
+ }
467
+ /**
468
+ * Builds `FlowStage()` CallExpressionShapes from `sys_hub_flow_stage` records
469
+ * for the header `stages: {}` config property.
470
+ *
471
+ * Only standard stages are included (type='subflow' stages are skipped).
472
+ *
473
+ * @returns Plain object keyed by stage `value` — e.g. `{ triage: FlowStage({...}) }`.
474
+ */
475
+ function buildStageShapes(stageRecords) {
476
+ const shapes = {};
477
+ const sorted = [...stageRecords].sort((a, b) => Number(a.get('order')?.getValue() ?? 0) - Number(b.get('order')?.getValue() ?? 0));
478
+ for (const rec of sorted) {
479
+ if (rec.get('type')?.getValue() !== 'standard') {
480
+ continue;
481
+ }
482
+ const value = rec.get('value')?.ifString()?.getValue() ?? '';
483
+ if (!value) {
484
+ continue;
485
+ }
486
+ // Build config properties
487
+ const props = {
488
+ label: rec.get('label')?.ifString()?.getValue() ?? '',
489
+ value,
490
+ };
491
+ // Duration — only emit when not the default (zero duration)
492
+ const durationStr = rec.get('duration')?.ifString()?.getValue() ?? flow_constants_1.STAGE_DEFAULT_DURATION;
493
+ if (durationStr && durationStr !== flow_constants_1.STAGE_DEFAULT_DURATION) {
494
+ try {
495
+ props['duration'] = sdk_build_core_1.DurationShape.from(rec, sdk_build_core_1.Shape.from(rec, durationStr).asString());
496
+ }
497
+ catch {
498
+ /* keep default */
499
+ }
500
+ }
501
+ // alwaysShow
502
+ const alwaysShow = rec.get('always_show')?.getValue();
503
+ if (alwaysShow === true || alwaysShow === 'true') {
504
+ props['alwaysShow'] = true;
505
+ }
506
+ // states — only emit when they differ from platform defaults
507
+ const statesStr = rec.get('states')?.ifString()?.getValue();
508
+ if (statesStr) {
509
+ try {
510
+ const parsed = JSON.parse(statesStr);
511
+ const isDefault = Object.keys(parsed).length === Object.keys(DEFAULT_STATES).length &&
512
+ Object.entries(parsed).every(([k, v]) => DEFAULT_STATES[k] === v);
513
+ if (!isDefault) {
514
+ const stateProps = {};
515
+ for (const [dbKey, label] of Object.entries(parsed)) {
516
+ const apiKey = REVERSE_STATE_KEY_MAP[dbKey];
517
+ if (apiKey && label) {
518
+ stateProps[apiKey] = label;
519
+ }
520
+ }
521
+ if (Object.keys(stateProps).length > 0) {
522
+ props['states'] = sdk_build_core_1.Shape.from(rec, stateProps).asObject();
523
+ }
524
+ }
525
+ }
526
+ catch {
527
+ /* skip malformed JSON */
528
+ }
529
+ }
530
+ let key = toSafeIdentifier(value);
531
+ if (key in shapes) {
532
+ let suffix = 2;
533
+ while (`${key}_${suffix}` in shapes) {
534
+ suffix++;
535
+ }
536
+ key = `${key}_${suffix}`;
537
+ }
538
+ shapes[key] = new sdk_build_core_1.CallExpressionShape({
539
+ source: rec,
540
+ callee: flow_constants_1.FLOW_STAGE_CALLEE,
541
+ args: [new sdk_build_core_1.ObjectShape({ source: rec, properties: props })],
542
+ });
543
+ }
544
+ return shapes;
545
+ }
546
+ /**
547
+ * Parses `component_indexes` from stage records and builds a map from
548
+ * action record order to the stage key(s) that should be inserted before it.
549
+ *
550
+ * component_index N means the stage belongs before the record with order = N + 1.
551
+ */
552
+ function buildStageInsertionMap(stageRecords) {
553
+ const map = new Map();
554
+ for (const rec of stageRecords) {
555
+ if (rec.get('type')?.getValue() !== 'standard') {
556
+ continue;
557
+ }
558
+ const value = rec.get('value')?.ifString()?.getValue() ?? '';
559
+ if (!value) {
560
+ continue;
561
+ }
562
+ const indexes = rec.get('component_indexes')?.ifString()?.getValue() ?? '';
563
+ if (!indexes) {
564
+ continue;
565
+ }
566
+ for (const part of indexes.split(',')) {
567
+ const actionOrder = parseInt(part.trim(), 10) + 1;
568
+ if (isNaN(actionOrder)) {
569
+ continue;
570
+ }
571
+ const existing = map.get(actionOrder) ?? [];
572
+ existing.push(toSafeIdentifier(value));
573
+ map.set(actionOrder, existing);
574
+ }
575
+ }
576
+ return map;
577
+ }
578
+ /**
579
+ * Creates a `wfa.stage(params.stages.<key>)` CallExpressionShape.
580
+ */
581
+ function createStageCallShape(stageKey, paramName, source) {
582
+ return new sdk_build_core_1.CallExpressionShape({
583
+ source,
584
+ callee: flow_constants_1.STAGE_API_NAME,
585
+ args: [
586
+ new sdk_build_core_1.PropertyAccessShape({
587
+ source,
588
+ elements: [paramName, 'stages', stageKey],
589
+ }),
590
+ ],
591
+ });
592
+ }
593
+ /**
594
+ * Scans `stmts` for records whose order matches an entry in `stageInsertionMap`
595
+ * and splices `wfa.stage()` calls before them. Matched entries are removed from
596
+ * the map so they aren't inserted twice.
597
+ */
598
+ function insertStagesIntoStatements(stmts, stageInsertionMap, paramName, source, orderFn) {
599
+ const insertions = [];
600
+ for (let i = 0; i < stmts.length; i++) {
601
+ const stmtSource = stmts[i].getSource();
602
+ if (!(stmtSource instanceof sdk_build_core_1.Record)) {
603
+ continue;
604
+ }
605
+ const recOrder = orderFn(stmtSource);
606
+ const keys = stageInsertionMap.get(recOrder);
607
+ if (keys && keys.length > 0) {
608
+ insertions.push({ before: i, keys });
609
+ stageInsertionMap.delete(recOrder);
610
+ }
611
+ }
612
+ for (let j = insertions.length - 1; j >= 0; j--) {
613
+ const { before, keys } = insertions[j];
614
+ const stageCalls = keys.map((k) => createStageCallShape(k, paramName, source));
615
+ stmts.splice(before, 0, ...stageCalls);
616
+ }
617
+ }
618
+ /**
619
+ * Walks through an array of body shapes and mutates flow logic bodies
620
+ * (if/elseIf/else/tryCatch) to insert `wfa.stage()` calls at positions identified
621
+ * by `stageInsertionMap`.
622
+ *
623
+ * Matched entries are removed from the map so they aren't inserted twice.
624
+ * Call this AFTER top-level stages have been handled.
625
+ */
626
+ function insertNestedStageShapes(shapes, stageInsertionMap, paramName, orderFn) {
627
+ for (const shape of shapes) {
628
+ const callExpr = shape instanceof sdk_build_core_1.VariableStatementShape ? shape.getInitializer() : shape;
629
+ if (!(callExpr instanceof sdk_build_core_1.CallExpressionShape)) {
630
+ continue;
631
+ }
632
+ const callee = callExpr.getCallee();
633
+ // Recurse into tryCatch try/catch handler bodies
634
+ if (callee === flow_logic_constants_1.FLOW_LOGIC.TRY_CATCH) {
635
+ const handlersArg = callExpr.getArgument(1, false);
636
+ if (handlersArg.if(sdk_build_core_1.ObjectShape)) {
637
+ const handlers = handlersArg.as(sdk_build_core_1.ObjectShape);
638
+ for (const handlerKey of ['try', 'catch']) {
639
+ const handler = handlers.get(handlerKey, false);
640
+ if (handler.if(arrow_function_plugin_1.ArrowFunctionShape)) {
641
+ const handlerBody = handler.as(arrow_function_plugin_1.ArrowFunctionShape);
642
+ const handlerStmts = handlerBody.getStatements();
643
+ insertStagesIntoStatements(handlerStmts, stageInsertionMap, paramName, handlerBody.getSource(), orderFn);
644
+ insertNestedStageShapes(handlerStmts, stageInsertionMap, paramName, orderFn);
645
+ }
646
+ }
647
+ }
648
+ continue;
649
+ }
650
+ // Only recurse into conditional bodies
651
+ if (callee !== flow_logic_constants_1.FLOW_LOGIC.IF && callee !== flow_logic_constants_1.FLOW_LOGIC.ELSEIF && callee !== flow_logic_constants_1.FLOW_LOGIC.ELSE) {
652
+ continue;
653
+ }
654
+ const bodyArg = callExpr.getArgument(1, false);
655
+ if (!bodyArg.if(arrow_function_plugin_1.ArrowFunctionShape)) {
656
+ continue;
657
+ }
658
+ const body = bodyArg.as(arrow_function_plugin_1.ArrowFunctionShape);
659
+ const stmts = body.getStatements(); // mutable reference
660
+ insertStagesIntoStatements(stmts, stageInsertionMap, paramName, body.getSource(), orderFn);
661
+ // Recurse into children for deeper nesting
662
+ insertNestedStageShapes(stmts, stageInsertionMap, paramName, orderFn);
663
+ }
664
+ }
665
+ //# sourceMappingURL=flow-stage-processor.js.map