@eventcatalog/core 5.0.0-beta.3 → 5.0.0-beta.30

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 (277) hide show
  1. package/LICENSE +234 -134
  2. package/README.md +5 -5
  3. package/dist/analytics/analytics.cjs +18 -3
  4. package/dist/analytics/analytics.d.cts +1 -1
  5. package/dist/analytics/analytics.d.ts +1 -1
  6. package/dist/analytics/analytics.js +3 -2
  7. package/dist/analytics/log-build.cjs +160 -77
  8. package/dist/analytics/log-build.d.cts +2 -2
  9. package/dist/analytics/log-build.d.ts +2 -2
  10. package/dist/analytics/log-build.js +7 -5
  11. package/dist/analytics/studio-usage.cjs +90 -0
  12. package/dist/analytics/studio-usage.d.cts +5 -0
  13. package/dist/analytics/studio-usage.d.ts +5 -0
  14. package/dist/analytics/studio-usage.js +10 -0
  15. package/dist/analytics/telemetry.cjs +42 -0
  16. package/dist/analytics/telemetry.d.cts +20 -0
  17. package/dist/analytics/telemetry.d.ts +20 -0
  18. package/dist/analytics/telemetry.js +8 -0
  19. package/dist/catalog-runtime.cjs +1 -1
  20. package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
  21. package/dist/{chunk-6OC46WQJ.js → chunk-55QETQZ3.js} +66 -35
  22. package/dist/{chunk-TQLRG35T.js → chunk-AD7CL772.js} +78 -45
  23. package/dist/chunk-CA6WCQ2T.js +54 -0
  24. package/dist/chunk-CPW6G62V.js +17 -0
  25. package/dist/{chunk-423S2KHN.js → chunk-FLAZ2JVN.js} +4 -2
  26. package/dist/{chunk-BH2F5WPN.js → chunk-GQI5UYXZ.js} +1 -1
  27. package/dist/{chunk-GYIVJXOJ.js → chunk-NA7OTBWW.js} +1 -1
  28. package/dist/{chunk-MDWB5HLO.js → chunk-NKNOXQ62.js} +1 -1
  29. package/dist/{chunk-3PKS2IIP.js → chunk-OX6TSVHY.js} +1 -1
  30. package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
  31. package/dist/chunk-S5GWAUG5.js +29 -0
  32. package/dist/{chunk-NDJOAITI.js → chunk-T3OROMAU.js} +9 -3
  33. package/dist/constants.cjs +1 -1
  34. package/dist/constants.js +1 -1
  35. package/dist/eventcatalog-config-file-utils.cjs +34 -41
  36. package/dist/eventcatalog-config-file-utils.d.cts +56 -58
  37. package/dist/eventcatalog-config-file-utils.d.ts +56 -58
  38. package/dist/eventcatalog-config-file-utils.js +1 -1
  39. package/dist/eventcatalog.cjs +531 -356
  40. package/dist/eventcatalog.config.d.cts +59 -1
  41. package/dist/eventcatalog.config.d.ts +59 -1
  42. package/dist/eventcatalog.js +63 -25
  43. package/dist/features.cjs +34 -41
  44. package/dist/features.js +2 -2
  45. package/dist/federation/federate.cjs +37 -44
  46. package/dist/federation/federate.js +2 -2
  47. package/dist/generate.cjs +37 -42
  48. package/dist/generate.js +4 -4
  49. package/dist/resolve-catalog-dependencies.cjs +34 -41
  50. package/dist/resolve-catalog-dependencies.js +2 -2
  51. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
  52. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
  53. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
  54. package/dist/runtime-dependencies/@hocuspocus__provider.mjs +3 -0
  55. package/dist/runtime-dependencies/@hocuspocus__server.mjs +3 -0
  56. package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +3 -0
  57. package/dist/runtime-dependencies/@mcp-b__webmcp-polyfill.mjs +3 -0
  58. package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
  59. package/dist/runtime-dependencies/manifest.json +13 -1
  60. package/dist/runtime-dependencies/react-hotkeys-hook.mjs +3 -0
  61. package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
  62. package/dist/runtime-dependencies/y-protocols.mjs +3 -0
  63. package/dist/runtime-dependencies/y-protocols__awareness.mjs +3 -0
  64. package/dist/runtime-dependencies/yjs.mjs +3 -0
  65. package/dist/utils/child-process-signals.cjs +53 -0
  66. package/dist/utils/child-process-signals.d.cts +19 -0
  67. package/dist/utils/child-process-signals.d.ts +19 -0
  68. package/dist/utils/child-process-signals.js +6 -0
  69. package/dist/utils/cli-logger.cjs +1 -1
  70. package/dist/utils/cli-logger.js +2 -2
  71. package/dist/utils/license-status.cjs +78 -45
  72. package/dist/utils/license-status.d.cts +15 -5
  73. package/dist/utils/license-status.d.ts +15 -5
  74. package/dist/utils/license-status.js +1 -1
  75. package/eventcatalog/astro.config.mjs +23 -1
  76. package/eventcatalog/integrations/config-loader.mjs +56 -58
  77. package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
  78. package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
  79. package/eventcatalog/integrations/storage.mjs +20 -0
  80. package/eventcatalog/integrations/studio-server.mjs +32 -0
  81. package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
  82. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
  83. package/eventcatalog/src/components/Header.astro +3 -3
  84. package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
  85. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
  86. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
  87. package/eventcatalog/src/components/NavigationProgress.astro +7 -0
  88. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
  89. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
  90. package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
  91. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
  92. package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
  93. package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
  94. package/eventcatalog/src/components/Search/search-utils.ts +26 -0
  95. package/eventcatalog/src/components/Seo.astro +5 -1
  96. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
  97. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
  98. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
  99. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
  100. package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
  101. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
  102. package/eventcatalog/src/components/Settings/Row.tsx +7 -4
  103. package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
  104. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +53 -83
  105. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
  106. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +131 -0
  107. package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
  108. package/eventcatalog/src/components/TrialBadge.astro +20 -9
  109. package/eventcatalog/src/content.config.ts +19 -2
  110. package/eventcatalog/src/features/auth/error.astro +4 -2
  111. package/eventcatalog/src/features/auth/login.astro +2 -1
  112. package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +10 -0
  113. package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
  114. package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
  115. package/eventcatalog/src/features/integrations/eventcatalog-features.ts +34 -1
  116. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
  117. package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +47 -0
  118. package/eventcatalog/src/features/mcp/apps/canvas/styles.css +24 -0
  119. package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +278 -0
  120. package/eventcatalog/src/features/mcp/apps/generated/canvas.html +272 -0
  121. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +65 -65
  122. package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +2 -1
  123. package/eventcatalog/src/features/mcp/mcp-apps.ts +6 -3
  124. package/eventcatalog/src/features/mcp/mcp-server.ts +36 -5
  125. package/eventcatalog/src/features/server/start.ts +25 -0
  126. package/eventcatalog/src/features/storage/database.ts +88 -0
  127. package/eventcatalog/src/features/storage/migrations.ts +85 -0
  128. package/eventcatalog/src/features/storage/sql/database.sql +5 -0
  129. package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
  130. package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
  131. package/eventcatalog/src/features/storage/sql.ts +28 -0
  132. package/eventcatalog/src/features/studio/agent-choreography.ts +384 -0
  133. package/eventcatalog/src/features/studio/agents.ts +28 -0
  134. package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
  135. package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
  136. package/eventcatalog/src/features/studio/api/client.ts +40 -0
  137. package/eventcatalog/src/features/studio/canvas-actions.ts +540 -0
  138. package/eventcatalog/src/features/studio/canvas-preview.ts +52 -0
  139. package/eventcatalog/src/features/studio/catalog-resources.ts +155 -0
  140. package/eventcatalog/src/features/studio/catalog.ts +173 -0
  141. package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +518 -0
  142. package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +118 -0
  143. package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +434 -0
  144. package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +143 -0
  145. package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
  146. package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
  147. package/eventcatalog/src/features/studio/components/JoinForm.tsx +109 -0
  148. package/eventcatalog/src/features/studio/components/LeftPanel.tsx +206 -0
  149. package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
  150. package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
  151. package/eventcatalog/src/features/studio/components/Presence.tsx +293 -0
  152. package/eventcatalog/src/features/studio/components/ShareDialog.tsx +396 -0
  153. package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
  154. package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +2091 -0
  155. package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
  156. package/eventcatalog/src/features/studio/document-name.ts +7 -0
  157. package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
  158. package/eventcatalog/src/features/studio/hooks/presence-sender.ts +63 -0
  159. package/eventcatalog/src/features/studio/hooks/presence-store.ts +119 -0
  160. package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +353 -0
  161. package/eventcatalog/src/features/studio/hooks/use-comments.ts +54 -0
  162. package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +109 -0
  163. package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +782 -0
  164. package/eventcatalog/src/features/studio/identity.ts +59 -0
  165. package/eventcatalog/src/features/studio/limits.ts +2 -0
  166. package/eventcatalog/src/features/studio/pages/[id].astro +69 -0
  167. package/eventcatalog/src/features/studio/pages/index.astro +784 -0
  168. package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +27 -0
  169. package/eventcatalog/src/features/studio/server/canvas-mcp.ts +495 -0
  170. package/eventcatalog/src/features/studio/server/runtime.ts +498 -0
  171. package/eventcatalog/src/features/studio/server/sign-in.ts +18 -0
  172. package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
  173. package/eventcatalog/src/features/studio/server/storage.ts +90 -0
  174. package/eventcatalog/src/features/studio/server/tool-icons.ts +30 -0
  175. package/eventcatalog/src/features/studio/tool-sync.ts +75 -0
  176. package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
  177. package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
  178. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +13 -5
  179. package/eventcatalog/src/pages/_index.astro +5 -342
  180. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
  181. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
  182. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
  183. package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
  184. package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
  185. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
  186. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
  187. package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
  188. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
  189. package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
  190. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
  191. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
  192. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
  193. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
  194. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
  195. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
  196. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
  197. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
  198. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
  199. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
  200. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
  201. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
  202. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
  203. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
  204. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
  205. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
  206. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
  207. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
  208. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
  209. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
  210. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
  211. package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
  212. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
  213. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
  214. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
  215. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
  216. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
  217. package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
  218. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
  219. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
  220. package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
  221. package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
  222. package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
  223. package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
  224. package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
  225. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
  226. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
  227. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
  228. package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
  229. package/eventcatalog/src/pages/index.astro +4 -2
  230. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
  231. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +1 -0
  232. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
  233. package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
  234. package/eventcatalog/src/pages/settings/license.astro +9 -1
  235. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
  236. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
  237. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
  238. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
  239. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
  240. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
  241. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
  242. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
  243. package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
  244. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
  245. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
  246. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
  247. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
  248. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
  249. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
  250. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
  251. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
  252. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
  253. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
  254. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
  255. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
  256. package/eventcatalog/src/utils/collections/util.ts +8 -4
  257. package/eventcatalog/src/utils/feature.ts +8 -0
  258. package/eventcatalog/src/utils/git.ts +22 -5
  259. package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
  260. package/eventcatalog/src/utils/license.ts +1 -1
  261. package/eventcatalog/src/utils/link-validation.ts +25 -19
  262. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
  263. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
  264. package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +0 -2
  265. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
  266. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
  267. package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
  268. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
  269. package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
  270. package/eventcatalog/src/utils/page-title.ts +15 -0
  271. package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
  272. package/eventcatalog/src/utils/trial.ts +14 -1
  273. package/package.json +19 -13
  274. package/dist/runtime-dependencies/shelljs.mjs +0 -3
  275. package/eventcatalog/public/studio-bg.png +0 -0
  276. package/eventcatalog/src/components/Studio/StudioPageModal.tsx +0 -150
  277. package/eventcatalog/src/pages/studio.astro +0 -316
