@codemation/host 0.0.1

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 (358) hide show
  1. package/README.md +75 -0
  2. package/dist/CodemationConfig-XCkSV2dj.d.ts +168 -0
  3. package/dist/CodemationConsumerConfigLoader-Dmm2TzAA.d.ts +61 -0
  4. package/dist/CodemationConsumerConfigLoader-scS_RQMy.js +334 -0
  5. package/dist/CodemationConsumerConfigLoader-scS_RQMy.js.map +1 -0
  6. package/dist/CodemationFrontendBootstrapRequest-CE6DjOWJ.js +5768 -0
  7. package/dist/CodemationFrontendBootstrapRequest-CE6DjOWJ.js.map +1 -0
  8. package/dist/CodemationPluginListMerger-BNmaoXQL.js +49 -0
  9. package/dist/CodemationPluginListMerger-BNmaoXQL.js.map +1 -0
  10. package/dist/CodemationPluginListMerger-BRYqEk0y.d.ts +793 -0
  11. package/dist/CodemationWhitelabelConfig-DgbjgtrR.d.ts +48 -0
  12. package/dist/ConsoleLogger-ClPU7jtc.js +35 -0
  13. package/dist/ConsoleLogger-ClPU7jtc.js.map +1 -0
  14. package/dist/CredentialServices-BKBGe7l3.js +1030 -0
  15. package/dist/CredentialServices-BKBGe7l3.js.map +1 -0
  16. package/dist/CredentialServices-DpDpm8mL.d.ts +291 -0
  17. package/dist/LogLevelPolicy-4cq9z0TI.d.ts +37 -0
  18. package/dist/PrismaMigrationDeployer-B1E_gYz7.js +8212 -0
  19. package/dist/PrismaMigrationDeployer-B1E_gYz7.js.map +1 -0
  20. package/dist/ServerLoggerFactory-BRHxIDS7.js +340 -0
  21. package/dist/ServerLoggerFactory-BRHxIDS7.js.map +1 -0
  22. package/dist/WorkflowViewContracts-DCLpTn25.d.ts +47 -0
  23. package/dist/chunk-7V6ThxGB.js +39 -0
  24. package/dist/client-Yh7-CQud.d.ts +21995 -0
  25. package/dist/client.d.ts +12 -0
  26. package/dist/client.js +15 -0
  27. package/dist/client.js.map +1 -0
  28. package/dist/consumer.d.ts +5 -0
  29. package/dist/consumer.js +7 -0
  30. package/dist/credentials.d.ts +50 -0
  31. package/dist/credentials.js +11 -0
  32. package/dist/credentials.js.map +1 -0
  33. package/dist/decorate-B-N_5S4p.js +10 -0
  34. package/dist/decorateParam-BTcc3KNk.js +15 -0
  35. package/dist/devServerSidecar.d.ts +52 -0
  36. package/dist/devServerSidecar.js +131 -0
  37. package/dist/devServerSidecar.js.map +1 -0
  38. package/dist/index-Bs4F1IsC.d.ts +1044 -0
  39. package/dist/index.d.ts +19 -0
  40. package/dist/index.js +14 -0
  41. package/dist/nextServer.d.ts +89 -0
  42. package/dist/nextServer.js +127 -0
  43. package/dist/nextServer.js.map +1 -0
  44. package/dist/persistenceServer-K5eqlZm3.d.ts +36 -0
  45. package/dist/persistenceServer-W9uRw0dJ.js +19 -0
  46. package/dist/persistenceServer-W9uRw0dJ.js.map +1 -0
  47. package/dist/persistenceServer.d.ts +6 -0
  48. package/dist/persistenceServer.js +6 -0
  49. package/dist/server-BBdsATju.d.ts +132 -0
  50. package/dist/server-BiHSuA13.js +175 -0
  51. package/dist/server-BiHSuA13.js.map +1 -0
  52. package/dist/server.d.ts +9 -0
  53. package/dist/server.js +13 -0
  54. package/package.json +152 -0
  55. package/playwright.config.ts +74 -0
  56. package/prisma/migrations/20260315063514_init/migration.sql +16 -0
  57. package/prisma/migrations/20260316090000_workflow_debugger_overlay/migration.sql +9 -0
  58. package/prisma/migrations/20260317120000_trigger_state_store/migration.sql +3 -0
  59. package/prisma/migrations/20260317153000_trigger_setup_state/migration.sql +8 -0
  60. package/prisma/migrations/20260318110000_credentials_v2/migration.sql +49 -0
  61. package/prisma/migrations/20260319110000_credential_oauth2_material/migration.sql +28 -0
  62. package/prisma/migrations/20260319200000_codemation_auth_tables/migration.sql +56 -0
  63. package/prisma/migrations/20260320140000_user_invites_account_status/migration.sql +20 -0
  64. package/prisma/migrations/20260325120000_workflow_activation/migration.sql +8 -0
  65. package/prisma/migrations/migration_lock.toml +3 -0
  66. package/prisma/schema.prisma +179 -0
  67. package/prisma.config.ts +12 -0
  68. package/scripts/ensure-prisma-runtime-sourcemaps.mjs +42 -0
  69. package/scripts/integration-database-global-setup.mjs +30 -0
  70. package/src/application/ApplicationRequestError.ts +12 -0
  71. package/src/application/auth/AuthenticatedPrincipal.ts +5 -0
  72. package/src/application/auth/SessionVerifier.ts +5 -0
  73. package/src/application/binary/OverlayPinnedBinaryUploadService.ts +119 -0
  74. package/src/application/binary/RunBinaryAttachmentLookupService.ts +139 -0
  75. package/src/application/binary/RunStateBinaryStorageKeysCollector.ts +57 -0
  76. package/src/application/bus/Command.ts +3 -0
  77. package/src/application/bus/CommandBus.ts +5 -0
  78. package/src/application/bus/CommandHandler.ts +5 -0
  79. package/src/application/bus/DomainEvent.ts +1 -0
  80. package/src/application/bus/DomainEventBus.ts +5 -0
  81. package/src/application/bus/DomainEventHandler.ts +5 -0
  82. package/src/application/bus/Query.ts +3 -0
  83. package/src/application/bus/QueryBus.ts +5 -0
  84. package/src/application/bus/QueryHandler.ts +5 -0
  85. package/src/application/commands/AcceptUserInviteCommand.ts +10 -0
  86. package/src/application/commands/AcceptUserInviteCommandHandler.ts +19 -0
  87. package/src/application/commands/CopyRunToWorkflowDebuggerCommand.ts +14 -0
  88. package/src/application/commands/CopyRunToWorkflowDebuggerCommandHandler.ts +56 -0
  89. package/src/application/commands/CreateCredentialInstanceCommand.ts +9 -0
  90. package/src/application/commands/CreateCredentialInstanceCommandHandler.ts +28 -0
  91. package/src/application/commands/CredentialCommandHandlers.ts +10 -0
  92. package/src/application/commands/DeleteCredentialInstanceCommand.ts +7 -0
  93. package/src/application/commands/DeleteCredentialInstanceCommandHandler.ts +27 -0
  94. package/src/application/commands/HandleWebhookInvocationCommand.ts +12 -0
  95. package/src/application/commands/HandleWebhookInvocationCommandHandler.ts +42 -0
  96. package/src/application/commands/InviteUserCommand.ts +12 -0
  97. package/src/application/commands/InviteUserCommandHandler.ts +22 -0
  98. package/src/application/commands/RegenerateUserInviteCommand.ts +12 -0
  99. package/src/application/commands/RegenerateUserInviteCommandHandler.ts +24 -0
  100. package/src/application/commands/ReplaceMutableRunWorkflowSnapshotCommand.ts +12 -0
  101. package/src/application/commands/ReplaceMutableRunWorkflowSnapshotCommandHandler.ts +47 -0
  102. package/src/application/commands/ReplaceWorkflowDebuggerOverlayCommand.ts +14 -0
  103. package/src/application/commands/ReplaceWorkflowDebuggerOverlayCommandHandler.ts +35 -0
  104. package/src/application/commands/ReplayWorkflowNodeCommand.ts +12 -0
  105. package/src/application/commands/ReplayWorkflowNodeCommandHandler.ts +164 -0
  106. package/src/application/commands/SetPinnedNodeInputCommand.ts +13 -0
  107. package/src/application/commands/SetPinnedNodeInputCommandHandler.ts +50 -0
  108. package/src/application/commands/SetWorkflowActivationCommand.ts +10 -0
  109. package/src/application/commands/SetWorkflowActivationCommandHandler.ts +39 -0
  110. package/src/application/commands/StartWorkflowRunCommand.ts +8 -0
  111. package/src/application/commands/StartWorkflowRunCommandHandler.ts +286 -0
  112. package/src/application/commands/TestCredentialInstanceCommand.ts +9 -0
  113. package/src/application/commands/TestCredentialInstanceCommandHandler.ts +28 -0
  114. package/src/application/commands/UpdateCredentialInstanceCommand.ts +12 -0
  115. package/src/application/commands/UpdateCredentialInstanceCommandHandler.ts +28 -0
  116. package/src/application/commands/UpdateUserAccountStatusCommand.ts +12 -0
  117. package/src/application/commands/UpdateUserAccountStatusCommandHandler.ts +24 -0
  118. package/src/application/commands/UploadOverlayPinnedBinaryCommand.ts +16 -0
  119. package/src/application/commands/UploadOverlayPinnedBinaryCommandHandler.ts +31 -0
  120. package/src/application/commands/UpsertCredentialBindingCommand.ts +11 -0
  121. package/src/application/commands/UpsertCredentialBindingCommandHandler.ts +28 -0
  122. package/src/application/commands/UpsertLocalBootstrapUserCommand.ts +12 -0
  123. package/src/application/commands/UpsertLocalBootstrapUserCommandHandler.ts +24 -0
  124. package/src/application/commands/UserAccountCommandHandlers.ts +10 -0
  125. package/src/application/contracts/CredentialContractsRegistry.ts +88 -0
  126. package/src/application/contracts/RunContracts.ts +41 -0
  127. package/src/application/contracts/WorkflowDebuggerContracts.ts +12 -0
  128. package/src/application/contracts/WorkflowViewContracts.ts +40 -0
  129. package/src/application/contracts/WorkflowWebsocketMessage.ts +8 -0
  130. package/src/application/contracts/userDirectoryContracts.types.ts +60 -0
  131. package/src/application/dev/BootRuntimeSnapshotHolder.ts +19 -0
  132. package/src/application/dev/BootRuntimeSummary.types.ts +11 -0
  133. package/src/application/dev/DevBootstrapSummaryAssembler.ts +84 -0
  134. package/src/application/dev/DevBootstrapSummaryJson.types.ts +9 -0
  135. package/src/application/logging/LogFilter.ts +7 -0
  136. package/src/application/logging/Logger.ts +10 -0
  137. package/src/application/mapping/DataMapper.ts +3 -0
  138. package/src/application/mapping/WorkflowDefinitionMapper.ts +171 -0
  139. package/src/application/mapping/WorkflowPolicyUiPresentationFactory.ts +39 -0
  140. package/src/application/queries/CredentialQueryHandlers.ts +12 -0
  141. package/src/application/queries/GetCredentialFieldEnvStatusQuery.ts +5 -0
  142. package/src/application/queries/GetCredentialFieldEnvStatusQueryHandler.ts +52 -0
  143. package/src/application/queries/GetCredentialInstanceQuery.ts +9 -0
  144. package/src/application/queries/GetCredentialInstanceQueryHandler.ts +27 -0
  145. package/src/application/queries/GetCredentialInstanceWithSecretsQuery.ts +9 -0
  146. package/src/application/queries/GetCredentialInstanceWithSecretsQueryHandler.ts +27 -0
  147. package/src/application/queries/GetRunBinaryAttachmentQuery.ts +11 -0
  148. package/src/application/queries/GetRunBinaryAttachmentQueryHandler.ts +23 -0
  149. package/src/application/queries/GetRunStateQuery.ts +8 -0
  150. package/src/application/queries/GetRunStateQueryHandler.ts +21 -0
  151. package/src/application/queries/GetWorkflowCredentialHealthQuery.ts +9 -0
  152. package/src/application/queries/GetWorkflowCredentialHealthQueryHandler.ts +27 -0
  153. package/src/application/queries/GetWorkflowDebuggerOverlayQuery.ts +8 -0
  154. package/src/application/queries/GetWorkflowDebuggerOverlayQueryHandler.ts +28 -0
  155. package/src/application/queries/GetWorkflowDetailQuery.ts +8 -0
  156. package/src/application/queries/GetWorkflowDetailQueryHandler.ts +24 -0
  157. package/src/application/queries/GetWorkflowOverlayBinaryAttachmentQuery.ts +11 -0
  158. package/src/application/queries/GetWorkflowOverlayBinaryAttachmentQueryHandler.ts +23 -0
  159. package/src/application/queries/GetWorkflowSummariesQuery.ts +4 -0
  160. package/src/application/queries/GetWorkflowSummariesQueryHandler.ts +23 -0
  161. package/src/application/queries/ListCredentialInstancesQuery.ts +5 -0
  162. package/src/application/queries/ListCredentialInstancesQueryHandler.ts +27 -0
  163. package/src/application/queries/ListCredentialTypesQuery.ts +5 -0
  164. package/src/application/queries/ListCredentialTypesQueryHandler.ts +28 -0
  165. package/src/application/queries/ListUserAccountsQuery.ts +5 -0
  166. package/src/application/queries/ListUserAccountsQueryHandler.ts +22 -0
  167. package/src/application/queries/ListWorkflowRunsQuery.ts +8 -0
  168. package/src/application/queries/ListWorkflowRunsQueryHandler.ts +21 -0
  169. package/src/application/queries/UserAccountQueryHandlers.ts +4 -0
  170. package/src/application/queries/VerifyUserInviteQuery.ts +9 -0
  171. package/src/application/queries/VerifyUserInviteQueryHandler.ts +21 -0
  172. package/src/application/runs/WorkflowRunRetentionPruneScheduler.ts +98 -0
  173. package/src/application/websocket/WorkflowRunEventWebsocketRelay.ts +36 -0
  174. package/src/application/websocket/WorkflowWebsocketPublisher.ts +5 -0
  175. package/src/application/workflows/WebhookEndpointPathValidator.ts +35 -0
  176. package/src/application/workflows/WorkflowDebuggerOverlayStateFactory.ts +122 -0
  177. package/src/applicationTokens.ts +72 -0
  178. package/src/bootstrap/CodemationBootstrapRequest.ts +27 -0
  179. package/src/bootstrap/CodemationContainerFactory.ts +310 -0
  180. package/src/bootstrap/CodemationContainerRegistration.ts +23 -0
  181. package/src/bootstrap/CodemationContainerRegistrationRegistrar.ts +42 -0
  182. package/src/bootstrap/CodemationFrontendBootstrapRequest.ts +16 -0
  183. package/src/bootstrap/CodemationWorkerBootstrapRequest.ts +19 -0
  184. package/src/bootstrap/PreparedCodemationRuntime.ts +37 -0
  185. package/src/bootstrap/PreparedCodemationRuntimeFactory.ts +308 -0
  186. package/src/bootstrap/boot/CliRuntimeBootService.ts +27 -0
  187. package/src/bootstrap/boot/FrontendRuntimeBootService.ts +86 -0
  188. package/src/bootstrap/boot/WorkerRuntimeBootService.ts +64 -0
  189. package/src/bootstrap/runtime/AppConfigFactory.ts +57 -0
  190. package/src/bootstrap/runtime/ResolvedImplementationSelectionFactory.ts +118 -0
  191. package/src/client.ts +3 -0
  192. package/src/codemationApplication.ts +311 -0
  193. package/src/consumer.ts +4 -0
  194. package/src/credentials.ts +24 -0
  195. package/src/devServerSidecar.ts +10 -0
  196. package/src/domain/credentials/CredentialBindingService.ts +139 -0
  197. package/src/domain/credentials/CredentialFieldEnvOverlayService.ts +60 -0
  198. package/src/domain/credentials/CredentialInstanceService.ts +391 -0
  199. package/src/domain/credentials/CredentialMaterialResolver.ts +55 -0
  200. package/src/domain/credentials/CredentialRuntimeMaterialService.ts +39 -0
  201. package/src/domain/credentials/CredentialSecretCipher.ts +70 -0
  202. package/src/domain/credentials/CredentialServices.ts +145 -0
  203. package/src/domain/credentials/CredentialSessionServiceImpl.ts +119 -0
  204. package/src/domain/credentials/CredentialTestService.ts +73 -0
  205. package/src/domain/credentials/CredentialTypeRegistryImpl.ts +29 -0
  206. package/src/domain/credentials/OAuth2ConnectServiceFactory.ts +396 -0
  207. package/src/domain/credentials/OAuth2ProviderRegistry.ts +75 -0
  208. package/src/domain/credentials/WorkflowCredentialNodeResolver.ts +246 -0
  209. package/src/domain/runs/WorkflowRunRepository.ts +11 -0
  210. package/src/domain/users/UserAccountServiceRegistry.ts +315 -0
  211. package/src/domain/users/userLoginMethodLabels.types.ts +29 -0
  212. package/src/domain/workflows/WorkflowActivationPreflight.ts +32 -0
  213. package/src/domain/workflows/WorkflowActivationPreflightRules.ts +77 -0
  214. package/src/domain/workflows/WorkflowActivationRepository.ts +9 -0
  215. package/src/domain/workflows/WorkflowDebuggerOverlayRepository.ts +7 -0
  216. package/src/domain/workflows/WorkflowDebuggerOverlayState.ts +8 -0
  217. package/src/domain/workflows/WorkflowDefinitionRepository.ts +11 -0
  218. package/src/index.ts +58 -0
  219. package/src/infrastructure/auth/AuthJsSessionVerifier.ts +26 -0
  220. package/src/infrastructure/auth/DevelopmentSessionBypassVerifier.ts +12 -0
  221. package/src/infrastructure/binary/BinaryBodyNodeReadableFactory.ts +22 -0
  222. package/src/infrastructure/binary/CountingSha256Transform.ts +26 -0
  223. package/src/infrastructure/binary/LocalFilesystemBinaryStorageRegistry.ts +86 -0
  224. package/src/infrastructure/config/CodemationPluginRegistrar.ts +44 -0
  225. package/src/infrastructure/credentials/FrameworkBuiltinCredentialTypesRegistrar.ts +21 -0
  226. package/src/infrastructure/credentials/OpenAiApiKeyCredentialHealthTester.ts +89 -0
  227. package/src/infrastructure/credentials/OpenAiApiKeyCredentialShapes.types.ts +15 -0
  228. package/src/infrastructure/credentials/OpenAiApiKeyCredentialTypeFactory.ts +47 -0
  229. package/src/infrastructure/di/HandlesCommandRegistry.ts +24 -0
  230. package/src/infrastructure/di/HandlesDomainEventRegistry.ts +24 -0
  231. package/src/infrastructure/di/HandlesQueryRegistry.ts +24 -0
  232. package/src/infrastructure/di/InMemoryCommandBus.ts +47 -0
  233. package/src/infrastructure/di/InMemoryDomainEventBus.ts +47 -0
  234. package/src/infrastructure/di/InMemoryQueryBus.ts +45 -0
  235. package/src/infrastructure/ids/CodemationIdFactory.ts +12 -0
  236. package/src/infrastructure/logging/BrowserLogger.ts +1 -0
  237. package/src/infrastructure/logging/BrowserLoggerFactory.ts +14 -0
  238. package/src/infrastructure/logging/ConsoleLogger.ts +41 -0
  239. package/src/infrastructure/logging/FilteringLogger.ts +38 -0
  240. package/src/infrastructure/logging/LogLevelPolicy.ts +148 -0
  241. package/src/infrastructure/logging/LogLevelPolicyFactory.ts +16 -0
  242. package/src/infrastructure/logging/PerformanceLogPolicy.ts +10 -0
  243. package/src/infrastructure/logging/PerformanceLogPolicyFactory.ts +14 -0
  244. package/src/infrastructure/logging/ServerLogger.ts +1 -0
  245. package/src/infrastructure/logging/ServerLoggerFactory.ts +28 -0
  246. package/src/infrastructure/persistence/CodemationPostgresPrismaClientFactory.ts +9 -0
  247. package/src/infrastructure/persistence/CredentialPersistenceStore.ts +139 -0
  248. package/src/infrastructure/persistence/DatabasePersistenceResolver.ts +91 -0
  249. package/src/infrastructure/persistence/InMemoryTriggerSetupStateRepository.ts +23 -0
  250. package/src/infrastructure/persistence/InMemoryWorkflowActivationRepository.ts +18 -0
  251. package/src/infrastructure/persistence/InMemoryWorkflowDebuggerOverlayRepository.ts +16 -0
  252. package/src/infrastructure/persistence/InMemoryWorkflowRunRepository.ts +94 -0
  253. package/src/infrastructure/persistence/PrismaClientFactory.ts +26 -0
  254. package/src/infrastructure/persistence/PrismaCredentialStore.ts +368 -0
  255. package/src/infrastructure/persistence/PrismaMigrationDeployer.ts +184 -0
  256. package/src/infrastructure/persistence/PrismaTriggerSetupStateRepository.ts +68 -0
  257. package/src/infrastructure/persistence/PrismaWorkflowActivationRepository.ts +36 -0
  258. package/src/infrastructure/persistence/PrismaWorkflowDebuggerOverlayRepository.ts +65 -0
  259. package/src/infrastructure/persistence/PrismaWorkflowRunRepository.ts +243 -0
  260. package/src/infrastructure/persistence/RuntimeWorkflowActivationPolicy.ts +27 -0
  261. package/src/infrastructure/persistence/SchedulerPersistenceCompatibilityValidator.ts +20 -0
  262. package/src/infrastructure/persistence/WorkflowDefinitionRepositoryAdapter.ts +31 -0
  263. package/src/infrastructure/persistence/WorkflowRunRepository.ts +46 -0
  264. package/src/infrastructure/persistence/generated/prisma/client.d.ts +1 -0
  265. package/src/infrastructure/persistence/generated/prisma/default.d.ts +1 -0
  266. package/src/infrastructure/persistence/generated/prisma/edge.d.ts +1 -0
  267. package/src/infrastructure/persistence/generated/prisma/index.d.ts +4766 -0
  268. package/src/infrastructure/persistence/generated/prisma/package.json +144 -0
  269. package/src/infrastructure/persistence/generated/prisma/query_compiler_fast_bg.wasm +0 -0
  270. package/src/infrastructure/persistence/generated/prisma/runtime/client.d.ts +3358 -0
  271. package/src/infrastructure/persistence/generated/prisma/runtime/index-browser.d.ts +90 -0
  272. package/src/infrastructure/persistence/generated/prisma/schema.prisma +35 -0
  273. package/src/infrastructure/persistence/generated/prisma/wasm-edge-light-loader.mjs +5 -0
  274. package/src/infrastructure/persistence/generated/prisma/wasm-worker-loader.mjs +5 -0
  275. package/src/infrastructure/persistence/generated/prisma-client/client.d.ts +1 -0
  276. package/src/infrastructure/persistence/generated/prisma-client/client.js +5 -0
  277. package/src/infrastructure/persistence/generated/prisma-client/default.d.ts +1 -0
  278. package/src/infrastructure/persistence/generated/prisma-client/default.js +5 -0
  279. package/src/infrastructure/persistence/generated/prisma-client/edge.d.ts +1 -0
  280. package/src/infrastructure/persistence/generated/prisma-client/edge.js +299 -0
  281. package/src/infrastructure/persistence/generated/prisma-client/index-browser.js +325 -0
  282. package/src/infrastructure/persistence/generated/prisma-client/index.d.ts +21623 -0
  283. package/src/infrastructure/persistence/generated/prisma-client/index.js +299 -0
  284. package/src/infrastructure/persistence/generated/prisma-client/package.json +144 -0
  285. package/src/infrastructure/persistence/generated/prisma-client/query_compiler_fast_bg.js +2 -0
  286. package/src/infrastructure/persistence/generated/prisma-client/query_compiler_fast_bg.wasm +0 -0
  287. package/src/infrastructure/persistence/generated/prisma-client/query_compiler_fast_bg.wasm-base64.js +2 -0
  288. package/src/infrastructure/persistence/generated/prisma-client/runtime/client.d.ts +3358 -0
  289. package/src/infrastructure/persistence/generated/prisma-client/runtime/client.js +86 -0
  290. package/src/infrastructure/persistence/generated/prisma-client/runtime/client.js.map +1 -0
  291. package/src/infrastructure/persistence/generated/prisma-client/runtime/index-browser.d.ts +90 -0
  292. package/src/infrastructure/persistence/generated/prisma-client/runtime/index-browser.js +6 -0
  293. package/src/infrastructure/persistence/generated/prisma-client/runtime/index-browser.js.map +1 -0
  294. package/src/infrastructure/persistence/generated/prisma-client/runtime/wasm-compiler-edge.js +76 -0
  295. package/src/infrastructure/persistence/generated/prisma-client/runtime/wasm-compiler-edge.js.map +1 -0
  296. package/src/infrastructure/persistence/generated/prisma-client/schema.prisma +179 -0
  297. package/src/infrastructure/persistence/generated/prisma-client/wasm-edge-light-loader.mjs +5 -0
  298. package/src/infrastructure/persistence/generated/prisma-client/wasm-worker-loader.mjs +5 -0
  299. package/src/infrastructure/runtime/LiveWorkflowRepository.ts +14 -0
  300. package/src/infrastructure/runtime/WorkerRuntimeScheduler.ts +35 -0
  301. package/src/infrastructure/server/http/ServerHttpRouteParams.ts +1 -0
  302. package/src/infrastructure/webhooks/RequestToWebhookItemMapper.ts +128 -0
  303. package/src/nextServer.ts +31 -0
  304. package/src/persistenceServer.ts +5 -0
  305. package/src/presentation/config/AppConfig.ts +25 -0
  306. package/src/presentation/config/CodemationAppContext.ts +19 -0
  307. package/src/presentation/config/CodemationApplicationFacade.ts +5 -0
  308. package/src/presentation/config/CodemationAuthConfig.ts +31 -0
  309. package/src/presentation/config/CodemationClassToken.ts +3 -0
  310. package/src/presentation/config/CodemationConfig.ts +86 -0
  311. package/src/presentation/config/CodemationConfigNormalizer.ts +179 -0
  312. package/src/presentation/config/CodemationLogConfig.ts +22 -0
  313. package/src/presentation/config/CodemationPackageManifest.ts +9 -0
  314. package/src/presentation/config/CodemationPlugin.ts +20 -0
  315. package/src/presentation/config/CodemationPluginListMerger.ts +46 -0
  316. package/src/presentation/config/CodemationWhitelabelConfig.ts +9 -0
  317. package/src/presentation/config/CodemationWorkflowDiscovery.ts +3 -0
  318. package/src/presentation/http/ApiPaths.ts +165 -0
  319. package/src/presentation/http/CodemationServerGatewayFactory.ts +120 -0
  320. package/src/presentation/http/HttpRequestJsonBodyReader.ts +12 -0
  321. package/src/presentation/http/ServerHttpErrorResponseFactory.ts +33 -0
  322. package/src/presentation/http/ServerHttpRouteParams.ts +1 -0
  323. package/src/presentation/http/hono/CodemationHonoApiAppFactory.ts +64 -0
  324. package/src/presentation/http/hono/HonoApiRouteRegistrar.ts +5 -0
  325. package/src/presentation/http/hono/HonoHttpAnonymousRoutePolicyRegistry.ts +27 -0
  326. package/src/presentation/http/hono/registrars/BinaryHonoApiRouteRegistrar.ts +21 -0
  327. package/src/presentation/http/hono/registrars/CredentialHonoApiRouteRegistrar.ts +34 -0
  328. package/src/presentation/http/hono/registrars/DevHonoApiRouteRegistrar.ts +17 -0
  329. package/src/presentation/http/hono/registrars/OAuth2HonoApiRouteRegistrar.ts +18 -0
  330. package/src/presentation/http/hono/registrars/RunHonoApiRouteRegistrar.ts +31 -0
  331. package/src/presentation/http/hono/registrars/UserHonoApiRouteRegistrar.ts +24 -0
  332. package/src/presentation/http/hono/registrars/WebhookHonoApiRouteRegistrar.ts +23 -0
  333. package/src/presentation/http/hono/registrars/WhitelabelHonoApiRouteRegistrar.ts +18 -0
  334. package/src/presentation/http/hono/registrars/WorkflowHonoApiRouteRegistrar.ts +33 -0
  335. package/src/presentation/http/routeHandlers/BinaryHttpRouteHandlerFactory.ts +101 -0
  336. package/src/presentation/http/routeHandlers/CredentialHttpRouteHandler.ts +129 -0
  337. package/src/presentation/http/routeHandlers/DevBootstrapSummaryHttpRouteHandler.ts +21 -0
  338. package/src/presentation/http/routeHandlers/OAuth2HttpRouteHandlerFactory.ts +129 -0
  339. package/src/presentation/http/routeHandlers/RunHttpRouteHandler.ts +82 -0
  340. package/src/presentation/http/routeHandlers/UserHttpRouteHandlerFactory.ts +109 -0
  341. package/src/presentation/http/routeHandlers/WebhookHttpRouteHandler.ts +42 -0
  342. package/src/presentation/http/routeHandlers/WhitelabelLogoHttpRouteHandler.ts +96 -0
  343. package/src/presentation/http/routeHandlers/WorkflowHttpRouteHandler.ts +104 -0
  344. package/src/presentation/server/CodemationConsumerAppResolver.ts +82 -0
  345. package/src/presentation/server/CodemationConsumerConfigExportsResolver.ts +33 -0
  346. package/src/presentation/server/CodemationConsumerConfigLoader.ts +270 -0
  347. package/src/presentation/server/CodemationPluginDiscovery.ts +151 -0
  348. package/src/presentation/server/CodemationTsyringeParamInfoReader.ts +26 -0
  349. package/src/presentation/server/CodemationTsyringeTypeInfoRegistrar.ts +121 -0
  350. package/src/presentation/server/DevelopmentRuntimeRouteGuard.ts +59 -0
  351. package/src/presentation/server/DiscoveredWorkflowsEmptyMessageFactory.ts +11 -0
  352. package/src/presentation/server/WorkflowDefinitionExportsResolver.ts +24 -0
  353. package/src/presentation/server/WorkflowDiscoveryPathSegmentsComputer.ts +53 -0
  354. package/src/presentation/server/WorkflowModulePathFinder.ts +47 -0
  355. package/src/presentation/websocket/WorkflowWebsocketServer.ts +169 -0
  356. package/src/server.ts +14 -0
  357. package/tsconfig.json +10 -0
  358. package/vitest.shared.ts +45 -0
