@eventcatalog/core 4.12.2 → 5.0.0-beta.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 (268) hide show
  1. package/LICENSE +226 -95
  2. package/NOTICE +30 -0
  3. package/README.md +3 -2
  4. package/dist/analytics/analytics.cjs +1 -1
  5. package/dist/analytics/analytics.js +2 -2
  6. package/dist/analytics/log-build.cjs +43 -16
  7. package/dist/analytics/log-build.d.cts +6 -5
  8. package/dist/analytics/log-build.d.ts +6 -5
  9. package/dist/analytics/log-build.js +4 -3
  10. package/dist/{chunk-U4YJSTGV.js → chunk-AYNZXUB5.js} +2 -10
  11. package/dist/{chunk-IVVM67LN.js → chunk-CR6AK5LR.js} +1 -1
  12. package/dist/{chunk-GTIC4R74.js → chunk-LR7AGRHN.js} +13 -16
  13. package/dist/chunk-TQLRG35T.js +203 -0
  14. package/dist/{chunk-WK4J6FP3.js → chunk-TWN43V4T.js} +1 -1
  15. package/dist/{chunk-ZW3MYAWF.js → chunk-WAIADKQE.js} +1 -1
  16. package/dist/{chunk-RPVA2SZY.js → chunk-ZHKEARLJ.js} +1 -1
  17. package/dist/constants.cjs +1 -1
  18. package/dist/constants.js +1 -1
  19. package/dist/eventcatalog.cjs +407 -291
  20. package/dist/eventcatalog.config.d.cts +2 -3
  21. package/dist/eventcatalog.config.d.ts +2 -3
  22. package/dist/eventcatalog.js +30 -93
  23. package/dist/federation/content-cache.d.cts +0 -5
  24. package/dist/federation/content-cache.d.ts +0 -5
  25. package/dist/federation/diagnostics.d.cts +0 -5
  26. package/dist/federation/diagnostics.d.ts +0 -5
  27. package/dist/federation/federate.cjs +0 -9
  28. package/dist/federation/federate.d.cts +0 -5
  29. package/dist/federation/federate.d.ts +0 -5
  30. package/dist/federation/federate.js +2 -3
  31. package/dist/federation/filesystem-source-provider.d.cts +0 -5
  32. package/dist/federation/filesystem-source-provider.d.ts +0 -5
  33. package/dist/federation/github-source-provider.d.cts +0 -5
  34. package/dist/federation/github-source-provider.d.ts +0 -5
  35. package/dist/federation/output-transaction.d.cts +0 -4
  36. package/dist/federation/output-transaction.d.ts +0 -4
  37. package/dist/federation/public-assets.d.cts +0 -5
  38. package/dist/federation/public-assets.d.ts +0 -5
  39. package/dist/federation/source-provider.d.cts +0 -5
  40. package/dist/federation/source-provider.d.ts +0 -5
  41. package/dist/federation/types.d.cts +0 -5
  42. package/dist/federation/types.d.ts +0 -5
  43. package/dist/generate.cjs +1 -1
  44. package/dist/generate.js +3 -3
  45. package/dist/license-C1y-56bb.d.cts +23 -0
  46. package/dist/license-C1y-56bb.d.ts +23 -0
  47. package/dist/runtime-dependencies/@eventcatalog__visualiser__layout.mjs +3 -0
  48. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps.mjs +3 -0
  49. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__react.mjs +3 -0
  50. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__server.mjs +3 -0
  51. package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +3 -0
  52. package/dist/runtime-dependencies/manifest.json +12 -1
  53. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__graphql.mjs +3 -0
  54. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__json.mjs +3 -0
  55. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__markup.mjs +3 -0
  56. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__protobuf.mjs +3 -0
  57. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__yaml.mjs +3 -0
  58. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-dark.mjs +3 -0
  59. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-light.mjs +3 -0
  60. package/dist/utils/cli-logger.cjs +1 -1
  61. package/dist/utils/cli-logger.js +2 -2
  62. package/dist/utils/license-status.cjs +240 -0
  63. package/dist/utils/license-status.d.cts +28 -0
  64. package/dist/utils/license-status.d.ts +28 -0
  65. package/dist/utils/license-status.js +12 -0
  66. package/eventcatalog/astro.config.mjs +1 -1
  67. package/eventcatalog/integrations/eventcatalog-runtime.mjs +1 -1
  68. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +29 -19
  69. package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +74 -0
  70. package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +24 -28
  71. package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +16 -11
  72. package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +4 -218
  73. package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +27 -36
  74. package/eventcatalog/src/components/Header.astro +43 -58
  75. package/eventcatalog/src/components/Lists/PillListFlat.styles.css +17 -17
  76. package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +1 -1
  77. package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -0
  78. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -0
  79. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +49 -18
  80. package/eventcatalog/src/components/MDX/RemoteFile.astro +2 -24
  81. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +59 -93
  82. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +1 -32
  83. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +20 -67
  84. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -11
  85. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +11 -60
  86. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -3
  87. package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +0 -3
  88. package/eventcatalog/src/components/SchemaExplorer/VersionHistoryModal.tsx +2 -9
  89. package/eventcatalog/src/components/SchemaExplorer/parse-schema.ts +46 -0
  90. package/eventcatalog/src/components/SchemaExplorer/utils.ts +11 -0
  91. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +2 -9
  92. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +288 -0
  93. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +3 -19
  94. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +85 -30
  95. package/eventcatalog/src/components/Settings/SettingsShared.tsx +7 -75
  96. package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +2 -2
  97. package/eventcatalog/src/components/TrialBadge.astro +82 -0
  98. package/eventcatalog/src/content.config.ts +9 -90
  99. package/eventcatalog/src/{enterprise → features}/ai/chat-api.ts +22 -34
  100. package/eventcatalog/src/{enterprise → features}/analytics/adapters/ga4.ts +0 -5
  101. package/eventcatalog/src/{enterprise → features}/analytics/adapters/gtm.ts +0 -5
  102. package/eventcatalog/src/{enterprise → features}/analytics/adapters/posthog.ts +0 -5
  103. package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsHead.astro +2 -4
  104. package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsTracker.astro +2 -4
  105. package/eventcatalog/src/{enterprise → features}/analytics/tracker.ts +0 -5
  106. package/eventcatalog/src/{enterprise → features}/api/catalog.ts +0 -5
  107. package/eventcatalog/src/{enterprise → features}/auth/[...auth].ts +0 -5
  108. package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware-auth.ts +0 -5
  109. package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware.ts +0 -5
  110. package/eventcatalog/src/{enterprise → features}/collections/custom-pages.ts +0 -5
  111. package/eventcatalog/src/{enterprise → features}/collections/index.ts +0 -5
  112. package/eventcatalog/src/{enterprise → features}/collections/resource-docs.ts +0 -5
  113. package/eventcatalog/src/{enterprise → features}/custom-documentation/collection.ts +0 -5
  114. package/eventcatalog/src/features/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
  115. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -5
  116. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +1 -6
  117. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +0 -5
  118. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/index.tsx +1 -6
  119. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/types.ts +0 -5
  120. package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/index.astro → features/custom-documentation/components/CustomDocumentationPage.astro} +5 -5
  121. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/badge-styles.ts +0 -5
  122. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/custom-docs.ts +1 -6
  123. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/docs-search.ts +0 -5
  124. package/eventcatalog/src/{enterprise → features}/custom-pages/routes.ts +0 -5
  125. package/eventcatalog/src/{enterprise → features}/directory/user-team-directory.ts +0 -5
  126. package/eventcatalog/src/{enterprise → features}/fields/field-extractor.ts +0 -5
  127. package/eventcatalog/src/{enterprise → features}/fields/field-indexer.ts +0 -5
  128. package/eventcatalog/src/{enterprise → features}/fields/fields-db.ts +0 -5
  129. package/eventcatalog/src/{enterprise → features}/fields/pages/api/fields.ts +1 -6
  130. package/eventcatalog/src/{enterprise → features}/fields/pages/fields.astro +1 -2
  131. package/eventcatalog/src/{enterprise → features}/integrations/eventcatalog-features.ts +17 -75
  132. package/eventcatalog/src/features/mcp/apps/architecture-diagram/links.ts +59 -0
  133. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +299 -0
  134. package/eventcatalog/src/features/mcp/apps/architecture-diagram/shared.ts +14 -0
  135. package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +454 -0
  136. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +432 -0
  137. package/eventcatalog/src/features/mcp/apps/mermaid-stub.ts +10 -0
  138. package/eventcatalog/src/features/mcp/apps/schema-viewer/schema-code.tsx +65 -0
  139. package/eventcatalog/src/features/mcp/apps/schema-viewer/shared.ts +23 -0
  140. package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +170 -0
  141. package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +98 -0
  142. package/eventcatalog/src/features/mcp/apps/shared/resource-types.ts +15 -0
  143. package/eventcatalog/src/features/mcp/apps/viewer/shared.ts +24 -0
  144. package/eventcatalog/src/features/mcp/apps/viewer/styles.css +25 -0
  145. package/eventcatalog/src/features/mcp/apps/viewer/view.tsx +59 -0
  146. package/eventcatalog/src/features/mcp/mcp-app-icons.ts +63 -0
  147. package/eventcatalog/src/features/mcp/mcp-apps.ts +160 -0
  148. package/eventcatalog/src/{enterprise → features}/mcp/mcp-auth.ts +0 -5
  149. package/eventcatalog/src/{enterprise → features}/mcp/mcp-scope.ts +7 -7
  150. package/eventcatalog/src/{enterprise → features}/mcp/mcp-scoped-tools.ts +47 -40
  151. package/eventcatalog/src/{enterprise → features}/mcp/mcp-server.ts +347 -34
  152. package/eventcatalog/src/{enterprise → features}/mcp/oauth-protected-resource.ts +0 -5
  153. package/eventcatalog/src/features/mcp/schema-viewer.ts +24 -0
  154. package/eventcatalog/src/{enterprise → features}/tools/catalog-tools.ts +133 -102
  155. package/eventcatalog/src/features/tools/index.ts +5 -0
  156. package/eventcatalog/src/{enterprise → features}/visualizer-layout/reset.ts +0 -5
  157. package/eventcatalog/src/{enterprise → features}/visualizer-layout/save.ts +0 -5
  158. package/eventcatalog/src/layouts/BaseLayout.astro +2 -2
  159. package/eventcatalog/src/layouts/Footer.astro +31 -39
  160. package/eventcatalog/src/layouts/SettingsLayout.astro +6 -6
  161. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +7 -37
  162. package/eventcatalog/src/{enterprise → pages}/api/schemas/[collection]/[id]/[version]/index.ts +0 -22
  163. package/eventcatalog/src/{enterprise → pages}/api/schemas/services/[id]/[version]/[specification]/index.ts +0 -19
  164. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +2 -6
  165. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -5
  166. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +2 -6
  167. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -5
  168. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].md.ts +2 -6
  169. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].mdx.ts +2 -6
  170. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +9 -5
  171. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +12 -0
  172. package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/root-index.astro → pages/docs/custom/index.astro} +1 -23
  173. package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -9
  174. package/eventcatalog/src/pages/docs/llm/llms.txt.ts +4 -4
  175. package/eventcatalog/src/pages/docs/llm/schemas.txt.ts +0 -11
  176. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +2 -2
  177. package/eventcatalog/src/pages/index.astro +2 -2
  178. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +0 -3
  179. package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -4
  180. package/eventcatalog/src/pages/settings/assistant.astro +2 -4
  181. package/eventcatalog/src/pages/settings/license.astro +18 -0
  182. package/eventcatalog/src/pages/settings/llm-access.astro +1 -4
  183. package/eventcatalog/src/pages/settings/mcp.astro +33 -4
  184. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -2
  185. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +2 -45
  186. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -1
  187. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +7 -109
  188. package/eventcatalog/src/pages/visualiser/_mermaid-route.ts +78 -0
  189. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/_index.data.ts +44 -0
  190. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -1
  191. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +56 -0
  192. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +3 -40
  193. package/eventcatalog/src/pages/visualiser/domains/[id]/[version].mermaid.ts +20 -0
  194. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/_index.data.ts +29 -0
  195. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +3 -38
  196. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +56 -0
  197. package/eventcatalog/src/pages/visualiser/systems/[id]/[version].mermaid.ts +20 -0
  198. package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +1 -1
  199. package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
  200. package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
  201. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -32
  202. package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +1 -1
  203. package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
  204. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -8
  205. package/eventcatalog/src/stores/sidebar-store/builders/system.ts +2 -12
  206. package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +0 -10
  207. package/eventcatalog/src/stores/sidebar-store/state.ts +4 -6
  208. package/eventcatalog/src/styles/theme.css +22 -18
  209. package/eventcatalog/src/styles/themes/forest.css +8 -8
  210. package/eventcatalog/src/styles/themes/ocean.css +8 -8
  211. package/eventcatalog/src/styles/themes/sapphire.css +8 -8
  212. package/eventcatalog/src/styles/themes/sunset.css +8 -8
  213. package/eventcatalog/src/utils/clipboard.ts +4 -4
  214. package/eventcatalog/src/utils/collections/flow-step-schema.ts +117 -0
  215. package/eventcatalog/src/utils/collections/pointer-schema.ts +7 -0
  216. package/eventcatalog/src/utils/collections/resource-docs.ts +677 -14
  217. package/eventcatalog/src/utils/collections/schema-loader.ts +0 -5
  218. package/eventcatalog/src/utils/feature.ts +14 -23
  219. package/eventcatalog/src/utils/license.ts +114 -0
  220. package/eventcatalog/src/utils/node-graphs/architecture-diagram-types.ts +32 -0
  221. package/eventcatalog/src/utils/node-graphs/architecture-diagram.ts +84 -0
  222. package/eventcatalog/src/utils/node-graphs/catalog-force-graph.ts +1 -0
  223. package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +4 -25
  224. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -39
  225. package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +11 -27
  226. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +679 -0
  227. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +3 -20
  228. package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +62 -4
  229. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +8 -23
  230. package/eventcatalog/src/utils/node-graphs/flow-lanes.ts +119 -0
  231. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +153 -45
  232. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +28 -0
  233. package/eventcatalog/src/utils/node-graphs/layout-persistence.ts +3 -3
  234. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +16 -34
  235. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -25
  236. package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +18 -54
  237. package/eventcatalog/src/utils/node-graphs/system-levels-node-graph.ts +59 -0
  238. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +20 -80
  239. package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -78
  240. package/eventcatalog/src/utils/trial.ts +36 -0
  241. package/eventcatalog/tsconfig.json +1 -1
  242. package/package.json +11 -11
  243. package/dist/chunk-FV56YFM4.js +0 -7
  244. package/dist/federation/entitlement.cjs +0 -31
  245. package/dist/federation/entitlement.d.cts +0 -12
  246. package/dist/federation/entitlement.d.ts +0 -12
  247. package/dist/federation/entitlement.js +0 -6
  248. package/dist/runtime-dependencies/dagre.mjs +0 -3
  249. package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +0 -265
  250. package/eventcatalog/src/enterprise/LICENSE +0 -57
  251. package/eventcatalog/src/enterprise/README.md +0 -5
  252. package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +0 -691
  253. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +0 -9
  254. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/[...path]/index.astro +0 -18
  255. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/feature.astro +0 -171
  256. package/eventcatalog/src/enterprise/feature.ts +0 -75
  257. package/eventcatalog/src/enterprise/tools/index.ts +0 -10
  258. package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +0 -126
  259. package/eventcatalog/src/pages/settings/billing.astro +0 -17
  260. package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +0 -26
  261. package/eventcatalog/src/types/mcp-modules.d.ts +0 -67
  262. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +0 -261
  263. package/eventcatalog/src/utils/node-graphs/export-node-graph.ts +0 -91
  264. /package/eventcatalog/src/{enterprise → features}/auth/error.astro +0 -0
  265. /package/eventcatalog/src/{enterprise → features}/auth/login.astro +0 -0
  266. /package/eventcatalog/src/{enterprise → features}/auth/unauthorized.astro +0 -0
  267. /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path]/_index.data.ts +0 -0
  268. /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path].mdx.ts +0 -0