@@ -1,7 +1,14 @@
1
1
  import { hideMessageNodes, layoutWithElk } from '@eventcatalog/visualiser/layout';
2
+ import { isSSR } from '@utils/feature';
2
3
 
3
4
  type Graph = { nodes: any[]; edges: any[] };
4
5
 
6
+ // A build renders one route at a time (every message's docs page, then every schema page), so the
7
+ // cache has to outlast a whole route to be reused. A server keeps running as the catalog changes and
8
+ // renders pages as they're asked for, so it keeps the most recent layouts only.
9
+ const MAX_CACHED_LAYOUTS = isSSR() ? 200 : 5000;
10
+ const layouts = new Map<string, ReturnType<typeof layoutWithElk>>();
11
+
5
12
  /**
6
13
  * Lays a node graph out for the visualiser (with ELK, left to right). Builders
7
14
  * create their nodes and edges without positions and lay the finished graph
@@ -9,7 +16,19 @@ type Graph = { nodes: any[]; edges: any[] };
9
16
  * (nodes with children) are sized to fit them, and edges get the route they're
10
17
  * drawn along (`data.route`), with room for their labels.
11
18
  */
12
- export const layoutNodeGraph = async <G extends Graph>(graph: G): Promise<G> => (await layoutWithElk(graph)) as unknown as G;
19
+ export const layoutNodeGraph = async <G extends Graph>(graph: G): Promise<G> => {
20
+ // A build lays the same graph out on several pages (a message's docs, visualiser and schema pages):
21
+ // reuse the layout. Each caller gets its own copy, so it can't change the one kept.
22
+ const key = JSON.stringify(graph);
23
+ let layout = layouts.get(key);
24
+ if (!layout) {
25
+ layout = layoutWithElk(graph);
26
+ layouts.set(key, layout);
27
+ layout.catch(() => layouts.delete(key));
28
+ if (layouts.size > MAX_CACHED_LAYOUTS) layouts.delete(layouts.keys().next().value!);
29
+ }
30
+ return structuredClone(await layout) as unknown as G;
31
+ };
13
32
 
