@elyx-code/editor-ui 0.0.2

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 (452) hide show
  1. package/README.md +2 -0
  2. package/package.json +109 -0
  3. package/src/App.tsx +31 -0
  4. package/src/Router.tsx +115 -0
  5. package/src/__mocks__/defaultModuleMock.ts +1 -0
  6. package/src/__mocks__/fileMock.ts +1 -0
  7. package/src/__mocks__/styleMock.ts +1 -0
  8. package/src/assets/Clock-11.1s-18px.svg +16 -0
  9. package/src/assets/Clock-11.1s-28px.svg +16 -0
  10. package/src/assets/authentication.svg +1 -0
  11. package/src/assets/canvas-backdrop-0.png +0 -0
  12. package/src/assets/canvas-backdrop-1.png +0 -0
  13. package/src/assets/canvas-backdrop-2.png +0 -0
  14. package/src/assets/canvas-backdrop-3.png +0 -0
  15. package/src/assets/canvas-backdrop-4.png +0 -0
  16. package/src/assets/canvas-backdrop-5.png +0 -0
  17. package/src/assets/canvas-backdrop.png +0 -0
  18. package/src/assets/checkmark-animation.gif +0 -0
  19. package/src/assets/checkmark-animation.mp4 +0 -0
  20. package/src/assets/code-formatting/format-black.svg +6 -0
  21. package/src/assets/code-formatting/format-dark-grey.svg +6 -0
  22. package/src/assets/code-formatting/format-light-grey.svg +6 -0
  23. package/src/assets/code-formatting/format-white.svg +6 -0
  24. package/src/assets/code-formatting/inline-black.svg +5 -0
  25. package/src/assets/code-formatting/inline-dark-grey.svg +5 -0
  26. package/src/assets/code-formatting/inline-light-grey.svg +5 -0
  27. package/src/assets/code-formatting/inline-white.svg +5 -0
  28. package/src/assets/contained-logo-full-word.png +0 -0
  29. package/src/assets/cron-job-color.png +0 -0
  30. package/src/assets/cron-job.png +0 -0
  31. package/src/assets/database-table-color.png +0 -0
  32. package/src/assets/database-table.png +0 -0
  33. package/src/assets/datatype-icons/black/any.svg +1 -0
  34. package/src/assets/datatype-icons/black/binary.svg +1 -0
  35. package/src/assets/datatype-icons/black/boolean.svg +3 -0
  36. package/src/assets/datatype-icons/black/date-time.svg +3 -0
  37. package/src/assets/datatype-icons/black/definition-entity.svg +6 -0
  38. package/src/assets/datatype-icons/black/key-file.svg +1 -0
  39. package/src/assets/datatype-icons/black/list.svg +3 -0
  40. package/src/assets/datatype-icons/black/null.svg +3 -0
  41. package/src/assets/datatype-icons/black/number.svg +13 -0
  42. package/src/assets/datatype-icons/black/project.svg +12 -0
  43. package/src/assets/datatype-icons/black/sql-program.svg +2 -0
  44. package/src/assets/datatype-icons/black/text.svg +3 -0
  45. package/src/assets/datatype-icons/black/unknown.svg +3 -0
  46. package/src/assets/datatype-icons/black/uuid.svg +4 -0
  47. package/src/assets/datatype-icons/black/void.svg +1 -0
  48. package/src/assets/datatype-icons/dark-grey/any.svg +1 -0
  49. package/src/assets/datatype-icons/dark-grey/boolean.svg +3 -0
  50. package/src/assets/datatype-icons/dark-grey/date-time.svg +3 -0
  51. package/src/assets/datatype-icons/dark-grey/definition-entity.svg +6 -0
  52. package/src/assets/datatype-icons/dark-grey/list.svg +3 -0
  53. package/src/assets/datatype-icons/dark-grey/null.svg +3 -0
  54. package/src/assets/datatype-icons/dark-grey/number.svg +13 -0
  55. package/src/assets/datatype-icons/dark-grey/project.svg +12 -0
  56. package/src/assets/datatype-icons/dark-grey/sql-program.svg +2 -0
  57. package/src/assets/datatype-icons/dark-grey/text.svg +3 -0
  58. package/src/assets/datatype-icons/dark-grey/unknown.svg +3 -0
  59. package/src/assets/datatype-icons/dark-grey/uuid.svg +4 -0
  60. package/src/assets/datatype-icons/dark-grey/void.svg +1 -0
  61. package/src/assets/datatype-icons/light-grey/any.svg +1 -0
  62. package/src/assets/datatype-icons/light-grey/boolean.svg +3 -0
  63. package/src/assets/datatype-icons/light-grey/date-time.svg +3 -0
  64. package/src/assets/datatype-icons/light-grey/definition-entity.svg +6 -0
  65. package/src/assets/datatype-icons/light-grey/list.svg +3 -0
  66. package/src/assets/datatype-icons/light-grey/null.svg +3 -0
  67. package/src/assets/datatype-icons/light-grey/number.svg +13 -0
  68. package/src/assets/datatype-icons/light-grey/project.svg +12 -0
  69. package/src/assets/datatype-icons/light-grey/sql-program.svg +2 -0
  70. package/src/assets/datatype-icons/light-grey/text.svg +3 -0
  71. package/src/assets/datatype-icons/light-grey/unknown.svg +3 -0
  72. package/src/assets/datatype-icons/light-grey/uuid.svg +4 -0
  73. package/src/assets/datatype-icons/light-grey/void.svg +1 -0
  74. package/src/assets/edit.png +0 -0
  75. package/src/assets/execution.svg +13 -0
  76. package/src/assets/favicon.svg +14 -0
  77. package/src/assets/file-search.svg +1 -0
  78. package/src/assets/http-endpoint.png +0 -0
  79. package/src/assets/image-input-placeholder.png +0 -0
  80. package/src/assets/logo-full-word-white.png +0 -0
  81. package/src/assets/logo-full-word.png +0 -0
  82. package/src/assets/password.svg +85 -0
  83. package/src/assets/pencil.png +0 -0
  84. package/src/assets/publish-project-rich-icon-2.svg +1 -0
  85. package/src/assets/publish-project-rich-icon.svg +1 -0
  86. package/src/assets/relational-database.png +0 -0
  87. package/src/assets/resources.svg +3 -0
  88. package/src/assets/resume-icon-14px.png +0 -0
  89. package/src/assets/server.png +0 -0
  90. package/src/assets/small-status/checkmark.svg +4 -0
  91. package/src/assets/small-status/error.svg +4 -0
  92. package/src/assets/small-status/loading.svg +4 -0
  93. package/src/assets/small-status/skipped.svg +11 -0
  94. package/src/assets/sql-connection-config.svg +1 -0
  95. package/src/assets/sql-row-transformer.svg +1 -0
  96. package/src/assets/ssl-certificate-config.svg +1 -0
  97. package/src/assets/sync.svg +1 -0
  98. package/src/assets/testing-logic-icon.svg +1 -0
  99. package/src/assets/versions.svg +25 -0
  100. package/src/assets/visual-programming-icon.svg +1 -0
  101. package/src/assets/warning-sign-24px.png +0 -0
  102. package/src/auth/index.ts +318 -0
  103. package/src/components/DialogLoader.tsx +94 -0
  104. package/src/components/EntityDialogHeader.tsx +110 -0
  105. package/src/components/EntityDialogSectionHeader.tsx +214 -0
  106. package/src/components/GalleryAddExternalIntegrationInfoDialog.tsx +87 -0
  107. package/src/components/GenerateProjectStartingLogicPromptDialog.tsx +281 -0
  108. package/src/components/LegacyRouteRedirector.tsx +55 -0
  109. package/src/components/ProPlanChip.tsx +23 -0
  110. package/src/components/ReportBugDialog.tsx +412 -0
  111. package/src/components/RequestIntegrationAccessDialog.tsx +261 -0
  112. package/src/components/UseTemplateProjectDialog.tsx +193 -0
  113. package/src/components/WorkspaceLayout.tsx +152 -0
  114. package/src/components/animated-svg/AnimatedCheckmark.tsx +41 -0
  115. package/src/components/animated-svg/AnimatedCrossmark.tsx +51 -0
  116. package/src/components/animated-svg/AnimatedEmailSending.tsx +38 -0
  117. package/src/components/animated-svg/AnimatedLoading.tsx +72 -0
  118. package/src/components/animated-svg/animated-svg.css +239 -0
  119. package/src/components/canvas/Canvas.tsx +16 -0
  120. package/src/components/canvas/CreateEntityMenu.tsx +2020 -0
  121. package/src/components/canvas/canvas.css +10 -0
  122. package/src/components/canvas/create-entity-menu.css +579 -0
  123. package/src/components/canvas-search/CanvasSearch.tsx +501 -0
  124. package/src/components/canvas-search/canvas-search.css +126 -0
  125. package/src/components/canvas-settings-menu/CanvasSettingsMenuButton.tsx +515 -0
  126. package/src/components/canvas-settings-menu/canvas-settings-menu.css +96 -0
  127. package/src/components/circular-image-upload/CircularImageUpload.tsx +113 -0
  128. package/src/components/circular-image-upload/circular-image-upload.css +69 -0
  129. package/src/components/costs/CostsDialog.tsx +459 -0
  130. package/src/components/data-type/DataTypeBuilder.tsx +3127 -0
  131. package/src/components/data-type/data-type-builder.css +45 -0
  132. package/src/components/dialogs/BetaAcknowledgeDialog.tsx +43 -0
  133. package/src/components/dialogs/ComplexDataDialog.tsx +458 -0
  134. package/src/components/dialogs/CronBuilderDialog.tsx +2145 -0
  135. package/src/components/dialogs/ExternalIntegrationConnections.tsx +565 -0
  136. package/src/components/dialogs/JsonEditorDialog.tsx +1392 -0
  137. package/src/components/dialogs/StringEditorDialog.tsx +268 -0
  138. package/src/components/dialogs/argument-declaration/ArgumentDeclaration.tsx +1167 -0
  139. package/src/components/dialogs/argument-declaration/ArgumentDeclarationDialogContent.tsx +128 -0
  140. package/src/components/dialogs/beta-dialog.css +165 -0
  141. package/src/components/dialogs/condition/Condition.tsx +431 -0
  142. package/src/components/dialogs/condition/ConditionDialogContent.tsx +126 -0
  143. package/src/components/dialogs/definition-entity/DefinitionEntityDialogContent.tsx +973 -0
  144. package/src/components/dialogs/function-call/FunctionCall.tsx +442 -0
  145. package/src/components/dialogs/function-call/FunctionCallDialogContent.tsx +126 -0
  146. package/src/components/dialogs/function-declaration/FunctionDeclaration.tsx +926 -0
  147. package/src/components/dialogs/function-declaration/FunctionDeclarationDialogContent.tsx +124 -0
  148. package/src/components/dialogs/generating-project-starting-logic-overlay/GeneratingProjectStartingLogicOverlay.tsx +176 -0
  149. package/src/components/dialogs/generating-project-starting-logic-overlay/generating-project-starting-logic-overlay.css +13 -0
  150. package/src/components/dialogs/global-event/GlobalEvent.tsx +475 -0
  151. package/src/components/dialogs/global-event/GlobalEventDialogContent.tsx +126 -0
  152. package/src/components/dialogs/help/HelpDialog.tsx +217 -0
  153. package/src/components/dialogs/help/HelpDilalogHomeContent.tsx +178 -0
  154. package/src/components/dialogs/help/help-dialog.css +116 -0
  155. package/src/components/dialogs/help/help-icon/HelpIconButton.tsx +41 -0
  156. package/src/components/dialogs/help/help-icon/help-icon.css +9 -0
  157. package/src/components/dialogs/input-map/InputMap.tsx +635 -0
  158. package/src/components/dialogs/input-map/InputMapDialogContent.tsx +126 -0
  159. package/src/components/dialogs/json-editor-dialog.css +4 -0
  160. package/src/components/dialogs/loop/Loop.tsx +650 -0
  161. package/src/components/dialogs/loop/LoopDialogContent.tsx +122 -0
  162. package/src/components/dialogs/operation/Operation.tsx +440 -0
  163. package/src/components/dialogs/operation/OperationDialogContent.tsx +126 -0
  164. package/src/components/dialogs/output-map/OutputMap.tsx +536 -0
  165. package/src/components/dialogs/output-map/OutputMapDialogContent.tsx +126 -0
  166. package/src/components/dialogs/property/Property.tsx +1490 -0
  167. package/src/components/dialogs/property/PropertyDialogContent.tsx +106 -0
  168. package/src/components/dialogs/search-statement/ColumnSelector.tsx +334 -0
  169. package/src/components/dialogs/search-statement/ConditionBuilder.tsx +750 -0
  170. package/src/components/dialogs/search-statement/DataAggregationSection.tsx +621 -0
  171. package/src/components/dialogs/search-statement/DataSourceSelection.tsx +734 -0
  172. package/src/components/dialogs/search-statement/EntityMetadataSection.tsx +135 -0
  173. package/src/components/dialogs/search-statement/FilterConditionsSection.tsx +151 -0
  174. package/src/components/dialogs/search-statement/InlineInputMap.tsx +153 -0
  175. package/src/components/dialogs/search-statement/LiteralValue.tsx +616 -0
  176. package/src/components/dialogs/search-statement/MainSourceAndInputsSection.tsx +271 -0
  177. package/src/components/dialogs/search-statement/NestedSearchStatementBuilder.tsx +170 -0
  178. package/src/components/dialogs/search-statement/OutputFormatSection.tsx +1779 -0
  179. package/src/components/dialogs/search-statement/ResultsSection.tsx +344 -0
  180. package/src/components/dialogs/search-statement/SearchStatementBuilder.tsx +251 -0
  181. package/src/components/dialogs/search-statement/SearchStatementDialogContent.tsx +398 -0
  182. package/src/components/dialogs/search-statement/ValueSelector.tsx +766 -0
  183. package/src/components/dialogs/search-statement/search-statement-context.tsx +1630 -0
  184. package/src/components/dialogs/search-statement/search-statement-dialog.css +56 -0
  185. package/src/components/dialogs/search-statement/test.sql +111 -0
  186. package/src/components/dialogs/value-descriptor/ValueDescriptor.tsx +824 -0
  187. package/src/components/dialogs/value-descriptor/ValueDescriptorDialogContent.tsx +124 -0
  188. package/src/components/dialogs/variable-declaration/VariableDeclaration.tsx +836 -0
  189. package/src/components/dialogs/variable-declaration/VariableDeclarationDialogContent.tsx +106 -0
  190. package/src/components/dialogs/variable-instance/VariableInstance.tsx +443 -0
  191. package/src/components/dialogs/variable-instance/VariableInstanceDialogContent.tsx +124 -0
  192. package/src/components/draggable-entity-card/ArgumentDeclaration.tsx +736 -0
  193. package/src/components/draggable-entity-card/CollapseEntityButton.tsx +170 -0
  194. package/src/components/draggable-entity-card/ConditionCard.tsx +1062 -0
  195. package/src/components/draggable-entity-card/ConnectionDeleteButton.tsx +309 -0
  196. package/src/components/draggable-entity-card/DataTypeIcon.tsx +624 -0
  197. package/src/components/draggable-entity-card/DraggableEntityCard.tsx +617 -0
  198. package/src/components/draggable-entity-card/ErrorMapProperty.tsx +464 -0
  199. package/src/components/draggable-entity-card/EventCard.tsx +700 -0
  200. package/src/components/draggable-entity-card/ExecutionInProgressValue.tsx +327 -0
  201. package/src/components/draggable-entity-card/FunctionDeclarationCard.tsx +819 -0
  202. package/src/components/draggable-entity-card/InputMapProperty.tsx +1067 -0
  203. package/src/components/draggable-entity-card/InternalCall.tsx +978 -0
  204. package/src/components/draggable-entity-card/InternalCallExecutionNode.tsx +643 -0
  205. package/src/components/draggable-entity-card/LogicScopeCallerNode.tsx +262 -0
  206. package/src/components/draggable-entity-card/LoopCard.tsx +791 -0
  207. package/src/components/draggable-entity-card/MainValueInput.tsx +523 -0
  208. package/src/components/draggable-entity-card/MainValueOutput.tsx +458 -0
  209. package/src/components/draggable-entity-card/MethodDeclaration.tsx +1088 -0
  210. package/src/components/draggable-entity-card/NestedCondition.tsx +1025 -0
  211. package/src/components/draggable-entity-card/OutputMapProperty.tsx +843 -0
  212. package/src/components/draggable-entity-card/PassthroughEntityCard.tsx +1247 -0
  213. package/src/components/draggable-entity-card/ReturnedError.tsx +549 -0
  214. package/src/components/draggable-entity-card/SmallSuccessFailureNodes.tsx +523 -0
  215. package/src/components/draggable-entity-card/SuccessFailureNodes.tsx +509 -0
  216. package/src/components/draggable-entity-card/TestEntityButton.tsx +946 -0
  217. package/src/components/draggable-entity-card/TestMenu.tsx +523 -0
  218. package/src/components/draggable-entity-card/TestMenuValidationDropdown.tsx +84 -0
  219. package/src/components/draggable-entity-card/UnreachableMarker.tsx +114 -0
  220. package/src/components/draggable-entity-card/VariableCard.tsx +1577 -0
  221. package/src/components/draggable-entity-card/VariableScopeMarker.tsx +117 -0
  222. package/src/components/draggable-entity-card/collapse-entity-button.css +44 -0
  223. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityCard.tsx +1181 -0
  224. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityIcon.tsx +36 -0
  225. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityProperty.tsx +478 -0
  226. package/src/components/draggable-entity-card/definition-entity/DynamicFooterActions.tsx +112 -0
  227. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/ExportCredentialsFooterAction.tsx +461 -0
  228. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/RestablishConnectionFooterAction.tsx +199 -0
  229. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/restablish-connection-footer-action.css +85 -0
  230. package/src/components/draggable-entity-card/definition-entity/actions/google-drive/GoogleDriveFilePickerAPIFooterAction.tsx +277 -0
  231. package/src/components/draggable-entity-card/definition-entity/actions/google-drive/google-drive-file-picker-api-footer-action.css +107 -0
  232. package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/DatabaseFooterAction.tsx +452 -0
  233. package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/database-footer-action.css +86 -0
  234. package/src/components/draggable-entity-card/definition-entity/definition-entity-card.css +17 -0
  235. package/src/components/draggable-entity-card/draggable-entity-card.css +1140 -0
  236. package/src/components/draggable-entity-card/entity-locked-icon/EntityLockedIcon.tsx +133 -0
  237. package/src/components/draggable-entity-card/entity-locked-icon/entity-locked.css +8 -0
  238. package/src/components/draggable-entity-card/expand-properties-icon-button/ExpandPropertiesIconButton.tsx +84 -0
  239. package/src/components/draggable-entity-card/expand-properties-icon-button/expand-properties-icon-button.css +21 -0
  240. package/src/components/draggable-entity-card/implement-entity-icon/ImplementEntityIcon.tsx +74 -0
  241. package/src/components/draggable-entity-card/implement-entity-icon/implement-entity-icon.css +13 -0
  242. package/src/components/draggable-entity-card/logic-error/LogicErrorIconMenu.tsx +424 -0
  243. package/src/components/draggable-entity-card/logic-error/logic-error.css +23 -0
  244. package/src/components/draggable-entity-card/new-card-input-button/NewCardInputButton.tsx +193 -0
  245. package/src/components/draggable-entity-card/new-card-input-button/NewDynamicInputButton.tsx +214 -0
  246. package/src/components/draggable-entity-card/new-card-input-button/new-card-input-button.css +71 -0
  247. package/src/components/draggable-entity-card/new-card-output-button/NewCardOutputButton.tsx +192 -0
  248. package/src/components/draggable-entity-card/new-card-output-button/new-card-output-button.css +71 -0
  249. package/src/components/draggable-entity-card/termination-statement/TerminationStatementCard.tsx +1543 -0
  250. package/src/components/draggable-entity-card/termination-statement/termination-statement-card.css +17 -0
  251. package/src/components/draggable-entity-card/test-entity-button.css +55 -0
  252. package/src/components/draggable-entity-card/test-menu.css +181 -0
  253. package/src/components/draggable-entity-card/unreachable-marker.css +43 -0
  254. package/src/components/draggable-entity-card/variable-scope-marker.css +22 -0
  255. package/src/components/dynamic-value/DynamicValue.tsx +2395 -0
  256. package/src/components/dynamic-value/DynamicValueEntry.tsx +1957 -0
  257. package/src/components/dynamic-value/dynamic-value.css +230 -0
  258. package/src/components/editor/ElyxMonacoEditor.tsx +38 -0
  259. package/src/components/entity-error/EntityErrorListItem.tsx +47 -0
  260. package/src/components/entity-error/entity-error.css +198 -0
  261. package/src/components/entity-icon/EntityIcon.tsx +292 -0
  262. package/src/components/entity-icon/entity-icon.css +39 -0
  263. package/src/components/gallery-card/CreateNewProject.tsx +222 -0
  264. package/src/components/gallery-card/GalleryCard.tsx +171 -0
  265. package/src/components/gallery-card/MarketplaceCard.tsx +87 -0
  266. package/src/components/gallery-card/ProjectDuplicationCard.tsx +575 -0
  267. package/src/components/gallery-card/gallery-card.css +25 -0
  268. package/src/components/notifications/NotificationsIconButton.tsx +124 -0
  269. package/src/components/notifications/NotificationsPanel.tsx +385 -0
  270. package/src/components/notifications/notifications.css +189 -0
  271. package/src/components/online-users/LocalOnlineUsers.tsx +175 -0
  272. package/src/components/online-users/PageOnlineUsers.tsx +297 -0
  273. package/src/components/online-users/online-users.css +72 -0
  274. package/src/components/page-backdrop/PageBackdrop.tsx +8 -0
  275. package/src/components/page-backdrop/page-backdrop.css +7 -0
  276. package/src/components/project-configuration/DeleteProjectConfirmationDialog.tsx +134 -0
  277. package/src/components/project-configuration/ProjectConfigurationDialog.tsx +972 -0
  278. package/src/components/project-configuration/ProjectDataForm.tsx +121 -0
  279. package/src/components/project-configuration/UnpublishProjectConfirmationDialog.tsx +162 -0
  280. package/src/components/project-configuration/project-configuration-content.css +209 -0
  281. package/src/components/project-name/ProjectName.tsx +2025 -0
  282. package/src/components/project-name/project-name.css +599 -0
  283. package/src/components/publishing/Publication.tsx +133 -0
  284. package/src/components/publishing/history/PublicationHistoryContent.tsx +414 -0
  285. package/src/components/publishing/history/PublicationHistoryDialog.tsx +234 -0
  286. package/src/components/publishing/preview/PublicationPreviewDialog.tsx +1158 -0
  287. package/src/components/publishing/preview/PublishingPriceForecast.tsx +160 -0
  288. package/src/components/publishing/preview/PublishingResourcesDetails.tsx +91 -0
  289. package/src/components/publishing/publication-sequence/PublishingSequenceContent.tsx +375 -0
  290. package/src/components/publishing/publication-sequence/PublishingSequenceDialog.tsx +344 -0
  291. package/src/components/publishing/publishing-dialog.css +142 -0
  292. package/src/components/publishing/utils.ts +227 -0
  293. package/src/components/resources/ResourcesDialog.tsx +591 -0
  294. package/src/components/resources/UpgradeBanner.tsx +102 -0
  295. package/src/components/resources/codebase/CodebaseDetails.tsx +156 -0
  296. package/src/components/resources/cron-job/CronJobsList.tsx +532 -0
  297. package/src/components/resources/functions/FunctionsList.tsx +454 -0
  298. package/src/components/resources/http-api/HttpAPI.tsx +566 -0
  299. package/src/components/resources/http-api/HttpAPIClientModule.tsx +37 -0
  300. package/src/components/resources/logs/LogsViewer.tsx +768 -0
  301. package/src/components/resources/query.ts +74 -0
  302. package/src/components/resources/relational-database/DatabaseTable.tsx +905 -0
  303. package/src/components/resources/relational-database/RelationalDatabase.tsx +83 -0
  304. package/src/components/resources/relational-database/RelationalDatabaseSecrets.tsx +361 -0
  305. package/src/components/resources/resources-dialog.css +74 -0
  306. package/src/components/test-relational-database/DatabaseTable.tsx +913 -0
  307. package/src/components/test-relational-database/TestDatabaseDialogContent.tsx +670 -0
  308. package/src/components/test-relational-database/query.ts +74 -0
  309. package/src/components/toolbar/ToolBar.tsx +236 -0
  310. package/src/components/toolbar/toolbar.css +78 -0
  311. package/src/components/transaction-history/TransactionHistoryDialog.tsx +268 -0
  312. package/src/components/user/CurrentUserAvatar.tsx +65 -0
  313. package/src/components/user/UserChip.tsx +62 -0
  314. package/src/components/user/user.css +39 -0
  315. package/src/components/user-profile/ChangePasswordForm.tsx +67 -0
  316. package/src/components/user-profile/OwnUserProfileContent.tsx +665 -0
  317. package/src/components/user-profile/PublicUserProfileContent.tsx +99 -0
  318. package/src/components/user-profile/UserDataForm.tsx +75 -0
  319. package/src/components/user-profile/UserProfileDialog.tsx +110 -0
  320. package/src/components/user-profile/user-profile-content.css +25 -0
  321. package/src/config.ts +130 -0
  322. package/src/globals.d.ts +13 -0
  323. package/src/index.html +27 -0
  324. package/src/index.tsx +23 -0
  325. package/src/lib/badge/Badge.tsx +35 -0
  326. package/src/lib/badge/badge.css +32 -0
  327. package/src/lib/button/Button.tsx +129 -0
  328. package/src/lib/button/button.css +145 -0
  329. package/src/lib/canvas/canvas-undo-redo.ts +263 -0
  330. package/src/lib/canvas/defs.ts +170 -0
  331. package/src/lib/canvas/index.test.ts +189 -0
  332. package/src/lib/canvas/index.ts +6999 -0
  333. package/src/lib/canvas/utils.ts +59 -0
  334. package/src/lib/card/Card.tsx +62 -0
  335. package/src/lib/card/LoadingCard.tsx +82 -0
  336. package/src/lib/card/card.css +259 -0
  337. package/src/lib/chip/Chip.tsx +79 -0
  338. package/src/lib/chip/chip.css +0 -0
  339. package/src/lib/dialog/Dialog.tsx +122 -0
  340. package/src/lib/dialog/SmallDialog.tsx +61 -0
  341. package/src/lib/dialog/dialog.css +40 -0
  342. package/src/lib/display-data-structure/index.tsx +21 -0
  343. package/src/lib/dropdown/CanvasDropdownMenuCard.tsx +68 -0
  344. package/src/lib/dropdown/CanvasDropdownMenuCardOption.tsx +136 -0
  345. package/src/lib/dropdown/DropdownButton.tsx +104 -0
  346. package/src/lib/dropdown/DropdownMenuCard.tsx +324 -0
  347. package/src/lib/dropdown/DropdownMenuPopup.tsx +27 -0
  348. package/src/lib/dropdown/dropdown-button.css +76 -0
  349. package/src/lib/dropdown/dropdown-menu.css +151 -0
  350. package/src/lib/json-editor/RawJsonEditor.tsx +137 -0
  351. package/src/lib/json-editor/json-editor.css +35 -0
  352. package/src/lib/loader/Loader.tsx +120 -0
  353. package/src/lib/loader/loader.css +38 -0
  354. package/src/lib/pagination/Pagination.tsx +64 -0
  355. package/src/lib/popup/CanvasPopupBaseComponent.tsx +103 -0
  356. package/src/lib/popup/Popup.tsx +243 -0
  357. package/src/lib/popup/popup.css +16 -0
  358. package/src/lib/table/RowForm.tsx +301 -0
  359. package/src/lib/table/Table.tsx +1069 -0
  360. package/src/lib/table/table.css +249 -0
  361. package/src/lib/table/types.ts +108 -0
  362. package/src/lib/text-area/TextArea.tsx +183 -0
  363. package/src/lib/text-area/text-area.css +156 -0
  364. package/src/lib/text-field/TextField.tsx +218 -0
  365. package/src/lib/text-field/index.ts +8 -0
  366. package/src/lib/text-field/text-field.css +201 -0
  367. package/src/lib/tooltip/Tooltip.tsx +24 -0
  368. package/src/lib/tooltip/tooltip.css +17 -0
  369. package/src/localization/index.ts +47 -0
  370. package/src/main.css +343 -0
  371. package/src/pages/Auth.tsx +848 -0
  372. package/src/pages/Editor.tsx +883 -0
  373. package/src/pages/ErrorPage.tsx +179 -0
  374. package/src/pages/Gallery.tsx +1693 -0
  375. package/src/pages/NewPaymentMethodCallback.tsx +53 -0
  376. package/src/pages/NotFoundPage.tsx +126 -0
  377. package/src/pages/PricingPlans.tsx +155 -0
  378. package/src/pages/auth.css +304 -0
  379. package/src/pages/gallery.css +421 -0
  380. package/src/payments/index.ts +187 -0
  381. package/src/popup-notification/index.ts +90 -0
  382. package/src/services/database/index.ts +1 -0
  383. package/src/services/database/utils.ts +1301 -0
  384. package/src/services/editor/CanvasElement.tsx +2934 -0
  385. package/src/services/editor/CanvasElementConnectionDeleteButton.ts +204 -0
  386. package/src/services/editor/CanvasPopup.tsx +749 -0
  387. package/src/services/editor/EditorService.ts +8157 -0
  388. package/src/services/editor/area.ts +1312 -0
  389. package/src/services/editor/connections.ts +1019 -0
  390. package/src/services/editor/create/condition.ts +25 -0
  391. package/src/services/editor/create/definition-entity.ts +29 -0
  392. package/src/services/editor/create/function-call.ts +25 -0
  393. package/src/services/editor/create/global-event.ts +33 -0
  394. package/src/services/editor/create/loop.ts +25 -0
  395. package/src/services/editor/create/operation.ts +30 -0
  396. package/src/services/editor/create/utils.ts +140 -0
  397. package/src/services/editor/create/variable-declaration.ts +135 -0
  398. package/src/services/editor/create/variable-instance.ts +100 -0
  399. package/src/services/editor/editor-ui-extensions-context.ts +43 -0
  400. package/src/services/editor/entities-metadata.json +9310 -0
  401. package/src/services/editor/icons.ts +1093 -0
  402. package/src/services/editor/index.ts +1 -0
  403. package/src/services/editor/layout.ts +102 -0
  404. package/src/services/editor/modules/built-in-function-implementations/base.ts +14 -0
  405. package/src/services/editor/modules/built-in-function-implementations/create-persisted-entity/index.ts +56 -0
  406. package/src/services/editor/modules/built-in-function-implementations/delete-persisted-entity/index.ts +55 -0
  407. package/src/services/editor/modules/built-in-function-implementations/index.ts +4 -0
  408. package/src/services/editor/modules/built-in-function-implementations/update-persisted-entity/index.ts +56 -0
  409. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/get-files.ts +183 -0
  410. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-drives.ts +124 -0
  411. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-root-folders.ts +125 -0
  412. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/smart-fetch-document.ts +702 -0
  413. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/upload-document.ts +535 -0
  414. package/src/services/editor/modules/operations-implementations/external-integrations/google-gemini/generate-content.ts +193 -0
  415. package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/get-emails.ts +586 -0
  416. package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/send-email.ts +386 -0
  417. package/src/services/editor/modules/operations-implementations/external-integrations/index.ts +12 -0
  418. package/src/services/editor/modules/operations-implementations/external-integrations/slack/channels.ts +240 -0
  419. package/src/services/editor/modules/operations-implementations/external-integrations/slack/messages.ts +210 -0
  420. package/src/services/editor/modules/operations-implementations/external-integrations/slack/replies.ts +200 -0
  421. package/src/services/editor/modules/operations-implementations/external-integrations/slack/send-message.ts +177 -0
  422. package/src/services/editor/modules/operations-implementations/index.ts +1 -0
  423. package/src/services/editor/modules/search-node-implementation/index.ts +42 -0
  424. package/src/services/editor/modules/sql-migrations-generation.tsx +1054 -0
  425. package/src/services/editor/publication/publication.ts +578 -0
  426. package/src/services/editor/ui.ts +1348 -0
  427. package/src/services/editor/utils.ts +5868 -0
  428. package/src/services/editor/value-store.ts +619 -0
  429. package/src/services/execution/built-in-function-implementations.ts +422 -0
  430. package/src/services/execution/index.ts +4747 -0
  431. package/src/services/execution/logic.ts +121 -0
  432. package/src/services/execution/test-instance.tsx +2296 -0
  433. package/src/services/execution/utils.ts +33 -0
  434. package/src/services/execution/value-resolution.test.ts +424 -0
  435. package/src/services/execution/value-resolution.ts +4087 -0
  436. package/src/services/integrations/ExternalIntegrationsService.ts +439 -0
  437. package/src/services/integrations/api.ts +175 -0
  438. package/src/services/local-relational-database/idb_helper.ts +66 -0
  439. package/src/services/local-relational-database/index.ts +3308 -0
  440. package/src/services/local-relational-database/utils.ts +403 -0
  441. package/src/services/notifications/index.ts +525 -0
  442. package/src/services/user/index.ts +144 -0
  443. package/src/setupTests.ts +1 -0
  444. package/src/socket/socket.ts +248 -0
  445. package/src/socket/utils.ts +10 -0
  446. package/src/store/workspace.ts +12 -0
  447. package/src/theme.ts +19 -0
  448. package/src/utils/DOM.ts +39 -0
  449. package/src/utils/date.ts +169 -0
  450. package/src/utils/index.ts +158 -0
  451. package/src/utils/react.tsx +679 -0
  452. package/src/utils/testing.ts +103 -0