@@ -1,7 +1,10 @@
1
+ import fs from 'node:fs';
2
+ import { join } from 'node:path';
1
3
  // Feature checks also run during Astro config evaluation, before @config exists.
2
4
  import config from './eventcatalog-config/source';
3
5
 
4
- // Open-source feature flags
6
+ const projectDirectory = () => process.env.PROJECT_DIR || process.cwd();
7
+
5
8
  export const isEventCatalogChatVisible = () => config?.chat?.enabled ?? true;
6
9
  export const isSSR = () => config?.output === 'server';
7
10
  export const isVisualiserEnabled = () => config?.visualiser?.enabled ?? true;
@@ -15,25 +18,13 @@ export const isMarkdownDownloadEnabled = () => config?.llmsTxt?.enabled ?? true;
15
18
  export const isFullCatalogAPIEnabled = () => config?.api?.fullCatalogAPIEnabled ?? false;
16
19
  export const isDevMode = () => process.env.EVENTCATALOG_DEV_MODE === 'true';
17
20
 
18
- // Re-export enterprise feature flags for backwards compatibility.
19
- // These functions are subject to the EventCatalog Commercial License.
20
- // See /packages/core/eventcatalog/src/enterprise/LICENSE
21
- export {
22
- isEventCatalogStarterEnabled,
23
- isEventCatalogScaleEnabled,
24
- isPrivateRemoteSchemaEnabled,
25
- isEmbedEnabled,
26
- showEventCatalogBranding,
27
- showCustomBranding,
28
- isCustomDocsEnabled,
29
- isResourceDocsEnabled,
30
- isEventCatalogChatEnabled,
31
- isEventCatalogUpgradeEnabled,
32
- isCustomLandingPageEnabled,
33
- isCustomPagesEnabled,
34
- isAuthEnabled,
35
- isCustomStylesEnabled,
36
- isEventCatalogMCPEnabled,
37
- isEventCatalogMCPAuthEnabled,
38
- isIntegrationsEnabled,
39
- } from '../enterprise/feature';
21
+ // The assistant needs a model configured (eventcatalog.chat.js) and a server to run on
22
+ export const isEventCatalogChatEnabled = () =>
23
+ fs.existsSync(join(projectDirectory(), 'eventcatalog.chat.js')) && isSSR() && isEventCatalogChatVisible();
24
+
25
+ // Authentication needs providers configured (eventcatalog.auth.js) and a server to run on
26
+ export const isAuthEnabled = () =>
27
+ (config?.auth?.enabled ?? false) && fs.existsSync(join(projectDirectory(), 'eventcatalog.auth.js')) && isSSR();
28
+
29
+ export const isEventCatalogMCPEnabled = () => isSSR() && (config?.mcp?.enabled ?? true);
30
+ export const isEventCatalogMCPAuthEnabled = () => isEventCatalogMCPEnabled() && (config?.mcp?.auth?.enabled ?? false);
@@ -0,0 +1,114 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { clearCache, hasCommercialLicense, verifyOfflineLicense } from '@eventcatalog/license';
4
+
5
+ export { LICENSE_FAQ_URL, LICENSE_RENEW_URL } from './trial';
6
+
7
+ // Details from the license token
8
+ export type LicenseDetails = { org?: string; licenseId?: string; issuedAt?: Date };
9
+
10
+ // Scale and Starter plans, licensed with a license key instead of a license.jwt
11
+ export type LicensePlan = 'scale' | 'starter';
12
+
13
+ export type LicenseStatus =
14
+ | { state: 'none' }
15
+ | ({ state: 'licensed'; expiresAt: Date } & LicenseDetails)
16
+ | { state: 'plan'; plan: LicensePlan }
17
+ | ({ state: 'expired'; expiresAt?: Date } & LicenseDetails)
18
+ | { state: 'invalid'; reason: string };
19
+
20
+ const toDate = (seconds: unknown) => (typeof seconds === 'number' ? new Date(seconds * 1000) : undefined);
21
+
22
+ const getDetails = (claims: Record<string, unknown>): LicenseDetails => ({
23
+ org: typeof claims.org === 'string' ? claims.org : undefined,
24
+ licenseId: typeof claims.licenseId === 'string' ? claims.licenseId : undefined,
25
+ issuedAt: toDate(claims.iat),
26
+ });
27
+
28
+ const INVALID_REASONS: Record<string, string> = {
29
+ LICENSE_FILE_EMPTY: 'the file is empty',
30
+ LICENSE_NOT_YET_VALID: 'it is not valid yet',
31
+ LICENSE_SIGNATURE_INVALID: 'its signature is invalid',
32
+ LICENSE_VALIDATION_FAILED: 'it was not issued by EventCatalog',
33
+ };
34
+
35
+ // The license file: EC_LICENSE, or license.jwt in the root of the catalog
36
+ export const getLicenseFilePath = (projectDirectory: string) =>
37
+ process.env.EC_LICENSE || path.join(projectDirectory, 'license.jwt');
38
+
39
+ // The token's claims, without verifying it (for an expired license, which the verifier rejects)
40
+ const readClaims = (licenseFilePath: string): Record<string, unknown> => {
41
+ try {
42
+ const payload = fs.readFileSync(licenseFilePath, 'utf8').trim().split('.')[1];
43
+ return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
44
+ } catch {
45
+ return {};
46
+ }
47
+ };
48
+
49
+ // Verified statuses by license file and its last change, so a license is checked once per change
50
+ const statusCache = new Map<string, Promise<LicenseStatus>>();
51
+
52
+ /**
53
+ * The Scale or Starter plan, checked by the CLI with its license key and passed to Astro
54
+ * (see checkPlanLicense in the CLI's license-status).
55
+ */
56
+ export const getLicensePlan = (): LicensePlan | undefined => {
57
+ if (process.env.EVENTCATALOG_SCALE === 'true') return 'scale';
58
+ if (process.env.EVENTCATALOG_STARTER === 'true') return 'starter';
59
+ };
60
+
61
+ /**
62
+ * Verifies the catalog's license.jwt offline (signature, issuer, audience and dates).
63
+ * Cached until the license file changes.
64
+ */
65
+ export const getCommercialLicenseStatus = (
66
+ projectDirectory = process.env.PROJECT_DIR || process.cwd()
67
+ ): Promise<LicenseStatus> => {
68
+ const licensePath = getLicenseFilePath(projectDirectory);
69
+ const modifiedAt = fs.statSync(licensePath, { throwIfNoEntry: false })?.mtimeMs;
70
+ if (modifiedAt === undefined) return Promise.resolve({ state: 'none' });
71
+
72
+ const key = `${licensePath}:${modifiedAt}`;
73
+ if (!statusCache.has(key)) statusCache.set(key, verifyLicense(licensePath));
74
+ return statusCache.get(key)!;
75
+ };
76
+
77
+ /**
78
+ * The catalog's license: a commercial license (license.jwt) first, then a Scale or Starter plan.
79
+ */
80
+ export const getLicenseStatus = async (projectDirectory?: string): Promise<LicenseStatus> => {
81
+ const license = await getCommercialLicenseStatus(projectDirectory);
82
+ if (license.state === 'licensed') return license;
83
+ const plan = getLicensePlan();
84
+ return plan ? { state: 'plan', plan } : license;
85
+ };
86
+
87
+ const verifyLicense = async (licensePath: string): Promise<LicenseStatus> => {
88
+ // The license package logs its own errors; callers report the status instead
89
+ const consoleError = console.error;
90
+ console.error = () => {};
91
+ try {
92
+ // The package keeps the first license it verifies; this file may have changed since
93
+ clearCache();
94
+ if (await hasCommercialLicense()) {
95
+ const entitlements = await verifyOfflineLicense({ licensePath });
96
+ return { state: 'licensed', ...getDetails(entitlements), expiresAt: new Date(entitlements.exp! * 1000) };
97
+ }
98
+
99
+ // Not a commercial license: verify it again to report why
100
+ clearCache();
101
+ const entitlements = await verifyOfflineLicense({ licensePath });
102
+ if (typeof entitlements.exp !== 'number') return { state: 'invalid', reason: 'it has no expiry date' };
103
+ // Verified within the verifier's clock tolerance, but past its expiry date
104
+ return { state: 'expired', ...getDetails(entitlements), expiresAt: new Date(entitlements.exp * 1000) };
105
+ } catch (error: any) {
106
+ if (error?.code === 'LICENSE_EXPIRED') {
107
+ const claims = readClaims(licensePath);
108
+ return { state: 'expired', ...getDetails(claims), expiresAt: toDate(claims.exp) };
109
+ }
110
+ return { state: 'invalid', reason: INVALID_REASONS[error?.code] || error?.message || String(error) };
111
+ } finally {
112
+ console.error = consoleError;
113
+ }
114
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The resources that have an architecture diagram, and the shape of a diagram. Has no imports so
3
+ * it can be shared by the diagram builders, the MCP tools and the MCP App view bundled for the browser.
4
+ */
5
+
6
+ export const ARCHITECTURE_DIAGRAM_COLLECTIONS = [
7
+ 'events',
8
+ 'commands',
9
+ 'queries',
10
+ 'agents',
11
+ 'services',
12
+ 'domains',
13
+ 'systems',
14
+ 'flows',
15
+ 'containers',
16
+ 'data-products',
17
+ ] as const;
18
+
19
+ export type ArchitectureDiagramCollection = (typeof ARCHITECTURE_DIAGRAM_COLLECTIONS)[number];
20
+
21
+ export const isArchitectureDiagramCollection = (collection: string): collection is ArchitectureDiagramCollection =>
22
+ (ARCHITECTURE_DIAGRAM_COLLECTIONS as readonly string[]).includes(collection);
23
+
24
+ export type ArchitectureDiagramDetail = 'overview' | 'full';
25
+
26
+ export type Graph = { nodes: any[]; edges: any[] };
27
+
28
+ /**
29
+ * The diagram with its levels, as the Diagram page shows it: the detailed graph, and for
30
+ * domains and systems the level 1 overview and the graph without messages and channels.
31
+ */
32
+ export type ArchitectureDiagramView = Graph & { overview?: Graph; hiddenMessages?: Graph };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The architecture diagram for a resource, built the same way as its Diagram page
3
+ * in the visualiser. Shared by the `.mermaid` visualiser route and the architecture
4
+ * diagram tool used by AI Chat and the MCP server, so they show the same thing.
5
+ */
6
+ import config from '@config';
7
+ import { getNodesAndEdges as getNodesAndEdgesForService } from '@utils/node-graphs/services-node-graph';
8
+ import { getNodesAndEdges as getNodesAndEdgesForAgent } from '@utils/node-graphs/agents-node-graph';
9
+ import {
10
+ getNodesAndEdgesForCommands,
11
+ getNodesAndEdgesForEvents,
12
+ getNodesAndEdgesForQueries,
13
+ } from '@utils/node-graphs/message-node-graph';
14
+ import { getNodesAndEdges as getNodesAndEdgesForFlows } from '@utils/node-graphs/flows-node-graph';
15
+ import { getNodesAndEdges as getNodesAndEdgesForDataProduct } from '@utils/node-graphs/data-products-node-graph';
16
+ import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
17
+ import { getNodesAndEdges as getNodesAndEdgesForDomainLevels } from '@utils/node-graphs/domain-levels-node-graph';
18
+ import { getNodesAndEdges as getNodesAndEdgesForSystemLevels } from '@utils/node-graphs/system-levels-node-graph';
19
+ import type {
20
+ ArchitectureDiagramCollection,
21
+ ArchitectureDiagramDetail,
22
+ ArchitectureDiagramView,
23
+ Graph,
24
+ } from '@utils/node-graphs/architecture-diagram-types';
25
+
26
+ // Domains and systems are shown in levels: level 1 (`overview`) is the domains and
27
+ // systems and how they relate, and the detailed graph expands systems into their
28
+ // services, messages and channels
29
+ const getLevelsFunctions = {
30
+ domains: getNodesAndEdgesForDomainLevels,
31
+ systems: getNodesAndEdgesForSystemLevels,
32
+ };
33
+
34
+ // A graph builder for every other collection with a diagram
35
+ const getNodesAndEdgesFunctions = {
36
+ agents: getNodesAndEdgesForAgent,
37
+ services: getNodesAndEdgesForService,
38
+ events: getNodesAndEdgesForEvents,
39
+ commands: getNodesAndEdgesForCommands,
40
+ queries: getNodesAndEdgesForQueries,
41
+ flows: getNodesAndEdgesForFlows,
42
+ containers: getNodesAndEdgesForContainer,
43
+ 'data-products': getNodesAndEdgesForDataProduct,
44
+ } satisfies Record<Exclude<ArchitectureDiagramCollection, keyof typeof getLevelsFunctions>, unknown>;
45
+
46
+ export async function getArchitectureDiagramView({
47
+ collection,
48
+ id,
49
+ version,
50
+ }: {
51
+ collection: ArchitectureDiagramCollection;
52
+ id: string;
53
+ version: string;
54
+ }): Promise<ArchitectureDiagramView> {
55
+ const options = {
56
+ id,
57
+ version,
58
+ mode: 'full' as const,
59
+ channelRenderMode: config.visualiser?.channels?.renderMode === 'single' ? ('single' as const) : ('flat' as const),
60
+ };
61
+
62
+ if (collection === 'domains' || collection === 'systems') {
63
+ const { nodes, edges, overview, hiddenMessages } = await getLevelsFunctions[collection](options);
64
+ return { nodes, edges, overview, hiddenMessages };
65
+ }
66
+
67
+ const { nodes, edges } = await getNodesAndEdgesFunctions[collection](options);
68
+ return { nodes, edges };
69
+ }
70
+
71
+ export async function getArchitectureDiagramGraph({
72
+ detail = 'full',
73
+ ...resource
74
+ }: {
75
+ collection: ArchitectureDiagramCollection;
76
+ id: string;
77
+ version: string;
78
+ detail?: ArchitectureDiagramDetail;
79
+ }): Promise<Graph> {
80
+ const view = await getArchitectureDiagramView(resource);
81
+ // A domain without systems or subdomains has no level 1, so it shows the full diagram
82
+ const graph = detail === 'overview' && view.overview ? view.overview : view;
83
+ return { nodes: graph.nodes, edges: graph.edges };
84
+ }
@@ -245,6 +245,7 @@ export const getCatalogForceGraph = async (): Promise<{ nodes: CatalogGraphNode[
245
245
  const key = nodeKey('flows', flow.data.id);
246
246
  for (const step of (flow.data as any).steps ?? []) {
247
247
  addLink(key, nodeKey('services', refId(step.service)!), 'references');
248
+ addLink(key, nodeKey('systems', refId(step.systems || step.system)!), 'references');
248
249
  addLink(key, nodeKey('agents', refId(step.agent)!), 'references');
249
250
  addLink(key, nodeKey('flows', refId(step.flow)!), 'has sub-flow');
250
251
  addLink(key, nodeKey('containers', refId(step.container)!), 'references');
@@ -4,8 +4,6 @@ import {
4
4
  buildContextMenuForMessage,
5
5
  buildContextMenuForResource,
6
6
  buildContextMenuForService,
7
- calculatedNodes,
8
- createDagreGraph,
9
7
  createEdge,
10
8
  createNode,
11
9
  generatedIdForEdge,
@@ -14,10 +12,8 @@ import {
14
12
  getEdgeLabelForMessageAsSource,
15
13
  getEdgeLabelForServiceAsTarget,
16
14
  getOperationFields,
17
- DEFAULT_NODE_WIDTH,
18
- DEFAULT_NODE_HEIGHT,
19
- layoutDagreGraph,
20
15
  } from './utils/utils';
16
+ import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
21
17
  import { createVersionedMap, findInMap } from '@utils/collections/util';
22
18
  import { getChannelChain, getChannels } from '@utils/collections/channels';
23
19
  import { type Node, type Edge } from '@xyflow/react';
@@ -111,12 +107,9 @@ type RoutedResource = {
111
107
  channelRoutes: ChannelRoute[];
112
108
  };
113
109
 
114
- type DagreGraph = any;
115
-
116
110
  interface Props {
117
111
  id: string;
118
112
  version: string;
119
- defaultFlow?: DagreGraph;
120
113
  mode?: 'simple' | 'full';
121
114
  layout?: boolean;
122
115
  }
@@ -126,8 +119,7 @@ interface Props {
126
119
  * everything that consumes out of it on the right, and any channels it routes to (or is
127
120
  * routed from) either side of it.
128
121
  */
129
- export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple', layout = true }: Props) => {
130
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
122
+ export const getNodesAndEdges = async ({ id, version, mode = 'simple', layout = true }: Props) => {
131
123
  const nodes: any[] = [];
132
124
  const edges: any[] = [];
133
125
 
@@ -448,20 +440,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
448
440
  );
449
441
  }
450
442
 
451
- nodes.forEach((node) => {
452
- flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
453
- });
454
-
455
- edges.forEach((edge) => {
456
- flow.setEdge(edge.source, edge.target);
457
- });
443
+ if (!layout) return { nodes, edges };
458
444
 
459
- if (layout) {
460
- layoutDagreGraph(flow);
461
- }
462
-
463
- return {
464
- nodes: calculatedNodes(flow, nodes),
465
- edges,
466
- };
445
+ return layoutNodeGraph({ nodes, edges });
467
446
  };
@@ -1,46 +1,31 @@
1
1
  import type { CollectionEntry } from 'astro:content';
2
2
  import {
3
- calculatedNodes,
4
- createDagreGraph,
5
3
  createEdge,
6
4
  generatedIdForEdge,
7
5
  generateIdForNode,
8
6
  buildContextMenuForService,
9
7
  buildContextMenuForResource,
10
- DEFAULT_NODE_WIDTH,
11
- DEFAULT_NODE_HEIGHT,
12
- layoutDagreGraph,
13
8
  } from './utils/utils';
9
+ import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
14
10
  import { MarkerType } from '@xyflow/react';
15
11
  import { findMatchingNodes } from '@utils/collections/util';
16
12
  import { getContainers } from '@utils/collections/containers';
17
13
 
18
- type DagreGraph = any;
19
-
20
14
  interface Props {
21
15
  id: string;
22
16
  version: string;
23
- defaultFlow?: DagreGraph;
24
17
  mode?: 'simple' | 'full';
25
18
  channelRenderMode?: 'flat' | 'single';
26
19
  collection?: CollectionEntry<'containers'>[];
27
20
  layout?: boolean;
28
21
  }
29
22
 
30
- export const getNodesAndEdges = async ({
31
- id,
32
- version,
33
- defaultFlow,
34
- mode = 'simple',
35
- channelRenderMode = 'flat',
36
- layout = true,
37
- }: Props) => {
23
+ export const getNodesAndEdges = async ({ id, version, mode = 'simple', channelRenderMode = 'flat', layout = true }: Props) => {
38
24
  // 1. Fetch data
39
25
  const containers = await getContainers();
40
26
 
41
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
42
- const nodes = [] as any,
43
- edges = [] as any;
27
+ const nodes: any[] = [],
28
+ edges: any[] = [];
44
29
 
45
30
  // Optimized: Use find since we're looking for a specific item
46
31
  const container = containers.find((container) => container.data.id === id && container.data.version === version);
@@ -80,7 +65,7 @@ export const getNodesAndEdges = async ({
80
65
  repository: service.data.repository as { url: string },
81
66
  }),
82
67
  },
83
- position: { x: 250, y: 0 },
68
+ position: { x: 0, y: 0 },
84
69
  });
85
70
 
86
71
  if (!bothSentAndReceived.includes(service)) {
@@ -116,7 +101,7 @@ export const getNodesAndEdges = async ({
116
101
  version: dataProduct.data.version,
117
102
  }),
118
103
  },
119
- position: { x: 250, y: 0 },
104
+ position: { x: 0, y: 0 },
120
105
  });
121
106
 
122
107
  if (!dataProductsBothSentAndReceived.includes(dataProduct)) {
@@ -244,7 +229,7 @@ export const getNodesAndEdges = async ({
244
229
  if (container) {
245
230
  edges.push(
246
231
  createEdge({
247
- id: generatedIdForEdge(container, _service) + '-both',
232
+ id: generatedIdForEdge(_service, container) + '-both',
248
233
  source: generateIdForNode(_service),
249
234
  target: generateIdForNode(container),
250
235
  label: `read and writes to \n (${container.data.technology})`,
@@ -269,7 +254,7 @@ export const getNodesAndEdges = async ({
269
254
  if (container) {
270
255
  edges.push(
271
256
  createEdge({
272
- id: generatedIdForEdge(container, _dataProduct) + '-both',
257
+ id: generatedIdForEdge(_dataProduct, container) + '-both',
273
258
  source: generateIdForNode(_dataProduct),
274
259
  target: generateIdForNode(container),
275
260
  label: `read and writes to \n (${container.data.technology})`,
@@ -289,21 +274,9 @@ export const getNodesAndEdges = async ({
289
274
  }
290
275
  });
291
276
 
292
- nodes.forEach((node: any) => {
293
- flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
294
- });
295
-
296
- edges.forEach((edge: any) => {
297
- flow.setEdge(edge.source, edge.target);
298
- });
299
-
300
- // Render the diagram in memory getting hte X and Y
301
- if (layout) {
302
- layoutDagreGraph(flow);
303
- }
277
+ // Resources that both read and write are added twice (as a writer and as a reader), keep the first
278
+ const uniqueNodes = nodes.filter((node: any, index: number) => nodes.findIndex((n: any) => n.id === node.id) === index);
279
+ const graph = { nodes: uniqueNodes, edges };
304
280
 
305
- return {
306
- nodes: calculatedNodes(flow, nodes),
307
- edges,
308
- };
281
+ return layout ? await layoutNodeGraph(graph) : graph;
309
282
  };
@@ -1,16 +1,12 @@
1
1
  import { getCollection, type CollectionEntry } from 'astro:content';
2
2
  import {
3
- createDagreGraph,
4
3
  generateIdForNode,
5
4
  generatedIdForEdge,
6
- calculatedNodes,
7
5
  createEdge,
8
6
  getColorFromString,
9
7
  buildContextMenuForResource,
10
- DEFAULT_NODE_WIDTH,
11
- DEFAULT_NODE_HEIGHT,
12
- layoutDagreGraph,
13
8
  } from '@utils/node-graphs/utils/utils';
9
+ import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
14
10
 
15
11
  import { findInMap, createVersionedMap, mergeMaps, collectionToResourceMap } from '@utils/collections/util';
16
12
  import { MarkerType } from '@xyflow/react';
@@ -19,12 +15,9 @@ import { getProducersOfMessage } from '@utils/collections/services';
19
15
  import type { CollectionMessageTypes } from '@types';
20
16
  import { getNodesAndEdgesForProducedMessage } from './message-node-graph';
21
17
 
22
- type DagreGraph = any;
23
-
24
18
  interface Props {
25
19
  id: string;
26
20
  version: string;
27
- defaultFlow?: DagreGraph;
28
21
  mode?: 'simple' | 'full';
29
22
  layout?: boolean;
30
23
  }
@@ -35,10 +28,9 @@ const getNodePropertyFromCollectionType = (type: string) => {
35
28
  return collectionToResourceMap[type as keyof typeof collectionToResourceMap];
36
29
  };
37
30
 
38
- export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simple', layout = true }: Props) => {
39
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
40
- let nodes = [] as any,
41
- edges = [] as any;
31
+ export const getNodesAndEdges = async ({ id, version, mode = 'simple', layout = true }: Props) => {
32
+ let nodes: any[] = [],
33
+ edges: any[] = [];
42
34
 
43
35
  const [dataProducts, containers, services, events, queries, commands, channels] = await Promise.all([
44
36
  getCollection('data-products'),
@@ -93,6 +85,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
93
85
 
94
86
  nodes.push({
95
87
  id: generateIdForNode(inputResource),
88
+ position: { x: 0, y: 0 },
96
89
  sourcePosition: 'right',
97
90
  targetPosition: 'left',
98
91
  data: { mode, [nodeDataKey]: { ...inputResource?.data } },
@@ -149,6 +142,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
149
142
  // The data product itself
150
143
  nodes.push({
151
144
  id: generateIdForNode(dataProduct),
145
+ position: { x: 0, y: 0 },
152
146
  sourcePosition: 'right',
153
147
  targetPosition: 'left',
154
148
  data: {
@@ -181,6 +175,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
181
175
 
182
176
  nodes.push({
183
177
  id: generateIdForNode(outputResource),
178
+ position: { x: 0, y: 0 },
184
179
  sourcePosition: 'right',
185
180
  targetPosition: 'left',
186
181
  data: { mode, [nodeDataKey]: { ...outputResource?.data } },
@@ -210,19 +205,6 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
210
205
  );
211
206
  });
212
207
 
213
- nodes.forEach((node: any) => {
214
- flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
215
- });
216
-
217
- edges.forEach((edge: any) => {
218
- flow.setEdge(edge.source, edge.target);
219
- });
220
-
221
- if (layout) {
222
- // Render the diagram in memory getting the X and Y
223
- layoutDagreGraph(flow);
224
- }
225
-
226
208
  // Find any duplicated edges, and merge them into one edge
227
209
  const uniqueEdgesById = new Map<string, any>();
228
210
  edges.forEach((edge: any) => {
@@ -232,8 +214,10 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
232
214
  });
233
215
  const uniqueEdges = Array.from(uniqueEdgesById.values());
234
216
 
235
- return {
236
- nodes: calculatedNodes(flow, nodes),
217
+ const graph = {
218
+ nodes: nodes.map((node: any) => ({ ...node, position: node.position ?? { x: 0, y: 0 } })),
237
219
  edges: uniqueEdges,
238
220
  };
221
+
222
+ return layout ? await layoutNodeGraph(graph) : graph;
239
223
  };