@@ -0,0 +1,129 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import serialize from "serialize-javascript";
3
+ import { CredentialInstanceService } from "../../../domain/credentials/CredentialServices";
4
+ import { OAuth2ConnectService } from "../../../domain/credentials/OAuth2ConnectServiceFactory";
5
+ import { ServerHttpErrorResponseFactory } from "../ServerHttpErrorResponseFactory";
6
+
7
+ @injectable()
8
+ export class OAuth2HttpRouteHandler {
9
+ constructor(
10
+ @inject(OAuth2ConnectService)
11
+ private readonly oauth2ConnectService: OAuth2ConnectService,
12
+ @inject(CredentialInstanceService)
13
+ private readonly credentialInstanceService: CredentialInstanceService,
14
+ ) {}
15
+
16
+ async getAuthRedirect(request: Request): Promise<Response> {
17
+ try {
18
+ const url = new URL(request.url);
19
+ const instanceId = url.searchParams.get("instanceId")?.trim();
20
+ if (!instanceId) {
21
+ return Response.json({ error: "Missing instanceId query parameter." }, { status: 400 });
22
+ }
23
+ const redirect = await this.oauth2ConnectService.createAuthRedirect(
24
+ instanceId,
25
+ this.resolveRequestOrigin(request),
26
+ );
27
+ return Response.redirect(redirect.redirectUrl, 302);
28
+ } catch (error) {
29
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
30
+ }
31
+ }
32
+
33
+ async getCallback(request: Request): Promise<Response> {
34
+ try {
35
+ const url = new URL(request.url);
36
+ const result = await this.oauth2ConnectService.handleCallback({
37
+ code: url.searchParams.get("code"),
38
+ state: url.searchParams.get("state"),
39
+ requestOrigin: this.resolveRequestOrigin(request),
40
+ });
41
+ return new Response(this.createPopupHtml({ kind: "oauth2.connected", ...result }), {
42
+ headers: {
43
+ "content-type": "text/html; charset=utf-8",
44
+ },
45
+ });
46
+ } catch (error) {
47
+ const message = error instanceof Error ? error.message : String(error);
48
+ return new Response(this.createPopupHtml({ kind: "oauth2.error", message }), {
49
+ status: 400,
50
+ headers: {
51
+ "content-type": "text/html; charset=utf-8",
52
+ },
53
+ });
54
+ }
55
+ }
56
+
57
+ async getRedirectUri(request: Request): Promise<Response> {
58
+ try {
59
+ return Response.json({
60
+ redirectUri: this.oauth2ConnectService.getRedirectUri(this.resolveRequestOrigin(request)),
61
+ });
62
+ } catch (error) {
63
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
64
+ }
65
+ }
66
+
67
+ async postDisconnect(request: Request): Promise<Response> {
68
+ try {
69
+ const url = new URL(request.url);
70
+ const instanceId = url.searchParams.get("instanceId")?.trim();
71
+ if (!instanceId) {
72
+ return Response.json({ error: "Missing instanceId query parameter." }, { status: 400 });
73
+ }
74
+ return Response.json(await this.credentialInstanceService.disconnectOAuth2(instanceId));
75
+ } catch (error) {
76
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
77
+ }
78
+ }
79
+
80
+ private resolveRequestOrigin(request: Request): string {
81
+ const forwardedProto = OAuth2HttpRouteHandler.firstCommaSeparatedValue(request.headers.get("x-forwarded-proto"));
82
+ const forwardedHost = OAuth2HttpRouteHandler.firstCommaSeparatedValue(request.headers.get("x-forwarded-host"));
83
+ if (forwardedProto && forwardedHost) {
84
+ return `${forwardedProto}://${forwardedHost}`;
85
+ }
86
+ const host = OAuth2HttpRouteHandler.firstCommaSeparatedValue(request.headers.get("host"));
87
+ if (host) {
88
+ return `${new URL(request.url).protocol}//${host}`;
89
+ }
90
+ return new URL(request.url).origin;
91
+ }
92
+
93
+ /** Proxies may send comma-separated lists (chain); use the first host/proto only. */
94
+ private static firstCommaSeparatedValue(value: string | null | undefined): string | undefined {
95
+ const trimmed = value?.trim();
96
+ if (!trimmed) {
97
+ return undefined;
98
+ }
99
+ return trimmed.split(",")[0]?.trim();
100
+ }
101
+
102
+ /**
103
+ * Serialize popup payload for an inline script using `serialize-javascript`
104
+ * (Webpack / HTML plugin stack): escapes angle brackets, slashes, and Unicode line
105
+ * terminators so string values cannot break out of the script block.
106
+ */
107
+ private createPopupHtml(message: Readonly<Record<string, unknown>>): string {
108
+ const safeLiteral = serialize(message, { isJSON: true });
109
+ return `<!doctype html>
110
+ <html>
111
+ <head>
112
+ <meta charset="utf-8" />
113
+ <title>OAuth2 connection</title>
114
+ </head>
115
+ <body>
116
+ <script>
117
+ (function () {
118
+ const message = ${safeLiteral};
119
+ if (window.opener) {
120
+ window.opener.postMessage(message, window.location.origin);
121
+ }
122
+ window.close();
123
+ })();
124
+ </script>
125
+ <p>You can close this window.</p>
126
+ </body>
127
+ </html>`;
128
+ }
129
+ }
@@ -0,0 +1,82 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import { HttpRequestJsonBodyReader } from "../HttpRequestJsonBodyReader";
3
+ import type { CommandBus } from "../../../application/bus/CommandBus";
4
+ import type { QueryBus } from "../../../application/bus/QueryBus";
5
+ import { ReplaceMutableRunWorkflowSnapshotCommand } from "../../../application/commands/ReplaceMutableRunWorkflowSnapshotCommand";
6
+ import { ReplayWorkflowNodeCommand } from "../../../application/commands/ReplayWorkflowNodeCommand";
7
+ import { SetPinnedNodeInputCommand } from "../../../application/commands/SetPinnedNodeInputCommand";
8
+ import { StartWorkflowRunCommand } from "../../../application/commands/StartWorkflowRunCommand";
9
+ import type {
10
+ CreateRunRequest,
11
+ RunNodeRequest,
12
+ UpdateRunNodePinRequest,
13
+ UpdateRunWorkflowSnapshotRequest,
14
+ } from "../../../application/contracts/RunContracts";
15
+ import { GetRunStateQuery } from "../../../application/queries/GetRunStateQuery";
16
+ import { ApplicationTokens } from "../../../applicationTokens";
17
+ import { ServerHttpErrorResponseFactory } from "../ServerHttpErrorResponseFactory";
18
+ import type { ServerHttpRouteParams } from "../ServerHttpRouteParams";
19
+
20
+ @injectable()
21
+ export class RunHttpRouteHandler {
22
+ constructor(
23
+ @inject(ApplicationTokens.QueryBus)
24
+ private readonly queryBus: QueryBus,
25
+ @inject(ApplicationTokens.CommandBus)
26
+ private readonly commandBus: CommandBus,
27
+ ) {}
28
+
29
+ async getRun(_: Request, params: ServerHttpRouteParams): Promise<Response> {
30
+ try {
31
+ const state = await this.queryBus.execute(new GetRunStateQuery(params.runId!));
32
+ if (!state) {
33
+ return Response.json({ error: "Unknown runId" }, { status: 404 });
34
+ }
35
+ return Response.json(state);
36
+ } catch (error) {
37
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
38
+ }
39
+ }
40
+
41
+ async postRuns(request: Request, _: ServerHttpRouteParams): Promise<Response> {
42
+ try {
43
+ const body = await HttpRequestJsonBodyReader.readJsonBody<CreateRunRequest>(request);
44
+ return Response.json(await this.commandBus.execute(new StartWorkflowRunCommand(body)));
45
+ } catch (error) {
46
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
47
+ }
48
+ }
49
+
50
+ async patchRunWorkflowSnapshot(request: Request, params: ServerHttpRouteParams): Promise<Response> {
51
+ try {
52
+ const body = await HttpRequestJsonBodyReader.readJsonBody<UpdateRunWorkflowSnapshotRequest>(request);
53
+ return Response.json(
54
+ await this.commandBus.execute(new ReplaceMutableRunWorkflowSnapshotCommand(params.runId!, body)),
55
+ );
56
+ } catch (error) {
57
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
58
+ }
59
+ }
60
+
61
+ async patchRunNodePin(request: Request, params: ServerHttpRouteParams): Promise<Response> {
62
+ try {
63
+ const body = await HttpRequestJsonBodyReader.readJsonBody<UpdateRunNodePinRequest>(request);
64
+ return Response.json(
65
+ await this.commandBus.execute(new SetPinnedNodeInputCommand(params.runId!, params.nodeId!, body)),
66
+ );
67
+ } catch (error) {
68
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
69
+ }
70
+ }
71
+
72
+ async postRunNode(request: Request, params: ServerHttpRouteParams): Promise<Response> {
73
+ try {
74
+ const body = await HttpRequestJsonBodyReader.readJsonBody<RunNodeRequest>(request);
75
+ return Response.json(
76
+ await this.commandBus.execute(new ReplayWorkflowNodeCommand(params.runId!, params.nodeId!, body)),
77
+ );
78
+ } catch (error) {
79
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,109 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import { ApplicationRequestError } from "../../../application/ApplicationRequestError";
3
+ import type { CommandBus } from "../../../application/bus/CommandBus";
4
+ import type { QueryBus } from "../../../application/bus/QueryBus";
5
+ import {
6
+ AcceptUserInviteCommand,
7
+ InviteUserCommand,
8
+ RegenerateUserInviteCommand,
9
+ UpdateUserAccountStatusCommand,
10
+ } from "../../../application/commands/UserAccountCommandHandlers";
11
+ import type {
12
+ AcceptUserInviteRequestDto,
13
+ InviteUserRequestDto,
14
+ UpdateUserAccountStatusRequestDto,
15
+ } from "../../../application/contracts/userDirectoryContracts.types";
16
+ import { ListUserAccountsQuery, VerifyUserInviteQuery } from "../../../application/queries/UserAccountQueryHandlers";
17
+ import { ApplicationTokens } from "../../../applicationTokens";
18
+ import { ServerHttpErrorResponseFactory } from "../ServerHttpErrorResponseFactory";
19
+ import type { ServerHttpRouteParams } from "../ServerHttpRouteParams";
20
+
21
+ @injectable()
22
+ export class UserHttpRouteHandler {
23
+ constructor(
24
+ @inject(ApplicationTokens.QueryBus)
25
+ private readonly queryBus: QueryBus,
26
+ @inject(ApplicationTokens.CommandBus)
27
+ private readonly commandBus: CommandBus,
28
+ ) {}
29
+
30
+ async getUsers(): Promise<Response> {
31
+ try {
32
+ return Response.json(await this.queryBus.execute(new ListUserAccountsQuery()));
33
+ } catch (error) {
34
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
35
+ }
36
+ }
37
+
38
+ async getInviteVerify(request: Request): Promise<Response> {
39
+ try {
40
+ const url = new URL(request.url);
41
+ const token = url.searchParams.get("token") ?? "";
42
+ return Response.json(await this.queryBus.execute(new VerifyUserInviteQuery(token)));
43
+ } catch (error) {
44
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
45
+ }
46
+ }
47
+
48
+ async postInvite(request: Request): Promise<Response> {
49
+ try {
50
+ const body = await this.readJsonBody<InviteUserRequestDto>(request);
51
+ const origin = this.resolveRequestOrigin(request);
52
+ return Response.json(await this.commandBus.execute(new InviteUserCommand(body.email, origin)), { status: 201 });
53
+ } catch (error) {
54
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
55
+ }
56
+ }
57
+
58
+ async postRegenerateInvite(request: Request, params: ServerHttpRouteParams): Promise<Response> {
59
+ try {
60
+ const userId = params.userId!;
61
+ const origin = this.resolveRequestOrigin(request);
62
+ return Response.json(await this.commandBus.execute(new RegenerateUserInviteCommand(userId, origin)));
63
+ } catch (error) {
64
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
65
+ }
66
+ }
67
+
68
+ async postAcceptInvite(request: Request): Promise<Response> {
69
+ try {
70
+ const body = await this.readJsonBody<AcceptUserInviteRequestDto>(request);
71
+ await this.commandBus.execute(new AcceptUserInviteCommand(body.token, body.password));
72
+ return new Response(null, { status: 204 });
73
+ } catch (error) {
74
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
75
+ }
76
+ }
77
+
78
+ async patchUserStatus(request: Request, params: ServerHttpRouteParams): Promise<Response> {
79
+ try {
80
+ const body = await this.readJsonBody<UpdateUserAccountStatusRequestDto>(request);
81
+ return Response.json(
82
+ await this.commandBus.execute(new UpdateUserAccountStatusCommand(params.userId!, body.status)),
83
+ );
84
+ } catch (error) {
85
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
86
+ }
87
+ }
88
+
89
+ private resolveRequestOrigin(request: Request): string {
90
+ const forwardedProto = request.headers.get("x-forwarded-proto");
91
+ const forwardedHost = request.headers.get("x-forwarded-host");
92
+ if (forwardedProto?.trim() && forwardedHost?.trim()) {
93
+ const proto = forwardedProto.split(",")[0]!.trim();
94
+ const host = forwardedHost.split(",")[0]!.trim();
95
+ return `${proto}://${host}`;
96
+ }
97
+ const url = new URL(request.url);
98
+ return `${url.protocol}//${url.host}`;
99
+ }
100
+
101
+ private async readJsonBody<TBody>(request: Request): Promise<TBody> {
102
+ try {
103
+ return (await request.json()) as TBody;
104
+ } catch (error) {
105
+ const message = error instanceof Error ? error.message : String(error);
106
+ throw new ApplicationRequestError(400, `Invalid JSON body: ${message}`);
107
+ }
108
+ }
109
+ }
@@ -0,0 +1,42 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import { RunIntentService } from "@codemation/core/bootstrap";
3
+ import type { CommandBus } from "../../../application/bus/CommandBus";
4
+ import { HandleWebhookInvocationCommand } from "../../../application/commands/HandleWebhookInvocationCommand";
5
+ import { ApplicationTokens } from "../../../applicationTokens";
6
+ import { RequestToWebhookItemMapper } from "../../../infrastructure/webhooks/RequestToWebhookItemMapper";
7
+ import { ServerHttpErrorResponseFactory } from "../ServerHttpErrorResponseFactory";
8
+ import type { ServerHttpRouteParams } from "../ServerHttpRouteParams";
9
+
10
+ @injectable()
11
+ export class WebhookHttpRouteHandler {
12
+ constructor(
13
+ @inject(ApplicationTokens.CommandBus)
14
+ private readonly commandBus: CommandBus,
15
+ @inject(RunIntentService)
16
+ private readonly runIntentService: RunIntentService,
17
+ @inject(RequestToWebhookItemMapper)
18
+ private readonly requestToWebhookItemMapper: RequestToWebhookItemMapper,
19
+ ) {}
20
+
21
+ async postWebhook(request: Request, params: ServerHttpRouteParams): Promise<Response> {
22
+ try {
23
+ const endpointPath = decodeURIComponent(params.endpointPath ?? "");
24
+ const method = request.method.toUpperCase() as "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
25
+ const resolution = this.runIntentService.resolveWebhookTrigger({ endpointPath, method });
26
+ if (resolution.status === "notFound") {
27
+ return Response.json({ error: "Unknown webhook endpoint" }, { status: 404 });
28
+ }
29
+ if (resolution.status === "methodNotAllowed") {
30
+ return Response.json({ error: "Method not allowed" }, { status: 405 });
31
+ }
32
+ const requestItem = await this.requestToWebhookItemMapper.map(request, resolution.match);
33
+ return Response.json(
34
+ await this.commandBus.execute(
35
+ new HandleWebhookInvocationCommand(endpointPath, request.method.toUpperCase(), requestItem),
36
+ ),
37
+ );
38
+ } catch (error) {
39
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,96 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import { createReadStream, existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { Readable } from "node:stream";
5
+
6
+ import { ApplicationTokens } from "../../../applicationTokens";
7
+ import type { AppConfig } from "../../config/AppConfig";
8
+ import type { CodemationWhitelabelConfig } from "../../config/CodemationWhitelabelConfig";
9
+
10
+ @injectable()
11
+ export class WhitelabelLogoHttpRouteHandler {
12
+ constructor(
13
+ @inject(ApplicationTokens.AppConfig)
14
+ private readonly appConfig: AppConfig,
15
+ @inject(ApplicationTokens.CodemationWhitelabelConfig)
16
+ private readonly whitelabel: CodemationWhitelabelConfig,
17
+ ) {}
18
+
19
+ async getLogo(): Promise<Response> {
20
+ const consumerRootRaw = this.appConfig.consumerRoot.trim();
21
+ if (!consumerRootRaw || consumerRootRaw.length === 0) {
22
+ return new Response(null, { status: 404 });
23
+ }
24
+ const logoPath = this.whitelabel.logoPath?.trim();
25
+ if (!logoPath || logoPath.length === 0) {
26
+ return new Response(null, { status: 404 });
27
+ }
28
+ const consumerRoot = path.resolve(consumerRootRaw);
29
+ let consumerRootReal: string;
30
+ try {
31
+ consumerRootReal = await this.safeRealpath(consumerRoot);
32
+ } catch {
33
+ return new Response(null, { status: 404 });
34
+ }
35
+ const candidate = path.resolve(consumerRoot, logoPath);
36
+ let fileReal: string;
37
+ try {
38
+ fileReal = await this.safeRealpath(candidate);
39
+ } catch {
40
+ return new Response(null, { status: 404 });
41
+ }
42
+ if (!this.isPathInsideDirectory(consumerRootReal, fileReal)) {
43
+ return new Response(null, { status: 404 });
44
+ }
45
+ if (!existsSync(fileReal)) {
46
+ return new Response(null, { status: 404 });
47
+ }
48
+ const contentType = this.resolveContentType(fileReal);
49
+ const stream = createReadStream(fileReal);
50
+ const webStream = Readable.toWeb(stream) as ReadableStream<Uint8Array>;
51
+ return new Response(webStream, {
52
+ status: 200,
53
+ headers: {
54
+ "content-type": contentType,
55
+ "cache-control": "public, max-age=3600",
56
+ },
57
+ });
58
+ }
59
+
60
+ private async safeRealpath(p: string): Promise<string> {
61
+ const { realpath } = await import("node:fs/promises");
62
+ return await realpath(p);
63
+ }
64
+
65
+ private isPathInsideDirectory(directoryReal: string, fileReal: string): boolean {
66
+ const relative = path.relative(directoryReal, fileReal);
67
+ if (relative.length === 0) {
68
+ return false;
69
+ }
70
+ if (relative.startsWith(`..${path.sep}`) || relative === "..") {
71
+ return false;
72
+ }
73
+ return !path.isAbsolute(relative);
74
+ }
75
+
76
+ private resolveContentType(filePath: string): string {
77
+ const ext = path.extname(filePath).toLowerCase();
78
+ switch (ext) {
79
+ case ".svg":
80
+ return "image/svg+xml";
81
+ case ".png":
82
+ return "image/png";
83
+ case ".jpg":
84
+ case ".jpeg":
85
+ return "image/jpeg";
86
+ case ".webp":
87
+ return "image/webp";
88
+ case ".gif":
89
+ return "image/gif";
90
+ case ".ico":
91
+ return "image/x-icon";
92
+ default:
93
+ return "application/octet-stream";
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,104 @@
1
+ import { inject, injectable } from "@codemation/core";
2
+ import { HttpRequestJsonBodyReader } from "../HttpRequestJsonBodyReader";
3
+ import type { CommandBus } from "../../../application/bus/CommandBus";
4
+ import type { QueryBus } from "../../../application/bus/QueryBus";
5
+ import { CopyRunToWorkflowDebuggerCommand } from "../../../application/commands/CopyRunToWorkflowDebuggerCommand";
6
+ import { ReplaceWorkflowDebuggerOverlayCommand } from "../../../application/commands/ReplaceWorkflowDebuggerOverlayCommand";
7
+ import { SetWorkflowActivationCommand } from "../../../application/commands/SetWorkflowActivationCommand";
8
+ import type {
9
+ CopyRunToWorkflowDebuggerRequest,
10
+ UpdateWorkflowDebuggerOverlayRequest,
11
+ } from "../../../application/contracts/WorkflowDebuggerContracts";
12
+ import { WorkflowDefinitionMapper } from "../../../application/mapping/WorkflowDefinitionMapper";
13
+ import { GetWorkflowDebuggerOverlayQuery } from "../../../application/queries/GetWorkflowDebuggerOverlayQuery";
14
+ import { GetWorkflowDetailQuery } from "../../../application/queries/GetWorkflowDetailQuery";
15
+ import { GetWorkflowSummariesQuery } from "../../../application/queries/GetWorkflowSummariesQuery";
16
+ import { ListWorkflowRunsQuery } from "../../../application/queries/ListWorkflowRunsQuery";
17
+ import { ApplicationTokens } from "../../../applicationTokens";
18
+ import { ServerHttpErrorResponseFactory } from "../ServerHttpErrorResponseFactory";
19
+ import type { ServerHttpRouteParams } from "../ServerHttpRouteParams";
20
+
21
+ @injectable()
22
+ export class WorkflowHttpRouteHandler {
23
+ constructor(
24
+ @inject(ApplicationTokens.QueryBus)
25
+ private readonly queryBus: QueryBus,
26
+ @inject(ApplicationTokens.CommandBus)
27
+ private readonly commandBus: CommandBus,
28
+ @inject(WorkflowDefinitionMapper)
29
+ private readonly workflowDefinitionMapper: WorkflowDefinitionMapper,
30
+ ) {}
31
+
32
+ async getWorkflows(_: Request, __: ServerHttpRouteParams): Promise<Response> {
33
+ try {
34
+ const workflows = await this.queryBus.execute(new GetWorkflowSummariesQuery());
35
+ return Response.json(workflows.map((workflow) => this.workflowDefinitionMapper.toSummary(workflow)));
36
+ } catch (error) {
37
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
38
+ }
39
+ }
40
+
41
+ async getWorkflow(_: Request, params: ServerHttpRouteParams): Promise<Response> {
42
+ try {
43
+ const workflow = await this.queryBus.execute(new GetWorkflowDetailQuery(params.workflowId!));
44
+ if (!workflow) {
45
+ return Response.json({ error: "Unknown workflowId" }, { status: 404 });
46
+ }
47
+ return Response.json(await this.workflowDefinitionMapper.map(workflow));
48
+ } catch (error) {
49
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
50
+ }
51
+ }
52
+
53
+ async patchWorkflowActivation(request: Request, params: ServerHttpRouteParams): Promise<Response> {
54
+ try {
55
+ const body = await HttpRequestJsonBodyReader.readJsonBody<Readonly<{ active?: unknown }>>(request);
56
+ if (typeof body.active !== "boolean") {
57
+ return Response.json({ error: "Request body must include boolean active" }, { status: 400 });
58
+ }
59
+ return Response.json(
60
+ await this.commandBus.execute(new SetWorkflowActivationCommand(params.workflowId!, body.active)),
61
+ );
62
+ } catch (error) {
63
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
64
+ }
65
+ }
66
+
67
+ async getWorkflowRuns(_: Request, params: ServerHttpRouteParams): Promise<Response> {
68
+ try {
69
+ return Response.json(await this.queryBus.execute(new ListWorkflowRunsQuery(params.workflowId!)));
70
+ } catch (error) {
71
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
72
+ }
73
+ }
74
+
75
+ async getWorkflowDebuggerOverlay(_: Request, params: ServerHttpRouteParams): Promise<Response> {
76
+ try {
77
+ return Response.json(await this.queryBus.execute(new GetWorkflowDebuggerOverlayQuery(params.workflowId!)));
78
+ } catch (error) {
79
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
80
+ }
81
+ }
82
+
83
+ async putWorkflowDebuggerOverlay(request: Request, params: ServerHttpRouteParams): Promise<Response> {
84
+ try {
85
+ const body = await HttpRequestJsonBodyReader.readJsonBody<UpdateWorkflowDebuggerOverlayRequest>(request);
86
+ return Response.json(
87
+ await this.commandBus.execute(new ReplaceWorkflowDebuggerOverlayCommand(params.workflowId!, body)),
88
+ );
89
+ } catch (error) {
90
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
91
+ }
92
+ }
93
+
94
+ async postCopyWorkflowDebuggerOverlay(request: Request, params: ServerHttpRouteParams): Promise<Response> {
95
+ try {
96
+ const body = await HttpRequestJsonBodyReader.readJsonBody<CopyRunToWorkflowDebuggerRequest>(request);
97
+ return Response.json(
98
+ await this.commandBus.execute(new CopyRunToWorkflowDebuggerCommand(params.workflowId!, body)),
99
+ );
100
+ } catch (error) {
101
+ return ServerHttpErrorResponseFactory.fromUnknown(error);
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,82 @@
1
+ import type { WorkflowDefinition } from "@codemation/core";
2
+ import type { CodemationConfig } from "../config/CodemationConfig";
3
+ import { CodemationConfigNormalizer } from "../config/CodemationConfigNormalizer";
4
+ import { CodemationConsumerConfigExportsResolver } from "./CodemationConsumerConfigExportsResolver";
5
+ import { DiscoveredWorkflowsEmptyMessageFactory } from "./DiscoveredWorkflowsEmptyMessageFactory";
6
+ import { WorkflowDefinitionExportsResolver } from "./WorkflowDefinitionExportsResolver";
7
+
8
+ export type CodemationConsumerApp = Readonly<{
9
+ config: CodemationConfig;
10
+ workflowSources: ReadonlyArray<string>;
11
+ }>;
12
+
13
+ export class CodemationConsumerAppResolver {
14
+ private readonly configExportsResolver = new CodemationConsumerConfigExportsResolver();
15
+ private readonly configNormalizer = new CodemationConfigNormalizer();
16
+ private readonly workflowDefinitionExportsResolver = new WorkflowDefinitionExportsResolver();
17
+ private readonly discoveredWorkflowsEmptyMessageFactory = new DiscoveredWorkflowsEmptyMessageFactory();
18
+
19
+ resolve(
20
+ args: Readonly<{
21
+ configModule: Readonly<Record<string, unknown>>;
22
+ workflowModules: ReadonlyArray<Readonly<Record<string, unknown>>>;
23
+ workflowSourcePaths: ReadonlyArray<string>;
24
+ workflowDiscoveryPathSegmentsList?: ReadonlyArray<readonly string[]>;
25
+ }>,
26
+ ): CodemationConsumerApp {
27
+ const rawConfig = this.configExportsResolver.resolveConfig(args.configModule);
28
+ if (!rawConfig) {
29
+ throw new Error("Consumer app module does not export a Codemation config object.");
30
+ }
31
+ const config = this.configNormalizer.normalize(rawConfig);
32
+ const discoveredWorkflows = this.resolveDiscoveredWorkflows(
33
+ args.workflowModules,
34
+ args.workflowSourcePaths,
35
+ args.workflowDiscoveryPathSegmentsList,
36
+ );
37
+ return {
38
+ config: {
39
+ ...config,
40
+ workflows: this.mergeWorkflows(config.workflows ?? [], discoveredWorkflows),
41
+ },
42
+ workflowSources: args.workflowSourcePaths,
43
+ };
44
+ }
45
+
46
+ private resolveDiscoveredWorkflows(
47
+ workflowModules: ReadonlyArray<Readonly<Record<string, unknown>>>,
48
+ workflowSourcePaths: ReadonlyArray<string>,
49
+ workflowDiscoveryPathSegmentsList: ReadonlyArray<readonly string[]> | undefined,
50
+ ): ReadonlyArray<WorkflowDefinition> {
51
+ const workflowsById = new Map<string, WorkflowDefinition>();
52
+ workflowModules.forEach((workflowModule: Readonly<Record<string, unknown>>, index: number) => {
53
+ const pathSegments = workflowDiscoveryPathSegmentsList?.[index];
54
+ const workflows = this.workflowDefinitionExportsResolver.resolve(workflowModule);
55
+ workflows.forEach((workflow: WorkflowDefinition) => {
56
+ const enriched =
57
+ pathSegments && pathSegments.length > 0
58
+ ? ({ ...workflow, discoveryPathSegments: pathSegments } satisfies WorkflowDefinition)
59
+ : workflow;
60
+ workflowsById.set(workflow.id, enriched);
61
+ });
62
+ });
63
+ if (workflowsById.size === 0 && workflowSourcePaths.length > 0) {
64
+ throw new Error(this.discoveredWorkflowsEmptyMessageFactory.create(workflowSourcePaths));
65
+ }
66
+ return [...workflowsById.values()];
67
+ }
68
+
69
+ private mergeWorkflows(
70
+ configuredWorkflows: ReadonlyArray<WorkflowDefinition>,
71
+ discoveredWorkflows: ReadonlyArray<WorkflowDefinition>,
72
+ ): ReadonlyArray<WorkflowDefinition> {
73
+ const workflowsById = new Map<string, WorkflowDefinition>();
74
+ for (const workflow of discoveredWorkflows) {
75
+ workflowsById.set(workflow.id, workflow);
76
+ }
77
+ for (const workflow of configuredWorkflows) {
78
+ workflowsById.set(workflow.id, workflow);
79
+ }
80
+ return [...workflowsById.values()];
81
+ }
82
+ }
@@ -0,0 +1,33 @@
1
+ import type { CodemationConfig } from "../config/CodemationConfig";
2
+
3
+ export class CodemationConsumerConfigExportsResolver {
4
+ resolveConfig(moduleExports: Readonly<Record<string, unknown>>): CodemationConfig | null {
5
+ const defaultExport = moduleExports.default;
6
+ if (this.isConfig(defaultExport)) {
7
+ return defaultExport;
8
+ }
9
+ const namedConfig = moduleExports.codemationHost ?? moduleExports.config;
10
+ if (this.isConfig(namedConfig)) {
11
+ return namedConfig;
12
+ }
13
+ return null;
14
+ }
15
+
16
+ private isConfig(value: unknown): value is CodemationConfig {
17
+ if (!value || typeof value !== "object") {
18
+ return false;
19
+ }
20
+ return (
21
+ "app" in value ||
22
+ "register" in value ||
23
+ "credentials" in value ||
24
+ "runtime" in value ||
25
+ "workflows" in value ||
26
+ "workflowDiscovery" in value ||
27
+ "plugins" in value ||
28
+ "whitelabel" in value ||
29
+ "auth" in value ||
30
+ "log" in value
31
+ );
32
+ }
33
+ }