@@ -0,0 +1,4747 @@
1
+ import {
2
+ ArgumentDeclarationState,
3
+ BreakStatementState,
4
+ BUILT_IN_BASE_ENTITY_IDS,
5
+ CallableEntityState,
6
+ ContinueStatementState,
7
+ createStateFromType,
8
+ DataTypeState,
9
+ EntityId,
10
+ EntityState,
11
+ EntityType,
12
+ EntityWithValueState,
13
+ ExecutionTerminationType,
14
+ getDeclaration,
15
+ IPrimitiveExecutionResult,
16
+ ILiteralValueTransfer,
17
+ LoopState,
18
+ PASS_THROUGH_CALLABLE_TYPES,
19
+ PassThroughCallableEntityState,
20
+ ProjectState,
21
+ resolveEntityName,
22
+ SearchState,
23
+ StandaloneOperatorTypes,
24
+ TERMINATION_TYPES,
25
+ TerminationEntityState,
26
+ toCamelCase,
27
+ UntypedObjectValue,
28
+ ValueReadingEntityState,
29
+ InputMapState,
30
+ ENTRY_POINT_TYPES,
31
+ VALUE_READING_TYPES,
32
+ PassThroughCallableEntityWithOutputs,
33
+ ExecutableEntityState,
34
+ InternalCallState,
35
+ BuiltInFunctionIds,
36
+ CALLER_TYPES,
37
+ CALLABLE_TYPES,
38
+ ConditionState,
39
+ FunctionCallState,
40
+ OperationState,
41
+ VariableDeclarationState,
42
+ FunctionDeclarationState,
43
+ DraggableExecutableEntityState,
44
+ DraggableCallerEntityState,
45
+ ReturnStatementState,
46
+ EntryPointEntityState,
47
+ flattenRelatedCanvasElementsOnTheRight,
48
+ VariableState,
49
+ LiteralValueState,
50
+ ISearchNodeImplementationModule,
51
+ DEFAULT_MODULE_IDS,
52
+ IBaseExtensionsContext,
53
+ DEFAULT_BASE_EXTENSIONS_CONTEXT,
54
+ BuiltInFunctionImplementationModule,
55
+ BUILT_IN_FUNCTION_IMPLEMENTATIONS__PREFIX,
56
+ GroupOperatorTypes,
57
+ flattenElementCalls,
58
+ CallerEntityState,
59
+ isObject,
60
+ getScopeOwner
61
+ } from '@elyx-code/project-logic-tree';
62
+ import {
63
+ resolveValue,
64
+ resolveNextValue,
65
+ assembleStandaloneLiteralValueFromDataType,
66
+ IValueResolutionContext,
67
+ getEntitiesToPropagateValuesTo
68
+ } from './value-resolution';
69
+ import {
70
+ DynamicValueTypes,
71
+ EfimeralValueStore,
72
+ IDynamicValue,
73
+ IValueStoreClient
74
+ } from '../editor/value-store';
75
+ import { getLiteralValueNameFromDataType } from './utils';
76
+ import {
77
+ Events,
78
+ Logger,
79
+ YieldOptions,
80
+ YieldTracker
81
+ } from '@elyx-code/common-ts-utils';
82
+
83
+ export type TestableEntityState = ExecutableEntityState;
84
+
85
+ export interface IExecutionResult {
86
+ value: ExecutionTerminationType;
87
+ entity: TestableEntityState;
88
+ error: IDynamicValue | null;
89
+ result: IDynamicValue | null;
90
+ }
91
+
92
+ export interface IExecutionCallbackContext {
93
+ detached: boolean;
94
+ execution?: Execution;
95
+ }
96
+
97
+ /*
98
+ This interface defines the methods that the execution client should implement
99
+
100
+ It is used to decouple the execution logic from the business logic that is executing it
101
+ This way, the execution logic can be reused in different contexts
102
+
103
+ It provides the callbacks to hook into lifecycle events of the execution
104
+ */
105
+ export interface IExecutionClient {
106
+ onBeforeEntityExecution?: (
107
+ entity: TestableEntityState,
108
+ inputs: IDynamicValue[],
109
+ context: IExecutionCallbackContext
110
+ ) => Promise<any>;
111
+ onEntityExecuted?: (
112
+ entity: TestableEntityState,
113
+ result: IExecutionResult,
114
+ context: IExecutionCallbackContext
115
+ ) => Promise<any>;
116
+ }
117
+
118
+ /**
119
+ * Converts an Error or unknown error object into a plain object
120
+ * with enumerable properties so it can be stringified/inspected.
121
+ */
122
+ function serializeError(err: any): any {
123
+ if (!(err instanceof Error) && typeof err === 'object' && err !== null) {
124
+ return err; // It's already a plain object
125
+ }
126
+
127
+ if (err instanceof Error) {
128
+ return {
129
+ // @ts-ignore
130
+ name: err.name,
131
+ // @ts-ignore
132
+ message: err.message,
133
+ stack: err.stack,
134
+ // Capture any custom properties added to the Error object
135
+ ...err
136
+ };
137
+ }
138
+
139
+ return err; // Primitive (string, number, etc.)
140
+ }
141
+
142
+ function extractRawValue(val: any): { single: any; list: any[] | null } {
143
+ if (val && typeof val === 'object' && 'value' in val) {
144
+ const dynamicVal = val as IDynamicValue;
145
+ return {
146
+ single:
147
+ dynamicVal.value?.valueAsTypeSingle ?? dynamicVal.value?.value,
148
+ list: dynamicVal.value?.valueAsTypeList ?? null
149
+ };
150
+ }
151
+ return {
152
+ single: val,
153
+ list: Array.isArray(val) ? val : null
154
+ };
155
+ }
156
+
157
+ const EXECUTION_CLIENT_DEFAULTS: IExecutionClient = {
158
+ onBeforeEntityExecution: async () => {},
159
+ onEntityExecuted: async () => {}
160
+ };
161
+
162
+ export class ExecutionStoppedError extends Error {
163
+ constructor() {
164
+ super('Execution was stopped');
165
+ this.name = 'ExecutionStoppedError';
166
+ }
167
+ }
168
+
169
+ export enum ExecutionState {
170
+ FinishedSuccess = 'finished-success',
171
+ FinishedError = 'finished-error',
172
+ Running = 'running',
173
+ Paused = 'paused',
174
+ Stopped = 'stopped',
175
+ NotStarted = 'not-started'
176
+ }
177
+
178
+ export interface IExecutionInstanceParentContext extends IBaseExtensionsContext {
179
+ // Value type preference for the resolution
180
+ getValueTypePreference: (
181
+ valueOwnerId: EntityId
182
+ ) => DynamicValueTypes.DefaultValue | DynamicValueTypes.Testing | null;
183
+ setValueTypePreference: (
184
+ valueOwnerId: EntityId,
185
+ valueTypePreference:
186
+ | DynamicValueTypes.DefaultValue
187
+ | DynamicValueTypes.Testing
188
+ | null
189
+ ) => void;
190
+ }
191
+
192
+ export const DEFAULT_EXECUTION_INSTANCE_PARENT_CONTEXT: IExecutionInstanceParentContext =
193
+ {
194
+ ...DEFAULT_BASE_EXTENSIONS_CONTEXT,
195
+ getValueTypePreference: () => null,
196
+ setValueTypePreference: () => {}
197
+ };
198
+
199
+ // Now Execution extends CombinedEfimeralValueStoreAndEvents and has both behaviors.
200
+ export class Execution extends Events {
201
+ project: ProjectState;
202
+ entryPoint: TestableEntityState;
203
+ state: ExecutionState = ExecutionState.NotStarted;
204
+
205
+ events: Events = new Events('fe-exec-inst-events');
206
+
207
+ // The entities that are part of the test
208
+ // Regardless of their execution state
209
+ entities: TestableEntityState[] = [];
210
+
211
+ // The parent execution of the current execution
212
+ // Null if the current execution is the root execution
213
+ parentExecution: Execution | null = null;
214
+
215
+ // The entities that are part of the test
216
+ // And are being executed at any given moment
217
+ executing: TestableEntityState[] = [];
218
+
219
+ // The entities that are part of the test
220
+ // And have already been executed
221
+ executed: TestableEntityState[] = [];
222
+
223
+ // The entities that are part of the test
224
+ // and which branch was skipped, so they will not be executed
225
+ skipped: TestableEntityState[] = [];
226
+
227
+ // Entities who have at least one of their callers having already completed its execution
228
+ // But have other callers that haven't completed yet, so they are "waiting" for them
229
+ scheduled: TestableEntityState[] = [];
230
+
231
+ // Local test values that the user can set in the canvas
232
+ localTestValues: EfimeralValueStore;
233
+ // Resolved values cached so the calculation doesn't have to be done every time
234
+ resolvedValues: EfimeralValueStore;
235
+ // Values saved from previous executions results
236
+ persistedExecutionResults: EfimeralValueStore;
237
+ // Last execution results values from the last execution of their respective entities
238
+ // This values are temporary and used to save them to the 'persistedExecutionResults' or discard them after the execution
239
+ lastExecutionResults: EfimeralValueStore;
240
+
241
+ onAddToSkippedListCallback:
242
+ | null
243
+ | ((
244
+ entity: TestableEntityState,
245
+ options?: YieldOptions & {
246
+ skipValidate?: boolean;
247
+ skipRender?: boolean;
248
+ skipNotify?: boolean;
249
+ }
250
+ ) => Promise<void> | void) = null;
251
+ onRemoveFromSkippedListCallback:
252
+ | null
253
+ | ((
254
+ entity: TestableEntityState,
255
+ options?: YieldOptions & {
256
+ skipValidate?: boolean;
257
+ skipRender?: boolean;
258
+ skipNotify?: boolean;
259
+ }
260
+ ) => Promise<void> | void) = null;
261
+ onAddEntityCallback:
262
+ | null
263
+ | ((
264
+ entity: TestableEntityState,
265
+ options?: YieldOptions & {
266
+ skipValidate?: boolean;
267
+ skipRender?: boolean;
268
+ skipNotify?: boolean;
269
+ }
270
+ ) => Promise<void> | void) = null;
271
+ onRemoveEntityCallback:
272
+ | null
273
+ | ((
274
+ entity: TestableEntityState,
275
+ options?: YieldOptions & {
276
+ skipValidate?: boolean;
277
+ skipRender?: boolean;
278
+ skipNotify?: boolean;
279
+ }
280
+ ) => Promise<void> | void) = null;
281
+ onAbortExecutionCallback:
282
+ | null
283
+ | ((
284
+ entity: TestableEntityState,
285
+ options?: YieldOptions & {
286
+ skipValidate?: boolean;
287
+ skipRender?: boolean;
288
+ skipNotify?: boolean;
289
+ }
290
+ ) => Promise<void> | void) = null;
291
+
292
+ constructor(
293
+ project: ProjectState,
294
+ entities: TestableEntityState[],
295
+ entryPoint: TestableEntityState,
296
+ parentExecution: Execution | null = null,
297
+ public readonly parentContext: IExecutionInstanceParentContext = DEFAULT_EXECUTION_INSTANCE_PARENT_CONTEXT
298
+ ) {
299
+ super();
300
+ this.entities = entities;
301
+ this.entryPoint = entryPoint;
302
+ this.project = project;
303
+ this.parentExecution = parentExecution;
304
+
305
+ this.localTestValues = new EfimeralValueStore(
306
+ ProjectState.UUID.uuid(),
307
+ this.project
308
+ );
309
+ this.resolvedValues = new EfimeralValueStore(
310
+ ProjectState.UUID.uuid(),
311
+ this.project
312
+ );
313
+ this.persistedExecutionResults = new EfimeralValueStore(
314
+ ProjectState.UUID.uuid(),
315
+ this.project
316
+ );
317
+ this.lastExecutionResults = new EfimeralValueStore(
318
+ ProjectState.UUID.uuid(),
319
+ this.project
320
+ );
321
+ }
322
+
323
+ get valueResolutionContext(): IValueResolutionContext {
324
+ return {
325
+ execution: this,
326
+ project: this.project,
327
+ // Local test values that the user can set in the canvas
328
+ localTestValues: this.localTestValues as IValueStoreClient,
329
+ // Resolved values cached so the calculation doesn't have to be done every time
330
+ resolvedValues: this.resolvedValues as IValueStoreClient,
331
+ // Values saved from previous executions results
332
+ persistedExecutionResults: this
333
+ .persistedExecutionResults as IValueStoreClient,
334
+ // Last execution results values from the last execution of their respective entities
335
+ // This values are temporary and used to save them to the 'persistedExecutionResults' or discard them after the execution
336
+ lastExecutionResults: this
337
+ .lastExecutionResults as IValueStoreClient,
338
+ getValueTypePreference: this.parentContext.getValueTypePreference,
339
+ setValueTypePreference: this.parentContext.setValueTypePreference
340
+ };
341
+ }
342
+
343
+ get rootExecution(): Execution {
344
+ let current: Execution = this;
345
+ while (current.parentExecution) {
346
+ current = current.parentExecution;
347
+ }
348
+ return current;
349
+ }
350
+
351
+ get rootState(): ExecutionState {
352
+ return this.rootExecution.state;
353
+ }
354
+
355
+ isStopped(): boolean {
356
+ return (
357
+ this.state === ExecutionState.Stopped ||
358
+ this.rootExecution.state === ExecutionState.Stopped
359
+ );
360
+ }
361
+
362
+ isPaused(): boolean {
363
+ return (
364
+ this.state === ExecutionState.Paused ||
365
+ this.rootExecution.state === ExecutionState.Paused
366
+ );
367
+ }
368
+
369
+ async checkStateAndPause(): Promise<void> {
370
+ if (this.isStopped()) {
371
+ throw new ExecutionStoppedError();
372
+ }
373
+ while (this.isPaused()) {
374
+ if (this.isStopped()) {
375
+ throw new ExecutionStoppedError();
376
+ }
377
+ await new Promise((resolve) => setTimeout(resolve, 100));
378
+ }
379
+ }
380
+
381
+ skip(entity: TestableEntityState): void {
382
+ if (!this.hasEntity(entity)) {
383
+ return;
384
+ }
385
+
386
+ // If the entity is scheduled, remove it from the scheduled list
387
+ this.removeFromScheduledList(entity);
388
+
389
+ if (!!this.skipped.includes(entity)) {
390
+ return;
391
+ }
392
+
393
+ this.skipped.push(entity);
394
+
395
+ if (this.onAddToSkippedListCallback) {
396
+ this.onAddToSkippedListCallback(entity);
397
+ }
398
+
399
+ // Flatten its calls and skipp all of them
400
+ if (CALLER_TYPES.includes(entity.type)) {
401
+ flattenElementCalls(entity as CallerEntityState).forEach((callee) =>
402
+ this.skip(callee)
403
+ );
404
+ }
405
+ }
406
+
407
+ // If all its callers have completed their execution, execute the entity
408
+ // Otherwise add it to the scheduled list
409
+ async schedule(
410
+ entity: TestableEntityState,
411
+ inputs?: IDynamicValue[],
412
+ client?: IExecutionClient
413
+ ): Promise<IExecutionResult | null> {
414
+ if (this.hasExecuted(entity)) {
415
+ return null;
416
+ }
417
+
418
+ if (ENTRY_POINT_TYPES.includes(entity.type)) {
419
+ return this.executeBranch(
420
+ entity as EntryPointEntityState,
421
+ client,
422
+ inputs
423
+ );
424
+ } else if (CALLABLE_TYPES.includes(entity.type)) {
425
+ const allCallersCompleted = (
426
+ entity as CallableEntityState
427
+ ).calledBy.every((caller) => {
428
+ // Check if the caller has been executed or if it not part of the execution
429
+ return this.hasExecuted(caller) || !this.hasEntity(caller);
430
+ });
431
+
432
+ if (allCallersCompleted) {
433
+ return this.executeBranch(
434
+ entity as EntryPointEntityState,
435
+ client,
436
+ inputs
437
+ );
438
+ } else {
439
+ if (!this.scheduled.includes(entity)) {
440
+ this.scheduled.push(entity);
441
+ }
442
+ }
443
+ }
444
+
445
+ return null;
446
+ }
447
+
448
+ // For entities that can be executed with external values,
449
+ // this function takes a list of external dynamic values
450
+ // as well as the entity itself, and it merges them based on the value owner
451
+ // And returns a resolved list of dynamic values to be used during the execution
452
+ mergeExernalValuesWithInternalInputs(
453
+ externalValues: IDynamicValue[],
454
+ entity: EntityState
455
+ ): IDynamicValue[] {
456
+ const childrenEntitiesWithValues: (
457
+ | ValueReadingEntityState
458
+ | ArgumentDeclarationState
459
+ )[] = [];
460
+
461
+ if (
462
+ [...PASS_THROUGH_CALLABLE_TYPES, ...ENTRY_POINT_TYPES].includes(
463
+ entity.type
464
+ )
465
+ ) {
466
+ childrenEntitiesWithValues.push(
467
+ ...(
468
+ entity as
469
+ | PassThroughCallableEntityState
470
+ | EntryPointEntityState
471
+ ).inputs
472
+ );
473
+ } else if (TERMINATION_TYPES.includes(entity.type)) {
474
+ childrenEntitiesWithValues.push(
475
+ ...(entity as TerminationEntityState).outputs
476
+ );
477
+ }
478
+
479
+ const resolvedInputs = childrenEntitiesWithValues.map(
480
+ (childEntityWithValue) => {
481
+ // Here get the external value for the input or the resolved 'next' value
482
+ let foundExternalValue = externalValues.find(
483
+ (value) => value.valueOwner.id === childEntityWithValue.id
484
+ );
485
+
486
+ if (foundExternalValue) {
487
+ return foundExternalValue;
488
+ }
489
+
490
+ if (
491
+ !foundExternalValue &&
492
+ ENTRY_POINT_TYPES.includes(entity.type)
493
+ ) {
494
+ foundExternalValue = externalValues.find(
495
+ (value) =>
496
+ (value.valueOwner as InputMapState).declaration
497
+ ?.id === childEntityWithValue.id
498
+ );
499
+ }
500
+
501
+ if (foundExternalValue) {
502
+ const clonedLiteralValue =
503
+ foundExternalValue.value?.clone(null);
504
+
505
+ clonedLiteralValue?.setStandaloneParent(
506
+ childEntityWithValue,
507
+ null
508
+ );
509
+
510
+ const dynamicValue: IDynamicValue = {
511
+ ...foundExternalValue,
512
+ valueOwner: childEntityWithValue,
513
+ value: clonedLiteralValue || null,
514
+ inheritanceLink: {
515
+ sources: [foundExternalValue],
516
+ target: childEntityWithValue
517
+ }
518
+ };
519
+
520
+ return dynamicValue;
521
+ }
522
+
523
+ if (VALUE_READING_TYPES.includes(childEntityWithValue.type)) {
524
+ const resolvedValue = resolveNextValue(
525
+ childEntityWithValue as ValueReadingEntityState,
526
+ this.valueResolutionContext
527
+ );
528
+ return resolvedValue;
529
+ } else {
530
+ const resolvedValue = resolveValue(
531
+ childEntityWithValue,
532
+ this.valueResolutionContext
533
+ );
534
+ return resolvedValue;
535
+ }
536
+ }
537
+ );
538
+
539
+ return resolvedInputs
540
+ .reduce((acc, value) => {
541
+ const entitiesToPropagateTo = getEntitiesToPropagateValuesTo(
542
+ value?.valueOwner as EntityWithValueState,
543
+ this.project
544
+ );
545
+
546
+ const propagatedValues: IDynamicValue[] = !!value
547
+ ? [value]
548
+ : [];
549
+
550
+ entitiesToPropagateTo.forEach((entityToPropagateTo) => {
551
+ if (entityToPropagateTo.id === value?.valueOwner.id) {
552
+ return;
553
+ }
554
+
555
+ const newValue: LiteralValueState | null =
556
+ assembleStandaloneLiteralValueFromDataType(
557
+ entityToPropagateTo.getDataType(null),
558
+ entityToPropagateTo,
559
+ this.project
560
+ );
561
+
562
+ newValue?.metaSync(
563
+ {
564
+ value: value?.value?.value
565
+ },
566
+ null
567
+ );
568
+
569
+ newValue?.setValueAsTypeList(
570
+ value?.value?.valueAsTypeList || null
571
+ );
572
+ newValue?.setValueAsTypeSingle(
573
+ value?.value?.valueAsTypeSingle || null
574
+ );
575
+
576
+ const newDynamicValue: IDynamicValue = {
577
+ ...(value as IDynamicValue),
578
+ valueOwner: entityToPropagateTo,
579
+ value: newValue
580
+ };
581
+
582
+ propagatedValues.push(newDynamicValue);
583
+ });
584
+
585
+ return [...acc, ...propagatedValues];
586
+ }, [] as IDynamicValue[])
587
+ .sort(
588
+ (a, b) =>
589
+ (a.valueOwner as InputMapState).index -
590
+ (b.valueOwner as InputMapState).index
591
+ );
592
+ }
593
+
594
+ inheritValuesFromContext(context: IValueResolutionContext) {
595
+ this.localTestValues = context.localTestValues as IValueStoreClient;
596
+ this.resolvedValues = context.resolvedValues as IValueStoreClient;
597
+ this.persistedExecutionResults =
598
+ context.persistedExecutionResults as IValueStoreClient;
599
+ // this.lastExecutionResults = context.lastExecutionResults as IValueStoreClient;
600
+ }
601
+
602
+ async executeInternalCall(
603
+ entity: InternalCallState,
604
+ inputs: IDynamicValue[],
605
+ project: ProjectState,
606
+ client: IExecutionClient = {}
607
+ ): Promise<IExecutionResult> {
608
+ this.logBeforeExecution('executeInternalCall', entity, inputs);
609
+ const clientWithDefaults: IExecutionClient = {
610
+ ...EXECUTION_CLIENT_DEFAULTS,
611
+ ...client
612
+ };
613
+
614
+ // Execute the operation based on its "implementation"
615
+ try {
616
+ let oPResult: IPrimitiveExecutionResult = {
617
+ value: ExecutionTerminationType.Success,
618
+ error: null,
619
+ result: null
620
+ };
621
+
622
+ // Sort inputs based on 'index'
623
+ inputs.sort(
624
+ (a, b) =>
625
+ (a.valueOwner as InputMapState).index -
626
+ (b.valueOwner as InputMapState).index
627
+ );
628
+
629
+ if (
630
+ Object.values(BuiltInFunctionIds).includes(
631
+ entity.declaration.id as BuiltInFunctionIds
632
+ )
633
+ ) {
634
+ const implementation =
635
+ this.parentContext.requestExtension<BuiltInFunctionImplementationModule>(
636
+ BUILT_IN_FUNCTION_IMPLEMENTATIONS__PREFIX +
637
+ entity.declaration.id
638
+ ).module.main;
639
+
640
+ if (implementation) {
641
+ oPResult = await implementation(entity, inputs, this);
642
+ } else {
643
+ Logger.warn(
644
+ `No implementation found for built-in function: ${entity.declaration.id}`
645
+ );
646
+ }
647
+ } else {
648
+ // Execute the function-declaration as a detached function
649
+ const detachedResult =
650
+ await this.executeDetachedFullFunctionDeclarationLogic(
651
+ entity.declaration as FunctionDeclarationState,
652
+ inputs,
653
+ project,
654
+ clientWithDefaults
655
+ );
656
+ oPResult = {
657
+ value: detachedResult.value,
658
+ error: detachedResult.error,
659
+ result: detachedResult.result
660
+ };
661
+ }
662
+
663
+ let errorValue: IDynamicValue | null = null;
664
+
665
+ if (oPResult.error && !!entity.error) {
666
+ Logger.warn(`Raw error executing entity: `, oPResult.error);
667
+ const { single: rawErrorSingle, list: rawErrorList } =
668
+ extractRawValue(oPResult.error);
669
+ const richError = serializeError(rawErrorSingle);
670
+ const resolvedDataType = entity.error?.getDataType(null);
671
+ const literalValueInstance =
672
+ assembleStandaloneLiteralValueFromDataType(
673
+ resolvedDataType || null,
674
+ entity.error as EntityWithValueState,
675
+ project
676
+ );
677
+
678
+ if (!!resolvedDataType?.asType) {
679
+ if (rawErrorList !== null) {
680
+ literalValueInstance?.setValueAsTypeList(rawErrorList);
681
+ } else {
682
+ literalValueInstance?.setValueAsTypeSingle(
683
+ rawErrorSingle
684
+ );
685
+ }
686
+ } else {
687
+ const sanitizedError = isObject(richError)
688
+ ? JSON.stringify(richError, null, 2)
689
+ : richError;
690
+ literalValueInstance?.metaSync(
691
+ {
692
+ value: sanitizedError
693
+ },
694
+ null
695
+ );
696
+ }
697
+
698
+ errorValue = {
699
+ valueOwner: entity.error as EntityWithValueState,
700
+ type: DynamicValueTypes.ExecutionResult,
701
+ inheritanceLink: null,
702
+ value: literalValueInstance
703
+ };
704
+ }
705
+
706
+ const resolvedDataType = entity?.getDataType(null);
707
+ const literalValueInstance =
708
+ assembleStandaloneLiteralValueFromDataType(
709
+ resolvedDataType,
710
+ entity,
711
+ project
712
+ );
713
+
714
+ const { single: rawResultSingle, list: rawResultList } =
715
+ extractRawValue(oPResult.result);
716
+ if (!!resolvedDataType?.asType) {
717
+ if (rawResultList !== null) {
718
+ literalValueInstance?.setValueAsTypeList(rawResultList);
719
+ } else {
720
+ literalValueInstance?.setValueAsTypeSingle(rawResultSingle);
721
+ }
722
+ } else {
723
+ literalValueInstance?.metaSync(
724
+ {
725
+ value: rawResultSingle
726
+ },
727
+ null
728
+ );
729
+ }
730
+
731
+ return {
732
+ value: oPResult.value,
733
+ entity: entity,
734
+ error: errorValue,
735
+ result: {
736
+ value: literalValueInstance || null,
737
+ valueOwner: entity,
738
+ type: DynamicValueTypes.ExecutionResult,
739
+ inheritanceLink: null
740
+ }
741
+ };
742
+ } catch (e) {
743
+ if (
744
+ e &&
745
+ ((e as any).name === 'ExecutionStoppedError' ||
746
+ (e as any).message === 'Execution was stopped')
747
+ )
748
+ throw e;
749
+ Logger.warn(`Internal call execution error: `, e);
750
+ let resolvedErrorValue: IDynamicValue | null = null;
751
+
752
+ // TODO: Add error to entity if not present
753
+ if (!!entity.error) {
754
+ const richError = serializeError(e);
755
+ const resolvedDataType = entity.error?.getDataType(null);
756
+ const literalValueInstance =
757
+ assembleStandaloneLiteralValueFromDataType(
758
+ resolvedDataType,
759
+ entity.error,
760
+ project
761
+ );
762
+
763
+ if (!!resolvedDataType?.asType) {
764
+ literalValueInstance?.setValueAsTypeSingle(e as any);
765
+ } else {
766
+ const sanitizedError = isObject(richError)
767
+ ? JSON.stringify(richError, null, 2)
768
+ : richError;
769
+ literalValueInstance?.metaSync(
770
+ {
771
+ value: sanitizedError
772
+ },
773
+ null
774
+ );
775
+ }
776
+
777
+ resolvedErrorValue = {
778
+ valueOwner: entity.error,
779
+ type: DynamicValueTypes.ExecutionResult,
780
+ inheritanceLink: null,
781
+ value: literalValueInstance
782
+ };
783
+ }
784
+
785
+ return {
786
+ value:
787
+ entity.catchesError || entity.errorCalls.length
788
+ ? ExecutionTerminationType.CaughtError
789
+ : ExecutionTerminationType.UnhandledError,
790
+ entity: entity,
791
+ error: resolvedErrorValue,
792
+ result: null
793
+ };
794
+ }
795
+ }
796
+
797
+ static async executeOperation(
798
+ operation: OperationState,
799
+ inputs: IDynamicValue[],
800
+ project: ProjectState,
801
+ execution?: Execution
802
+ ): Promise<IExecutionResult> {
803
+ if (execution) {
804
+ execution.logBeforeExecution('executeOperation', operation, inputs);
805
+ } else {
806
+ console.log(
807
+ `executeOperation (${operation.type}) -> [${resolveEntityName(operation, project)}] Inputs:${!!inputs.length ? `\n ` : ''}${inputs
808
+ .map(
809
+ (d) =>
810
+ `${d.valueOwner?.type} (${d.valueOwner?.id}) "${resolveEntityName(d.valueOwner as any, project)}": ${JSON.stringify(d.value?.value, null, 2)}`
811
+ )
812
+ .join('\n ')}\n`
813
+ );
814
+ }
815
+ // Execute the operation based on its "implementation"
816
+ try {
817
+ let oPResult: IPrimitiveExecutionResult = {
818
+ value: ExecutionTerminationType.Success,
819
+ error: null,
820
+ result: null
821
+ };
822
+
823
+ // Sort inputs based on 'index'
824
+ inputs.sort(
825
+ (a, b) =>
826
+ (a.valueOwner as InputMapState).index -
827
+ (b.valueOwner as InputMapState).index
828
+ );
829
+
830
+ if (operation.declaration.implementation) {
831
+ oPResult = await operation.declaration.implementation(
832
+ operation,
833
+ inputs.sort(
834
+ (a, b) =>
835
+ (a.valueOwner as InputMapState).index -
836
+ (b.valueOwner as InputMapState).index
837
+ )
838
+ );
839
+ }
840
+
841
+ let errorValue: IDynamicValue | null = null;
842
+
843
+ if (oPResult.error && !!operation.error) {
844
+ const richError = serializeError(oPResult.error);
845
+
846
+ const resolvedDataType =
847
+ operation.error?.getDataType(null) || null;
848
+ const literalValueInstance =
849
+ assembleStandaloneLiteralValueFromDataType(
850
+ resolvedDataType,
851
+ operation.error,
852
+ project
853
+ );
854
+
855
+ if (!!resolvedDataType?.asType) {
856
+ literalValueInstance?.setValueAsTypeSingle(oPResult.error);
857
+ } else {
858
+ // Make payload digestible
859
+ const sanitizedError = isObject(richError)
860
+ ? JSON.stringify(richError, null, 2) // Pretty print helps debugging
861
+ : richError;
862
+
863
+ literalValueInstance?.metaSync(
864
+ {
865
+ value: sanitizedError
866
+ },
867
+ null
868
+ );
869
+ }
870
+
871
+ errorValue = {
872
+ valueOwner: operation.error,
873
+ type: DynamicValueTypes.ExecutionResult,
874
+ inheritanceLink: null,
875
+ value: literalValueInstance
876
+ };
877
+ }
878
+
879
+ const resolvedDataType = operation?.getDataType(null);
880
+ const literalValueInstance =
881
+ assembleStandaloneLiteralValueFromDataType(
882
+ resolvedDataType,
883
+ operation,
884
+ project
885
+ );
886
+
887
+ if (!!resolvedDataType?.asType) {
888
+ literalValueInstance?.setValueAsTypeSingle(oPResult.result);
889
+ } else {
890
+ literalValueInstance?.metaSync(
891
+ {
892
+ value: oPResult.result
893
+ },
894
+ null
895
+ );
896
+ }
897
+
898
+ return {
899
+ value: oPResult.value,
900
+ entity: operation,
901
+ error: errorValue,
902
+ result: {
903
+ value: literalValueInstance || null,
904
+ valueOwner: operation,
905
+ type: DynamicValueTypes.ExecutionResult,
906
+ inheritanceLink: null
907
+ }
908
+ };
909
+ } catch (e) {
910
+ if (
911
+ e &&
912
+ ((e as any).name === 'ExecutionStoppedError' ||
913
+ (e as any).message === 'Execution was stopped')
914
+ )
915
+ throw e;
916
+ console.warn(`Operation execution error: `, e);
917
+ let resolvedErrorValue: IDynamicValue | null = null;
918
+
919
+ // TODO: Add error to entity if not present
920
+ if (!!operation.error) {
921
+ const richError = serializeError(e);
922
+ const resolvedDataType = operation.error?.getDataType(null);
923
+ const literalValueInstance =
924
+ assembleStandaloneLiteralValueFromDataType(
925
+ resolvedDataType,
926
+ operation.error,
927
+ project
928
+ );
929
+
930
+ if (!!resolvedDataType?.asType) {
931
+ literalValueInstance?.setValueAsTypeSingle(e as any);
932
+ } else {
933
+ const sanitizedError = isObject(richError)
934
+ ? JSON.stringify(richError, null, 2)
935
+ : richError;
936
+ literalValueInstance?.metaSync(
937
+ {
938
+ value: sanitizedError
939
+ },
940
+ null
941
+ );
942
+ }
943
+
944
+ resolvedErrorValue = {
945
+ valueOwner: operation.error,
946
+ type: DynamicValueTypes.ExecutionResult,
947
+ inheritanceLink: null,
948
+ value: literalValueInstance
949
+ };
950
+ }
951
+
952
+ return {
953
+ value:
954
+ operation.catchesError || operation.errorCalls.length
955
+ ? ExecutionTerminationType.CaughtError
956
+ : ExecutionTerminationType.UnhandledError,
957
+ entity: operation,
958
+ error: resolvedErrorValue,
959
+ result: null
960
+ };
961
+ }
962
+ }
963
+
964
+ async executeSearch(
965
+ entity: SearchState,
966
+ inputs: IDynamicValue[],
967
+ project: ProjectState
968
+ ): Promise<IExecutionResult> {
969
+ this.logBeforeExecution('executeSearch', entity, inputs);
970
+ try {
971
+ let oPResult: IPrimitiveExecutionResult = {
972
+ value: ExecutionTerminationType.Success,
973
+ error: null,
974
+ result: null
975
+ };
976
+
977
+ const newValue = await (
978
+ await this.parentContext.requestExtension<ISearchNodeImplementationModule>(
979
+ DEFAULT_MODULE_IDS.SEARCH_NODE_IMPLEMENTATION
980
+ )
981
+ ).module.main(entity, inputs);
982
+
983
+ // Create a new literal value instance
984
+ const resolvedDataType = entity?.getDataType(null);
985
+ const literalValueInstance =
986
+ assembleStandaloneLiteralValueFromDataType(
987
+ resolvedDataType,
988
+ entity,
989
+ project
990
+ );
991
+
992
+ literalValueInstance?.metaSync(
993
+ {
994
+ value: newValue
995
+ },
996
+ null
997
+ );
998
+
999
+ if (newValue.error) {
1000
+ return {
1001
+ value: ExecutionTerminationType.UnhandledError,
1002
+ entity: entity,
1003
+ error: {
1004
+ valueOwner: entity,
1005
+ type: DynamicValueTypes.ExecutionResult,
1006
+ inheritanceLink: null,
1007
+ value: literalValueInstance
1008
+ },
1009
+ result: null
1010
+ };
1011
+ }
1012
+
1013
+ return {
1014
+ value: oPResult.value,
1015
+ entity: entity,
1016
+ error: null,
1017
+ result: {
1018
+ value: literalValueInstance,
1019
+ valueOwner: entity,
1020
+ type: DynamicValueTypes.ExecutionResult,
1021
+ inheritanceLink: null
1022
+ }
1023
+ };
1024
+ } catch (e) {
1025
+ if (
1026
+ e &&
1027
+ ((e as any).name === 'ExecutionStoppedError' ||
1028
+ (e as any).message === 'Execution was stopped')
1029
+ )
1030
+ throw e;
1031
+ Logger.warn(`Search node execution error: ${e}`);
1032
+ if (!entity.error) {
1033
+ return {
1034
+ value:
1035
+ entity.catchesError || entity.errorCalls.length
1036
+ ? ExecutionTerminationType.CaughtError
1037
+ : ExecutionTerminationType.UnhandledError,
1038
+ entity: entity,
1039
+ error: null,
1040
+ result: null
1041
+ };
1042
+ }
1043
+
1044
+ const richError = serializeError(e);
1045
+ const resolvedDataType = entity.error?.getDataType(null);
1046
+
1047
+ const errorLiteralValueInstance =
1048
+ assembleStandaloneLiteralValueFromDataType(
1049
+ resolvedDataType,
1050
+ entity.error,
1051
+ project
1052
+ );
1053
+
1054
+ const sanitizedError = isObject(richError)
1055
+ ? JSON.stringify(richError, null, 2)
1056
+ : richError;
1057
+ errorLiteralValueInstance?.metaSync(
1058
+ {
1059
+ value: sanitizedError
1060
+ },
1061
+ null
1062
+ );
1063
+
1064
+ return {
1065
+ value:
1066
+ entity.catchesError || entity.errorCalls.length
1067
+ ? ExecutionTerminationType.CaughtError
1068
+ : ExecutionTerminationType.UnhandledError,
1069
+ entity: entity,
1070
+ error: {
1071
+ valueOwner: entity.error,
1072
+ type: DynamicValueTypes.ExecutionResult,
1073
+ inheritanceLink: null,
1074
+ value: errorLiteralValueInstance
1075
+ },
1076
+ result: null
1077
+ };
1078
+ }
1079
+ }
1080
+
1081
+ async executeLoop(
1082
+ loop: LoopState,
1083
+ inputs: IDynamicValue[],
1084
+ project: ProjectState,
1085
+ client: IExecutionClient = {}
1086
+ ): Promise<IExecutionResult> {
1087
+ this.logBeforeExecution('executeLoop', loop, inputs);
1088
+ const clientWithDefaults: IExecutionClient = {
1089
+ ...EXECUTION_CLIENT_DEFAULTS,
1090
+ ...client
1091
+ };
1092
+
1093
+ /*
1094
+ Execute the loop based on its "declaration"
1095
+ Each loop type works differently, but executing a loop always means executing its body function-declaration
1096
+ What changes are the inputs and outputs, both of the loop and the body function-declaration
1097
+
1098
+ In this function, we:
1099
+ - Keep track of the iterations and add a circuit breaker to avoid infinite loops
1100
+ - Based on the loop type, pass the correct values as the arguments of the body function on each iteration
1101
+ - Agregate any returned values from the body function and pass them as the next iteration's arguments
1102
+ - Terminate the loop if a break statement is called/executed
1103
+ - Terminate the loop if a return statement is called/executed
1104
+ - Map the final aggregated results if any, to the loop's output map values
1105
+
1106
+ All loop types are passed the current iteration number as an argument to the body function
1107
+ Loops that iterate over an iterable value are passed the current value of the iterable as an argument to the body function
1108
+ */
1109
+ try {
1110
+ let oPResult: IPrimitiveExecutionResult = {
1111
+ value: ExecutionTerminationType.Success,
1112
+ error: null,
1113
+ result: null
1114
+ };
1115
+
1116
+ const rawInputValues = inputs.map(
1117
+ (argValue) =>
1118
+ argValue?.value?.valueAsType || argValue?.value?.value
1119
+ );
1120
+
1121
+ let aggregateListResults: {
1122
+ [key: EntityId]: IDynamicValue;
1123
+ } = {};
1124
+
1125
+ const uniqueInputMaps = loop.getUniqueInputMaps();
1126
+
1127
+ // Initialized the aggregateListResults with empty arrays for each return declaration
1128
+ uniqueInputMaps.forEach((inputMap) => {
1129
+ const input = loop.body.inputs.find(
1130
+ (input) =>
1131
+ resolveEntityName(input, project) ===
1132
+ resolveEntityName(inputMap, project)
1133
+ );
1134
+
1135
+ const resolvedDataType = inputMap?.getDataType(null);
1136
+ const literalValueInstance =
1137
+ assembleStandaloneLiteralValueFromDataType(
1138
+ resolvedDataType,
1139
+ input as EntityWithValueState,
1140
+ project
1141
+ );
1142
+
1143
+ if (!!resolvedDataType?.asType) {
1144
+ literalValueInstance?.setValueAsTypeList([]);
1145
+ } else {
1146
+ literalValueInstance?.metaSync(
1147
+ {
1148
+ value: []
1149
+ },
1150
+ null
1151
+ );
1152
+ }
1153
+
1154
+ this.lastExecutionResults.writeValue(
1155
+ input as EntityWithValueState,
1156
+ literalValueInstance as LiteralValueState
1157
+ );
1158
+
1159
+ const newDynamicValue: IDynamicValue = {
1160
+ value: literalValueInstance,
1161
+ valueOwner: input as EntityWithValueState,
1162
+ type: DynamicValueTypes.ExecutionResult,
1163
+ inheritanceLink: null
1164
+ };
1165
+
1166
+ aggregateListResults[(input as EntityWithValueState).id] =
1167
+ newDynamicValue;
1168
+ });
1169
+
1170
+ let lastBodyResult: IExecutionResult = {
1171
+ value: ExecutionTerminationType.Success,
1172
+ entity: loop.body,
1173
+ error: null,
1174
+ result: null
1175
+ };
1176
+
1177
+ switch (loop.declaration.id) {
1178
+ case BUILT_IN_BASE_ENTITY_IDS.loop['counted-loop'].id: {
1179
+ const maxCount = rawInputValues[0] as number;
1180
+
1181
+ let currentIteration = 1;
1182
+
1183
+ while (
1184
+ currentIteration <= maxCount &&
1185
+ currentIteration <= 50
1186
+ ) {
1187
+ await this.checkStateAndPause();
1188
+ const resolvedBodyInputsForCurrentIteration =
1189
+ loop.body.inputs
1190
+ .map((input) => {
1191
+ if (
1192
+ input ===
1193
+ loop.currentIterationNumberArgumentDeclaration
1194
+ ) {
1195
+ const resolvedDataType: DataTypeState | null =
1196
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
1197
+ null
1198
+ );
1199
+ const resolvedLiteralValueName =
1200
+ getLiteralValueNameFromDataType(
1201
+ resolvedDataType
1202
+ );
1203
+
1204
+ const existingValue =
1205
+ this.lastExecutionResults.readValue(
1206
+ input.id
1207
+ );
1208
+
1209
+ if (existingValue) {
1210
+ existingValue.metaSync(
1211
+ {
1212
+ value: currentIteration
1213
+ },
1214
+ null
1215
+ );
1216
+
1217
+ this.lastExecutionResults.writeValue(
1218
+ input,
1219
+ existingValue
1220
+ );
1221
+
1222
+ const existingDynamicValue: IDynamicValue =
1223
+ {
1224
+ value: existingValue,
1225
+ valueOwner:
1226
+ loop.currentIterationNumberArgumentDeclaration,
1227
+ type: DynamicValueTypes.ExecutionResult,
1228
+ inheritanceLink: null
1229
+ };
1230
+ aggregateListResults[input.id] =
1231
+ existingDynamicValue;
1232
+
1233
+ return existingDynamicValue;
1234
+ }
1235
+
1236
+ const newLiteralValueTransfer: ILiteralValueTransfer =
1237
+ {
1238
+ id: ProjectState.UUID.uuid(),
1239
+ deletable: true,
1240
+ editable: true,
1241
+ type: EntityType.LiteralValue,
1242
+ autogeneration: null,
1243
+ version:
1244
+ ProjectState.UUID.uuid(),
1245
+ createdAt:
1246
+ new Date().toISOString(),
1247
+ author: ProjectState.sessionAuthor,
1248
+ deleted: false,
1249
+ previousVersion: null,
1250
+ value: currentIteration,
1251
+ valueAsTypeSingle: null,
1252
+ valueAsTypeList: null,
1253
+ parent: null,
1254
+ name: resolvedLiteralValueName,
1255
+ standaloneParent:
1256
+ input.toReference()
1257
+ };
1258
+
1259
+ const newLiteralValueInstance =
1260
+ createStateFromType(
1261
+ newLiteralValueTransfer,
1262
+ project
1263
+ ) as LiteralValueState;
1264
+
1265
+ this.lastExecutionResults.writeValue(
1266
+ input,
1267
+ newLiteralValueInstance
1268
+ );
1269
+
1270
+ const newDynamicValue: IDynamicValue = {
1271
+ value: newLiteralValueInstance,
1272
+ valueOwner:
1273
+ loop.currentIterationNumberArgumentDeclaration,
1274
+ type: DynamicValueTypes.ExecutionResult,
1275
+ inheritanceLink: null
1276
+ };
1277
+
1278
+ aggregateListResults[input.id] =
1279
+ newDynamicValue;
1280
+
1281
+ return newDynamicValue;
1282
+ } else {
1283
+ return aggregateListResults[input.id];
1284
+ }
1285
+ })
1286
+ .filter((input) => !!input) as IDynamicValue[];
1287
+
1288
+ lastBodyResult =
1289
+ await this.executeFullFunctionDeclarationLogic(
1290
+ loop.body,
1291
+ resolvedBodyInputsForCurrentIteration,
1292
+ clientWithDefaults
1293
+ );
1294
+
1295
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
1296
+ // @ts-ignore
1297
+ (lastBodyResult.results || []).forEach((value) => {
1298
+ // Only returned values can be aggregated
1299
+ if (
1300
+ value.valueOwner.type !== EntityType.InputMap ||
1301
+ TERMINATION_TYPES.includes(
1302
+ value.valueOwner.parent.type
1303
+ )
1304
+ ) {
1305
+ return;
1306
+ }
1307
+
1308
+ const input = loop.body.inputs.find(
1309
+ (input) =>
1310
+ resolveEntityName(input, project) ===
1311
+ resolveEntityName(
1312
+ value.valueOwner as InputMapState,
1313
+ project
1314
+ )
1315
+ );
1316
+
1317
+ const lastRawValue: any[] =
1318
+ (aggregateListResults?.[
1319
+ (input as EntityWithValueState).id
1320
+ ]?.value?.value as any[]) || [];
1321
+
1322
+ const newValue = [
1323
+ ...lastRawValue,
1324
+ value?.value?.value || null
1325
+ ];
1326
+
1327
+ aggregateListResults[
1328
+ (input as EntityWithValueState).id
1329
+ ].value?.metaSync(
1330
+ {
1331
+ value: newValue
1332
+ },
1333
+ null
1334
+ );
1335
+
1336
+ this.lastExecutionResults.writeValue(
1337
+ input as EntityWithValueState,
1338
+ aggregateListResults[
1339
+ (input as EntityWithValueState).id
1340
+ ].value as LiteralValueState
1341
+ );
1342
+ });
1343
+
1344
+ if (
1345
+ [
1346
+ ExecutionTerminationType.CaughtError,
1347
+ ExecutionTerminationType.UnhandledError,
1348
+ ExecutionTerminationType.Break,
1349
+ ExecutionTerminationType.Return
1350
+ ].includes(lastBodyResult.value)
1351
+ ) {
1352
+ break;
1353
+ }
1354
+
1355
+ currentIteration++;
1356
+ }
1357
+
1358
+ break;
1359
+ }
1360
+ case BUILT_IN_BASE_ENTITY_IDS.loop['manual-flow-loop'].id: {
1361
+ let currentIteration = 1;
1362
+
1363
+ while (currentIteration <= 50) {
1364
+ await this.checkStateAndPause();
1365
+ const resolvedBodyInputsForCurrentIteration =
1366
+ loop.body.inputs
1367
+ .map((input) => {
1368
+ if (
1369
+ input ===
1370
+ loop.currentIterationNumberArgumentDeclaration
1371
+ ) {
1372
+ const existingValue =
1373
+ this.lastExecutionResults.readValue(
1374
+ input.id
1375
+ );
1376
+
1377
+ if (existingValue) {
1378
+ existingValue.metaSync(
1379
+ {
1380
+ value: currentIteration
1381
+ },
1382
+ null
1383
+ );
1384
+
1385
+ this.lastExecutionResults.writeValue(
1386
+ input,
1387
+ existingValue
1388
+ );
1389
+
1390
+ const existingDynamicValue: IDynamicValue =
1391
+ {
1392
+ value: existingValue,
1393
+ valueOwner: input,
1394
+ type: DynamicValueTypes.ExecutionResult,
1395
+ inheritanceLink: null
1396
+ };
1397
+ aggregateListResults[input.id] =
1398
+ existingDynamicValue;
1399
+
1400
+ return existingDynamicValue;
1401
+ }
1402
+
1403
+ const resolvedDataType: DataTypeState | null =
1404
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
1405
+ null
1406
+ );
1407
+ const literalValueInstance =
1408
+ assembleStandaloneLiteralValueFromDataType(
1409
+ resolvedDataType,
1410
+ input,
1411
+ project
1412
+ );
1413
+
1414
+ literalValueInstance?.metaSync(
1415
+ {
1416
+ value: currentIteration
1417
+ },
1418
+ null
1419
+ );
1420
+
1421
+ this.lastExecutionResults.writeValue(
1422
+ input,
1423
+ literalValueInstance as LiteralValueState
1424
+ );
1425
+
1426
+ const newDynamicValue: IDynamicValue = {
1427
+ value: literalValueInstance,
1428
+ valueOwner: input,
1429
+ type: DynamicValueTypes.ExecutionResult,
1430
+ inheritanceLink: null
1431
+ };
1432
+
1433
+ return newDynamicValue;
1434
+ } else {
1435
+ return aggregateListResults[input.id];
1436
+ }
1437
+ })
1438
+ .filter((input) => !!input) as IDynamicValue[];
1439
+
1440
+ lastBodyResult =
1441
+ await this.executeFullFunctionDeclarationLogic(
1442
+ loop.body,
1443
+ resolvedBodyInputsForCurrentIteration,
1444
+ clientWithDefaults
1445
+ );
1446
+
1447
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
1448
+ // @ts-ignore
1449
+ (lastBodyResult.results || []).forEach((value) => {
1450
+ // Only returned values can be aggregated
1451
+ if (
1452
+ value.valueOwner.type !== EntityType.InputMap ||
1453
+ TERMINATION_TYPES.includes(
1454
+ value.valueOwner.parent.type
1455
+ )
1456
+ ) {
1457
+ return;
1458
+ }
1459
+
1460
+ const input = loop.body.inputs.find(
1461
+ (input) =>
1462
+ resolveEntityName(input, project) ===
1463
+ resolveEntityName(
1464
+ value.valueOwner as InputMapState,
1465
+ project
1466
+ )
1467
+ );
1468
+
1469
+ const lastRawValue: any[] = aggregateListResults[
1470
+ (input as EntityWithValueState).id
1471
+ ].value?.value as any[];
1472
+
1473
+ const newValue = [
1474
+ ...lastRawValue,
1475
+ value.value?.value || null
1476
+ ];
1477
+
1478
+ aggregateListResults[
1479
+ (input as EntityWithValueState).id
1480
+ ].value?.metaSync(
1481
+ {
1482
+ value: newValue
1483
+ },
1484
+ null
1485
+ );
1486
+
1487
+ this.lastExecutionResults.writeValue(
1488
+ input as EntityWithValueState,
1489
+ aggregateListResults[
1490
+ (input as EntityWithValueState).id
1491
+ ].value as LiteralValueState
1492
+ );
1493
+ });
1494
+
1495
+ if (
1496
+ [
1497
+ ExecutionTerminationType.CaughtError,
1498
+ ExecutionTerminationType.UnhandledError,
1499
+ ExecutionTerminationType.Break,
1500
+ ExecutionTerminationType.Return
1501
+ ].includes(lastBodyResult.value)
1502
+ ) {
1503
+ break;
1504
+ }
1505
+
1506
+ currentIteration++;
1507
+ }
1508
+
1509
+ break;
1510
+ }
1511
+ case BUILT_IN_BASE_ENTITY_IDS.loop['list-loop'].id: {
1512
+ const iterable = rawInputValues[0];
1513
+
1514
+ let currentIteration = 1;
1515
+
1516
+ const iterableListOfValues = iterable as any[];
1517
+
1518
+ for (let i = 0; i < iterableListOfValues.length; i++) {
1519
+ await this.checkStateAndPause();
1520
+ const currentValue = iterableListOfValues[i];
1521
+
1522
+ const resolvedBodyInputsForCurrentIteration =
1523
+ loop.body.inputs
1524
+ .map((input) => {
1525
+ if (
1526
+ input ===
1527
+ loop.currentIterationNumberArgumentDeclaration
1528
+ ) {
1529
+ const existingValue =
1530
+ this.lastExecutionResults.readValue(
1531
+ input.id
1532
+ );
1533
+
1534
+ if (existingValue) {
1535
+ existingValue.metaSync(
1536
+ {
1537
+ value: currentIteration
1538
+ },
1539
+ null
1540
+ );
1541
+
1542
+ this.lastExecutionResults.writeValue(
1543
+ input,
1544
+ existingValue
1545
+ );
1546
+
1547
+ const existingDynamicValue: IDynamicValue =
1548
+ {
1549
+ value: existingValue,
1550
+ valueOwner: input,
1551
+ type: DynamicValueTypes.ExecutionResult,
1552
+ inheritanceLink: null
1553
+ };
1554
+
1555
+ return existingDynamicValue;
1556
+ }
1557
+
1558
+ const resolvedDataType: DataTypeState | null =
1559
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
1560
+ null
1561
+ );
1562
+ const literalValueInstance =
1563
+ assembleStandaloneLiteralValueFromDataType(
1564
+ resolvedDataType,
1565
+ input,
1566
+ project
1567
+ );
1568
+
1569
+ literalValueInstance?.metaSync(
1570
+ {
1571
+ value: currentIteration
1572
+ },
1573
+ null
1574
+ );
1575
+
1576
+ this.lastExecutionResults.writeValue(
1577
+ input,
1578
+ literalValueInstance as LiteralValueState
1579
+ );
1580
+
1581
+ const newDynamicValue: IDynamicValue = {
1582
+ value: literalValueInstance,
1583
+ valueOwner:
1584
+ loop.currentIterationNumberArgumentDeclaration,
1585
+ type: DynamicValueTypes.ExecutionResult,
1586
+ inheritanceLink: null
1587
+ };
1588
+
1589
+ return newDynamicValue;
1590
+ } else if (
1591
+ input ===
1592
+ loop.currentValueArgumentDeclaration
1593
+ ) {
1594
+ const resolvedDataType: DataTypeState | null =
1595
+ loop.currentValueArgumentDeclaration.getDataType(
1596
+ null
1597
+ );
1598
+ const resolvedLiteralValueName =
1599
+ getLiteralValueNameFromDataType(
1600
+ resolvedDataType
1601
+ );
1602
+
1603
+ const existingValue =
1604
+ this.lastExecutionResults.readValue(
1605
+ input.id
1606
+ );
1607
+
1608
+ if (existingValue) {
1609
+ existingValue.metaSync(
1610
+ {
1611
+ value: currentValue
1612
+ },
1613
+ null
1614
+ );
1615
+
1616
+ this.lastExecutionResults.writeValue(
1617
+ input,
1618
+ existingValue
1619
+ );
1620
+
1621
+ const existingDynamicValue: IDynamicValue =
1622
+ {
1623
+ value: existingValue,
1624
+ valueOwner: input,
1625
+ type: DynamicValueTypes.ExecutionResult,
1626
+ inheritanceLink: null
1627
+ };
1628
+
1629
+ return existingDynamicValue;
1630
+ }
1631
+
1632
+ const newLiteralValueTransfer: ILiteralValueTransfer =
1633
+ {
1634
+ id: ProjectState.UUID.uuid(),
1635
+ deletable: true,
1636
+ editable: true,
1637
+ type: EntityType.LiteralValue,
1638
+ autogeneration: null,
1639
+ version:
1640
+ ProjectState.UUID.uuid(),
1641
+ createdAt:
1642
+ new Date().toISOString(),
1643
+ author: ProjectState.sessionAuthor,
1644
+ deleted: false,
1645
+ previousVersion: null,
1646
+ value: currentValue,
1647
+ valueAsTypeSingle: null,
1648
+ valueAsTypeList: null,
1649
+ parent: null,
1650
+ name: resolvedLiteralValueName,
1651
+ standaloneParent:
1652
+ input.toReference()
1653
+ };
1654
+
1655
+ const newLiteralValueInstance =
1656
+ createStateFromType(
1657
+ newLiteralValueTransfer,
1658
+ project
1659
+ ) as LiteralValueState;
1660
+
1661
+ this.lastExecutionResults.writeValue(
1662
+ input,
1663
+ newLiteralValueInstance
1664
+ );
1665
+
1666
+ const newDynamicValue: IDynamicValue = {
1667
+ value: newLiteralValueInstance,
1668
+ valueOwner:
1669
+ loop.currentValueArgumentDeclaration,
1670
+ type: DynamicValueTypes.ExecutionResult,
1671
+ inheritanceLink: null
1672
+ };
1673
+
1674
+ return newDynamicValue;
1675
+ } else {
1676
+ return aggregateListResults[input.id];
1677
+ }
1678
+ })
1679
+ .filter((input) => !!input) as IDynamicValue[];
1680
+
1681
+ lastBodyResult =
1682
+ await this.executeFullFunctionDeclarationLogic(
1683
+ loop.body,
1684
+ resolvedBodyInputsForCurrentIteration,
1685
+ clientWithDefaults
1686
+ );
1687
+
1688
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
1689
+ // @ts-ignore
1690
+ (lastBodyResult.results || []).forEach((value) => {
1691
+ // Only returned values can be aggregated
1692
+ if (
1693
+ value.valueOwner.type !== EntityType.InputMap ||
1694
+ TERMINATION_TYPES.includes(
1695
+ value.valueOwner.parent.type
1696
+ )
1697
+ ) {
1698
+ return;
1699
+ }
1700
+
1701
+ const input = loop.body.inputs.find(
1702
+ (input) =>
1703
+ resolveEntityName(input, project) ===
1704
+ resolveEntityName(
1705
+ value.valueOwner as InputMapState,
1706
+ project
1707
+ )
1708
+ );
1709
+
1710
+ const lastRawValue: any[] = aggregateListResults[
1711
+ (input as EntityWithValueState).id
1712
+ ].value?.value as any[];
1713
+
1714
+ const newValue = [
1715
+ ...lastRawValue,
1716
+ value.value?.value || null
1717
+ ];
1718
+
1719
+ aggregateListResults[
1720
+ (input as EntityWithValueState).id
1721
+ ].value?.metaSync(
1722
+ {
1723
+ value: newValue
1724
+ },
1725
+ null
1726
+ );
1727
+
1728
+ this.lastExecutionResults.writeValue(
1729
+ input as EntityWithValueState,
1730
+ aggregateListResults[
1731
+ (input as EntityWithValueState).id
1732
+ ].value as LiteralValueState
1733
+ );
1734
+ });
1735
+
1736
+ if (
1737
+ [
1738
+ ExecutionTerminationType.CaughtError,
1739
+ ExecutionTerminationType.UnhandledError,
1740
+ ExecutionTerminationType.Break,
1741
+ ExecutionTerminationType.Return
1742
+ ].includes(lastBodyResult.value)
1743
+ ) {
1744
+ break;
1745
+ }
1746
+
1747
+ currentIteration++;
1748
+ }
1749
+
1750
+ break;
1751
+ }
1752
+ case BUILT_IN_BASE_ENTITY_IDS.loop['object-keys-loop'].id: {
1753
+ const iterable = rawInputValues[0];
1754
+
1755
+ let currentIteration = 1;
1756
+
1757
+ const iterableListOfValues = !!iterable
1758
+ ? Object.keys(iterable)
1759
+ : [];
1760
+
1761
+ for (let i = 0; i < iterableListOfValues.length; i++) {
1762
+ await this.checkStateAndPause();
1763
+ const currentValue = iterableListOfValues[i];
1764
+
1765
+ const resolvedBodyInputsForCurrentIteration =
1766
+ loop.body.inputs
1767
+ .map((input) => {
1768
+ if (
1769
+ input ===
1770
+ loop.currentIterationNumberArgumentDeclaration
1771
+ ) {
1772
+ const existingValue =
1773
+ this.lastExecutionResults.readValue(
1774
+ input.id
1775
+ );
1776
+
1777
+ if (existingValue) {
1778
+ existingValue.metaSync(
1779
+ {
1780
+ value: currentIteration
1781
+ },
1782
+ null
1783
+ );
1784
+
1785
+ this.lastExecutionResults.writeValue(
1786
+ input,
1787
+ existingValue
1788
+ );
1789
+
1790
+ const existingDynamicValue: IDynamicValue =
1791
+ {
1792
+ value: existingValue,
1793
+ valueOwner: input,
1794
+ type: DynamicValueTypes.ExecutionResult,
1795
+ inheritanceLink: null
1796
+ };
1797
+
1798
+ return existingDynamicValue;
1799
+ }
1800
+
1801
+ const resolvedDataType: DataTypeState | null =
1802
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
1803
+ null
1804
+ );
1805
+ const literalValueInstance =
1806
+ assembleStandaloneLiteralValueFromDataType(
1807
+ resolvedDataType,
1808
+ input,
1809
+ project
1810
+ );
1811
+
1812
+ literalValueInstance?.metaSync(
1813
+ {
1814
+ value: currentIteration
1815
+ },
1816
+ null
1817
+ );
1818
+
1819
+ this.lastExecutionResults.writeValue(
1820
+ input,
1821
+ literalValueInstance as LiteralValueState
1822
+ );
1823
+
1824
+ const newDynamicValue: IDynamicValue = {
1825
+ value: literalValueInstance,
1826
+ valueOwner:
1827
+ loop.currentIterationNumberArgumentDeclaration,
1828
+ type: DynamicValueTypes.ExecutionResult,
1829
+ inheritanceLink: null
1830
+ };
1831
+
1832
+ return newDynamicValue;
1833
+ } else if (
1834
+ input ===
1835
+ loop.currentValueArgumentDeclaration
1836
+ ) {
1837
+ const resolvedDataType: DataTypeState | null =
1838
+ loop.currentValueArgumentDeclaration.getDataType(
1839
+ null
1840
+ );
1841
+ const resolvedLiteralValueName =
1842
+ getLiteralValueNameFromDataType(
1843
+ resolvedDataType
1844
+ );
1845
+
1846
+ const existingValue =
1847
+ this.lastExecutionResults.readValue(
1848
+ input.id
1849
+ );
1850
+
1851
+ if (existingValue) {
1852
+ existingValue.metaSync(
1853
+ {
1854
+ value: currentValue
1855
+ },
1856
+ null
1857
+ );
1858
+
1859
+ this.lastExecutionResults.writeValue(
1860
+ input,
1861
+ existingValue
1862
+ );
1863
+
1864
+ const existingDynamicValue: IDynamicValue =
1865
+ {
1866
+ value: existingValue,
1867
+ valueOwner: input,
1868
+ type: DynamicValueTypes.ExecutionResult,
1869
+ inheritanceLink: null
1870
+ };
1871
+
1872
+ return existingDynamicValue;
1873
+ }
1874
+
1875
+ const newLiteralValueTransfer: ILiteralValueTransfer =
1876
+ {
1877
+ id: ProjectState.UUID.uuid(),
1878
+ deletable: true,
1879
+ editable: true,
1880
+ type: EntityType.LiteralValue,
1881
+ autogeneration: null,
1882
+ version:
1883
+ ProjectState.UUID.uuid(),
1884
+ createdAt:
1885
+ new Date().toISOString(),
1886
+ author: ProjectState.sessionAuthor,
1887
+ deleted: false,
1888
+ previousVersion: null,
1889
+ value: currentValue,
1890
+ valueAsTypeSingle: null,
1891
+ valueAsTypeList: null,
1892
+ parent: null,
1893
+ name: resolvedLiteralValueName,
1894
+ standaloneParent:
1895
+ input.toReference()
1896
+ };
1897
+
1898
+ const newLiteralValueInstance =
1899
+ createStateFromType(
1900
+ newLiteralValueTransfer,
1901
+ project
1902
+ ) as LiteralValueState;
1903
+
1904
+ this.lastExecutionResults.writeValue(
1905
+ input,
1906
+ newLiteralValueInstance
1907
+ );
1908
+
1909
+ const newDynamicValue: IDynamicValue = {
1910
+ value: newLiteralValueInstance,
1911
+ valueOwner:
1912
+ loop.currentValueArgumentDeclaration,
1913
+ type: DynamicValueTypes.ExecutionResult,
1914
+ inheritanceLink: null
1915
+ };
1916
+
1917
+ return newDynamicValue;
1918
+ } else {
1919
+ return aggregateListResults[input.id];
1920
+ }
1921
+ })
1922
+ .filter((input) => !!input) as IDynamicValue[];
1923
+
1924
+ lastBodyResult =
1925
+ await this.executeFullFunctionDeclarationLogic(
1926
+ loop.body,
1927
+ resolvedBodyInputsForCurrentIteration,
1928
+ clientWithDefaults
1929
+ );
1930
+
1931
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
1932
+ // @ts-ignore
1933
+ (lastBodyResult.results || []).forEach((value) => {
1934
+ // Only returned values can be aggregated
1935
+ if (
1936
+ value.valueOwner.type !== EntityType.InputMap ||
1937
+ TERMINATION_TYPES.includes(
1938
+ value.valueOwner.parent.type
1939
+ )
1940
+ ) {
1941
+ return;
1942
+ }
1943
+
1944
+ const input = loop.body.inputs.find(
1945
+ (input) =>
1946
+ resolveEntityName(input, project) ===
1947
+ resolveEntityName(
1948
+ value.valueOwner as InputMapState,
1949
+ project
1950
+ )
1951
+ );
1952
+
1953
+ const lastRawValue: any[] = aggregateListResults[
1954
+ (input as EntityWithValueState).id
1955
+ ].value?.value as any[];
1956
+
1957
+ const newValue = [
1958
+ ...lastRawValue,
1959
+ value.value?.value || null
1960
+ ];
1961
+
1962
+ aggregateListResults[
1963
+ (input as EntityWithValueState).id
1964
+ ].value?.metaSync(
1965
+ {
1966
+ value: newValue
1967
+ },
1968
+ null
1969
+ );
1970
+
1971
+ this.lastExecutionResults.writeValue(
1972
+ input as EntityWithValueState,
1973
+ aggregateListResults[
1974
+ (input as EntityWithValueState).id
1975
+ ].value as LiteralValueState
1976
+ );
1977
+ });
1978
+
1979
+ if (
1980
+ [
1981
+ ExecutionTerminationType.CaughtError,
1982
+ ExecutionTerminationType.UnhandledError,
1983
+ ExecutionTerminationType.Break,
1984
+ ExecutionTerminationType.Return
1985
+ ].includes(lastBodyResult.value)
1986
+ ) {
1987
+ break;
1988
+ }
1989
+
1990
+ currentIteration++;
1991
+ }
1992
+
1993
+ break;
1994
+ }
1995
+ case BUILT_IN_BASE_ENTITY_IDS.loop['object-values-loop'].id: {
1996
+ const iterable = rawInputValues[0];
1997
+
1998
+ let currentIteration = 1;
1999
+
2000
+ const iterableListOfValues = !!iterable
2001
+ ? Object.values(iterable)
2002
+ : [];
2003
+
2004
+ for (let i = 0; i < iterableListOfValues.length; i++) {
2005
+ await this.checkStateAndPause();
2006
+ const currentValue = iterableListOfValues[i];
2007
+
2008
+ const resolvedBodyInputsForCurrentIteration =
2009
+ loop.body.inputs
2010
+ .map((input) => {
2011
+ if (
2012
+ input ===
2013
+ loop.currentIterationNumberArgumentDeclaration
2014
+ ) {
2015
+ const existingValue =
2016
+ this.lastExecutionResults.readValue(
2017
+ input.id
2018
+ );
2019
+
2020
+ if (existingValue) {
2021
+ existingValue.metaSync(
2022
+ {
2023
+ value: currentIteration
2024
+ },
2025
+ null
2026
+ );
2027
+
2028
+ this.lastExecutionResults.writeValue(
2029
+ input,
2030
+ existingValue
2031
+ );
2032
+
2033
+ const existingDynamicValue: IDynamicValue =
2034
+ {
2035
+ value: existingValue,
2036
+ valueOwner: input,
2037
+ type: DynamicValueTypes.ExecutionResult,
2038
+ inheritanceLink: null
2039
+ };
2040
+
2041
+ return existingDynamicValue;
2042
+ }
2043
+
2044
+ const resolvedDataType: DataTypeState | null =
2045
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
2046
+ null
2047
+ );
2048
+ const literalValueInstance =
2049
+ assembleStandaloneLiteralValueFromDataType(
2050
+ resolvedDataType,
2051
+ input,
2052
+ project
2053
+ );
2054
+
2055
+ literalValueInstance?.metaSync(
2056
+ {
2057
+ value: currentIteration
2058
+ },
2059
+ null
2060
+ );
2061
+
2062
+ this.lastExecutionResults.writeValue(
2063
+ input,
2064
+ literalValueInstance as LiteralValueState
2065
+ );
2066
+
2067
+ const newDynamicValue: IDynamicValue = {
2068
+ value: literalValueInstance,
2069
+ valueOwner:
2070
+ loop.currentIterationNumberArgumentDeclaration,
2071
+ type: DynamicValueTypes.ExecutionResult,
2072
+ inheritanceLink: null
2073
+ };
2074
+
2075
+ return newDynamicValue;
2076
+ } else if (
2077
+ input ===
2078
+ loop.currentValueArgumentDeclaration
2079
+ ) {
2080
+ const resolvedDataType: DataTypeState | null =
2081
+ loop.currentValueArgumentDeclaration.getDataType(
2082
+ null
2083
+ );
2084
+ const resolvedLiteralValueName =
2085
+ getLiteralValueNameFromDataType(
2086
+ resolvedDataType
2087
+ );
2088
+
2089
+ const existingValue =
2090
+ this.lastExecutionResults.readValue(
2091
+ input.id
2092
+ );
2093
+
2094
+ if (existingValue) {
2095
+ existingValue.metaSync(
2096
+ {
2097
+ value: currentValue
2098
+ },
2099
+ null
2100
+ );
2101
+
2102
+ this.lastExecutionResults.writeValue(
2103
+ input,
2104
+ existingValue
2105
+ );
2106
+
2107
+ const existingDynamicValue: IDynamicValue =
2108
+ {
2109
+ value: existingValue,
2110
+ valueOwner: input,
2111
+ type: DynamicValueTypes.ExecutionResult,
2112
+ inheritanceLink: null
2113
+ };
2114
+
2115
+ return existingDynamicValue;
2116
+ }
2117
+
2118
+ const newLiteralValueTransfer: ILiteralValueTransfer =
2119
+ {
2120
+ id: ProjectState.UUID.uuid(),
2121
+ deletable: true,
2122
+ editable: true,
2123
+ type: EntityType.LiteralValue,
2124
+ autogeneration: null,
2125
+ version:
2126
+ ProjectState.UUID.uuid(),
2127
+ createdAt:
2128
+ new Date().toISOString(),
2129
+ author: ProjectState.sessionAuthor,
2130
+ deleted: false,
2131
+ previousVersion: null,
2132
+ value: currentValue,
2133
+ valueAsTypeSingle: null,
2134
+ valueAsTypeList: null,
2135
+ parent: null,
2136
+ name: resolvedLiteralValueName,
2137
+ standaloneParent:
2138
+ input.toReference()
2139
+ };
2140
+
2141
+ const newLiteralValueInstance =
2142
+ createStateFromType(
2143
+ newLiteralValueTransfer,
2144
+ project
2145
+ ) as LiteralValueState;
2146
+
2147
+ this.lastExecutionResults.writeValue(
2148
+ input,
2149
+ newLiteralValueInstance
2150
+ );
2151
+
2152
+ const newDynamicValue: IDynamicValue = {
2153
+ value: newLiteralValueInstance,
2154
+ valueOwner:
2155
+ loop.currentValueArgumentDeclaration,
2156
+ type: DynamicValueTypes.ExecutionResult,
2157
+ inheritanceLink: null
2158
+ };
2159
+
2160
+ return newDynamicValue;
2161
+ } else {
2162
+ return aggregateListResults[input.id];
2163
+ }
2164
+ })
2165
+ .filter((input) => !!input) as IDynamicValue[];
2166
+
2167
+ lastBodyResult =
2168
+ await this.executeFullFunctionDeclarationLogic(
2169
+ loop.body,
2170
+ resolvedBodyInputsForCurrentIteration,
2171
+ clientWithDefaults
2172
+ );
2173
+
2174
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
2175
+ // @ts-ignore
2176
+ (lastBodyResult.results || []).forEach((value) => {
2177
+ // Only returned values can be aggregated
2178
+ if (
2179
+ value.valueOwner.type !== EntityType.InputMap ||
2180
+ TERMINATION_TYPES.includes(
2181
+ value.valueOwner.parent.type
2182
+ )
2183
+ ) {
2184
+ return;
2185
+ }
2186
+
2187
+ const input = loop.body.inputs.find(
2188
+ (input) =>
2189
+ resolveEntityName(input, project) ===
2190
+ resolveEntityName(
2191
+ value.valueOwner as InputMapState,
2192
+ project
2193
+ )
2194
+ );
2195
+
2196
+ const lastRawValue: any[] = aggregateListResults[
2197
+ (input as EntityWithValueState).id
2198
+ ].value?.value as any[];
2199
+
2200
+ const newValue = [
2201
+ ...lastRawValue,
2202
+ value.value?.value || null
2203
+ ];
2204
+
2205
+ aggregateListResults[
2206
+ (input as EntityWithValueState).id
2207
+ ].value?.metaSync(
2208
+ {
2209
+ value: newValue
2210
+ },
2211
+ null
2212
+ );
2213
+
2214
+ this.lastExecutionResults.writeValue(
2215
+ input as EntityWithValueState,
2216
+ aggregateListResults[
2217
+ (input as EntityWithValueState).id
2218
+ ].value as LiteralValueState
2219
+ );
2220
+ });
2221
+
2222
+ if (
2223
+ [
2224
+ ExecutionTerminationType.CaughtError,
2225
+ ExecutionTerminationType.UnhandledError,
2226
+ ExecutionTerminationType.Break,
2227
+ ExecutionTerminationType.Return
2228
+ ].includes(lastBodyResult.value)
2229
+ ) {
2230
+ break;
2231
+ }
2232
+
2233
+ currentIteration++;
2234
+ }
2235
+
2236
+ break;
2237
+ }
2238
+ case BUILT_IN_BASE_ENTITY_IDS.loop['string-loop'].id: {
2239
+ const iterable = rawInputValues[0];
2240
+
2241
+ let currentIteration = 1;
2242
+
2243
+ const iterableListOfValues = (iterable as string).split('');
2244
+
2245
+ for (let i = 0; i < iterableListOfValues.length; i++) {
2246
+ await this.checkStateAndPause();
2247
+ const currentValue = iterableListOfValues[i];
2248
+
2249
+ const resolvedBodyInputsForCurrentIteration =
2250
+ loop.body.inputs
2251
+ .map((input) => {
2252
+ if (
2253
+ input ===
2254
+ loop.currentIterationNumberArgumentDeclaration
2255
+ ) {
2256
+ const existingValue =
2257
+ this.lastExecutionResults.readValue(
2258
+ input.id
2259
+ );
2260
+
2261
+ if (existingValue) {
2262
+ existingValue.metaSync(
2263
+ {
2264
+ value: currentIteration
2265
+ },
2266
+ null
2267
+ );
2268
+
2269
+ this.lastExecutionResults.writeValue(
2270
+ input,
2271
+ existingValue
2272
+ );
2273
+
2274
+ const existingDynamicValue: IDynamicValue =
2275
+ {
2276
+ value: existingValue,
2277
+ valueOwner: input,
2278
+ type: DynamicValueTypes.ExecutionResult,
2279
+ inheritanceLink: null
2280
+ };
2281
+
2282
+ return existingDynamicValue;
2283
+ }
2284
+
2285
+ const resolvedDataType: DataTypeState | null =
2286
+ loop.currentIterationNumberArgumentDeclaration.getDataType(
2287
+ null
2288
+ );
2289
+ const literalValueInstance =
2290
+ assembleStandaloneLiteralValueFromDataType(
2291
+ resolvedDataType,
2292
+ input,
2293
+ project
2294
+ );
2295
+
2296
+ literalValueInstance?.metaSync(
2297
+ {
2298
+ value: currentIteration
2299
+ },
2300
+ null
2301
+ );
2302
+
2303
+ this.lastExecutionResults.writeValue(
2304
+ input,
2305
+ literalValueInstance as LiteralValueState
2306
+ );
2307
+
2308
+ const newDynamicValue: IDynamicValue = {
2309
+ value: literalValueInstance,
2310
+ valueOwner:
2311
+ loop.currentIterationNumberArgumentDeclaration,
2312
+ type: DynamicValueTypes.ExecutionResult,
2313
+ inheritanceLink: null
2314
+ };
2315
+
2316
+ return newDynamicValue;
2317
+ } else if (
2318
+ input ===
2319
+ loop.currentValueArgumentDeclaration
2320
+ ) {
2321
+ const resolvedDataType: DataTypeState | null =
2322
+ loop.currentValueArgumentDeclaration.getDataType(
2323
+ null
2324
+ );
2325
+ const resolvedLiteralValueName =
2326
+ getLiteralValueNameFromDataType(
2327
+ resolvedDataType
2328
+ );
2329
+
2330
+ const existingValue =
2331
+ this.lastExecutionResults.readValue(
2332
+ input.id
2333
+ );
2334
+
2335
+ if (existingValue) {
2336
+ existingValue.metaSync(
2337
+ {
2338
+ value: currentValue
2339
+ },
2340
+ null
2341
+ );
2342
+
2343
+ this.lastExecutionResults.writeValue(
2344
+ input,
2345
+ existingValue
2346
+ );
2347
+
2348
+ const existingDynamicValue: IDynamicValue =
2349
+ {
2350
+ value: existingValue,
2351
+ valueOwner: input,
2352
+ type: DynamicValueTypes.ExecutionResult,
2353
+ inheritanceLink: null
2354
+ };
2355
+
2356
+ return existingDynamicValue;
2357
+ }
2358
+
2359
+ const newLiteralValueTransfer: ILiteralValueTransfer =
2360
+ {
2361
+ id: ProjectState.UUID.uuid(),
2362
+ deletable: true,
2363
+ editable: true,
2364
+ type: EntityType.LiteralValue,
2365
+ autogeneration: null,
2366
+ version:
2367
+ ProjectState.UUID.uuid(),
2368
+ createdAt:
2369
+ new Date().toISOString(),
2370
+ author: ProjectState.sessionAuthor,
2371
+ deleted: false,
2372
+ previousVersion: null,
2373
+ value: currentValue,
2374
+ valueAsTypeSingle: null,
2375
+ valueAsTypeList: null,
2376
+ parent: null,
2377
+ name: resolvedLiteralValueName,
2378
+ standaloneParent:
2379
+ input.toReference()
2380
+ };
2381
+
2382
+ const newLiteralValueInstance =
2383
+ createStateFromType(
2384
+ newLiteralValueTransfer,
2385
+ project
2386
+ ) as LiteralValueState;
2387
+
2388
+ this.lastExecutionResults.writeValue(
2389
+ input,
2390
+ newLiteralValueInstance
2391
+ );
2392
+
2393
+ const newDynamicValue: IDynamicValue = {
2394
+ value: newLiteralValueInstance,
2395
+ valueOwner:
2396
+ loop.currentValueArgumentDeclaration,
2397
+ type: DynamicValueTypes.ExecutionResult,
2398
+ inheritanceLink: null
2399
+ };
2400
+
2401
+ return newDynamicValue;
2402
+ } else {
2403
+ return aggregateListResults[input.id];
2404
+ }
2405
+ })
2406
+ .filter((input) => !!input) as IDynamicValue[];
2407
+
2408
+ lastBodyResult =
2409
+ await this.executeFullFunctionDeclarationLogic(
2410
+ loop.body,
2411
+ resolvedBodyInputsForCurrentIteration,
2412
+ clientWithDefaults
2413
+ );
2414
+
2415
+ // Aggregate the results of the body function to their list values in 'aggregateListResults'
2416
+ // @ts-ignore
2417
+ (lastBodyResult.results || []).forEach((value) => {
2418
+ // Only returned values can be aggregated
2419
+ if (
2420
+ value.valueOwner.type !== EntityType.InputMap ||
2421
+ TERMINATION_TYPES.includes(
2422
+ value.valueOwner.parent.type
2423
+ )
2424
+ ) {
2425
+ return;
2426
+ }
2427
+
2428
+ const input = loop.body.inputs.find(
2429
+ (input) =>
2430
+ resolveEntityName(input, project) ===
2431
+ resolveEntityName(
2432
+ value.valueOwner as InputMapState,
2433
+ project
2434
+ )
2435
+ );
2436
+
2437
+ const lastRawValue: any[] = aggregateListResults[
2438
+ (input as EntityWithValueState).id
2439
+ ].value?.value as any[];
2440
+
2441
+ const newValue = [
2442
+ ...lastRawValue,
2443
+ value.value?.value || null
2444
+ ];
2445
+
2446
+ aggregateListResults[
2447
+ (input as EntityWithValueState).id
2448
+ ].value?.metaSync(
2449
+ {
2450
+ value: newValue
2451
+ },
2452
+ null
2453
+ );
2454
+
2455
+ this.lastExecutionResults.writeValue(
2456
+ input as EntityWithValueState,
2457
+ aggregateListResults[
2458
+ (input as EntityWithValueState).id
2459
+ ].value as LiteralValueState
2460
+ );
2461
+ });
2462
+
2463
+ if (
2464
+ [
2465
+ ExecutionTerminationType.CaughtError,
2466
+ ExecutionTerminationType.UnhandledError,
2467
+ ExecutionTerminationType.Break,
2468
+ ExecutionTerminationType.Return
2469
+ ].includes(lastBodyResult.value)
2470
+ ) {
2471
+ break;
2472
+ }
2473
+
2474
+ currentIteration++;
2475
+ }
2476
+
2477
+ break;
2478
+ }
2479
+ }
2480
+
2481
+ let value = ExecutionTerminationType.Success;
2482
+
2483
+ if (
2484
+ lastBodyResult.value === ExecutionTerminationType.UnhandledError
2485
+ ) {
2486
+ if (loop.catchesError || loop.errorCalls.length) {
2487
+ value = ExecutionTerminationType.CaughtError;
2488
+ } else {
2489
+ value = ExecutionTerminationType.UnhandledError;
2490
+ }
2491
+ } else if (
2492
+ [
2493
+ ExecutionTerminationType.CaughtError,
2494
+ ExecutionTerminationType.Return
2495
+ ].includes(lastBodyResult.value)
2496
+ ) {
2497
+ value = lastBodyResult.value;
2498
+ }
2499
+
2500
+ oPResult = {
2501
+ value: value,
2502
+ error: lastBodyResult.error?.value?.value || null,
2503
+ result: lastBodyResult?.result?.value?.value || null
2504
+ };
2505
+
2506
+ if (
2507
+ oPResult.value === ExecutionTerminationType.UnhandledError ||
2508
+ oPResult.value === ExecutionTerminationType.CaughtError
2509
+ ) {
2510
+ let errorValue: IDynamicValue | null = null;
2511
+ if (!!loop.error) {
2512
+ const richError = serializeError(oPResult.error);
2513
+ const resolvedDataType = loop.error?.getDataType(null);
2514
+ const literalValueInstance =
2515
+ assembleStandaloneLiteralValueFromDataType(
2516
+ resolvedDataType || null,
2517
+ loop.error,
2518
+ project
2519
+ );
2520
+
2521
+ if (!!resolvedDataType?.asType) {
2522
+ literalValueInstance?.setValueAsTypeSingle(
2523
+ oPResult.error
2524
+ );
2525
+ } else {
2526
+ const sanitizedError = isObject(richError)
2527
+ ? JSON.stringify(richError, null, 2)
2528
+ : richError;
2529
+ literalValueInstance?.metaSync(
2530
+ {
2531
+ value: sanitizedError
2532
+ },
2533
+ null
2534
+ );
2535
+ }
2536
+
2537
+ errorValue = {
2538
+ valueOwner: loop.error,
2539
+ type: DynamicValueTypes.ExecutionResult,
2540
+ inheritanceLink: null,
2541
+ value: literalValueInstance
2542
+ };
2543
+ }
2544
+
2545
+ return {
2546
+ value: oPResult.value,
2547
+ entity: loop,
2548
+ error: errorValue,
2549
+ result: null
2550
+ };
2551
+ }
2552
+
2553
+ const resolvedDataType = loop?.getDataType(null);
2554
+ const literalValueInstance =
2555
+ assembleStandaloneLiteralValueFromDataType(
2556
+ resolvedDataType,
2557
+ loop,
2558
+ project
2559
+ );
2560
+
2561
+ if (!!resolvedDataType?.asType) {
2562
+ literalValueInstance?.setValueAsTypeSingle(oPResult.result);
2563
+ } else {
2564
+ literalValueInstance?.metaSync(
2565
+ {
2566
+ value: oPResult.result
2567
+ },
2568
+ null
2569
+ );
2570
+ }
2571
+
2572
+ return {
2573
+ value: oPResult.value,
2574
+ entity: loop,
2575
+ error: null,
2576
+ result: {
2577
+ value: literalValueInstance || null,
2578
+ valueOwner: loop,
2579
+ type: DynamicValueTypes.ExecutionResult,
2580
+ inheritanceLink: null
2581
+ }
2582
+ };
2583
+ } catch (e) {
2584
+ if (
2585
+ e &&
2586
+ ((e as any).name === 'ExecutionStoppedError' ||
2587
+ (e as any).message === 'Execution was stopped')
2588
+ )
2589
+ throw e;
2590
+ Logger.warn('Error executing loop: ', e);
2591
+ // TODO: Add error to entity if not present
2592
+ if (loop.error) {
2593
+ const richError = serializeError(e);
2594
+ const resolvedDataType = loop.error?.getDataType(null);
2595
+ const literalValueInstance =
2596
+ assembleStandaloneLiteralValueFromDataType(
2597
+ resolvedDataType,
2598
+ loop.error,
2599
+ project
2600
+ );
2601
+
2602
+ if (!!resolvedDataType?.asType) {
2603
+ literalValueInstance?.setValueAsTypeSingle(e as any);
2604
+ } else {
2605
+ const sanitizedError = isObject(richError)
2606
+ ? JSON.stringify(richError, null, 2)
2607
+ : richError;
2608
+ literalValueInstance?.metaSync(
2609
+ {
2610
+ value: sanitizedError
2611
+ },
2612
+ null
2613
+ );
2614
+ }
2615
+
2616
+ return {
2617
+ value:
2618
+ loop.catchesError || loop.errorCalls.length
2619
+ ? ExecutionTerminationType.CaughtError
2620
+ : ExecutionTerminationType.UnhandledError,
2621
+ entity: loop,
2622
+ error: {
2623
+ valueOwner: loop.error,
2624
+ type: DynamicValueTypes.ExecutionResult,
2625
+ inheritanceLink: null,
2626
+ value: literalValueInstance
2627
+ },
2628
+ result: null
2629
+ };
2630
+ } else {
2631
+ return {
2632
+ value:
2633
+ loop.catchesError || loop.errorCalls.length
2634
+ ? ExecutionTerminationType.CaughtError
2635
+ : ExecutionTerminationType.UnhandledError,
2636
+ entity: loop,
2637
+ error: null,
2638
+ result: null
2639
+ };
2640
+ }
2641
+ }
2642
+ }
2643
+
2644
+ async executeFunctionCall(
2645
+ functionCall: FunctionCallState,
2646
+ inputs: IDynamicValue[],
2647
+ project: ProjectState,
2648
+ client: IExecutionClient = {}
2649
+ ): Promise<IExecutionResult> {
2650
+ const clientWithDefaults: IExecutionClient = {
2651
+ ...EXECUTION_CLIENT_DEFAULTS,
2652
+ ...client
2653
+ };
2654
+
2655
+ // Execute the functionCall based on its "implementation"
2656
+ try {
2657
+ this.logBeforeExecution(
2658
+ 'executeFunctionCall',
2659
+ functionCall,
2660
+ inputs
2661
+ );
2662
+ const oPResult =
2663
+ await this.executeDetachedFullFunctionDeclarationLogic(
2664
+ functionCall.declaration as FunctionDeclarationState,
2665
+ inputs,
2666
+ project,
2667
+ clientWithDefaults
2668
+ );
2669
+
2670
+ let errorValue: IDynamicValue | null = null;
2671
+
2672
+ if (oPResult.error && !!functionCall.error) {
2673
+ Logger.warn(`Raw error executing entity: `, oPResult.error);
2674
+ const resolvedErrorDataType =
2675
+ functionCall.error?.getDataType(null);
2676
+ const errorLiteralValueInstance =
2677
+ assembleStandaloneLiteralValueFromDataType(
2678
+ resolvedErrorDataType || null,
2679
+ functionCall.error,
2680
+ project
2681
+ );
2682
+
2683
+ if (!!resolvedErrorDataType?.asType) {
2684
+ if (!!oPResult.error?.value?.valueAsTypeSingle) {
2685
+ errorLiteralValueInstance?.setValueAsTypeSingle(
2686
+ oPResult.error?.value?.valueAsTypeSingle
2687
+ );
2688
+ } else if (
2689
+ !!oPResult.error?.value?.valueAsTypeList &&
2690
+ Array.isArray(oPResult.error?.value?.valueAsTypeList)
2691
+ ) {
2692
+ errorLiteralValueInstance?.setValueAsTypeList(
2693
+ oPResult.error?.value?.valueAsTypeList
2694
+ );
2695
+ }
2696
+ } else {
2697
+ errorLiteralValueInstance?.metaSync(
2698
+ {
2699
+ value: oPResult.error?.value?.value
2700
+ },
2701
+ null
2702
+ );
2703
+ }
2704
+
2705
+ errorValue = {
2706
+ valueOwner: functionCall.error,
2707
+ type: DynamicValueTypes.ExecutionResult,
2708
+ inheritanceLink: null,
2709
+ value: errorLiteralValueInstance
2710
+ };
2711
+ }
2712
+
2713
+ let value = ExecutionTerminationType.Success;
2714
+
2715
+ if (oPResult.value === ExecutionTerminationType.UnhandledError) {
2716
+ if (
2717
+ functionCall.catchesError ||
2718
+ functionCall.errorCalls.length
2719
+ ) {
2720
+ value = ExecutionTerminationType.CaughtError;
2721
+ } else {
2722
+ value = ExecutionTerminationType.UnhandledError;
2723
+ }
2724
+ }
2725
+
2726
+ const resolvedDataType = functionCall?.getDataType(null);
2727
+ const literalValueInstance =
2728
+ assembleStandaloneLiteralValueFromDataType(
2729
+ resolvedDataType,
2730
+ functionCall,
2731
+ project
2732
+ );
2733
+
2734
+ if (!!resolvedDataType?.asType) {
2735
+ if (!!oPResult.result?.value?.valueAsTypeSingle) {
2736
+ literalValueInstance?.setValueAsTypeSingle(
2737
+ oPResult.result?.value?.valueAsTypeSingle
2738
+ );
2739
+ } else if (
2740
+ !!oPResult.result?.value?.valueAsTypeList &&
2741
+ Array.isArray(oPResult.result?.value?.valueAsTypeList)
2742
+ ) {
2743
+ literalValueInstance?.setValueAsTypeList(
2744
+ oPResult.result?.value?.valueAsTypeList
2745
+ );
2746
+ }
2747
+ } else {
2748
+ literalValueInstance?.metaSync(
2749
+ {
2750
+ value: oPResult.result?.value?.value || null
2751
+ },
2752
+ null
2753
+ );
2754
+ }
2755
+
2756
+ return {
2757
+ value: value,
2758
+ entity: functionCall,
2759
+ error: errorValue,
2760
+ result: {
2761
+ value: literalValueInstance || null,
2762
+ valueOwner: functionCall,
2763
+ type: DynamicValueTypes.ExecutionResult,
2764
+ inheritanceLink: null
2765
+ }
2766
+ };
2767
+ } catch (e) {
2768
+ if (
2769
+ e &&
2770
+ ((e as any).name === 'ExecutionStoppedError' ||
2771
+ (e as any).message === 'Execution was stopped')
2772
+ )
2773
+ throw e;
2774
+ if (!functionCall.error) {
2775
+ return {
2776
+ value:
2777
+ functionCall.catchesError ||
2778
+ functionCall.errorCalls.length
2779
+ ? ExecutionTerminationType.CaughtError
2780
+ : ExecutionTerminationType.UnhandledError,
2781
+ entity: functionCall,
2782
+ error: null,
2783
+ result: null
2784
+ };
2785
+ }
2786
+
2787
+ const richError = serializeError(e);
2788
+ const resolvedDataType = functionCall.error?.getDataType(null);
2789
+ const literalValueInstance =
2790
+ assembleStandaloneLiteralValueFromDataType(
2791
+ resolvedDataType,
2792
+ functionCall.error,
2793
+ project
2794
+ );
2795
+
2796
+ if (!!resolvedDataType?.asType) {
2797
+ literalValueInstance?.setValueAsTypeSingle(e as any);
2798
+ } else {
2799
+ const sanitizedError = isObject(richError)
2800
+ ? JSON.stringify(richError, null, 2)
2801
+ : richError;
2802
+ literalValueInstance?.metaSync(
2803
+ {
2804
+ value: sanitizedError
2805
+ },
2806
+ null
2807
+ );
2808
+ }
2809
+ return {
2810
+ value:
2811
+ functionCall.catchesError || functionCall.errorCalls.length
2812
+ ? ExecutionTerminationType.CaughtError
2813
+ : ExecutionTerminationType.UnhandledError,
2814
+ entity: functionCall,
2815
+ error: {
2816
+ valueOwner: functionCall.error,
2817
+ type: DynamicValueTypes.ExecutionResult,
2818
+ inheritanceLink: null,
2819
+ value: literalValueInstance
2820
+ },
2821
+ result: null
2822
+ };
2823
+ }
2824
+ }
2825
+
2826
+ async executeCondition(
2827
+ condition: ConditionState,
2828
+ inputs: IDynamicValue[]
2829
+ ): Promise<IExecutionResult> {
2830
+ this.logBeforeExecution('executeCondition', condition, inputs);
2831
+ let hasConditionBeenMet = false;
2832
+
2833
+ switch (condition.declaration.id) {
2834
+ /* ------------------------ BOOLEAN ----------------------- */
2835
+ case StandaloneOperatorTypes.BooleanIsTrue: {
2836
+ const v = inputs[0]?.value?.value;
2837
+ if (typeof v !== 'boolean') {
2838
+ throw new TypeError(
2839
+ 'BooleanIsTrue expects a boolean input.'
2840
+ );
2841
+ }
2842
+ hasConditionBeenMet = v === true;
2843
+ break;
2844
+ }
2845
+ case StandaloneOperatorTypes.BooleanIsFalse: {
2846
+ const v = inputs[0]?.value?.value;
2847
+ if (typeof v !== 'boolean') {
2848
+ throw new TypeError(
2849
+ 'BooleanIsFalse expects a boolean input.'
2850
+ );
2851
+ }
2852
+ hasConditionBeenMet = v === false;
2853
+ break;
2854
+ }
2855
+
2856
+ case GroupOperatorTypes.And: {
2857
+ const results = await Promise.all(
2858
+ (condition.andChildrenGroup as ConditionState[]).map(
2859
+ async (childCondition) => {
2860
+ const resolvedInputs =
2861
+ this.mergeExernalValuesWithInternalInputs(
2862
+ inputs,
2863
+ childCondition
2864
+ );
2865
+
2866
+ const nestedResult = await this.executeCondition(
2867
+ childCondition,
2868
+ resolvedInputs
2869
+ );
2870
+ return (
2871
+ nestedResult.value ===
2872
+ ExecutionTerminationType.Success
2873
+ );
2874
+ }
2875
+ )
2876
+ );
2877
+ hasConditionBeenMet = results.every((result) => result);
2878
+ break;
2879
+ }
2880
+ case GroupOperatorTypes.Or: {
2881
+ const results = await Promise.all(
2882
+ (condition.orChildrenGroup as ConditionState[]).map(
2883
+ async (childCondition) => {
2884
+ const resolvedInputs =
2885
+ this.mergeExernalValuesWithInternalInputs(
2886
+ inputs,
2887
+ childCondition
2888
+ );
2889
+
2890
+ const nestedResult = await this.executeCondition(
2891
+ childCondition,
2892
+ resolvedInputs
2893
+ );
2894
+ return (
2895
+ nestedResult.value ===
2896
+ ExecutionTerminationType.Success
2897
+ );
2898
+ }
2899
+ )
2900
+ );
2901
+
2902
+ hasConditionBeenMet = results.some((result) => result);
2903
+ break;
2904
+ }
2905
+ default: {
2906
+ throw new Error(
2907
+ `Condition declaration ${condition.declaration.name} does not have an implementation.`
2908
+ );
2909
+ }
2910
+ }
2911
+
2912
+ return {
2913
+ value: hasConditionBeenMet
2914
+ ? ExecutionTerminationType.Success
2915
+ : ExecutionTerminationType.ConditionNotMet,
2916
+ entity: condition,
2917
+ error: null,
2918
+ result: null
2919
+ };
2920
+ }
2921
+
2922
+ async executeDetachedFullFunctionDeclarationLogic(
2923
+ functionDeclaration: FunctionDeclarationState,
2924
+ inputs: IDynamicValue[],
2925
+ project: ProjectState,
2926
+ client: IExecutionClient = {}
2927
+ ): Promise<IExecutionResult> {
2928
+ this.logBeforeExecution(
2929
+ 'executeDetachedFullFunctionDeclarationLogic',
2930
+ functionDeclaration,
2931
+ inputs
2932
+ );
2933
+ const clientWithDefaults: IExecutionClient = {
2934
+ ...EXECUTION_CLIENT_DEFAULTS,
2935
+ ...client,
2936
+ onBeforeEntityExecution: (entity, values, context) => {
2937
+ return (
2938
+ client?.onBeforeEntityExecution?.(entity, values, {
2939
+ ...context,
2940
+ detached: true
2941
+ }) || Promise.resolve()
2942
+ );
2943
+ },
2944
+ onEntityExecuted: (entity, result, context) => {
2945
+ return (
2946
+ client?.onEntityExecuted?.(entity, result, {
2947
+ ...context,
2948
+ detached: true
2949
+ }) || Promise.resolve()
2950
+ );
2951
+ }
2952
+ };
2953
+
2954
+ // Execute the body of the function declaration
2955
+ const functionBodyExecution = new Execution(
2956
+ project,
2957
+ [
2958
+ functionDeclaration,
2959
+ ...(flattenRelatedCanvasElementsOnTheRight(
2960
+ functionDeclaration
2961
+ ) as (
2962
+ | DraggableExecutableEntityState
2963
+ | DraggableCallerEntityState
2964
+ | VariableDeclarationState
2965
+ )[])
2966
+ ],
2967
+ functionDeclaration,
2968
+ this,
2969
+ this.parentContext
2970
+ );
2971
+
2972
+ functionBodyExecution.inheritValuesFromContext(this);
2973
+
2974
+ const result = await functionBodyExecution.execute(
2975
+ clientWithDefaults,
2976
+ inputs
2977
+ );
2978
+
2979
+ return result;
2980
+ }
2981
+
2982
+ async executeFullFunctionDeclarationLogic(
2983
+ functionDeclaration: FunctionDeclarationState,
2984
+ inputs: IDynamicValue[],
2985
+ // project: ProjectState,
2986
+ client: IExecutionClient = {}
2987
+ ): Promise<IExecutionResult> {
2988
+ this.logBeforeExecution(
2989
+ 'executeFullFunctionDeclarationLogic',
2990
+ functionDeclaration,
2991
+ inputs
2992
+ );
2993
+ const clientWithDefaults: IExecutionClient = {
2994
+ ...EXECUTION_CLIENT_DEFAULTS,
2995
+ ...client
2996
+ };
2997
+
2998
+ // Execute the body of the function declaration
2999
+ // Add all children if they aren't already added
3000
+ const childrenEntities = flattenRelatedCanvasElementsOnTheRight(
3001
+ functionDeclaration
3002
+ ) as CallableEntityState[];
3003
+
3004
+ const internalCalls: CallableEntityState[] = [];
3005
+ childrenEntities.forEach((entity) => {
3006
+ if (
3007
+ entity.type === EntityType.VariableDeclaration ||
3008
+ entity.type === EntityType.VariableInstance
3009
+ ) {
3010
+ const varState = entity as any;
3011
+ if (varState.internalCalls) {
3012
+ internalCalls.push(...varState.internalCalls);
3013
+ }
3014
+ }
3015
+ });
3016
+ childrenEntities.push(...internalCalls);
3017
+
3018
+ console.log(
3019
+ `[executeFullFunctionDeclarationLogic] Reseting children for: ${resolveEntityName(functionDeclaration, this.project)}\nChildren:`,
3020
+ childrenEntities.map((e) => `${e.type} "${resolveEntityName(e, this.project)}"`).join(', ')
3021
+ );
3022
+
3023
+ childrenEntities.forEach((entity) => {
3024
+ this.addEntity(entity);
3025
+ this.removeFromAlreadyExecutedList(entity);
3026
+ this.removeFromSkippedList(entity);
3027
+ this.removeFromScheduledList(entity);
3028
+ });
3029
+
3030
+ // Clear last executed values for the entities declared withing the scope of the function
3031
+ const allDeclaredValueEntities = childrenEntities.reduce(
3032
+ (acc: EntityWithValueState[], entity) => {
3033
+ if (TERMINATION_TYPES.includes(entity.type)) {
3034
+ return [
3035
+ ...acc,
3036
+ ...(entity as TerminationEntityState).outputs
3037
+ ];
3038
+ } else if (
3039
+ PASS_THROUGH_CALLABLE_TYPES.includes(entity.type) &&
3040
+ entity.type !== EntityType.Condition
3041
+ ) {
3042
+ return [
3043
+ ...acc,
3044
+ ...((entity as PassThroughCallableEntityWithOutputs)
3045
+ .outputs as EntityWithValueState[]),
3046
+ ...((entity as PassThroughCallableEntityWithOutputs)
3047
+ .inputs as EntityWithValueState[])
3048
+ ];
3049
+ } else if (entity.type === EntityType.Condition) {
3050
+ return [...acc, ...(entity as ConditionState).inputs];
3051
+ }
3052
+
3053
+ return acc;
3054
+ },
3055
+ [] as EntityWithValueState[]
3056
+ );
3057
+
3058
+ allDeclaredValueEntities.forEach((entity) => {
3059
+ this.lastExecutionResults.removeValue(entity.id);
3060
+ });
3061
+
3062
+ const result = await this.executeBranch(
3063
+ functionDeclaration,
3064
+ clientWithDefaults,
3065
+ inputs
3066
+ );
3067
+
3068
+ return {
3069
+ ...(result || {}),
3070
+ value: result?.value || ExecutionTerminationType.Success,
3071
+ entity: functionDeclaration,
3072
+ error: result?.error || null,
3073
+ result: result?.result || null
3074
+ };
3075
+ }
3076
+
3077
+ // This function only "executes" the individual entity, the entry point card.
3078
+ // To execute the full logic of the body of the function declaration we have another function
3079
+ static async executeEntryPointEntity(
3080
+ entryPointEntity: EntryPointEntityState,
3081
+ inputs: IDynamicValue[],
3082
+ execution?: Execution
3083
+ ): Promise<IExecutionResult> {
3084
+ if (execution) {
3085
+ execution.logBeforeExecution(
3086
+ 'executeEntryPointEntity',
3087
+ entryPointEntity,
3088
+ inputs
3089
+ );
3090
+ } else {
3091
+ console.log(
3092
+ `executeEntryPointEntity (${entryPointEntity.type}) -> [${entryPointEntity.name || entryPointEntity.id}] Inputs:${!!inputs.length ? `\n ` : ''}${inputs
3093
+ .map(
3094
+ (d) =>
3095
+ `${d.valueOwner?.type} (${d.valueOwner?.id}) "${resolveEntityName(d.valueOwner as any, entryPointEntity.project)}": ${JSON.stringify(d.value?.value, null, 2)}`
3096
+ )
3097
+ .join('\n ')}\n`
3098
+ );
3099
+ }
3100
+ return {
3101
+ value: ExecutionTerminationType.Success,
3102
+ entity: entryPointEntity,
3103
+ error: null,
3104
+ result: null
3105
+ };
3106
+ }
3107
+
3108
+ async executeReturnStatement(
3109
+ entity: ReturnStatementState,
3110
+ inputs: IDynamicValue[]
3111
+ ): Promise<IExecutionResult> {
3112
+ this.logBeforeExecution('executeReturnStatement', entity, inputs);
3113
+ if (entity.throws?.readsValue) {
3114
+ // Resolve the next value of the error, then return it
3115
+ const errorValue = resolveNextValue(
3116
+ entity.throws,
3117
+ this.valueResolutionContext as IValueResolutionContext
3118
+ );
3119
+
3120
+ return {
3121
+ value: ExecutionTerminationType.UnhandledError,
3122
+ entity: entity,
3123
+ error: {
3124
+ valueOwner: entity.throws,
3125
+ type: DynamicValueTypes.ExecutionResult,
3126
+ inheritanceLink: null,
3127
+ value: errorValue?.value || null
3128
+ },
3129
+ result: null
3130
+ };
3131
+ }
3132
+
3133
+ let returnedValue = resolveNextValue(
3134
+ entity,
3135
+ this.valueResolutionContext as IValueResolutionContext
3136
+ );
3137
+
3138
+ const dataType = entity.getDataType(null);
3139
+
3140
+ if (dataType?.isObject()) {
3141
+ // The working object to add data to
3142
+ let initialDefaultValue: UntypedObjectValue = {};
3143
+
3144
+ if (dataType?.entity?.type === EntityType.DefinitionEntity) {
3145
+ initialDefaultValue = {
3146
+ ...initialDefaultValue,
3147
+ ...dataType.entity.getActiveRawDefaultValue()
3148
+ };
3149
+ }
3150
+
3151
+ if (!!returnedValue?.value) {
3152
+ if (isObject(returnedValue?.value?.value)) {
3153
+ initialDefaultValue = {
3154
+ ...initialDefaultValue,
3155
+ ...(returnedValue?.value?.value as UntypedObjectValue)
3156
+ };
3157
+ }
3158
+
3159
+ returnedValue?.value.metaSync(
3160
+ {
3161
+ value: initialDefaultValue
3162
+ },
3163
+ null
3164
+ );
3165
+ } else {
3166
+ const newLiteralValueEntity =
3167
+ assembleStandaloneLiteralValueFromDataType(
3168
+ dataType,
3169
+ entity,
3170
+ this.project
3171
+ );
3172
+
3173
+ newLiteralValueEntity?.metaSync(
3174
+ {
3175
+ value: initialDefaultValue
3176
+ },
3177
+ null
3178
+ );
3179
+
3180
+ returnedValue = {
3181
+ valueOwner: entity,
3182
+ type: DynamicValueTypes.ExecutionResult,
3183
+ inheritanceLink: null,
3184
+ value: newLiteralValueEntity
3185
+ };
3186
+ }
3187
+
3188
+ this.lastExecutionResults.writeValue(
3189
+ entity,
3190
+ returnedValue.value as LiteralValueState
3191
+ );
3192
+
3193
+ entity.outputs.forEach((output) => {
3194
+ if (
3195
+ output.declaration?.type === EntityType.Property &&
3196
+ output.declaration.static
3197
+ ) {
3198
+ const existingValue = this.lastExecutionResults.readValue(
3199
+ output.declaration.id
3200
+ );
3201
+
3202
+ const inputName = resolveEntityName(output, this.project);
3203
+ const resolveCodeName =
3204
+ output.codeName ||
3205
+ output.declaration?.codeName ||
3206
+ toCamelCase(inputName);
3207
+
3208
+ if (existingValue) {
3209
+ existingValue.metaSync(
3210
+ {
3211
+ value: initialDefaultValue[resolveCodeName]
3212
+ },
3213
+ null
3214
+ );
3215
+
3216
+ this.lastExecutionResults.writeValue(
3217
+ output.declaration,
3218
+ existingValue
3219
+ );
3220
+ } else {
3221
+ const literalValueInstance =
3222
+ assembleStandaloneLiteralValueFromDataType(
3223
+ output.getDataType(null),
3224
+ output,
3225
+ this.project
3226
+ );
3227
+
3228
+ literalValueInstance?.metaSync(
3229
+ {
3230
+ value: initialDefaultValue[resolveCodeName]
3231
+ },
3232
+ null
3233
+ );
3234
+
3235
+ this.lastExecutionResults.writeValue(
3236
+ output.declaration,
3237
+ literalValueInstance as LiteralValueState
3238
+ );
3239
+ }
3240
+ }
3241
+
3242
+ return;
3243
+ });
3244
+ } else {
3245
+ this.lastExecutionResults.writeValue(
3246
+ entity,
3247
+ returnedValue?.value as LiteralValueState
3248
+ );
3249
+ }
3250
+
3251
+ const activeOutputMapResults: IDynamicValue[] = [];
3252
+
3253
+ const newRawValue: { [key: string]: any } =
3254
+ !!returnedValue?.value?.value &&
3255
+ isObject(returnedValue.value?.value)
3256
+ ? returnedValue.value?.value || {}
3257
+ : {};
3258
+
3259
+ entity.outputs.map((outputMap) => {
3260
+ const resolveCodeName =
3261
+ outputMap.codeName ||
3262
+ outputMap.declaration?.codeName ||
3263
+ toCamelCase(resolveEntityName(outputMap, this.project));
3264
+
3265
+ const propertyValue = (newRawValue as UntypedObjectValue)[
3266
+ resolveCodeName
3267
+ ];
3268
+
3269
+ const literalValue = assembleStandaloneLiteralValueFromDataType(
3270
+ outputMap.getDataType(null),
3271
+ outputMap,
3272
+ this.project
3273
+ );
3274
+
3275
+ literalValue?.metaSync(
3276
+ {
3277
+ value: propertyValue
3278
+ },
3279
+ null
3280
+ );
3281
+
3282
+ const newOutputDynamicValue: IDynamicValue = {
3283
+ value: literalValue,
3284
+ valueOwner: outputMap,
3285
+ type: DynamicValueTypes.ExecutionResult,
3286
+ inheritanceLink: !!returnedValue
3287
+ ? {
3288
+ sources: [returnedValue],
3289
+ target: entity
3290
+ }
3291
+ : null
3292
+ };
3293
+
3294
+ activeOutputMapResults.push(newOutputDynamicValue);
3295
+ });
3296
+
3297
+ (returnedValue as IDynamicValue).type =
3298
+ DynamicValueTypes.ExecutionResult;
3299
+
3300
+ return {
3301
+ value: ExecutionTerminationType.Return,
3302
+ entity: entity,
3303
+ error: null,
3304
+ result: returnedValue
3305
+ };
3306
+ }
3307
+
3308
+ async executeContinueStatement(
3309
+ entity: ContinueStatementState,
3310
+ inputs: IDynamicValue[]
3311
+ ): Promise<IExecutionResult> {
3312
+ this.logBeforeExecution('executeContinueStatement', entity, inputs);
3313
+ if (entity.throws?.readsValue) {
3314
+ // Resolve the next value of the error, then return it
3315
+ const errorValue = resolveNextValue(
3316
+ entity.throws,
3317
+ this.valueResolutionContext as IValueResolutionContext
3318
+ );
3319
+
3320
+ return {
3321
+ value: ExecutionTerminationType.UnhandledError,
3322
+ entity: entity,
3323
+ error: {
3324
+ valueOwner: entity.throws,
3325
+ type: DynamicValueTypes.ExecutionResult,
3326
+ inheritanceLink: null,
3327
+ value: errorValue?.value || null
3328
+ },
3329
+ result: null
3330
+ };
3331
+ }
3332
+
3333
+ let returnedValue = resolveNextValue(
3334
+ entity,
3335
+ this.valueResolutionContext as IValueResolutionContext
3336
+ );
3337
+
3338
+ const dataType = entity.getDataType(null);
3339
+
3340
+ if (dataType?.isObject()) {
3341
+ // The working object to add data to
3342
+ let initialDefaultValue: UntypedObjectValue = {};
3343
+
3344
+ if (dataType?.entity?.type === EntityType.DefinitionEntity) {
3345
+ initialDefaultValue = {
3346
+ ...initialDefaultValue,
3347
+ ...dataType.entity.getActiveRawDefaultValue()
3348
+ };
3349
+ }
3350
+
3351
+ if (!!returnedValue?.value) {
3352
+ if (isObject(returnedValue?.value?.value)) {
3353
+ initialDefaultValue = {
3354
+ ...initialDefaultValue,
3355
+ ...(returnedValue?.value?.value as UntypedObjectValue)
3356
+ };
3357
+ }
3358
+
3359
+ returnedValue?.value.metaSync(
3360
+ {
3361
+ value: initialDefaultValue
3362
+ },
3363
+ null
3364
+ );
3365
+ } else {
3366
+ const newLiteralValueEntity =
3367
+ assembleStandaloneLiteralValueFromDataType(
3368
+ dataType,
3369
+ entity,
3370
+ this.project
3371
+ );
3372
+
3373
+ newLiteralValueEntity?.metaSync(
3374
+ {
3375
+ value: initialDefaultValue
3376
+ },
3377
+ null
3378
+ );
3379
+
3380
+ returnedValue = {
3381
+ valueOwner: entity,
3382
+ type: DynamicValueTypes.ExecutionResult,
3383
+ inheritanceLink: null,
3384
+ value: newLiteralValueEntity
3385
+ };
3386
+ }
3387
+
3388
+ this.lastExecutionResults.writeValue(
3389
+ entity,
3390
+ returnedValue.value as LiteralValueState
3391
+ );
3392
+
3393
+ entity.outputs.forEach((output) => {
3394
+ if (
3395
+ output.declaration?.type === EntityType.Property &&
3396
+ output.declaration.static
3397
+ ) {
3398
+ const existingValue = this.lastExecutionResults.readValue(
3399
+ output.declaration.id
3400
+ );
3401
+
3402
+ const inputName = resolveEntityName(output, this.project);
3403
+ const resolveCodeName =
3404
+ output.codeName ||
3405
+ output.declaration?.codeName ||
3406
+ toCamelCase(inputName);
3407
+
3408
+ if (existingValue) {
3409
+ existingValue.metaSync(
3410
+ {
3411
+ value: initialDefaultValue[resolveCodeName]
3412
+ },
3413
+ null
3414
+ );
3415
+
3416
+ this.lastExecutionResults.writeValue(
3417
+ output.declaration,
3418
+ existingValue
3419
+ );
3420
+ } else {
3421
+ const literalValueInstance =
3422
+ assembleStandaloneLiteralValueFromDataType(
3423
+ output.getDataType(null),
3424
+ output,
3425
+ this.project
3426
+ );
3427
+
3428
+ literalValueInstance?.metaSync(
3429
+ {
3430
+ value: initialDefaultValue[resolveCodeName]
3431
+ },
3432
+ null
3433
+ );
3434
+
3435
+ this.lastExecutionResults.writeValue(
3436
+ output.declaration,
3437
+ literalValueInstance as LiteralValueState
3438
+ );
3439
+ }
3440
+ }
3441
+
3442
+ return;
3443
+ });
3444
+ } else {
3445
+ this.lastExecutionResults.writeValue(
3446
+ entity,
3447
+ returnedValue?.value as LiteralValueState
3448
+ );
3449
+ }
3450
+
3451
+ const activeOutputMapResults: IDynamicValue[] = [];
3452
+
3453
+ const newRawValue: { [key: string]: any } =
3454
+ !!returnedValue?.value?.value &&
3455
+ isObject(returnedValue.value?.value)
3456
+ ? returnedValue.value?.value || {}
3457
+ : {};
3458
+
3459
+ entity.outputs.map((outputMap) => {
3460
+ const resolveCodeName =
3461
+ outputMap.codeName ||
3462
+ outputMap.declaration?.codeName ||
3463
+ toCamelCase(resolveEntityName(outputMap, this.project));
3464
+
3465
+ const propertyValue = (newRawValue as UntypedObjectValue)[
3466
+ resolveCodeName
3467
+ ];
3468
+
3469
+ const literalValue = assembleStandaloneLiteralValueFromDataType(
3470
+ outputMap.getDataType(null),
3471
+ outputMap,
3472
+ this.project
3473
+ );
3474
+
3475
+ literalValue?.metaSync(
3476
+ {
3477
+ value: propertyValue
3478
+ },
3479
+ null
3480
+ );
3481
+
3482
+ const newOutputDynamicValue: IDynamicValue = {
3483
+ value: literalValue,
3484
+ valueOwner: outputMap,
3485
+ type: DynamicValueTypes.ExecutionResult,
3486
+ inheritanceLink: !!returnedValue
3487
+ ? {
3488
+ sources: [returnedValue],
3489
+ target: entity
3490
+ }
3491
+ : null
3492
+ };
3493
+
3494
+ activeOutputMapResults.push(newOutputDynamicValue);
3495
+ });
3496
+
3497
+ (returnedValue as IDynamicValue).type =
3498
+ DynamicValueTypes.ExecutionResult;
3499
+
3500
+ return {
3501
+ value: ExecutionTerminationType.Continue,
3502
+ entity: entity,
3503
+ error: null,
3504
+ result: returnedValue
3505
+ };
3506
+ }
3507
+
3508
+ async executeBreakStatement(
3509
+ entity: BreakStatementState,
3510
+ inputs: IDynamicValue[]
3511
+ ): Promise<IExecutionResult> {
3512
+ this.logBeforeExecution('executeBreakStatement', entity, inputs);
3513
+ if (entity.throws?.readsValue) {
3514
+ // Resolve the next value of the error, then return it
3515
+ const errorValue = resolveNextValue(
3516
+ entity.throws,
3517
+ this.valueResolutionContext as IValueResolutionContext
3518
+ );
3519
+
3520
+ return {
3521
+ value: ExecutionTerminationType.UnhandledError,
3522
+ entity: entity,
3523
+ error: {
3524
+ valueOwner: entity.throws,
3525
+ type: DynamicValueTypes.ExecutionResult,
3526
+ inheritanceLink: null,
3527
+ value: errorValue?.value || null
3528
+ },
3529
+ result: null
3530
+ };
3531
+ }
3532
+
3533
+ let returnedValue = resolveNextValue(
3534
+ entity,
3535
+ this.valueResolutionContext as IValueResolutionContext
3536
+ );
3537
+
3538
+ const dataType = entity.getDataType(null);
3539
+
3540
+ if (dataType?.isObject()) {
3541
+ // The working object to add data to
3542
+ let initialDefaultValue: UntypedObjectValue = {};
3543
+
3544
+ if (dataType?.entity?.type === EntityType.DefinitionEntity) {
3545
+ initialDefaultValue = {
3546
+ ...initialDefaultValue,
3547
+ ...dataType.entity.getActiveRawDefaultValue()
3548
+ };
3549
+ }
3550
+
3551
+ if (!!returnedValue?.value) {
3552
+ if (isObject(returnedValue?.value?.value)) {
3553
+ initialDefaultValue = {
3554
+ ...initialDefaultValue,
3555
+ ...(returnedValue?.value?.value as UntypedObjectValue)
3556
+ };
3557
+ }
3558
+
3559
+ returnedValue?.value.metaSync(
3560
+ {
3561
+ value: initialDefaultValue
3562
+ },
3563
+ null
3564
+ );
3565
+ } else {
3566
+ const newLiteralValueEntity =
3567
+ assembleStandaloneLiteralValueFromDataType(
3568
+ dataType,
3569
+ entity,
3570
+ this.project
3571
+ );
3572
+
3573
+ newLiteralValueEntity?.metaSync(
3574
+ {
3575
+ value: initialDefaultValue
3576
+ },
3577
+ null
3578
+ );
3579
+
3580
+ returnedValue = {
3581
+ valueOwner: entity,
3582
+ type: DynamicValueTypes.ExecutionResult,
3583
+ inheritanceLink: null,
3584
+ value: newLiteralValueEntity
3585
+ };
3586
+ }
3587
+
3588
+ this.lastExecutionResults.writeValue(
3589
+ entity,
3590
+ returnedValue.value as LiteralValueState
3591
+ );
3592
+
3593
+ entity.outputs.forEach((output) => {
3594
+ if (
3595
+ output.declaration?.type === EntityType.Property &&
3596
+ output.declaration.static
3597
+ ) {
3598
+ const existingValue = this.lastExecutionResults.readValue(
3599
+ output.declaration.id
3600
+ );
3601
+
3602
+ const inputName = resolveEntityName(output, this.project);
3603
+ const resolveCodeName =
3604
+ output.codeName ||
3605
+ output.declaration?.codeName ||
3606
+ toCamelCase(inputName);
3607
+
3608
+ if (existingValue) {
3609
+ existingValue.metaSync(
3610
+ {
3611
+ value: initialDefaultValue[resolveCodeName]
3612
+ },
3613
+ null
3614
+ );
3615
+
3616
+ this.lastExecutionResults.writeValue(
3617
+ output.declaration,
3618
+ existingValue
3619
+ );
3620
+ } else {
3621
+ const literalValueInstance =
3622
+ assembleStandaloneLiteralValueFromDataType(
3623
+ output.getDataType(null),
3624
+ output,
3625
+ this.project
3626
+ );
3627
+
3628
+ literalValueInstance?.metaSync(
3629
+ {
3630
+ value: initialDefaultValue[resolveCodeName]
3631
+ },
3632
+ null
3633
+ );
3634
+
3635
+ this.lastExecutionResults.writeValue(
3636
+ output.declaration,
3637
+ literalValueInstance as LiteralValueState
3638
+ );
3639
+ }
3640
+ }
3641
+
3642
+ return;
3643
+ });
3644
+ } else {
3645
+ this.lastExecutionResults.writeValue(
3646
+ entity,
3647
+ returnedValue?.value as LiteralValueState
3648
+ );
3649
+ }
3650
+
3651
+ const activeOutputMapResults: IDynamicValue[] = [];
3652
+
3653
+ const newRawValue: { [key: string]: any } =
3654
+ !!returnedValue?.value?.value &&
3655
+ isObject(returnedValue.value?.value)
3656
+ ? returnedValue.value?.value || {}
3657
+ : {};
3658
+
3659
+ entity.outputs.map((outputMap) => {
3660
+ const resolveCodeName =
3661
+ outputMap.codeName ||
3662
+ outputMap.declaration?.codeName ||
3663
+ toCamelCase(resolveEntityName(outputMap, this.project));
3664
+
3665
+ const propertyValue = (newRawValue as UntypedObjectValue)[
3666
+ resolveCodeName
3667
+ ];
3668
+
3669
+ const literalValue = assembleStandaloneLiteralValueFromDataType(
3670
+ outputMap.getDataType(null),
3671
+ outputMap,
3672
+ this.project
3673
+ );
3674
+
3675
+ literalValue?.metaSync(
3676
+ {
3677
+ value: propertyValue
3678
+ },
3679
+ null
3680
+ );
3681
+
3682
+ const newOutputDynamicValue: IDynamicValue = {
3683
+ value: literalValue,
3684
+ valueOwner: outputMap,
3685
+ type: DynamicValueTypes.ExecutionResult,
3686
+ inheritanceLink: !!returnedValue
3687
+ ? {
3688
+ sources: [returnedValue],
3689
+ target: entity
3690
+ }
3691
+ : null
3692
+ };
3693
+
3694
+ activeOutputMapResults.push(newOutputDynamicValue);
3695
+ });
3696
+
3697
+ (returnedValue as IDynamicValue).type =
3698
+ DynamicValueTypes.ExecutionResult;
3699
+
3700
+ return {
3701
+ value: ExecutionTerminationType.Break,
3702
+ entity: entity,
3703
+ error: null,
3704
+ result: returnedValue
3705
+ };
3706
+ }
3707
+
3708
+ async executeVariable(
3709
+ entity: VariableState,
3710
+ inputs: IDynamicValue[]
3711
+ ): Promise<IExecutionResult> {
3712
+ this.logBeforeExecution('executeVariable', entity, inputs);
3713
+ let varValue = resolveNextValue(
3714
+ entity,
3715
+ this.valueResolutionContext as IValueResolutionContext
3716
+ );
3717
+
3718
+ const varDeclaration = getDeclaration(entity);
3719
+
3720
+ const dataType = varDeclaration.getDataType(null);
3721
+
3722
+ if (dataType?.isObject()) {
3723
+ // The working object to add data to
3724
+ let initialDefaultValue: UntypedObjectValue = {};
3725
+
3726
+ if (dataType?.entity?.type === EntityType.DefinitionEntity) {
3727
+ initialDefaultValue = {
3728
+ ...initialDefaultValue,
3729
+ ...dataType.entity.getActiveRawDefaultValue()
3730
+ };
3731
+ } else if (
3732
+ dataType?.entity?.type === EntityType.BuiltInBaseEntity
3733
+ ) {
3734
+ initialDefaultValue = {
3735
+ ...initialDefaultValue,
3736
+ ...dataType.entity.getRawDefaultValue()
3737
+ };
3738
+ }
3739
+
3740
+ if (!!varValue?.value) {
3741
+ if (isObject(varValue?.value?.value)) {
3742
+ initialDefaultValue = {
3743
+ ...initialDefaultValue,
3744
+ ...(varValue?.value?.value as UntypedObjectValue)
3745
+ };
3746
+ }
3747
+
3748
+ varValue?.value.metaSync(
3749
+ {
3750
+ value: initialDefaultValue
3751
+ },
3752
+ null
3753
+ );
3754
+ } else {
3755
+ const newLiteralValueEntity =
3756
+ assembleStandaloneLiteralValueFromDataType(
3757
+ dataType,
3758
+ entity,
3759
+ this.project
3760
+ );
3761
+
3762
+ newLiteralValueEntity?.metaSync(
3763
+ {
3764
+ value: initialDefaultValue
3765
+ },
3766
+ null
3767
+ );
3768
+
3769
+ varValue = {
3770
+ valueOwner: varDeclaration,
3771
+ type: DynamicValueTypes.ExecutionResult,
3772
+ inheritanceLink: null,
3773
+ value: newLiteralValueEntity
3774
+ };
3775
+ }
3776
+
3777
+ entity.inputs.forEach((input) => {
3778
+ const inputNextValue = resolveNextValue(
3779
+ input,
3780
+ this.valueResolutionContext as IValueResolutionContext
3781
+ );
3782
+
3783
+ const inputInVarDeclaration = varDeclaration.inputs.find(
3784
+ (declInput) =>
3785
+ declInput.declaration?.id === input.declaration?.id
3786
+ );
3787
+
3788
+ if (
3789
+ inputInVarDeclaration?.declaration?.type ===
3790
+ EntityType.Property &&
3791
+ inputInVarDeclaration?.declaration?.static
3792
+ ) {
3793
+ if (inputNextValue?.value) {
3794
+ this.lastExecutionResults.writeValue(
3795
+ inputInVarDeclaration?.declaration,
3796
+ inputNextValue?.value as LiteralValueState
3797
+ );
3798
+ } else {
3799
+ this.lastExecutionResults.removeValue(
3800
+ inputInVarDeclaration?.declaration.id
3801
+ );
3802
+ }
3803
+ } else {
3804
+ if (!!inputNextValue?.value) {
3805
+ const inputName = resolveEntityName(
3806
+ input,
3807
+ this.project
3808
+ );
3809
+ const resolveCodeName =
3810
+ input.codeName ||
3811
+ input.declaration?.codeName ||
3812
+ toCamelCase(inputName);
3813
+
3814
+ varValue?.value?.metaSync(
3815
+ {
3816
+ value: {
3817
+ ...(varValue.value?.value as {
3818
+ [key: string]: any;
3819
+ }),
3820
+ [resolveCodeName]:
3821
+ inputNextValue?.value?.value
3822
+ }
3823
+ },
3824
+ null
3825
+ );
3826
+ }
3827
+ }
3828
+ });
3829
+
3830
+ this.lastExecutionResults.writeValue(
3831
+ varDeclaration,
3832
+ varValue.value as LiteralValueState
3833
+ );
3834
+ } else {
3835
+ this.lastExecutionResults.writeValue(
3836
+ varDeclaration,
3837
+ varValue?.value as LiteralValueState
3838
+ );
3839
+ }
3840
+
3841
+ const activeOutputMapResults: IDynamicValue[] = [];
3842
+
3843
+ const newRawValue: { [key: string]: any } =
3844
+ !!varValue?.value?.value && isObject(varValue.value?.value)
3845
+ ? varValue.value?.value || {}
3846
+ : {};
3847
+
3848
+ entity.outputs.map((outputMap) => {
3849
+ const resolveCodeName =
3850
+ outputMap.codeName ||
3851
+ outputMap.declaration?.codeName ||
3852
+ toCamelCase(resolveEntityName(outputMap, this.project));
3853
+
3854
+ const propertyValue = (newRawValue as UntypedObjectValue)[
3855
+ resolveCodeName
3856
+ ];
3857
+
3858
+ const literalValue = assembleStandaloneLiteralValueFromDataType(
3859
+ outputMap.getDataType(null),
3860
+ outputMap,
3861
+ this.project
3862
+ );
3863
+
3864
+ literalValue?.metaSync(
3865
+ {
3866
+ value: propertyValue
3867
+ },
3868
+ null
3869
+ );
3870
+
3871
+ const newOutputDynamicValue: IDynamicValue = {
3872
+ value: literalValue,
3873
+ valueOwner: outputMap,
3874
+ type: DynamicValueTypes.ExecutionResult,
3875
+ inheritanceLink: !!varValue
3876
+ ? {
3877
+ sources: [varValue],
3878
+ target: entity
3879
+ }
3880
+ : null
3881
+ };
3882
+
3883
+ activeOutputMapResults.push(newOutputDynamicValue);
3884
+ });
3885
+
3886
+ (varValue as IDynamicValue).type = DynamicValueTypes.ExecutionResult;
3887
+
3888
+ return {
3889
+ value: ExecutionTerminationType.Success,
3890
+ entity: entity,
3891
+ error: null,
3892
+ result: varValue
3893
+ };
3894
+ }
3895
+
3896
+ // This function merges the values passed by previous entities's results of the execution
3897
+ // And their own defined default values
3898
+ // Based on the index, the input value is prioritized over the default value
3899
+ mergeValues(
3900
+ inputs: IDynamicValue[],
3901
+ defaultValues: IDynamicValue[]
3902
+ ): IDynamicValue[] {
3903
+ const mergedValues: IDynamicValue[] = [];
3904
+
3905
+ // Merge the values of the inputs with the default values
3906
+ // If the input value is not null, it is prioritized over the default value
3907
+ for (let i = 0; i < defaultValues.length; i++) {
3908
+ if (inputs?.[i]) {
3909
+ mergedValues.push(inputs[i]);
3910
+ } else {
3911
+ mergedValues.push(defaultValues[i]);
3912
+ }
3913
+ }
3914
+
3915
+ return mergedValues;
3916
+ }
3917
+
3918
+ async executeEntity(
3919
+ entity: ExecutableEntityState,
3920
+ inputs: IDynamicValue[] = [],
3921
+ client: IExecutionClient = {}
3922
+ ): Promise<IExecutionResult> {
3923
+ this.logBeforeExecution('executeEntity', entity, inputs);
3924
+ const clientWithDefaults: IExecutionClient = {
3925
+ ...EXECUTION_CLIENT_DEFAULTS,
3926
+ ...client
3927
+ };
3928
+ const executionContext: IExecutionCallbackContext = {
3929
+ detached: false,
3930
+ execution: this
3931
+ };
3932
+
3933
+ switch (entity.type) {
3934
+ case EntityType.Condition: {
3935
+ const resolvedInputs =
3936
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
3937
+
3938
+ await clientWithDefaults.onBeforeEntityExecution?.(
3939
+ entity,
3940
+ resolvedInputs,
3941
+ executionContext
3942
+ );
3943
+ return this.executeCondition(entity, resolvedInputs);
3944
+ }
3945
+ case EntityType.InternalCall: {
3946
+ const resolvedInputs =
3947
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
3948
+
3949
+ await clientWithDefaults.onBeforeEntityExecution?.(
3950
+ entity,
3951
+ resolvedInputs,
3952
+ executionContext
3953
+ );
3954
+ return this.executeInternalCall(
3955
+ entity,
3956
+ resolvedInputs,
3957
+ this.project
3958
+ );
3959
+ }
3960
+ case EntityType.Operation: {
3961
+ const resolvedInputs =
3962
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
3963
+
3964
+ await clientWithDefaults.onBeforeEntityExecution?.(
3965
+ entity,
3966
+ resolvedInputs,
3967
+ executionContext
3968
+ );
3969
+ return Execution.executeOperation(
3970
+ entity,
3971
+ resolvedInputs,
3972
+ this.project,
3973
+ this
3974
+ );
3975
+ }
3976
+ case EntityType.VariableInstance:
3977
+ case EntityType.VariableDeclaration: {
3978
+ const resolvedInputs =
3979
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
3980
+
3981
+ await clientWithDefaults.onBeforeEntityExecution?.(
3982
+ entity,
3983
+ resolvedInputs,
3984
+ executionContext
3985
+ );
3986
+
3987
+ return this.executeVariable(entity, resolvedInputs);
3988
+ }
3989
+ case EntityType.FunctionCall: {
3990
+ const resolvedInputs =
3991
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
3992
+
3993
+ await clientWithDefaults.onBeforeEntityExecution?.(
3994
+ entity,
3995
+ resolvedInputs,
3996
+ executionContext
3997
+ );
3998
+ return this.executeFunctionCall(
3999
+ entity as FunctionCallState,
4000
+ resolvedInputs,
4001
+ this.project
4002
+ );
4003
+ }
4004
+ case EntityType.FunctionDeclaration: {
4005
+ const resolvedInputs =
4006
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4007
+
4008
+ await clientWithDefaults.onBeforeEntityExecution?.(
4009
+ entity,
4010
+ resolvedInputs,
4011
+ executionContext
4012
+ );
4013
+
4014
+ resolvedInputs.forEach((input) => {
4015
+ if (input.value && input.valueOwner) {
4016
+ this.lastExecutionResults.writeValue(
4017
+ input.valueOwner as EntityWithValueState,
4018
+ input.value as LiteralValueState
4019
+ );
4020
+ }
4021
+ });
4022
+
4023
+ return Execution.executeEntryPointEntity(
4024
+ entity,
4025
+ resolvedInputs,
4026
+ this
4027
+ );
4028
+ }
4029
+ case EntityType.Search: {
4030
+ const resolvedInputs =
4031
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4032
+
4033
+ await clientWithDefaults.onBeforeEntityExecution?.(
4034
+ entity,
4035
+ resolvedInputs,
4036
+ executionContext
4037
+ );
4038
+ return this.executeSearch(entity, resolvedInputs, this.project);
4039
+ }
4040
+ case EntityType.Loop: {
4041
+ const resolvedInputs =
4042
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4043
+
4044
+ await clientWithDefaults.onBeforeEntityExecution?.(
4045
+ entity,
4046
+ resolvedInputs,
4047
+ executionContext
4048
+ );
4049
+ return this.executeLoop(
4050
+ entity,
4051
+ resolvedInputs,
4052
+ this.project,
4053
+ clientWithDefaults
4054
+ );
4055
+ }
4056
+ case EntityType.ReturnStatement: {
4057
+ const resolvedInputs =
4058
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4059
+
4060
+ await clientWithDefaults.onBeforeEntityExecution?.(
4061
+ entity,
4062
+ resolvedInputs,
4063
+ executionContext
4064
+ );
4065
+ return this.executeReturnStatement(entity, resolvedInputs);
4066
+ }
4067
+ case EntityType.ContinueStatement: {
4068
+ const resolvedInputs =
4069
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4070
+
4071
+ await clientWithDefaults.onBeforeEntityExecution?.(
4072
+ entity,
4073
+ resolvedInputs,
4074
+ executionContext
4075
+ );
4076
+ return this.executeContinueStatement(entity, resolvedInputs);
4077
+ }
4078
+ case EntityType.BreakStatement: {
4079
+ const resolvedInputs =
4080
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4081
+
4082
+ await clientWithDefaults.onBeforeEntityExecution?.(
4083
+ entity,
4084
+ resolvedInputs,
4085
+ executionContext
4086
+ );
4087
+ return this.executeBreakStatement(entity, resolvedInputs);
4088
+ }
4089
+ case EntityType.GlobalEvent: {
4090
+ const resolvedInputs =
4091
+ this.mergeExernalValuesWithInternalInputs(inputs, entity);
4092
+
4093
+ await clientWithDefaults.onBeforeEntityExecution?.(
4094
+ entity,
4095
+ resolvedInputs,
4096
+ executionContext
4097
+ );
4098
+
4099
+ resolvedInputs.forEach((input) => {
4100
+ if (input.value && input.valueOwner) {
4101
+ this.lastExecutionResults.writeValue(
4102
+ input.valueOwner as EntityWithValueState,
4103
+ input.value as LiteralValueState
4104
+ );
4105
+ }
4106
+ });
4107
+
4108
+ return Execution.executeEntryPointEntity(
4109
+ entity,
4110
+ resolvedInputs,
4111
+ this
4112
+ );
4113
+ }
4114
+ default:
4115
+ // If the entity is not recognized, we return an error
4116
+ throw new Error(
4117
+ // @ts-ignore
4118
+ `Entity type ${entity?.type} is not recognized for execution.`
4119
+ );
4120
+ }
4121
+ }
4122
+
4123
+ storeLastExecutionValues(result: IExecutionResult) {
4124
+ if (result.error && !!result.error.valueOwner) {
4125
+ this.lastExecutionResults.writeValue(
4126
+ result.error.valueOwner,
4127
+ result.error.value as LiteralValueState
4128
+ );
4129
+ }
4130
+
4131
+ if (!result.result || !result.result?.valueOwner) {
4132
+ return;
4133
+ }
4134
+
4135
+ const propagatedValueOwners = getEntitiesToPropagateValuesTo(
4136
+ result.result?.valueOwner as EntityWithValueState,
4137
+ this.project
4138
+ );
4139
+
4140
+ if (!!result.result?.value) {
4141
+ propagatedValueOwners.forEach((propagatedValueOwner) => {
4142
+ this.lastExecutionResults.writeValue(
4143
+ propagatedValueOwner,
4144
+ result.result?.value as LiteralValueState
4145
+ );
4146
+ });
4147
+ } else {
4148
+ propagatedValueOwners.forEach((propagatedValueOwner) => {
4149
+ this.lastExecutionResults.removeValue(propagatedValueOwner.id);
4150
+ });
4151
+ }
4152
+ }
4153
+
4154
+ // Takes the given entity as the entry point to its own branch
4155
+ // Then, it recursively executes its own branches
4156
+ async executeBranch(
4157
+ localEntryPoint: TestableEntityState,
4158
+ client: IExecutionClient = {},
4159
+ // A set of external values which take the place of internally resolved ones,
4160
+ // Good for exernally executing a logic chain with specific arguments
4161
+ values: IDynamicValue[] = []
4162
+ ): Promise<IExecutionResult | null> {
4163
+ this.logBeforeExecution('executeBranch', localEntryPoint, values);
4164
+ await this.checkStateAndPause();
4165
+
4166
+ const clientWithDefaults: IExecutionClient = {
4167
+ ...EXECUTION_CLIENT_DEFAULTS,
4168
+ ...client
4169
+ };
4170
+ const executionContext: IExecutionCallbackContext = {
4171
+ detached: false,
4172
+ execution: this
4173
+ };
4174
+
4175
+ const isPartOfTest = this.hasEntity(localEntryPoint);
4176
+
4177
+ if (!isPartOfTest) {
4178
+ return null;
4179
+ }
4180
+
4181
+ if (this.hasSkipped(localEntryPoint)) {
4182
+ return null;
4183
+ }
4184
+
4185
+ // Add entity to the list of entities that are currently being executed
4186
+ this.addToExecutingList(localEntryPoint);
4187
+
4188
+ if (this.hasScheduled(localEntryPoint)) {
4189
+ // Remove from scheduled
4190
+ this.removeScheduled(localEntryPoint);
4191
+ }
4192
+
4193
+ // Execute self first, then based on success or error cases
4194
+ const result = await this.executeEntity(
4195
+ localEntryPoint,
4196
+ values,
4197
+ clientWithDefaults
4198
+ );
4199
+
4200
+ console.log(
4201
+ `executeBranch (${localEntryPoint.type}) -> [${resolveEntityName(localEntryPoint, this.project)}] result:\n ${result.error ? `Error: ${JSON.stringify(result.error.value?.value, null, 2)}` : `Value: ${JSON.stringify(result.result?.value?.value, null, 2)}`}`
4202
+ );
4203
+
4204
+ // Remove entity from the list of entities that are currently being executed
4205
+ this.removeFromExecutingList(localEntryPoint);
4206
+ this.addToAlreadyExecutedList(localEntryPoint);
4207
+
4208
+ // Execute the results in the projects' execution values store
4209
+ this.storeLastExecutionValues(result);
4210
+
4211
+ await clientWithDefaults.onEntityExecuted?.(
4212
+ localEntryPoint,
4213
+ result,
4214
+ executionContext
4215
+ );
4216
+
4217
+ // Recursively order based on dependency, and execute the respective branch (success, or error calls)
4218
+ if (result.value === ExecutionTerminationType.Success) {
4219
+ // Filter out entities called by the success branch that aren't part of the test
4220
+ const successCallsInTest: CallableEntityState[] = (
4221
+ (localEntryPoint as FunctionCallState).successCalls ||
4222
+ (localEntryPoint as FunctionDeclarationState).calls ||
4223
+ []
4224
+ ).filter((call) => this.hasEntity(call));
4225
+
4226
+ const otherCallsInTest: CallableEntityState[] =
4227
+ (localEntryPoint as FunctionCallState).errorCalls || [];
4228
+
4229
+ otherCallsInTest.forEach((call) => {
4230
+ this.skip(call);
4231
+ });
4232
+
4233
+ let agregateResults: IExecutionResult[] = [];
4234
+
4235
+ const groupResults: IExecutionResult[] = (
4236
+ await Promise.all(
4237
+ successCallsInTest.map((call) =>
4238
+ this.schedule(call, [], clientWithDefaults)
4239
+ )
4240
+ )
4241
+ ).filter((result) => !!result) as IExecutionResult[];
4242
+
4243
+ const terminationResult = groupResults
4244
+ // Filter out results that didn't go through the with their own execution
4245
+ .filter((result) => !!result)
4246
+ .find(
4247
+ (result) =>
4248
+ result.value === ExecutionTerminationType.CaughtError ||
4249
+ result.value === ExecutionTerminationType.Return ||
4250
+ result.value === ExecutionTerminationType.Break ||
4251
+ result.value === ExecutionTerminationType.Continue
4252
+ );
4253
+
4254
+ if (terminationResult) {
4255
+ return terminationResult;
4256
+ }
4257
+
4258
+ agregateResults = [...agregateResults, ...groupResults];
4259
+
4260
+ // If there are no success calls, return the result
4261
+ return result;
4262
+ } else if (
4263
+ result.value === ExecutionTerminationType.CaughtError ||
4264
+ result.value === ExecutionTerminationType.ConditionNotMet
4265
+ ) {
4266
+ // Filter out entities called by the error branch that aren't part of the test
4267
+ const errorCallsInTest: CallableEntityState[] = (
4268
+ (localEntryPoint as FunctionCallState).errorCalls || []
4269
+ ).filter((call) => this.hasEntity(call));
4270
+
4271
+ const otherCallsInTest: CallableEntityState[] =
4272
+ (localEntryPoint as FunctionCallState).successCalls ||
4273
+ (localEntryPoint as FunctionDeclarationState).calls ||
4274
+ [];
4275
+
4276
+ otherCallsInTest.forEach((call) => {
4277
+ this.skip(call);
4278
+ });
4279
+
4280
+ let agregateResults: IExecutionResult[] = [];
4281
+
4282
+ const groupResults: IExecutionResult[] = (
4283
+ await Promise.all(
4284
+ errorCallsInTest.map((call) =>
4285
+ this.schedule(call, [], clientWithDefaults)
4286
+ )
4287
+ )
4288
+ ).filter((result) => !!result) as IExecutionResult[];
4289
+
4290
+ const terminationResult = groupResults
4291
+ // Filter out results that didn't go through the with their own execution
4292
+ .filter((result) => !!result)
4293
+ .find(
4294
+ (result) =>
4295
+ result.value === ExecutionTerminationType.CaughtError ||
4296
+ result.value ===
4297
+ ExecutionTerminationType.UnhandledError ||
4298
+ result.value === ExecutionTerminationType.Return ||
4299
+ result.value === ExecutionTerminationType.Break ||
4300
+ result.value === ExecutionTerminationType.Continue
4301
+ );
4302
+
4303
+ if (terminationResult) {
4304
+ return terminationResult;
4305
+ }
4306
+
4307
+ agregateResults = [...agregateResults, ...groupResults];
4308
+
4309
+ // If there are no error calls, return the result
4310
+ return result;
4311
+ } else if (result.value === ExecutionTerminationType.UnhandledError) {
4312
+ // Abort the execution of the test
4313
+ this.executing.forEach((entity) => {
4314
+ // this.removeFromExecutingList(entity);
4315
+ this.skip(entity);
4316
+ });
4317
+
4318
+ // Unschedule all entities that were scheduled
4319
+ // And skip them
4320
+ this.scheduled.forEach((entity) => {
4321
+ this.skip(entity);
4322
+ });
4323
+
4324
+ if (CALLER_TYPES.includes(result.entity.type)) {
4325
+ flattenElementCalls(result.entity as CallerEntityState).forEach(
4326
+ (call) => {
4327
+ this.skip(call);
4328
+ }
4329
+ );
4330
+ }
4331
+
4332
+ return result;
4333
+ } else if (result.value === ExecutionTerminationType.Return) {
4334
+ return result;
4335
+ } else if (result.value === ExecutionTerminationType.Break) {
4336
+ return result;
4337
+ } else if (result.value === ExecutionTerminationType.Continue) {
4338
+ return result;
4339
+ }
4340
+
4341
+ return result;
4342
+ }
4343
+
4344
+ /*
4345
+ Execute the chain of entities, starting with the entry point
4346
+ And sorting any branching by dependency order so all values are fulfilled before their entity is executed
4347
+ Explore each branch by checking if it is part of the test, then execute it
4348
+ Revert to next sibling branch if it isn't.
4349
+
4350
+ If two branches aren't dependent, we can execute them in parallel
4351
+ */
4352
+ async execute(
4353
+ client: IExecutionClient = {},
4354
+ // A set of external values which take the place of internally resolved ones,
4355
+ // Good for exernally executing a logic chain with specific arguments
4356
+ values: IDynamicValue[] = []
4357
+ ): Promise<IExecutionResult> {
4358
+ console.log(
4359
+ `%cexecute -> [Execution] initialExternalValues:\n ${values
4360
+ .map(
4361
+ (d) =>
4362
+ `${d.valueOwner?.type} (${d.valueOwner?.id}) "${resolveEntityName(
4363
+ d.valueOwner as any,
4364
+ this.project
4365
+ )}": ${JSON.stringify(d.value?.value, null, 2)}`
4366
+ )
4367
+ .join('\n ')}\n`,
4368
+ 'color: #3b82f6; font-weight: bold;'
4369
+ );
4370
+ const clientWithDefaults: IExecutionClient = {
4371
+ ...EXECUTION_CLIENT_DEFAULTS,
4372
+ ...client
4373
+ };
4374
+
4375
+ this.state = ExecutionState.Running;
4376
+
4377
+ const originalActiveExecution = (this.project as any).activeExecution;
4378
+ (this.project as any).activeExecution = this;
4379
+
4380
+ try {
4381
+ const finalResult = await this.executeBranch(
4382
+ this.entryPoint,
4383
+ clientWithDefaults,
4384
+ values
4385
+ );
4386
+
4387
+ this.state = ExecutionState.FinishedSuccess;
4388
+
4389
+ return finalResult as IExecutionResult;
4390
+ } finally {
4391
+ (this.project as any).activeExecution = originalActiveExecution;
4392
+ }
4393
+ }
4394
+
4395
+ getExecutionLevels(): string {
4396
+ const levels: string[] = [];
4397
+ let current: Execution | null = this;
4398
+ while (current) {
4399
+ const ep = current.entryPoint;
4400
+ const name = ep ? resolveEntityName(ep, this.project) : 'Unknown';
4401
+ const type = ep ? ep.type : 'unknown';
4402
+ levels.unshift(`${type} "${name}"`);
4403
+ current = current.parentExecution;
4404
+ }
4405
+ return levels.join(' -> ');
4406
+ }
4407
+
4408
+ logBeforeExecution(
4409
+ methodName: string,
4410
+ entity: EntityState,
4411
+ inputs: IDynamicValue[]
4412
+ ) {
4413
+ const levels = this.getExecutionLevels();
4414
+ const scopeOwner = getScopeOwner(entity, this.project);
4415
+ const scopeOwnerName = scopeOwner
4416
+ ? resolveEntityName(scopeOwner as any, this.project)
4417
+ : 'Project';
4418
+ const scopeOwnerType = scopeOwner
4419
+ ? (scopeOwner as any).type
4420
+ : 'Project';
4421
+ const entityName = resolveEntityName(entity, this.project);
4422
+
4423
+ console.log(
4424
+ `%c[Execution: ${levels}] %c[Scope: ${scopeOwnerType} "${scopeOwnerName}"]`,
4425
+ 'color: #3b82f6; font-weight: bold;',
4426
+ 'color: #10b981; font-weight: bold;'
4427
+ );
4428
+
4429
+ console.log(
4430
+ `%c${methodName} (${entity.type}) -> [${entityName}]%c Inputs:`,
4431
+ 'font-weight: bold; color: #224370ff;',
4432
+ 'color: #9ca3af;'
4433
+ );
4434
+
4435
+ if (inputs.length) {
4436
+ inputs.forEach((d) => {
4437
+ const ownerName = resolveEntityName(
4438
+ d.valueOwner as any,
4439
+ this.project
4440
+ );
4441
+ console.log(
4442
+ ` %c${d.valueOwner?.type}%c (${d.valueOwner?.id}) %c"${ownerName}"%c:`,
4443
+ 'color: #8b5cf6; font-weight: bold;',
4444
+ 'color: #9ca3af;',
4445
+ 'color: #10b981; font-weight: bold;',
4446
+ 'color: #667a9bff;',
4447
+ d.value?.value
4448
+ );
4449
+ });
4450
+ } else {
4451
+ console.log(' (none)');
4452
+ }
4453
+
4454
+ if (
4455
+ entity.type === EntityType.VariableInstance ||
4456
+ entity.type === EntityType.VariableDeclaration
4457
+ ) {
4458
+ const varDeclaration = getDeclaration(entity as VariableState);
4459
+ const varValue = resolveValue(
4460
+ varDeclaration,
4461
+ this.valueResolutionContext as any
4462
+ );
4463
+ console.log(
4464
+ ` %cExisting Value%c of [${resolveEntityName(varDeclaration, this.project)}]:`,
4465
+ 'color: #ec4899; font-weight: bold;',
4466
+ 'color: #667a9bff;',
4467
+ varValue?.value?.value
4468
+ );
4469
+ }
4470
+
4471
+ if (entity.type === EntityType.InternalCall) {
4472
+ const parentVar = (entity as InternalCallState).parent;
4473
+ if (parentVar) {
4474
+ const parentVarValue = resolveValue(
4475
+ parentVar,
4476
+ this.valueResolutionContext as any
4477
+ );
4478
+ console.log(
4479
+ ` %cParent Variable%c [${resolveEntityName(parentVar, this.project)}] Value:`,
4480
+ 'color: #f59e0b; font-weight: bold;',
4481
+ 'color: #667a9bff;',
4482
+ parentVarValue?.value?.value
4483
+ );
4484
+ }
4485
+ }
4486
+ }
4487
+
4488
+ addEntity(entity: TestableEntityState) {
4489
+ if (!this.entities.includes(entity)) {
4490
+ this.entities.push(entity);
4491
+ this.onAddEntityCallback?.(entity, {});
4492
+ }
4493
+ }
4494
+
4495
+ async addEntityAsync(
4496
+ entity: TestableEntityState,
4497
+ options: YieldOptions & {
4498
+ skipValidate?: boolean;
4499
+ skipRender?: boolean;
4500
+ skipNotify?: boolean;
4501
+ } = {}
4502
+ ) {
4503
+ if (!this.entities.includes(entity)) {
4504
+ this.entities.push(entity);
4505
+ await this.onAddEntityCallback?.(entity, options);
4506
+ }
4507
+ }
4508
+
4509
+ addEntities(entities: TestableEntityState[]) {
4510
+ entities.forEach((entity) => this.addEntity(entity));
4511
+ }
4512
+
4513
+ async addEntitiesAsync(
4514
+ entities: TestableEntityState[],
4515
+ options: YieldOptions & {
4516
+ skipValidate?: boolean;
4517
+ skipRender?: boolean;
4518
+ skipNotify?: boolean;
4519
+ } = {}
4520
+ ) {
4521
+ const tracker = YieldTracker.from(options);
4522
+
4523
+ const promises: Promise<void>[] = [];
4524
+
4525
+ for (const entity of entities) {
4526
+ promises.push(this.addEntityAsync(entity, options));
4527
+
4528
+ await tracker.tick();
4529
+ }
4530
+
4531
+ await Promise.all(promises);
4532
+ }
4533
+
4534
+ // Remove entity if it isn't the entry point
4535
+ removeEntity(entity: TestableEntityState) {
4536
+ if (entity !== this.entryPoint) {
4537
+ const index = this.entities.indexOf(entity);
4538
+ if (index > -1) {
4539
+ this.entities.splice(index, 1);
4540
+ this.onRemoveEntityCallback?.(entity, {});
4541
+ }
4542
+ }
4543
+ }
4544
+
4545
+ hasEntity(entity: EntityState): boolean {
4546
+ if (this.entities.includes(entity as TestableEntityState)) {
4547
+ return true;
4548
+ }
4549
+
4550
+ if (
4551
+ (entity as any).parent &&
4552
+ (entity as any).parent?.id !== entity?.id
4553
+ ) {
4554
+ return this.hasEntity((entity as any).parent as any);
4555
+ }
4556
+
4557
+ return false;
4558
+ }
4559
+
4560
+ removeScheduled(entity: TestableEntityState) {
4561
+ const index = this.scheduled.indexOf(entity);
4562
+ if (index > -1) {
4563
+ this.scheduled.splice(index, 1);
4564
+ }
4565
+ }
4566
+
4567
+ hasScheduled(entity: TestableEntityState): boolean {
4568
+ if (this.scheduled.includes(entity)) {
4569
+ return true;
4570
+ }
4571
+
4572
+ return false;
4573
+ }
4574
+
4575
+ hasSkipped(entity: TestableEntityState): boolean {
4576
+ if (this.skipped.includes(entity)) {
4577
+ return true;
4578
+ }
4579
+
4580
+ return false;
4581
+ }
4582
+
4583
+ hasExecuted(entity: TestableEntityState): boolean {
4584
+ if (this.executed.includes(entity)) {
4585
+ return true;
4586
+ }
4587
+
4588
+ return false;
4589
+ }
4590
+
4591
+ hasEntityWithId(id: string): boolean {
4592
+ const entity = this.project.get(id);
4593
+
4594
+ return !!entity ? this.hasEntity(entity) : false;
4595
+ }
4596
+
4597
+ onAddToSkippedList(
4598
+ callback: (
4599
+ entity: TestableEntityState,
4600
+ options?: YieldOptions & {
4601
+ skipValidate?: boolean;
4602
+ skipRender?: boolean;
4603
+ skipNotify?: boolean;
4604
+ }
4605
+ ) => Promise<void> | void
4606
+ ) {
4607
+ this.onAddToSkippedListCallback = callback;
4608
+ }
4609
+
4610
+ onAbortExecution(
4611
+ callback: (
4612
+ entity: TestableEntityState,
4613
+ options?: YieldOptions & {
4614
+ skipValidate?: boolean;
4615
+ skipRender?: boolean;
4616
+ skipNotify?: boolean;
4617
+ }
4618
+ ) => Promise<void> | void
4619
+ ) {
4620
+ this.onAbortExecutionCallback = callback;
4621
+ }
4622
+
4623
+ onAddEntity(
4624
+ callback: (
4625
+ entity: TestableEntityState,
4626
+ options?: YieldOptions & {
4627
+ skipValidate?: boolean;
4628
+ skipRender?: boolean;
4629
+ skipNotify?: boolean;
4630
+ }
4631
+ ) => Promise<void> | void
4632
+ ) {
4633
+ this.onAddEntityCallback = callback;
4634
+ }
4635
+
4636
+ onRemoveFromSkippedList(
4637
+ callback: (
4638
+ entity: TestableEntityState,
4639
+ options?: YieldOptions & {
4640
+ skipValidate?: boolean;
4641
+ skipRender?: boolean;
4642
+ skipNotify?: boolean;
4643
+ }
4644
+ ) => Promise<void> | void
4645
+ ) {
4646
+ this.onRemoveFromSkippedListCallback = callback;
4647
+ }
4648
+
4649
+ onRemoveEntity(
4650
+ callback: (
4651
+ entity: TestableEntityState,
4652
+ options?: YieldOptions & {
4653
+ skipValidate?: boolean;
4654
+ skipRender?: boolean;
4655
+ skipNotify?: boolean;
4656
+ }
4657
+ ) => Promise<void> | void
4658
+ ) {
4659
+ this.onRemoveEntityCallback = callback;
4660
+ }
4661
+
4662
+ addToExecutingList(entity: TestableEntityState) {
4663
+ if (!this.executing.includes(entity)) {
4664
+ this.executing.push(entity);
4665
+ }
4666
+ }
4667
+
4668
+ addToScheduledList(entity: TestableEntityState) {
4669
+ if (!this.scheduled.includes(entity)) {
4670
+ this.scheduled.push(entity);
4671
+ }
4672
+ }
4673
+
4674
+ removeFromScheduledList(entity: TestableEntityState) {
4675
+ const index = this.scheduled.indexOf(entity);
4676
+ if (index > -1) {
4677
+ this.scheduled.splice(index, 1);
4678
+ }
4679
+ }
4680
+
4681
+ removeFromExecutingList(entity: TestableEntityState) {
4682
+ const index = this.executing.indexOf(entity);
4683
+ if (index > -1) {
4684
+ this.executing.splice(index, 1);
4685
+ this.onAbortExecutionCallback?.(entity, {});
4686
+ }
4687
+ }
4688
+
4689
+ removeFromAlreadyExecutedList(entity: TestableEntityState) {
4690
+ const index = this.executed.indexOf(entity);
4691
+ if (index > -1) {
4692
+ this.executed.splice(index, 1);
4693
+ }
4694
+ }
4695
+
4696
+ removeFromSkippedList(entity: TestableEntityState) {
4697
+ const index = this.skipped.indexOf(entity);
4698
+ if (index > -1) {
4699
+ this.skipped.splice(index, 1);
4700
+ this.onRemoveFromSkippedListCallback?.(entity, {});
4701
+ }
4702
+ }
4703
+
4704
+ addToAlreadyExecutedList(entity: TestableEntityState) {
4705
+ if (!this.executed.includes(entity)) {
4706
+ this.executed.push(entity);
4707
+ }
4708
+ }
4709
+
4710
+ addToSkippedList(entity: TestableEntityState) {
4711
+ if (!this.skipped.includes(entity)) {
4712
+ this.skipped.push(entity);
4713
+ this.onAddToSkippedListCallback?.(entity, {});
4714
+ }
4715
+ }
4716
+
4717
+ getValueTypePreference(
4718
+ valueOwnerId: EntityId
4719
+ ): DynamicValueTypes.DefaultValue | DynamicValueTypes.Testing | null {
4720
+ // Check local storage for preference
4721
+ const storedPreference =
4722
+ this.parentContext.getValueTypePreference(valueOwnerId);
4723
+
4724
+ return (
4725
+ (storedPreference as
4726
+ | DynamicValueTypes.DefaultValue
4727
+ | DynamicValueTypes.Testing) || null
4728
+ );
4729
+ }
4730
+
4731
+ setValueTypePreference(
4732
+ valueOwnerId: EntityId,
4733
+ valueTypePreference:
4734
+ | DynamicValueTypes.DefaultValue
4735
+ | DynamicValueTypes.Testing
4736
+ | null
4737
+ ) {
4738
+ // Store preference in local storage
4739
+ this.parentContext.setValueTypePreference(
4740
+ valueOwnerId,
4741
+ valueTypePreference
4742
+ );
4743
+
4744
+ // Emit event
4745
+ this.emit(valueOwnerId, {});
4746
+ }
4747
+ }