14
33
  /**
15
34
  * Lays out the graphs of a levels page: level 1 (`overview`: domains, systems
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The catalog resource a diagram node shows, for the node types the node graphs build. Has no imports so it can
3
+ * be shared by the server and the browser (the visualiser's "Open in Studio", the MCP App views).
4
+ */
5
+
6
+ // The collection each node type shows a resource of
7
+ const NODE_COLLECTIONS: Record<string, string> = {
8
+ service: 'services',
9
+ services: 'services',
10
+ agent: 'agents',
11
+ agents: 'agents',
12
+ event: 'events',
13
+ events: 'events',
14
+ command: 'commands',
15
+ commands: 'commands',
16
+ query: 'queries',
17
+ queries: 'queries',
18
+ channel: 'channels',
19
+ channels: 'channels',
20
+ flow: 'flows',
21
+ flows: 'flows',
22
+ data: 'containers',
23
+ containers: 'containers',
24
+ 'data-products': 'data-products',
25
+ domain: 'domains',
26
+ domains: 'domains',
27
+ 'context-domain': 'domains',
28
+ 'domain-group': 'domains',
29
+ system: 'systems',
30
+ systems: 'systems',
31
+ 'system-group': 'systems',
32
+ };
33
+
34
+ // Where each node type keeps the resource it shows
35
+ const RESOURCE_DATA_KEYS = [
36
+ 'service',
37
+ 'agent',
38
+ 'message',
39
+ 'channel',
40
+ 'data',
41
+ 'dataProduct',
42
+ 'flow',
43
+ 'entity',
44
+ 'domain',
45
+ 'system',
46
+ 'custom',
47
+ ];
48
+
49
+ type DiagramNode = { type?: string; data?: Record<string, unknown> };
50
+ type ResourceDetails = { id?: unknown; version?: unknown; [key: string]: unknown };
51
+
52
+ /** The resource a node shows, as in its data: the fields shown, or the catalog entry's data (if it holds the entry) */
53
+ export const getNodeResourceDetails = (node: DiagramNode): ResourceDetails | undefined => {
54
+ const data = node.data ?? {};
55
+ const resource = RESOURCE_DATA_KEYS.map((key) => data[key]).find(Boolean) as
56
+ | (ResourceDetails & { data?: ResourceDetails })
57
+ | undefined;
58
+ return resource?.data ?? resource;
59
+ };
60
+
61
+ /** The catalog resource a node shows (its collection, id and version), if it shows one */
62
+ export const getNodeCatalogResource = (node: DiagramNode): { collection: string; id: string; version?: string } | undefined => {
63
+ const collection = NODE_COLLECTIONS[node.type ?? ''];
64
+ const details = getNodeResourceDetails(node);
65
+ if (!collection || typeof details?.id !== 'string') return undefined;
66
+ return { collection, id: details.id, ...(typeof details.version === 'string' && { version: details.version }) };
67
+ };
@@ -142,7 +142,7 @@ const wrapNodesInSystemGroup = (systemNodes: any[], system: any) => {
142
142
  draggable: false,
143
143
  selectable: false,
144
144
  data: {
145
- system: { name: system.data.name, version: system.data.version },
145
+ system: { id: system.data.id, name: system.data.name, version: system.data.version },
146
146
  // The system is the resource being viewed on its own diagram
147
147
  isFocused: true,
148
148
  },
@@ -24,7 +24,9 @@ export class HybridPage<T = any> {
24
24
  }
25
25
 
26
26
  /**
27
- * Static method for getting data
27
+ * The page's data: its props in a static build, or looked up from its URL on a server. Undefined
28
+ * when nothing matches (an unknown resource or version): the page then returns
29
+ * `Astro.rewrite('/404')`. Throwing a Response instead made Astro answer with an empty 500.
28
30
  */
29
31
  static async getData(astro: AstroGlobal): Promise<any> {
30
32
  // Try props first (static mode)
@@ -32,13 +34,7 @@ export class HybridPage<T = any> {
32
34
  return this.transformProps(astro.props);
33
35
  }
34
36
 
35
- const data = await this.fetchData(astro.params);
36
-
37
- if (!data) {
38
- throw this.createNotFoundResponse();
39
- }
40
-
41
- return data;
37
+ return (await this.fetchData(astro.params)) ?? undefined;
42
38
  }
43
39
 
44
40
  /**
@@ -58,11 +54,4 @@ export class HybridPage<T = any> {
58
54
  protected static transformProps(props: any): any {
59
55
  return props;
60
56
  }
61
-
62
- protected static createNotFoundResponse(): Response {
63
- return new Response(null, {
64
- status: 404,
65
- statusText: 'Not found',
66
- });
67
- }
68
57
  }
@@ -0,0 +1,15 @@
1
+ import config from '@config';
2
+
3
+ /** The catalog's name: `title` in eventcatalog.config.js, or EventCatalog when it has none */
4
+ export const getCatalogTitle = (): string => config?.title?.trim() || 'EventCatalog';
5
+
6
+ /**
7
+ * A page's title, as browser tabs and link previews show it: the page's own title, then the
8
+ * catalog's (`Domains | Ordering | Acme Inc`), so tabs show the page first. A page without a title
9
+ * of its own (the homepage) is just the catalog's.
10
+ */
11
+ export const formatPageTitle = (title?: string): string => {
12
+ const catalogTitle = getCatalogTitle();
13
+ const pageTitle = title?.trim();
14
+ return pageTitle && pageTitle !== catalogTitle ? `${pageTitle} | ${catalogTitle}` : catalogTitle;
15
+ };
@@ -0,0 +1,64 @@
1
+ import { createElement, type CSSProperties, type ReactNode } from 'react';
2
+ import { createStyleObject } from 'react-syntax-highlighter/dist/cjs/create-element.js';
3
+
4
+ type Stylesheet = { [selector: string]: CSSProperties };
5
+ type HighlightedNode = {
6
+ type: 'element' | 'text';
7
+ value?: string | number;
8
+ tagName?: any;
9
+ properties?: { className?: string[]; style?: CSSProperties; [key: string]: unknown };
10
+ children?: HighlightedNode[];
11
+ };
12
+
13
+ const selectorsByStylesheet = new WeakMap<Stylesheet, Set<string>>();
14
+
15
+ /** The class names a theme styles, worked out once per theme */
16
+ const stylesheetSelectors = (stylesheet: Stylesheet) => {
17
+ let selectors = selectorsByStylesheet.get(stylesheet);
18
+ if (!selectors) {
19
+ selectors = new Set(Object.keys(stylesheet).flatMap((selector) => selector.split('.')));
20
+ selectorsByStylesheet.set(stylesheet, selectors);
21
+ }
22
+ return selectors;
23
+ };
24
+
25
+ const renderNode = (node: HighlightedNode, stylesheet: Stylesheet, useInlineStyles: boolean, key: string): ReactNode => {
26
+ if (node.type === 'text') return node.value;
27
+ if (!node.tagName) return undefined;
28
+
29
+ const properties = node.properties ?? {};
30
+ const classNames = properties.className;
31
+ let props;
32
+ if (!useInlineStyles) {
33
+ props = { ...properties, className: classNames?.join(' ') };
34
+ } else {
35
+ // Theme classes become inline styles; any other class names stay
36
+ const selectors = stylesheetSelectors(stylesheet);
37
+ const className =
38
+ classNames && (classNames.includes('token') ? ['token'] : []).concat(classNames.filter((name) => !selectors.has(name)));
39
+ props = {
40
+ ...properties,
41
+ className: className?.join(' ') || undefined,
42
+ style: createStyleObject(classNames ?? [], { ...properties.style }, stylesheet),
43
+ };
44
+ }
45
+
46
+ const children = (node.children ?? []).map((child, i) => renderNode(child, stylesheet, useInlineStyles, `code-segment-1-${i}`));
47
+ return createElement(node.tagName, { key, ...props }, children);
48
+ };
49
+
50
+ /**
51
+ * Renders react-syntax-highlighter's rows as its default renderer does (same elements, styles and keys), but
52
+ * works out the theme's class names once per theme rather than for every token: the default renderer did
53
+ * that for every token, which made highlighting a schema on the server take tens of milliseconds a page.
54
+ * Set `wrapLines`: with a custom renderer, react-syntax-highlighter turns it on when it isn't set.
55
+ */
56
+ export const renderHighlightedRows = ({
57
+ rows,
58
+ stylesheet,
59
+ useInlineStyles,
60
+ }: {
61
+ rows: HighlightedNode[];
62
+ stylesheet: Stylesheet;
63
+ useInlineStyles: boolean;
64
+ }): ReactNode[] => rows.map((node, i) => renderNode(node, stylesheet, useInlineStyles, `code-segment-${i}`));
@@ -1,10 +1,23 @@
1
- export const TRIAL_LENGTH_DAYS = 90;
1
+ export const TRIAL_LENGTH_DAYS = 60;
2
2
 
3
3
  export const LICENSE_FAQ_URL = 'https://www.eventcatalog.dev/license-faq';
4
4
 
5
5
  // Where a commercial license is renewed
6
6
  export const LICENSE_RENEW_URL = 'https://eventcatalog.cloud';
7
7
 
8
+ // Where the Business plan is bought: the order form on the website
9
+ export const BUY_BUSINESS_URL = 'https://www.eventcatalog.dev/buy?source=cli';
10
+
11
+ // Prices for a commercial license, linked while the trial is running
12
+ export const PRICING_URL = 'https://www.eventcatalog.dev/pricing';
13
+
14
+ // Questions about licensing or buying: talk to the EventCatalog team
15
+ export const TALK_TO_US_URL = 'https://www.eventcatalog.dev/book-demo';
16
+
17
+ // Shown with the trial, so organisations that qualify for Free Use don't read it as "EventCatalog is now paid"
18
+ export const FREE_USE_NOTE =
19
+ 'Under $10M revenue and $10M raised, an individual or an open-source project? You qualify for Free Use; get a free key at eventcatalog.cloud.';
20
+
8
21
  const DAY_IN_MS = 24 * 60 * 60 * 1000;
9
22
 
10
23
  export type TrialStatus = {
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "BUSL-1.1",
9
9
  "type": "module",
10
- "version": "5.0.0-beta.3",
10
+ "version": "5.0.0-beta.30",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -47,10 +47,10 @@
47
47
  ],
48
48
  "dependencies": {
49
49
  "@ai-sdk/react": "^4.0.109",
50
- "@astrojs/markdown-remark": "^7.3.1",
51
- "@astrojs/mdx": "^8.0.1",
52
- "@astrojs/node": "^11.1.6",
53
- "@astrojs/react": "^6.0.6",
50
+ "@astrojs/markdown-remark": "^7.3.2",
51
+ "@astrojs/mdx": "^8.0.3",
52
+ "@astrojs/node": "^11.1.7",
53
+ "@astrojs/react": "^7.0.1",
54
54
  "@astrojs/rss": "^4.0.19",
55
55
  "@asyncapi/avro-schema-parser": "3.0.24",
56
56
  "@asyncapi/parser": "^3.6.0",
@@ -60,7 +60,11 @@
60
60
  "@fontsource/inter": "^5.2.5",
61
61
  "@headlessui/react": "^2.0.3",
62
62
  "@heroicons/react": "^2.1.3",
63
+ "@hocuspocus/provider": "^4.7.0",
64
+ "@hocuspocus/server": "^4.7.0",
63
65
  "@iconify-json/logos": "^1.2.4",
66
+ "@mcp-b/webmcp-local-relay": "5.1.0",
67
+ "@mcp-b/webmcp-polyfill": "5.1.0",
64
68
  "@mermaid-js/layout-elk": "^0.2.0",
65
69
  "@modelcontextprotocol/ext-apps": "^1.7.5",
66
70
  "@modelcontextprotocol/sdk": "^1.30.0",
@@ -77,9 +81,9 @@
77
81
  "@tanstack/react-table": "^8.17.3",
78
82
  "@xyflow/react": "^12.12.0",
79
83
  "ai": "^7.0.106",
80
- "astro": "7.3.3",
84
+ "astro": "7.3.8",
81
85
  "astro-expressive-code": "^0.44.0",
82
- "astro-seo": "^0.8.4",
86
+ "astro-seo": "^1.2.0",
83
87
  "boxen": "^8.0.1",
84
88
  "commander": "^12.1.0",
85
89
  "cross-env": "^7.0.3",
@@ -93,8 +97,9 @@
93
97
  "elkjs": "^0.10.0",
94
98
  "glob": "^13.0.6",
95
99
  "gray-matter": "^4.0.3",
96
- "hono": "4.13.5",
100
+ "hono": "^4.13.7",
97
101
  "html-to-image": "^1.11.11",
102
+ "htmlparser2": "^12.0.0",
98
103
  "js-yaml": "^4.3.2",
99
104
  "jsonpath-plus": "^10.4.0",
100
105
  "jsonwebtoken": "^9.0.2",
@@ -113,6 +118,7 @@
113
118
  "picomatch": "^4.0.4",
114
119
  "react": "^19.2.0",
115
120
  "react-dom": "^19.2.0",
121
+ "react-hotkeys-hook": "^5.3.3",
116
122
  "react-markdown": "^10.1.0",
117
123
  "react-syntax-highlighter": "^16.1.1",
118
124
  "recast": "^0.23.11",
@@ -125,7 +131,6 @@
125
131
  "rimraf": "^6.1.3",
126
132
  "semver": "7.6.3",
127
133
  "set-cookie-parser": "^2.7.1",
128
- "shelljs": "^0.9.0",
129
134
  "sonner": "^2.0.7",
130
135
  "sql.js": "^1.12.0",
131
136
  "tailwindcss": "^4.3.1",
@@ -133,10 +138,12 @@
133
138
  "unist-util-visit": "^5.0.0",
134
139
  "update-notifier": "^7.3.1",
135
140
  "uuid": "^11.1.1",
141
+ "y-protocols": "^1.0.7",
142
+ "yjs": "^13.6.33",
136
143
  "zod": "^4.3.6",
137
- "@eventcatalog/linter": "1.2.0-beta.0",
138
- "@eventcatalog/sdk": "2.30.0-beta.0",
139
- "@eventcatalog/visualiser": "^5.0.0-beta.2"
144
+ "@eventcatalog/linter": "1.2.0-beta.4",
145
+ "@eventcatalog/sdk": "2.30.0-beta.1",
146
+ "@eventcatalog/visualiser": "^5.0.0-beta.7"
140
147
  },
141
148
  "devDependencies": {
142
149
  "@astrojs/check": "^0.9.10",
@@ -156,7 +163,6 @@
156
163
  "@types/react-syntax-highlighter": "^15.5.13",
157
164
  "@types/semver": "^7.5.8",
158
165
  "@types/set-cookie-parser": "^2.4.10",
159
- "@types/shelljs": "^0.8.15",
160
166
  "@types/update-notifier": "^6.0.8",
161
167
  "@types/uuid": "^10.0.0",
162
168
  "jsdom": "27.0.0",
@@ -1,3 +0,0 @@
1
- export * from "shelljs";
2
- import * as dependency from "shelljs";
3
- export default dependency.default;
Binary file
@@ -1,150 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import * as Dialog from '@radix-ui/react-dialog';
3
- import { ExternalLinkIcon, CheckIcon, ClipboardIcon, Loader2 } from 'lucide-react';
4
-
5
- const StudioPageModal: React.FC = () => {
6
- const [isOpen, setIsOpen] = useState(false);
7
- const [copySuccess, setCopySuccess] = useState(false);
8
- const [hasCopied, setHasCopied] = useState(false);
9
- const [isLoading, setIsLoading] = useState(false);
10
- const [error, setError] = useState<string | null>(null);
11
-
12
- useEffect(() => {
13
- const handleOpen = () => setIsOpen(true);
14
- window.addEventListener('openStudioModal', handleOpen);
15
- return () => window.removeEventListener('openStudioModal', handleOpen);
16
- }, []);
17
-
18
- const handleCopyResources = async () => {
19
- setIsLoading(true);
20
- setError(null);
21
-
22
- try {
23
- const response = await fetch('/api/catalog');
24
-
25
- if (!response.ok) {
26
- throw new Error('Failed to fetch catalog data');
27
- }
28
-
29
- const catalogData = await response.json();
30
-
31
- await navigator.clipboard.writeText(JSON.stringify(catalogData, null, 2));
32
- setCopySuccess(true);
33
- setHasCopied(true);
34
- setTimeout(() => setCopySuccess(false), 2000);
35
- } catch (err) {
36
- console.error('Failed to copy resources:', err);
37
- setError('Failed to copy resources. Please try again.');
38
- } finally {
39
- setIsLoading(false);
40
- }
41
- };
42
-
43
- const handleOpenStudio = () => {
44
- window.open(
45
- 'https://app.eventcatalog.studio/playground?import-resources=true&utm_source=eventcatalog&utm_medium=referral&utm_campaign=studio-page',
46
- '_blank'
47
- );
48
- setIsOpen(false);
49
- };
50
-
51
- return (
52
- <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
53
- <Dialog.Portal>
54
- <Dialog.Overlay className="fixed inset-0 bg-black/50 data-[state=open]:animate-overlayShow z-50" />
55
- <Dialog.Content className="fixed top-1/2 left-1/2 w-[90vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-xl focus:outline-hidden data-[state=open]:animate-contentShow z-[100]">
56
- <Dialog.Title className="text-lg font-semibold text-gray-900 mb-3">Open EventCatalog Studio</Dialog.Title>
57
-
58
- <Dialog.Description className="text-sm text-gray-600 mb-6">
59
- Import your catalog resources into{' '}
60
- <a
61
- href="https://eventcatalog.studio"
62
- className="text-gray-900 hover:text-gray-700 underline font-semibold"
63
- target="_blank"
64
- rel="noopener noreferrer"
65
- >
66
- EventCatalog Studio
67
- </a>{' '}
68
- to create architecture diagrams.
69
- </Dialog.Description>
70
-
71
- <div className="space-y-4">
72
- {/* Step 1: Copy Resources */}
73
- <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
74
- <h4 className="text-sm font-bold text-gray-900 mb-2">Step 1: Copy your resources</h4>
75
- <p className="text-xs text-gray-600 mb-3">Copy your EventCatalog resources to your clipboard.</p>
76
-
77
- <button
78
- onClick={handleCopyResources}
79
- disabled={isLoading}
80
- className={`w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md border transition-colors ${
81
- copySuccess
82
- ? 'bg-green-50 border-green-200 text-green-700'
83
- : isLoading
84
- ? 'bg-gray-100 border-gray-300 text-gray-400 cursor-not-allowed'
85
- : 'bg-white border-gray-300 text-gray-700 hover:bg-gray-50'
86
- }`}
87
- >
88
- {isLoading ? (
89
- <>
90
- <Loader2 className="w-4 h-4 animate-spin" />
91
- <span>Loading resources...</span>
92
- </>
93
- ) : copySuccess ? (
94
- <>
95
- <CheckIcon className="w-4 h-4" />
96
- <span>Copied!</span>
97
- </>
98
- ) : (
99
- <>
100
- <ClipboardIcon className="w-4 h-4" />
101
- <span>Copy resources to clipboard</span>
102
- </>
103
- )}
104
- </button>
105
-
106
- {error && <p className="text-xs text-red-600 mt-2">{error}</p>}
107
- </div>
108
-
109
- {/* Step 2: Open Studio */}
110
- <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
111
- <h4 className="text-sm font-bold text-gray-900 mb-2">Step 2: Open EventCatalog Studio</h4>
112
- <p className="text-xs text-gray-600 mb-3">
113
- Go to EventCatalog Studio and paste your resources into the modal dialog.
114
- </p>
115
-
116
- <button
117
- onClick={handleOpenStudio}
118
- disabled={!hasCopied}
119
- className={`w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md transition-colors ${
120
- hasCopied ? 'bg-gray-900 text-white hover:bg-gray-800' : 'bg-gray-300 text-gray-500 cursor-not-allowed'
121
- }`}
122
- >
123
- <ExternalLinkIcon className="w-4 h-4" />
124
- <span>Open EventCatalog Studio</span>
125
- </button>
126
-
127
- <p className="text-[12px] text-gray-500 italic mt-4 mb-0">
128
- All data is stored locally in your browser. Nothing is sent to external servers.
129
- </p>
130
- </div>
131
- </div>
132
-
133
- <div className="mt-6 flex justify-end">
134
- <Dialog.Close asChild>
135
- <button
136
- type="button"
137
- className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors"
138
- onClick={() => setIsOpen(false)}
139
- >
140
- Close
141
- </button>
142
- </Dialog.Close>
143
- </div>
144
- </Dialog.Content>
145
- </Dialog.Portal>
146
- </Dialog.Root>
147
- );
148
- };
149
-
150
- export default StudioPageModal;