@codemation/host 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{AppConfigFactory-BiFHnorf.d.ts → AppConfigFactory-DHdAGOmC.d.ts} +3 -3
  3. package/dist/{AppContainerFactory-BRU02PTm.js → AppContainerFactory-BKaAUIi-.js} +91 -27
  4. package/dist/AppContainerFactory-BKaAUIi-.js.map +1 -0
  5. package/dist/{CodemationConfig-DuGk7uN5.d.ts → CodemationConfig-DBbMU3HB.d.ts} +2 -2
  6. package/dist/{CodemationConfigNormalizer-BP2-0ZDE.d.ts → CodemationConfigNormalizer-C8wC0skq.d.ts} +2 -2
  7. package/dist/{CodemationConsumerConfigLoader-D5CSz3TQ.d.ts → CodemationConsumerConfigLoader-Ceh6sB3X.d.ts} +3 -2
  8. package/dist/{CodemationConsumerConfigLoader-C_ISRrpI.js → CodemationConsumerConfigLoader-D6LFSlp5.js} +20 -7
  9. package/dist/CodemationConsumerConfigLoader-D6LFSlp5.js.map +1 -0
  10. package/dist/{CodemationPluginListMerger-DFzGgfyI.d.ts → CodemationPluginListMerger-Cx9DnyR-.d.ts} +5 -5
  11. package/dist/{CredentialServices-Bhejvys-.d.ts → CredentialServices-CYETzKyb.d.ts} +14 -5
  12. package/dist/{CredentialServices-xVxVA9Tq.js → CredentialServices-D8BBZH1i.js} +40 -6
  13. package/dist/CredentialServices-D8BBZH1i.js.map +1 -0
  14. package/dist/{PublicFrontendBootstrapFactory-CSgWyTra.d.ts → PublicFrontendBootstrapFactory-DeMjp3cs.d.ts} +5 -2
  15. package/dist/consumer.d.ts +4 -4
  16. package/dist/consumer.js +1 -1
  17. package/dist/credentials.d.ts +3 -3
  18. package/dist/credentials.js +1 -1
  19. package/dist/devServerSidecar.d.ts +1 -1
  20. package/dist/{index-BQaZZmOm.d.ts → index-dK05sTQ4.d.ts} +50 -60
  21. package/dist/index.d.ts +97 -12
  22. package/dist/index.js +4 -4
  23. package/dist/nextServer.d.ts +16 -8
  24. package/dist/nextServer.js +2 -2
  25. package/dist/{persistenceServer-fdldtXJH.d.ts → persistenceServer-D9vUTMqc.d.ts} +2 -2
  26. package/dist/persistenceServer.d.ts +5 -5
  27. package/dist/{server-ChTCEc6R.js → server-C-WZcsId.js} +5 -6
  28. package/dist/{server-ChTCEc6R.js.map → server-C-WZcsId.js.map} +1 -1
  29. package/dist/{server-Cpzpy1Ar.d.ts → server-fxqY2WEi.d.ts} +5 -5
  30. package/dist/server.d.ts +8 -8
  31. package/dist/server.js +4 -4
  32. package/package.json +6 -5
  33. package/playwright.config.ts +10 -6
  34. package/src/application/contracts/WorkflowViewContracts.ts +3 -0
  35. package/src/application/mapping/WorkflowDefinitionMapper.ts +117 -19
  36. package/src/bootstrap/AppContainerFactory.ts +2 -0
  37. package/src/domain/credentials/CredentialInstanceService.ts +8 -1
  38. package/src/domain/credentials/CredentialOAuth2ScopeResolver.ts +61 -0
  39. package/src/domain/credentials/CredentialServices.ts +1 -0
  40. package/src/domain/credentials/OAuth2ConnectServiceFactory.ts +9 -2
  41. package/src/presentation/http/routeHandlers/CredentialHttpRouteHandler.ts +2 -1
  42. package/src/presentation/http/routeHandlers/WorkflowHttpRouteHandler.ts +4 -2
  43. package/src/presentation/server/CodemationConsumerConfigLoader.ts +28 -5
  44. package/src/presentation/server/CodemationPluginDiscovery.ts +4 -6
  45. package/dist/AppContainerFactory-BRU02PTm.js.map +0 -1
  46. package/dist/CodemationConsumerConfigLoader-C_ISRrpI.js.map +0 -1
  47. package/dist/CredentialServices-xVxVA9Tq.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @codemation/host
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#60](https://github.com/MadeRelevant/codemation/pull/60) [`056c045`](https://github.com/MadeRelevant/codemation/commit/056c045d7813e7e6b749f0dc03bb43855ff7f58c) Thanks [@cblokland90](https://github.com/cblokland90)! - Harden the Gmail plugin so it imports reliably from the package root, returns an authenticated official Gmail session, and supports trigger/read/send/reply/label workflows with one OAuth credential.
8
+
9
+ Add framework support for OAuth scope presets and custom per-credential scope replacement, and update the plugin starter/docs so future plugins scaffold the same publishable root-entrypoint conventions.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [[`056c045`](https://github.com/MadeRelevant/codemation/commit/056c045d7813e7e6b749f0dc03bb43855ff7f58c)]:
14
+ - @codemation/core@0.5.0
15
+ - @codemation/core-nodes@0.1.1
16
+ - @codemation/eventbus-redis@0.0.27
17
+
18
+ ## 0.1.7
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [[`35b78bb`](https://github.com/MadeRelevant/codemation/commit/35b78bb4d8c7ee2998a8b8e51e5ffc3fd901e4c7), [`eb97e53`](https://github.com/MadeRelevant/codemation/commit/eb97e5376f4f620099c32c14d7797ed3039bf7bb)]:
23
+ - @codemation/core@0.4.0
24
+ - @codemation/core-nodes@0.1.0
25
+ - @codemation/eventbus-redis@0.0.26
26
+
3
27
  ## 0.1.6
4
28
 
5
29
  ### Patch Changes
@@ -1,5 +1,5 @@
1
- import { _ as AppPersistenceConfig, g as AppConfig } from "./CodemationConfig-DuGk7uN5.js";
2
- import { t as NormalizedCodemationConfig } from "./CodemationConfigNormalizer-BP2-0ZDE.js";
1
+ import { _ as AppPersistenceConfig, g as AppConfig } from "./CodemationConfig-DBbMU3HB.js";
2
+ import { t as NormalizedCodemationConfig } from "./CodemationConfigNormalizer-C8wC0skq.js";
3
3
  import { AnyNull, AnyNullClass, DbNull, DbNullClass, Decimal, JsonNull, JsonNullClass, NullTypes as NullTypes$1, ObjectEnumValue, PrismaClientInitializationError, PrismaClientKnownRequestError, PrismaClientRustPanicError, PrismaClientUnknownRequestError, PrismaClientValidationError, RawValue, Sql, Value, empty, isAnyNull, isDbNull, isJsonNull, isObjectEnumValue, join, raw, sql as sqltag } from "@prisma/client-runtime-utils";
4
4
 
5
5
  //#region src/infrastructure/persistence/generated/prisma-postgresql-client/runtime/client.d.ts
@@ -28903,4 +28903,4 @@ declare class AppConfigFactory {
28903
28903
  }
28904
28904
  //#endregion
28905
28905
  export { PrismaClient as i, PrismaMigrationDeployer as n, PrismaDatabaseClient as r, AppConfigFactory as t };
28906
- //# sourceMappingURL=AppConfigFactory-BiFHnorf.d.ts.map
28906
+ //# sourceMappingURL=AppConfigFactory-DHdAGOmC.d.ts.map
@@ -2,7 +2,7 @@ import { i as __toESM, r as __require, t as __commonJS } from "./chunk-7V6ThxGB.
2
2
  import { o as LogLevelPolicyFactory, s as logLevelPolicyFactory, t as ServerLoggerFactory } from "./ServerLoggerFactory-BltIIDfQ.js";
3
3
  import { n as __decorateMetadata, t as __decorateParam } from "./decorateParam-DrsXNPuw.js";
4
4
  import { t as __decorate } from "./decorate-B0PP651O.js";
5
- import { a as CredentialInstanceService, c as CredentialFieldEnvOverlayService, d as ApplicationRequestError, f as CredentialTypeRegistryImpl, i as CredentialBindingService, l as WorkflowCredentialNodeResolver, m as OpenAiApiKeyCredentialHealthTester, n as CredentialSessionServiceImpl, o as CredentialMaterialResolver, p as OpenAiApiKeyCredentialTypeFactory, r as CredentialRuntimeMaterialService, s as CredentialSecretCipher, t as CredentialTestService, u as ApplicationTokens } from "./CredentialServices-xVxVA9Tq.js";
5
+ import { a as CredentialInstanceService, c as CredentialSecretCipher, d as ApplicationTokens, f as ApplicationRequestError, h as OpenAiApiKeyCredentialHealthTester, i as CredentialBindingService, l as CredentialFieldEnvOverlayService, m as OpenAiApiKeyCredentialTypeFactory, n as CredentialSessionServiceImpl, o as CredentialOAuth2ScopeResolver, p as CredentialTypeRegistryImpl, r as CredentialRuntimeMaterialService, s as CredentialMaterialResolver, t as CredentialTestService, u as WorkflowCredentialNodeResolver } from "./CredentialServices-D8BBZH1i.js";
6
6
  import { i as require_client$2, r as PrismaMigrationDeployer } from "./AppConfigFactory-ByT1D8dM.js";
7
7
  import { mkdir, rm, stat } from "node:fs/promises";
8
8
  import path from "node:path";
@@ -2080,13 +2080,13 @@ OAuth2ProviderRegistry = _OAuth2ProviderRegistry = __decorate([injectable()], OA
2080
2080
 
2081
2081
  //#endregion
2082
2082
  //#region src/domain/credentials/OAuth2ConnectServiceFactory.ts
2083
- var _ref$33, _ref2$9, _ref3$4, _ref4$2, _ref5$1, _ref6, _ref7, _OAuth2ConnectService;
2083
+ var _ref$33, _ref2$9, _ref3$4, _ref4$2, _ref5$1, _ref6, _ref7, _ref8, _OAuth2ConnectService;
2084
2084
  let OAuth2ConnectService = class OAuth2ConnectService$1 {
2085
2085
  static {
2086
2086
  _OAuth2ConnectService = this;
2087
2087
  }
2088
2088
  static stateTtlMs = 600 * 1e3;
2089
- constructor(credentialStore, credentialInstanceService, credentialTypeRegistry, credentialRuntimeMaterialService, credentialFieldEnvOverlayService, credentialMaterialResolver, credentialSecretCipher, oauth2ProviderRegistry, appConfig) {
2089
+ constructor(credentialStore, credentialInstanceService, credentialTypeRegistry, credentialRuntimeMaterialService, credentialFieldEnvOverlayService, credentialMaterialResolver, credentialSecretCipher, credentialOAuth2ScopeResolver, oauth2ProviderRegistry, appConfig) {
2090
2090
  this.credentialStore = credentialStore;
2091
2091
  this.credentialInstanceService = credentialInstanceService;
2092
2092
  this.credentialTypeRegistry = credentialTypeRegistry;
@@ -2094,6 +2094,7 @@ let OAuth2ConnectService = class OAuth2ConnectService$1 {
2094
2094
  this.credentialFieldEnvOverlayService = credentialFieldEnvOverlayService;
2095
2095
  this.credentialMaterialResolver = credentialMaterialResolver;
2096
2096
  this.credentialSecretCipher = credentialSecretCipher;
2097
+ this.credentialOAuth2ScopeResolver = credentialOAuth2ScopeResolver;
2097
2098
  this.oauth2ProviderRegistry = oauth2ProviderRegistry;
2098
2099
  this.appConfig = appConfig;
2099
2100
  }
@@ -2107,6 +2108,7 @@ let OAuth2ConnectService = class OAuth2ConnectService$1 {
2107
2108
  material: emptyMaterial
2108
2109
  });
2109
2110
  const provider = this.oauth2ProviderRegistry.resolve(credentialType.definition, resolvedPublicConfig);
2111
+ const requestedScopes = this.credentialOAuth2ScopeResolver.resolveRequestedScopes(credentialType.definition.auth, resolvedPublicConfig);
2110
2112
  const redirectUri = this.getRedirectUri(requestOrigin);
2111
2113
  const state = this.createOpaqueValue();
2112
2114
  const codeVerifier = this.createOpaqueValue();
@@ -2118,7 +2120,7 @@ let OAuth2ConnectService = class OAuth2ConnectService$1 {
2118
2120
  instanceId,
2119
2121
  codeVerifier,
2120
2122
  providerId: provider.providerId,
2121
- requestedScopes: credentialType.definition.auth.scopes,
2123
+ requestedScopes,
2122
2124
  createdAt: createdAt.toISOString(),
2123
2125
  expiresAt: expiresAt.toISOString()
2124
2126
  });
@@ -2126,7 +2128,7 @@ let OAuth2ConnectService = class OAuth2ConnectService$1 {
2126
2128
  authorizeUrl.searchParams.set("response_type", "code");
2127
2129
  authorizeUrl.searchParams.set("client_id", this.oauth2ProviderRegistry.resolveClientId(credentialType.definition.auth, resolvedPublicConfig));
2128
2130
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
2129
- authorizeUrl.searchParams.set("scope", credentialType.definition.auth.scopes.join(" "));
2131
+ authorizeUrl.searchParams.set("scope", requestedScopes.join(" "));
2130
2132
  authorizeUrl.searchParams.set("state", state);
2131
2133
  authorizeUrl.searchParams.set("code_challenge", codeChallenge);
2132
2134
  authorizeUrl.searchParams.set("code_challenge_method", "S256");
@@ -2324,8 +2326,9 @@ OAuth2ConnectService = _OAuth2ConnectService = __decorate([
2324
2326
  __decorateParam(4, inject(CredentialFieldEnvOverlayService)),
2325
2327
  __decorateParam(5, inject(CredentialMaterialResolver)),
2326
2328
  __decorateParam(6, inject(CredentialSecretCipher)),
2327
- __decorateParam(7, inject(OAuth2ProviderRegistry)),
2328
- __decorateParam(8, inject(ApplicationTokens.AppConfig)),
2329
+ __decorateParam(7, inject(CredentialOAuth2ScopeResolver)),
2330
+ __decorateParam(8, inject(OAuth2ProviderRegistry)),
2331
+ __decorateParam(9, inject(ApplicationTokens.AppConfig)),
2329
2332
  __decorateMetadata("design:paramtypes", [
2330
2333
  Object,
2331
2334
  typeof (_ref$33 = typeof CredentialInstanceService !== "undefined" && CredentialInstanceService) === "function" ? _ref$33 : Object,
@@ -2334,7 +2337,8 @@ OAuth2ConnectService = _OAuth2ConnectService = __decorate([
2334
2337
  typeof (_ref4$2 = typeof CredentialFieldEnvOverlayService !== "undefined" && CredentialFieldEnvOverlayService) === "function" ? _ref4$2 : Object,
2335
2338
  typeof (_ref5$1 = typeof CredentialMaterialResolver !== "undefined" && CredentialMaterialResolver) === "function" ? _ref5$1 : Object,
2336
2339
  typeof (_ref6 = typeof CredentialSecretCipher !== "undefined" && CredentialSecretCipher) === "function" ? _ref6 : Object,
2337
- typeof (_ref7 = typeof OAuth2ProviderRegistry !== "undefined" && OAuth2ProviderRegistry) === "function" ? _ref7 : Object,
2340
+ typeof (_ref7 = typeof CredentialOAuth2ScopeResolver !== "undefined" && CredentialOAuth2ScopeResolver) === "function" ? _ref7 : Object,
2341
+ typeof (_ref8 = typeof OAuth2ProviderRegistry !== "undefined" && OAuth2ProviderRegistry) === "function" ? _ref8 : Object,
2338
2342
  Object
2339
2343
  ])
2340
2344
  ], OAuth2ConnectService);
@@ -2494,13 +2498,14 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2494
2498
  return this.mapSync(workflow);
2495
2499
  }
2496
2500
  mapSync(workflow) {
2501
+ const mapped = this.mapNodesAndEdges(workflow);
2497
2502
  return {
2498
2503
  id: workflow.id,
2499
2504
  name: workflow.name,
2500
2505
  active: this.workflowActivationPolicy.isActive(workflow.id),
2501
2506
  hasWorkflowErrorHandler: this.policyUi.workflowHasErrorHandler(workflow),
2502
- nodes: this.toNodes(workflow),
2503
- edges: this.toEdges(workflow)
2507
+ nodes: mapped.nodes,
2508
+ edges: mapped.edges
2504
2509
  };
2505
2510
  }
2506
2511
  toSummary(workflow) {
@@ -2519,17 +2524,40 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2519
2524
  });
2520
2525
  return map;
2521
2526
  }
2522
- toNodes(workflow) {
2527
+ mapNodesAndEdges(workflow) {
2523
2528
  const connectionChildMeta = this.buildConnectionChildMeta(workflow);
2524
2529
  const materializedConnectionNodeIds = new Set(connectionChildMeta.keys());
2530
+ const nodesById = new Map(workflow.nodes.map((node) => [node.id, node]));
2531
+ const agentConnectionDescriptors = this.buildAgentConnectionDescriptorIndex(workflow);
2532
+ return {
2533
+ nodes: this.toNodes({
2534
+ workflow,
2535
+ connectionChildMeta,
2536
+ materializedConnectionNodeIds,
2537
+ nodesById,
2538
+ agentConnectionDescriptors
2539
+ }),
2540
+ edges: this.toEdges({
2541
+ workflow,
2542
+ materializedConnectionNodeIds,
2543
+ agentConnectionDescriptors
2544
+ })
2545
+ };
2546
+ }
2547
+ toNodes(args) {
2548
+ const workflow = args.workflow;
2549
+ const connectionChildMeta = args.connectionChildMeta;
2550
+ const materializedConnectionNodeIds = args.materializedConnectionNodeIds;
2551
+ const nodesById = args.nodesById;
2552
+ const agentConnectionDescriptors = args.agentConnectionDescriptors;
2525
2553
  const nodes = [];
2526
2554
  for (const node of workflow.nodes) {
2527
2555
  const conn = connectionChildMeta.get(node.id);
2528
2556
  if (conn) {
2529
- const parentNode = workflow.nodes.find((n) => n.id === conn.parentNodeId);
2557
+ const parentNode = nodesById.get(conn.parentNodeId);
2530
2558
  let role = conn.connectionName === "llm" ? "languageModel" : "tool";
2531
2559
  if (parentNode && AgentConfigInspector.isAgentNodeConfig(parentNode.config)) {
2532
- const descriptor = AgentConnectionNodeCollector.collect(conn.parentNodeId, parentNode.config).find((d) => d.nodeId === node.id);
2560
+ const descriptor = agentConnectionDescriptors.byChildNodeIdByAgentNodeId.get(conn.parentNodeId)?.get(node.id);
2533
2561
  if (descriptor) role = descriptor.role;
2534
2562
  }
2535
2563
  nodes.push({
@@ -2541,6 +2569,7 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2541
2569
  icon: node.config?.icon,
2542
2570
  retryPolicySummary: this.policyUi.nodeRetrySummary(node.config),
2543
2571
  hasNodeErrorHandler: this.policyUi.nodeHasErrorHandler(node.config),
2572
+ ...this.nodePortFieldsFromConfig(node.config),
2544
2573
  parentNodeId: conn.parentNodeId
2545
2574
  });
2546
2575
  continue;
@@ -2553,21 +2582,23 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2553
2582
  role: AgentConfigInspector.isAgentNodeConfig(node.config) ? "agent" : "workflowNode",
2554
2583
  icon: node.config?.icon,
2555
2584
  retryPolicySummary: this.policyUi.nodeRetrySummary(node.config),
2556
- hasNodeErrorHandler: this.policyUi.nodeHasErrorHandler(node.config)
2585
+ hasNodeErrorHandler: this.policyUi.nodeHasErrorHandler(node.config),
2586
+ ...this.nodePortFieldsFromConfig(node.config)
2557
2587
  });
2558
- if (AgentConfigInspector.isAgentNodeConfig(node.config)) this.appendVirtualConnectionNodes(node.id, node.config, materializedConnectionNodeIds, nodes);
2588
+ if (AgentConfigInspector.isAgentNodeConfig(node.config)) this.appendVirtualConnectionNodes(materializedConnectionNodeIds, nodes, agentConnectionDescriptors.byAgentNodeId.get(node.id) ?? []);
2559
2589
  }
2560
2590
  return nodes;
2561
2591
  }
2562
- toEdges(workflow) {
2563
- const connectionChildMeta = this.buildConnectionChildMeta(workflow);
2564
- const materializedConnectionNodeIds = new Set(connectionChildMeta.keys());
2592
+ toEdges(args) {
2593
+ const workflow = args.workflow;
2594
+ const materializedConnectionNodeIds = args.materializedConnectionNodeIds;
2595
+ const agentConnectionDescriptors = args.agentConnectionDescriptors;
2565
2596
  const edges = [...workflow.edges];
2566
2597
  const edgeKeys = new Set(edges.map((edge) => this.edgeKey(edge.from.nodeId, edge.to.nodeId, edge.to.input)));
2567
2598
  this.appendMaterializedConnectionEdges(workflow, edgeKeys, edges);
2568
2599
  for (const node of workflow.nodes) {
2569
2600
  if (!AgentConfigInspector.isAgentNodeConfig(node.config)) continue;
2570
- this.appendVirtualConnectionEdges(node.id, node.config, materializedConnectionNodeIds, edgeKeys, edges);
2601
+ this.appendVirtualConnectionEdges(materializedConnectionNodeIds, edgeKeys, edges, agentConnectionDescriptors.byAgentNodeId.get(node.id) ?? []);
2571
2602
  }
2572
2603
  return edges;
2573
2604
  }
@@ -2588,14 +2619,30 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2588
2619
  edgeKeys.add(key);
2589
2620
  }
2590
2621
  }
2591
- appendVirtualConnectionNodes(rootAgentNodeId, agentConfig, materializedConnectionNodeIds, nodes) {
2592
- for (const connectionNode of AgentConnectionNodeCollector.collect(rootAgentNodeId, agentConfig)) {
2622
+ buildAgentConnectionDescriptorIndex(workflow) {
2623
+ const byAgentNodeId = /* @__PURE__ */ new Map();
2624
+ const byChildNodeIdByAgentNodeId = /* @__PURE__ */ new Map();
2625
+ for (const node of workflow.nodes) {
2626
+ if (!AgentConfigInspector.isAgentNodeConfig(node.config)) continue;
2627
+ const descriptors = AgentConnectionNodeCollector.collect(node.id, node.config);
2628
+ byAgentNodeId.set(node.id, descriptors);
2629
+ const byChildId = /* @__PURE__ */ new Map();
2630
+ for (const descriptor of descriptors) byChildId.set(descriptor.nodeId, descriptor);
2631
+ byChildNodeIdByAgentNodeId.set(node.id, byChildId);
2632
+ }
2633
+ return {
2634
+ byAgentNodeId,
2635
+ byChildNodeIdByAgentNodeId
2636
+ };
2637
+ }
2638
+ appendVirtualConnectionNodes(materializedConnectionNodeIds, nodes, descriptors) {
2639
+ for (const connectionNode of descriptors) {
2593
2640
  if (materializedConnectionNodeIds.has(connectionNode.nodeId)) continue;
2594
2641
  nodes.push(this.createConnectionNode(connectionNode));
2595
2642
  }
2596
2643
  }
2597
- appendVirtualConnectionEdges(rootAgentNodeId, agentConfig, materializedConnectionNodeIds, edgeKeys, edges) {
2598
- for (const connectionNode of AgentConnectionNodeCollector.collect(rootAgentNodeId, agentConfig)) {
2644
+ appendVirtualConnectionEdges(materializedConnectionNodeIds, edgeKeys, edges, descriptors) {
2645
+ for (const connectionNode of descriptors) {
2599
2646
  if (materializedConnectionNodeIds.has(connectionNode.nodeId)) continue;
2600
2647
  const key = this.edgeKey(connectionNode.parentNodeId, connectionNode.nodeId, "in");
2601
2648
  if (edgeKeys.has(key)) continue;
@@ -2626,6 +2673,19 @@ let WorkflowDefinitionMapper = class WorkflowDefinitionMapper$1 {
2626
2673
  parentNodeId: connectionNode.parentNodeId
2627
2674
  };
2628
2675
  }
2676
+ /**
2677
+ * Omit optional port fields when undefined so persisted snapshot DTOs (which never serialize
2678
+ * undefined keys) stay aligned with live workflow mapping.
2679
+ */
2680
+ nodePortFieldsFromConfig(config$1) {
2681
+ if (!config$1 || typeof config$1 !== "object") return {};
2682
+ const c = config$1;
2683
+ return {
2684
+ ...c.continueWhenEmptyOutput !== void 0 && { continueWhenEmptyOutput: c.continueWhenEmptyOutput },
2685
+ ...c.declaredOutputPorts !== void 0 && { declaredOutputPorts: c.declaredOutputPorts },
2686
+ ...c.declaredInputPorts !== void 0 && { declaredInputPorts: c.declaredInputPorts }
2687
+ };
2688
+ }
2629
2689
  nodeTypeName(node) {
2630
2690
  const configToken = node.config?.type;
2631
2691
  if (typeof configToken?.name === "string" && configToken.name) return configToken.name;
@@ -4025,7 +4085,8 @@ let CredentialHttpRouteHandler = class CredentialHttpRouteHandler$1 {
4025
4085
  }
4026
4086
  async getWorkflowCredentialHealth(_$1, params) {
4027
4087
  try {
4028
- return Response.json(await this.queryBus.execute(new GetWorkflowCredentialHealthQuery(params.workflowId)));
4088
+ const health = await this.queryBus.execute(new GetWorkflowCredentialHealthQuery(params.workflowId));
4089
+ return Response.json(health);
4029
4090
  } catch (error) {
4030
4091
  return ServerHttpErrorResponseFactory.fromUnknown(error);
4031
4092
  }
@@ -4639,14 +4700,16 @@ let WorkflowHttpRouteHandler = class WorkflowHttpRouteHandler$1 {
4639
4700
  }
4640
4701
  async getWorkflowRuns(_$1, params) {
4641
4702
  try {
4642
- return Response.json(await this.queryBus.execute(new ListWorkflowRunsQuery(params.workflowId)));
4703
+ const runs = await this.queryBus.execute(new ListWorkflowRunsQuery(params.workflowId));
4704
+ return Response.json(runs);
4643
4705
  } catch (error) {
4644
4706
  return ServerHttpErrorResponseFactory.fromUnknown(error);
4645
4707
  }
4646
4708
  }
4647
4709
  async getWorkflowDebuggerOverlay(_$1, params) {
4648
4710
  try {
4649
- return Response.json(await this.queryBus.execute(new GetWorkflowDebuggerOverlayQuery(params.workflowId)));
4711
+ const overlay = await this.queryBus.execute(new GetWorkflowDebuggerOverlayQuery(params.workflowId));
4712
+ return Response.json(overlay);
4650
4713
  } catch (error) {
4651
4714
  return ServerHttpErrorResponseFactory.fromUnknown(error);
4652
4715
  }
@@ -14950,6 +15013,7 @@ var AppContainerFactory = class AppContainerFactory {
14950
15013
  VerifyUserInviteQueryHandler,
14951
15014
  GetRunBinaryAttachmentQueryHandler,
14952
15015
  GetRunStateQueryHandler,
15016
+ GetWorkflowRunDetailQueryHandler,
14953
15017
  GetWorkflowDebuggerOverlayQueryHandler,
14954
15018
  GetWorkflowDetailQueryHandler,
14955
15019
  GetWorkflowOverlayBinaryAttachmentQueryHandler,
@@ -15273,4 +15337,4 @@ var AppContainerFactory = class AppContainerFactory {
15273
15337
 
15274
15338
  //#endregion
15275
15339
  export { GetWorkflowDetailQuery as C, ListUserAccountsQuery as E, GetWorkflowSummariesQuery as S, UpsertLocalBootstrapUserCommand as T, CodemationFrontendAuthSnapshotFactory as _, AppContainerLifecycle as a, WorkflowDefinitionMapper as b, RequestToWebhookItemMapper as c, CredentialHttpRouteHandler as d, CodemationHonoApiApp as f, FrontendAppConfigFactory as g, InternalAuthBootstrapFactory as h, DatabaseMigrations as i, RunHttpRouteHandler as l, PublicFrontendBootstrapFactory as m, WorkerRuntime as n, WorkflowHttpRouteHandler as o, BinaryHttpRouteHandler as p, FrontendRuntime as r, WebhookHttpRouteHandler as s, AppContainerFactory as t, OAuth2HttpRouteHandler as u, WorkflowWebsocketServer as v, RunBinaryAttachmentLookupService as w, WorkflowPolicyUiPresentationFactory as x, ApiPaths as y };
15276
- //# sourceMappingURL=AppContainerFactory-BRU02PTm.js.map
15340
+ //# sourceMappingURL=AppContainerFactory-BKaAUIi-.js.map