@eventcatalog/core 5.0.0-beta.9 → 5.0.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 (460) hide show
  1. package/LICENSE +13 -12
  2. package/README.md +5 -5
  3. package/dist/analytics/analytics.cjs +1 -1
  4. package/dist/analytics/analytics.js +2 -2
  5. package/dist/analytics/log-build.cjs +91 -44
  6. package/dist/analytics/log-build.d.cts +2 -2
  7. package/dist/analytics/log-build.d.ts +2 -2
  8. package/dist/analytics/log-build.js +6 -5
  9. package/dist/analytics/studio-usage.cjs +90 -0
  10. package/dist/analytics/studio-usage.d.cts +5 -0
  11. package/dist/analytics/studio-usage.d.ts +5 -0
  12. package/dist/analytics/studio-usage.js +10 -0
  13. package/dist/catalog-runtime.cjs +1 -1
  14. package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
  15. package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
  16. package/dist/chunk-CA6WCQ2T.js +54 -0
  17. package/dist/{chunk-GAHKCOQM.js → chunk-JZN4RSMF.js} +1 -1
  18. package/dist/{chunk-JQMYHZWI.js → chunk-NEAVAFSJ.js} +16 -8
  19. package/dist/{chunk-4CFZUHGG.js → chunk-NIVST4WY.js} +1 -1
  20. package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
  21. package/dist/{chunk-ZEY2XUJN.js → chunk-OX6TSVHY.js} +6 -6
  22. package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
  23. package/dist/{chunk-EUNQJO3J.js → chunk-RE7UTPWH.js} +1 -1
  24. package/dist/chunk-S5GWAUG5.js +29 -0
  25. package/dist/{chunk-TZVDMWQX.js → chunk-YQGRMDRB.js} +4 -2
  26. package/dist/constants.cjs +1 -1
  27. package/dist/constants.js +1 -1
  28. package/dist/docs/api/02-config.md +57 -7
  29. package/dist/docs/development/00-why-eventcatalog.md +11 -11
  30. package/dist/docs/development/01-fundamentals.md +20 -13
  31. package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
  32. package/dist/docs/development/01-getting-started/installation.md +9 -1
  33. package/dist/docs/development/_getting-started.mdx +1 -1
  34. package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
  35. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
  36. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
  37. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
  38. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
  39. package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
  40. package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
  41. package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
  42. package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
  43. package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
  44. package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
  45. package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
  46. package/dist/docs/development/authentication/01-introduction.md +2 -23
  47. package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
  48. package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
  49. package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
  50. package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
  51. package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
  52. package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
  53. package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
  54. package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
  55. package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
  56. package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
  57. package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
  58. package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
  59. package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
  60. package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
  61. package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
  62. package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
  63. package/dist/docs/development/components/components/11-flow.md +17 -0
  64. package/dist/docs/development/components/components/15-nodegraph.md +43 -10
  65. package/dist/docs/development/components/components/18-remote-schema.md +1 -4
  66. package/dist/docs/development/components/custom-components/07-reference.md +14 -0
  67. package/dist/docs/development/customization/02-themes.md +0 -5
  68. package/dist/docs/development/customization/03-search.md +1 -1
  69. package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
  70. package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
  71. package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
  72. package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
  73. package/dist/docs/development/deployment/hosting-options.md +7 -2
  74. package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
  75. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
  76. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
  77. package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
  78. package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
  79. package/dist/docs/development/guides/97-architecture-graph.md +1 -1
  80. package/dist/docs/development/guides/99-adding-analytics.md +0 -7
  81. package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
  82. package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
  83. package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
  84. package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
  85. package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
  86. package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
  87. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
  88. package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
  89. package/dist/docs/development/guides/domains/09-reference.md +4 -4
  90. package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
  91. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
  92. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
  93. package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
  94. package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
  95. package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
  96. package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
  97. package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
  98. package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
  99. package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
  100. package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
  101. package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
  102. package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
  103. package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
  104. package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
  105. package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
  106. package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
  107. package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
  108. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
  109. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
  110. package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
  111. package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
  112. package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
  113. package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
  114. package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
  115. package/dist/docs/development/guides/systems/01-introduction.md +1 -1
  116. package/dist/docs/development/guides/systems/02-create-system.md +2 -2
  117. package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
  118. package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
  119. package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
  120. package/dist/docs/development/guides/systems/06-reference.md +4 -4
  121. package/dist/docs/development/license/01-license-file.md +151 -0
  122. package/dist/docs/development/license/_category_.json +12 -0
  123. package/dist/docs/development/license-keys/_category_.json +3 -3
  124. package/dist/docs/development/license-keys/integrations.md +7 -37
  125. package/dist/docs/development/license-keys/license-validation.md +4 -0
  126. package/dist/docs/development/license-keys/overview.md +5 -1
  127. package/dist/docs/development/license-keys/plans.md +4 -2
  128. package/dist/docs/development/studio/01-introduction.md +60 -0
  129. package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
  130. package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
  131. package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
  132. package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
  133. package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
  134. package/dist/docs/development/studio/07-reference.md +294 -0
  135. package/dist/docs/development/studio/_category_.json +12 -0
  136. package/dist/docs/development/upgrading/v5.md +345 -0
  137. package/dist/docs/federation/00-overview.md +2 -8
  138. package/dist/docs/federation/01-first-federation.md +6 -18
  139. package/dist/docs/federation/explanation/how-it-works.md +0 -4
  140. package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
  141. package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
  142. package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
  143. package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
  144. package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
  145. package/dist/docs/federation/how-to/run-in-ci.md +2 -9
  146. package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
  147. package/dist/docs/federation/how-to/use-local-sources.md +0 -4
  148. package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
  149. package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
  150. package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
  151. package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
  152. package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
  153. package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
  154. package/dist/docs/federation/reference/cli.md +2 -8
  155. package/dist/docs/federation/reference/configuration.md +0 -4
  156. package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
  157. package/dist/docs/federation/reference/generated-output.md +0 -4
  158. package/dist/docs/federation/reference/supported-content.md +0 -4
  159. package/dist/docs/federation/reference/troubleshooting.md +0 -14
  160. package/dist/docs/plugins/02-generators.md +1 -1
  161. package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
  162. package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
  163. package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
  164. package/dist/docs/plugins/apicurio/00-intro.md +2 -31
  165. package/dist/docs/plugins/apicurio/01-installation.md +2 -26
  166. package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
  167. package/dist/docs/plugins/apicurio/03-features.md +1 -3
  168. package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
  169. package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
  170. package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
  171. package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
  172. package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
  173. package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
  174. package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
  175. package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
  176. package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
  177. package/dist/docs/plugins/backstage/00-overview.md +1 -7
  178. package/dist/docs/plugins/backstage/01-get-started.md +6 -15
  179. package/dist/docs/plugins/backstage/06-configuration.md +2 -8
  180. package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
  181. package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
  182. package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
  183. package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
  184. package/dist/docs/plugins/eventbridge/03-api.md +2 -20
  185. package/dist/docs/plugins/github/00-intro.md +0 -31
  186. package/dist/docs/plugins/github/01-installation.md +2 -34
  187. package/dist/docs/plugins/graphql/00-intro.md +0 -30
  188. package/dist/docs/plugins/graphql/01-installation.md +1 -53
  189. package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
  190. package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
  191. package/dist/docs/plugins/openapi/00-intro.md +0 -30
  192. package/dist/docs/plugins/openapi/01-installation.md +1 -57
  193. package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
  194. package/dist/docs/plugins/openapi/03-features.md +0 -4
  195. package/dist/eventcatalog-config-file-utils.cjs +34 -41
  196. package/dist/eventcatalog-config-file-utils.d.cts +56 -58
  197. package/dist/eventcatalog-config-file-utils.d.ts +56 -58
  198. package/dist/eventcatalog-config-file-utils.js +1 -1
  199. package/dist/eventcatalog.cjs +340 -249
  200. package/dist/eventcatalog.config.d.cts +18 -15
  201. package/dist/eventcatalog.config.d.ts +18 -15
  202. package/dist/eventcatalog.js +51 -33
  203. package/dist/features.cjs +36 -49
  204. package/dist/features.d.cts +1 -3
  205. package/dist/features.d.ts +1 -3
  206. package/dist/features.js +4 -6
  207. package/dist/federation/federate.cjs +37 -44
  208. package/dist/federation/federate.js +5 -5
  209. package/dist/federation/source-provider.js +2 -2
  210. package/dist/generate.cjs +37 -42
  211. package/dist/generate.js +4 -4
  212. package/dist/resolve-catalog-dependencies.cjs +34 -41
  213. package/dist/resolve-catalog-dependencies.js +2 -2
  214. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
  215. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
  216. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
  217. package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
  218. package/dist/runtime-dependencies/manifest.json +5 -1
  219. package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
  220. package/dist/utils/child-process-signals.cjs +53 -0
  221. package/dist/utils/child-process-signals.d.cts +19 -0
  222. package/dist/utils/child-process-signals.d.ts +19 -0
  223. package/dist/utils/child-process-signals.js +6 -0
  224. package/dist/utils/cli-logger.cjs +1 -1
  225. package/dist/utils/cli-logger.js +2 -2
  226. package/dist/utils/license-status.cjs +11 -4
  227. package/dist/utils/license-status.d.cts +3 -2
  228. package/dist/utils/license-status.d.ts +3 -2
  229. package/dist/utils/license-status.js +1 -1
  230. package/eventcatalog/astro.config.mjs +21 -1
  231. package/eventcatalog/integrations/config-loader.mjs +56 -58
  232. package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
  233. package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
  234. package/eventcatalog/integrations/storage.mjs +20 -0
  235. package/eventcatalog/integrations/studio-server.mjs +4 -1
  236. package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
  237. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
  238. package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
  239. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
  240. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
  241. package/eventcatalog/src/components/NavigationProgress.astro +7 -0
  242. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
  243. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
  244. package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
  245. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
  246. package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
  247. package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
  248. package/eventcatalog/src/components/Search/search-utils.ts +26 -0
  249. package/eventcatalog/src/components/Seo.astro +5 -1
  250. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
  251. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
  252. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
  253. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
  254. package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
  255. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
  256. package/eventcatalog/src/components/Settings/Row.tsx +7 -4
  257. package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
  258. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
  259. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
  260. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
  261. package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
  262. package/eventcatalog/src/components/TrialBadge.astro +20 -9
  263. package/eventcatalog/src/content.config.ts +19 -2
  264. package/eventcatalog/src/features/auth/error.astro +4 -2
  265. package/eventcatalog/src/features/auth/login.astro +2 -1
  266. package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
  267. package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
  268. package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
  269. package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
  270. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
  271. package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
  272. package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
  273. package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
  274. package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
  275. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
  276. package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
  277. package/eventcatalog/src/features/server/start.ts +25 -0
  278. package/eventcatalog/src/features/storage/database.ts +88 -0
  279. package/eventcatalog/src/features/storage/migrations.ts +85 -0
  280. package/eventcatalog/src/features/storage/sql/database.sql +5 -0
  281. package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
  282. package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
  283. package/eventcatalog/src/features/storage/sql.ts +28 -0
  284. package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
  285. package/eventcatalog/src/features/studio/agents.ts +28 -0
  286. package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
  287. package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
  288. package/eventcatalog/src/features/studio/api/client.ts +40 -0
  289. package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
  290. package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
  291. package/eventcatalog/src/features/studio/catalog.ts +16 -14
  292. package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
  293. package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
  294. package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
  295. package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
  296. package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
  297. package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
  298. package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
  299. package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
  300. package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
  301. package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
  302. package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
  303. package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
  304. package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
  305. package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
  306. package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
  307. package/eventcatalog/src/features/studio/document-name.ts +7 -0
  308. package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
  309. package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
  310. package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
  311. package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
  312. package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
  313. package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
  314. package/eventcatalog/src/features/studio/identity.ts +25 -1
  315. package/eventcatalog/src/features/studio/limits.ts +2 -0
  316. package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
  317. package/eventcatalog/src/features/studio/pages/index.astro +596 -373
  318. package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
  319. package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
  320. package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
  321. package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
  322. package/eventcatalog/src/features/studio/server/storage.ts +53 -73
  323. package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
  324. package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
  325. package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
  326. package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
  327. package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
  328. package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
  329. package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
  330. package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
  331. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
  332. package/eventcatalog/src/pages/_index.astro +5 -342
  333. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
  334. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
  335. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
  336. package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
  337. package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
  338. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
  339. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
  340. package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
  341. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
  342. package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
  343. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
  344. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
  345. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
  346. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
  347. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
  348. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
  349. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
  350. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
  351. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
  352. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
  353. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
  354. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
  355. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
  356. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
  357. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
  358. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
  359. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
  360. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
  361. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
  362. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
  363. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
  364. package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
  365. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
  366. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
  367. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
  368. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
  369. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
  370. package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
  371. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
  372. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
  373. package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
  374. package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
  375. package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
  376. package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
  377. package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
  378. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
  379. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
  380. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
  381. package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
  382. package/eventcatalog/src/pages/index.astro +4 -2
  383. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
  384. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
  385. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
  386. package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
  387. package/eventcatalog/src/pages/settings/license.astro +9 -1
  388. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
  389. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
  390. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
  391. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
  392. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
  393. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
  394. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
  395. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
  396. package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
  397. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
  398. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
  399. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
  400. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
  401. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
  402. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
  403. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
  404. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
  405. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
  406. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
  407. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
  408. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
  409. package/eventcatalog/src/utils/collections/flows.ts +20 -7
  410. package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
  411. package/eventcatalog/src/utils/collections/resources.ts +2 -0
  412. package/eventcatalog/src/utils/collections/util.ts +8 -4
  413. package/eventcatalog/src/utils/git.ts +11 -0
  414. package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
  415. package/eventcatalog/src/utils/license.ts +1 -1
  416. package/eventcatalog/src/utils/link-validation.ts +25 -19
  417. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
  418. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
  419. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
  420. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
  421. package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
  422. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
  423. package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
  424. package/eventcatalog/src/utils/page-title.ts +15 -0
  425. package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
  426. package/eventcatalog/src/utils/trial.ts +13 -0
  427. package/package.json +11 -11
  428. package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
  429. package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
  430. package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
  431. package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
  432. package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
  433. package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
  434. package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
  435. package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
  436. package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
  437. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
  438. package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
  439. package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
  440. package/eventcatalog/src/features/studio/clipboard.ts +0 -97
  441. package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
  442. package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
  443. package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
  444. package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
  445. package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
  446. package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
  447. package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
  448. package/eventcatalog/src/features/studio/components/icons.ts +0 -53
  449. package/eventcatalog/src/features/studio/components/status.ts +0 -51
  450. package/eventcatalog/src/features/studio/edges.ts +0 -56
  451. package/eventcatalog/src/features/studio/flow-state.ts +0 -92
  452. package/eventcatalog/src/features/studio/grouping.ts +0 -226
  453. package/eventcatalog/src/features/studio/layout.ts +0 -42
  454. package/eventcatalog/src/features/studio/levels.ts +0 -282
  455. package/eventcatalog/src/features/studio/node-types.ts +0 -205
  456. package/eventcatalog/src/features/studio/pages/new.astro +0 -24
  457. package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
  458. package/eventcatalog/src/features/studio/placement.ts +0 -197
  459. package/eventcatalog/src/features/studio/studio.css +0 -273
  460. package/dist/{chunk-A2RZR3U4.js → chunk-6K7XZAYI.js} +3 -3
@@ -12,6 +12,7 @@ export const getStaticPaths = Page.getStaticPaths;
12
12
 
13
13
  // Get data
14
14
  const props = await Page.getData(Astro);
15
+ if (!props) return Astro.rewrite('/404');
15
16
 
16
17
  const {
17
18
  data: { id },
@@ -0,0 +1,38 @@
1
+ import type { PageTypes } from '@types';
2
+ import { isVisualiserEnabled } from '@utils/feature';
3
+ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
4
+
5
+ /** Resources with a visualiser page (domains and systems have their own, under the same URLs) */
6
+ const VISUALISER_TYPES: PageTypes[] = [
7
+ 'domains',
8
+ 'systems',
9
+ 'agents',
10
+ 'services',
11
+ 'events',
12
+ 'commands',
13
+ 'queries',
14
+ 'flows',
15
+ 'containers',
16
+ 'channels',
17
+ 'data-products',
18
+ ];
19
+
20
+ const isVisualiserType = (type: string | undefined): type is PageTypes => VISUALISER_TYPES.includes(type as PageTypes);
21
+
22
+ const getLatestWithVisualiser = async (type: PageTypes) =>
23
+ (await pageDataLoader[type]({ getAllVersions: false })).filter((item) => (item.data as any).visualiser !== false);
24
+
25
+ /** The latest version of every resource with a visualiser page: the pages a static build redirects from */
26
+ export const getVisualiserResources = async () => {
27
+ if (!isVisualiserEnabled()) return [];
28
+ const resources = await Promise.all(
29
+ VISUALISER_TYPES.map(async (type) => (await getLatestWithVisualiser(type)).map((item) => ({ type, item })))
30
+ );
31
+ return resources.flat();
32
+ };
33
+
34
+ /** The latest version of a resource with a visualiser page, looked up from its URL (a server renders pages on request) */
35
+ export const findVisualiserResource = async (type: string | undefined, id: string | undefined) => {
36
+ if (!isVisualiserEnabled() || !isVisualiserType(type) || !id) return undefined;
37
+ return (await getLatestWithVisualiser(type)).find((item) => item.data.id === id);
38
+ };
@@ -1,59 +1,36 @@
1
1
  ---
2
2
  import Seo from '@components/Seo.astro';
3
3
  import { buildUrl } from '@utils/url-builder';
4
- import { getEvents } from '@utils/collections/events';
5
- import { getCommands } from '@utils/collections/commands';
6
- import { getServices } from '@utils/collections/services';
7
- import { getDomains } from '@utils/collections/domains';
8
- import { getContainers } from '@utils/collections/containers';
9
- import type { CollectionEntry } from 'astro:content';
10
- import type { CollectionTypes } from '@types';
11
- import { isVisualiserEnabled } from '@utils/feature';
4
+ import { isSSR } from '@utils/feature';
5
+ import { findVisualiserResource, getVisualiserResources } from './_index.data';
12
6
 
13
- export async function getStaticPaths() {
14
- if (!isVisualiserEnabled()) {
15
- return [];
16
- }
17
-
18
- const [events, commands, services, domains, containers] = await Promise.all([
19
- getEvents(),
20
- getCommands(),
21
- getServices(),
22
- getDomains(),
23
- getContainers(),
24
- ]);
7
+ export const prerender = !isSSR();
25
8
 
26
- const resources = [...domains, ...events, ...services, ...commands, ...containers];
27
- const resourcesWithVisualiserEnabled = resources.filter((resource) => resource.data.visualiser !== false);
9
+ export async function getStaticPaths() {
10
+ const resources = await getVisualiserResources();
11
+ return resources.map(({ type, item }) => ({ params: { type, id: item.data.id }, props: item }));
12
+ }
28
13
 
29
- const buildPages = (collection: CollectionEntry<CollectionTypes>[]) => {
30
- return collection.map((item) => ({
31
- params: {
32
- type: item.collection,
33
- id: item.data.id,
34
- },
35
- props: {
36
- type: item.collection,
37
- ...item,
38
- },
39
- }));
40
- };
14
+ // A static build gets the resource from getStaticPaths; a server, which has no static paths, looks it up
15
+ const resource = isSSR() ? await findVisualiserResource(Astro.params.type, Astro.params.id) : Astro.props;
41
16
 
42
- return [...buildPages(resourcesWithVisualiserEnabled)];
17
+ if (!resource?.data) {
18
+ return new Response(null, { status: 404, statusText: 'Not found' });
43
19
  }
44
20
 
45
- const props = Astro.props;
46
- const pageTitle = `${props.collection} | ${props.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
47
-
48
- const { pathname } = Astro.url;
21
+ const pageTitle = `${resource.collection} | ${resource.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
22
+ const redirectUrl = buildUrl(`${Astro.url.pathname.replace(/\/$/, '')}/${resource.data.latestVersion}`, false, true);
49
23
 
50
- const redirectUrl = buildUrl(pathname + '/' + props.data.latestVersion, false, true);
24
+ // A server redirects straight away (with any query string); a static page redirects in the browser
25
+ if (isSSR()) {
26
+ return Astro.redirect(`${redirectUrl}${Astro.url.search}`);
27
+ }
51
28
  ---
52
29
 
53
30
  <!doctype html>
54
31
  <html lang="en">
55
32
  <head>
56
- <Seo title={`EventCatalog | ${pageTitle}`} ogTitle={pageTitle} />
33
+ <Seo title={pageTitle} />
57
34
  </head>
58
35
  <body>
59
36
  <p>You are being redirected to <a href={redirectUrl}>{redirectUrl}</a></p>
@@ -45,13 +45,6 @@ export class Page extends HybridPage {
45
45
  };
46
46
  }
47
47
 
48
- protected static createNotFoundResponse(): Response {
49
- return new Response(null, {
50
- status: 404,
51
- statusText: 'Design not found',
52
- });
53
- }
54
-
55
48
  static get clientAuthScript(): string {
56
49
  if (!isAuthEnabled() || !isVisualiserEnabled()) {
57
50
  return '';
@@ -13,7 +13,8 @@ const isChatEnabled = isEventCatalogChatVisible();
13
13
  export const prerender = Page.prerender;
14
14
  export const getStaticPaths = Page.getStaticPaths;
15
15
 
16
- const props = Astro.props;
16
+ const props = await Page.getData(Astro);
17
+ if (!props) return Astro.rewrite('/404');
17
18
 
18
19
  const { data } = props;
19
20
  ---
@@ -47,13 +47,6 @@ export class Page extends HybridPage {
47
47
  return item;
48
48
  }
49
49
 
50
- protected static createNotFoundResponse(): Response {
51
- return new Response(null, {
52
- status: 404,
53
- statusText: 'Domain entity map page not found',
54
- });
55
- }
56
-
57
50
  static get clientAuthScript(): string {
58
51
  if (!isAuthEnabled() || !isVisualiserEnabled()) {
59
52
  return '';
@@ -10,6 +10,7 @@ export const getStaticPaths = Page.getStaticPaths;
10
10
 
11
11
  // Get data
12
12
  const props = await Page.getData(Astro);
13
+ if (!props) return Astro.rewrite('/404');
13
14
 
14
15
  const {
15
16
  data: { id },
@@ -11,6 +11,7 @@ export const getStaticPaths = Page.getStaticPaths;
11
11
 
12
12
  // Get data
13
13
  const props = await Page.getData(Astro);
14
+ if (!props) return Astro.rewrite('/404');
14
15
 
15
16
  const {
16
17
  data: { id },
@@ -58,13 +58,6 @@ export class Page extends HybridPage {
58
58
  return item;
59
59
  }
60
60
 
61
- protected static createNotFoundResponse(): Response {
62
- return new Response(null, {
63
- status: 404,
64
- statusText: 'Domain System Diagram page not found',
65
- });
66
- }
67
-
68
61
  static get clientAuthScript(): string {
69
62
  if (!isAuthEnabled() || !isVisualiserEnabled()) {
70
63
  return '';
@@ -8,6 +8,7 @@ export const getStaticPaths = Page.getStaticPaths;
8
8
 
9
9
  // Get data
10
10
  const props = await Page.getData(Astro);
11
+ if (!props) return Astro.rewrite('/404');
11
12
 
12
13
  // The System Diagram is now level 1 of the domain's visualiser page
13
14
  return Astro.redirect(buildUrl(`/visualiser/domains/${props.data.id}/${props.data.version}?level=1`));
@@ -61,13 +61,6 @@ export class Page extends HybridPage {
61
61
  return item;
62
62
  }
63
63
 
64
- protected static createNotFoundResponse(): Response {
65
- return new Response(null, {
66
- status: 404,
67
- statusText: 'System Diagram page not found',
68
- });
69
- }
70
-
71
64
  static get clientAuthScript(): string {
72
65
  if (!isAuthEnabled() || !isVisualiserEnabled()) {
73
66
  return '';
@@ -8,6 +8,7 @@ export const getStaticPaths = Page.getStaticPaths;
8
8
 
9
9
  // Get data
10
10
  const props = await Page.getData(Astro);
11
+ if (!props) return Astro.rewrite('/404');
11
12
 
12
13
  // The System Context diagram is now level 1 of the system's visualiser page
13
14
  return Astro.redirect(buildUrl(`/visualiser/systems/${props.data.id}/${props.data.version}?level=1`));
@@ -11,6 +11,7 @@ export const getStaticPaths = Page.getStaticPaths;
11
11
 
12
12
  // Get data
13
13
  const props = await Page.getData(Astro);
14
+ if (!props) return Astro.rewrite('/404');
14
15
 
15
16
  const {
16
17
  data: { id },
@@ -12,3 +12,13 @@ declare module 'react-syntax-highlighter' {
12
12
  }
13
13
 
14
14
  declare module 'react-syntax-highlighter/dist/esm/styles/prism/material-light';
15
+
16
+ declare module 'react-syntax-highlighter/dist/cjs/create-element.js' {
17
+ import type { CSSProperties } from 'react';
18
+
19
+ export function createStyleObject(
20
+ classNames: string[],
21
+ elementStyle?: CSSProperties,
22
+ stylesheet?: { [selector: string]: CSSProperties }
23
+ ): CSSProperties;
24
+ }
@@ -166,30 +166,43 @@ export const getFlowsWithServiceStep = (
166
166
  );
167
167
  };
168
168
 
169
- /** A catalog entry a flow step points at (a service, message, agent, data store, data product or flow). */
169
+ /** A catalog entry a flow step points at (a service, system, channel, message, agent, data store, data product or flow). */
170
170
  type FlowStepResource = { collection: string; data: { id: string; version: string; [key: string]: any } };
171
171
 
172
172
  /**
173
173
  * The catalog resources a flow's steps point at, each listed once in step order: messages,
174
- * services, agents, data stores, data products and sub-flows (the same steps the flow's
175
- * sidebar lists). Expects steps as getFlows returns them, where messages, agents, data stores
176
- * and data products are already resolved; services and sub-flows are resolved here, with a
177
- * pointer without a version meaning the latest.
174
+ * services, systems, channels, agents, data stores, data products and sub-flows (the same steps
175
+ * the flow's sidebar lists). Expects steps as getFlows returns them, where messages, agents, data
176
+ * stores and data products are already resolved; services, systems, channels and sub-flows are
177
+ * resolved here, with a pointer without a version meaning the latest.
178
178
  */
179
179
  export const getFlowStepResources = (
180
180
  flow: Flow,
181
- catalog: { services: CollectionEntry<'services'>[]; flows: Flow[] }
181
+ catalog: {
182
+ services: CollectionEntry<'services'>[];
183
+ flows: Flow[];
184
+ systems?: CollectionEntry<'systems'>[];
185
+ channels?: CollectionEntry<'channels'>[];
186
+ }
182
187
  ): FlowStepResource[] => {
183
188
  const serviceMap = getVersionedMap(catalog.services);
184
189
  const flowMap = getVersionedMap(catalog.flows);
190
+ const systemMap = getVersionedMap(catalog.systems ?? []);
191
+ const channelMap = getVersionedMap(catalog.channels ?? []);
185
192
  const resources: FlowStepResource[] = [];
186
193
 
187
194
  for (const step of (flow.data.steps || []) as any[]) {
195
+ // `systems` is another name for a step's `system`
196
+ const system = step.system ?? step.systems;
188
197
  const resource = step.service
189
198
  ? findInMap(serviceMap, step.service.id, step.service.version)
190
199
  : step.flow
191
200
  ? findInMap(flowMap, step.flow.id, step.flow.version)
192
- : [step.message, step.agent, step.container, step.dataProduct].find(Array.isArray)?.[0];
201
+ : system
202
+ ? findInMap(systemMap, system.id, system.version)
203
+ : step.channel
204
+ ? findInMap(channelMap, step.channel.id, step.channel.version)
205
+ : [step.message, step.agent, step.container, step.dataProduct].find(Array.isArray)?.[0];
193
206
  if (resource?.data) resources.push(resource);
194
207
  }
195
208
 
@@ -70,6 +70,7 @@ export const createResourcesCatalog = () => {
70
70
  allFlows: once(() => getFlows()),
71
71
  currentFlows: once(() => getFlows({ getAllVersions: false })),
72
72
  rawChannels: once(() => getCollection('channels')),
73
+ rawSystems: once(() => getCollection('systems')),
73
74
  rawMessages: once(async () => [
74
75
  ...(await getCollection('events')),
75
76
  ...(await getCollection('commands')),
@@ -108,10 +109,15 @@ const relatedResourcesFor = async (type: ResourceOwnerCollection, catalog: Resou
108
109
  });
109
110
  }
110
111
  case 'flows': {
111
- const [services, flows] = await Promise.all([catalog.services(), catalog.allFlows()]);
112
+ const [services, flows, systems, channels] = await Promise.all([
113
+ catalog.services(),
114
+ catalog.allFlows(),
115
+ catalog.rawSystems(),
116
+ catalog.rawChannels(),
117
+ ]);
112
118
  return (owner) => ({
113
119
  adrs: adrsFor(owner),
114
- stepResources: getFlowStepResources(asEntry<'flows'>(owner), { services, flows }),
120
+ stepResources: getFlowStepResources(asEntry<'flows'>(owner), { services, flows, systems, channels }),
115
121
  });
116
122
  }
117
123
  case 'channels': {
@@ -94,6 +94,7 @@ const messageGroups = (messages: any[]): ResourceGroup[] => [
94
94
 
95
95
  // The collections a flow step can point at, in the order the page groups them.
96
96
  const FLOW_STEP_COLLECTIONS: ResourceCollection[] = [
97
+ 'systems',
97
98
  'services',
98
99
  'agents',
99
100
  'flows',
@@ -102,6 +103,7 @@ const FLOW_STEP_COLLECTIONS: ResourceCollection[] = [
102
103
  'events',
103
104
  'commands',
104
105
  'queries',
106
+ 'channels',
105
107
  ];
106
108
 
107
109
  export const getResourceGroups = (
@@ -1,16 +1,19 @@
1
1
  import type { CollectionTypes } from '@types';
2
2
  import type { CollectionEntry } from 'astro:content';
3
- import path from 'node:path';
4
3
  import { compareVersions, toComparableVersion, versionSatisfiesRange } from './version-compare';
5
4
 
6
5
  // --- FILE PATH HELPERS ---
7
6
 
7
+ // Without node:path: node graph builders that import this module also run in the browser (the Fields Explorer)
8
+ const pathSegments = (filePath: string) => filePath.split(/[\\/]/).filter(Boolean);
9
+ const getBasename = (filePath: string) => pathSegments(filePath).at(-1) ?? '';
10
+
8
11
  /**
9
12
  * Extract the folder name from an Astro collection entry's filePath.
10
13
  * Replaces the expensive SDK getResourceFolderName which globs + reads every file.
11
14
  */
12
15
  export const getFolderNameFromFilePath = (filePath: string): string => {
13
- return path.basename(path.dirname(filePath));
16
+ return pathSegments(filePath).at(-2) ?? '';
14
17
  };
15
18
 
16
19
  // --- SPECIFICATION HELPERS ---
@@ -73,8 +76,9 @@ export const processSpecifications = (
73
76
  return specs.map((spec) => ({
74
77
  ...spec,
75
78
  name: spec.name || getDefaultSpecificationName(spec.type),
76
- filename: path.basename(spec.path),
77
- filenameWithoutExtension: path.basename(spec.path, path.extname(spec.path)),
79
+ filename: getBasename(spec.path),
80
+ // Keeps a leading dot, as path.extname does (`.env` has no extension)
81
+ filenameWithoutExtension: getBasename(spec.path).replace(/(?<=.)\.[^.]*$/, ''),
78
82
  }));
79
83
  };
80
84
 
@@ -87,6 +87,17 @@ const readCommit = (filePath: string, age: 'newest' | 'oldest'): Commit => {
87
87
  return parseCommit(match.groups.header);
88
88
  };
89
89
 
90
+ /**
91
+ * When a file was last committed, from the history read once for the whole repository: never runs git for one file,
92
+ * so it's cheap to ask for many (e.g. every resource on the homepage). Undefined without git, or for a file that isn't
93
+ * committed.
94
+ */
95
+ export function getLastCommitDate(filePath: string): Date | undefined {
96
+ if (!hasGit()) return undefined;
97
+ const commit = getNewestCommits()?.get(toRealPath(filePath));
98
+ return commit ? new Date(commit.timestamp) : undefined;
99
+ }
100
+
90
101
  export function getGitHistory(
91
102
  filePath: string,
92
103
  {
@@ -0,0 +1,143 @@
1
+ import path from 'node:path';
2
+ import { statSync } from 'node:fs';
3
+ import { getCollection } from 'astro:content';
4
+ import { getLastCommitDate } from '@utils/git';
5
+ import { buildUrl } from '@utils/url-builder';
6
+
7
+ /** The resources the dashboard shows, by collection */
8
+ export type DashboardCollection = 'domains' | 'services' | 'events' | 'commands' | 'queries' | 'flows';
9
+
10
+ type Owner = { id: string };
11
+
12
+ /** The fields the dashboard reads from a collection entry */
13
+ export type DashboardEntry = {
14
+ filePath?: string;
15
+ data: {
16
+ id: string;
17
+ name?: string;
18
+ version: string;
19
+ summary?: string;
20
+ hidden?: boolean;
21
+ owners?: Owner[];
22
+ schemaPath?: string;
23
+ };
24
+ };
25
+
26
+ export type DashboardResource = {
27
+ collection: DashboardCollection;
28
+ id: string;
29
+ version: string;
30
+ name: string;
31
+ summary?: string;
32
+ href: string;
33
+ owners: { id: string; name: string }[];
34
+ updatedAt?: number;
35
+ };
36
+
37
+ export type DashboardData = {
38
+ counts: Record<DashboardCollection | 'messages' | 'schemas' | 'teams' | 'users', number>;
39
+ recentlyUpdated: DashboardResource[];
40
+ };
41
+
42
+ const MESSAGE_COLLECTIONS = ['events', 'commands', 'queries'] as const;
43
+
44
+ // The latest version of a resource that isn't hidden (older versions live in a `versioned` folder)
45
+ const isCurrent = (entry: DashboardEntry) => entry.data.hidden !== true && !entry.filePath?.includes('versioned');
46
+
47
+ /**
48
+ * Everything the homepage dashboard shows, from the catalog's collections: counts, and what changed recently.
49
+ */
50
+ export const buildDashboard = ({
51
+ collections,
52
+ teams,
53
+ users,
54
+ getUpdatedAt,
55
+ }: {
56
+ collections: Record<DashboardCollection, DashboardEntry[]>;
57
+ teams: DashboardEntry[];
58
+ users: DashboardEntry[];
59
+ /** When a resource's file last changed (unix ms), if known */
60
+ getUpdatedAt: (entry: DashboardEntry) => number | undefined;
61
+ }): DashboardData => {
62
+ const ownerNames = new Map<string, string>();
63
+ for (const owner of [...teams, ...users]) ownerNames.set(owner.data.id, owner.data.name ?? owner.data.id);
64
+
65
+ const toResource = (collection: DashboardCollection, entry: DashboardEntry): DashboardResource => ({
66
+ collection,
67
+ id: entry.data.id,
68
+ version: entry.data.version,
69
+ name: entry.data.name ?? entry.data.id,
70
+ summary: entry.data.summary?.trim() || undefined,
71
+ href: buildUrl(`/docs/${collection}/${entry.data.id}/${entry.data.version}`),
72
+ owners: (entry.data.owners ?? []).map(({ id }) => ({ id, name: ownerNames.get(id) ?? id })),
73
+ updatedAt: getUpdatedAt(entry),
74
+ });
75
+
76
+ const current = Object.fromEntries(
77
+ Object.entries(collections).map(([collection, entries]) => [collection, entries.filter(isCurrent)])
78
+ ) as Record<DashboardCollection, DashboardEntry[]>;
79
+ const messages = MESSAGE_COLLECTIONS.flatMap((collection) => current[collection]);
80
+ const all = (Object.keys(current) as DashboardCollection[]).flatMap((collection) =>
81
+ current[collection].map((entry) => ({ entry, resource: toResource(collection, entry) }))
82
+ );
83
+
84
+ const recentlyUpdated = all
85
+ .map(({ resource }) => resource)
86
+ .filter((resource) => resource.updatedAt !== undefined)
87
+ .sort((a, b) => b.updatedAt! - a.updatedAt!)
88
+ .slice(0, 8);
89
+
90
+ const withSchema = messages.filter((entry) => entry.data.schemaPath).length;
91
+
92
+ return {
93
+ counts: {
94
+ domains: current.domains.length,
95
+ services: current.services.length,
96
+ events: current.events.length,
97
+ commands: current.commands.length,
98
+ queries: current.queries.length,
99
+ flows: current.flows.length,
100
+ messages: messages.length,
101
+ schemas: withSchema,
102
+ teams: teams.filter(isCurrent).length,
103
+ users: users.filter(isCurrent).length,
104
+ },
105
+ recentlyUpdated,
106
+ };
107
+ };
108
+
109
+ // When a resource's file last changed: its last commit, or (without git, or before it's committed) the file's date
110
+ const getUpdatedAt = (entry: DashboardEntry) => {
111
+ if (!entry.filePath) return undefined;
112
+ const file = path.resolve(process.env.PROJECT_DIR || process.cwd(), entry.filePath);
113
+ const committed = getLastCommitDate(file);
114
+ if (committed) return committed.getTime();
115
+ try {
116
+ return statSync(file).mtimeMs;
117
+ } catch {
118
+ return undefined;
119
+ }
120
+ };
121
+
122
+ /** The homepage dashboard for this catalog */
123
+ export const getDashboard = async (): Promise<DashboardData> => {
124
+ const [domains, services, events, commands, queries, flows, teams, users] = await Promise.all([
125
+ getCollection('domains'),
126
+ getCollection('services'),
127
+ getCollection('events'),
128
+ getCollection('commands'),
129
+ getCollection('queries'),
130
+ getCollection('flows'),
131
+ getCollection('teams'),
132
+ getCollection('users'),
133
+ ]);
134
+ return buildDashboard({
135
+ collections: { domains, services, events, commands, queries, flows } as unknown as Record<
136
+ DashboardCollection,
137
+ DashboardEntry[]
138
+ >,
139
+ teams: teams as unknown as DashboardEntry[],
140
+ users: users as unknown as DashboardEntry[],
141
+ getUpdatedAt,
142
+ });
143
+ };
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { clearCache, hasCommercialLicense, verifyOfflineLicense } from '@eventcatalog/license';
4
4
 
5
- export { LICENSE_FAQ_URL, LICENSE_RENEW_URL } from './trial';
5
+ export { BUY_BUSINESS_URL, LICENSE_FAQ_URL, LICENSE_RENEW_URL, PRICING_URL } from './trial';
6
6
 
7
7
  // Details from the license token
8
8
  export type LicenseDetails = { org?: string; licenseId?: string; issuedAt?: Date };
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { parse, type DefaultTreeAdapterMap } from 'parse5';
3
+ import { Parser } from 'htmlparser2';
4
4
  import picomatch from 'picomatch';
5
5
 
6
6
  export type LinkValidationSeverity = 'warn' | 'error' | 'ignore';
@@ -42,30 +42,36 @@ const decodeUrlPart = (value: string): string => {
42
42
  }
43
43
  };
44
44
 
45
+ // Elements whose contents browsers don't render as markup (<noscript> when scripts run)
46
+ const INERT_ELEMENTS = new Set(['template', 'noscript']);
47
+
45
48
  // Parse HTML rather than searching markup with a regex: attributes can contain
46
49
  // entities, quoted > characters, or single/unquoted values. Scripts and inert
47
50
  // template contents must not be mistaken for rendered links or anchor targets.
51
+ // A streaming parser, not a document tree: pages can be large (island props),
52
+ // and building a tree of each one made link validation a large part of a build.
48
53
  const readPage = (html: string, source: string): PageLinks => {
49
54
  const page: PageLinks = { source, anchors: new Set(), links: new Set() };
50
- const nodes: DefaultTreeAdapterMap['node'][] = [parse(html)];
51
- while (nodes.length > 0) {
52
- const node = nodes.pop()!;
53
- if ('tagName' in node) {
54
- const attrs = new Map(node.attrs.map((attr) => [attr.name, attr.value]));
55
- const id = attrs.get('id');
56
- if (id) page.anchors.add(id);
57
- if (node.tagName === 'a' && attrs.get('name')) page.anchors.add(attrs.get('name')!);
58
- const href = attrs.get('href');
59
- if (href !== undefined) {
60
- if (node.tagName === 'base' && page.baseHref === undefined) page.baseHref = href;
61
- if (node.tagName === 'a' || node.tagName === 'area') page.links.add(href);
55
+ let inert = 0;
56
+ const parser = new Parser({
57
+ onopentag(tagName, attrs) {
58
+ if (inert === 0) {
59
+ if (attrs.id) page.anchors.add(attrs.id);
60
+ if (tagName === 'a' && attrs.name) page.anchors.add(attrs.name);
61
+ const href = attrs.href;
62
+ if (href !== undefined) {
63
+ // Parsed in document order, so the first <base href> wins
64
+ if (tagName === 'base' && page.baseHref === undefined) page.baseHref = href;
65
+ if (tagName === 'a' || tagName === 'area') page.links.add(href);
66
+ }
62
67
  }
63
- }
64
- // Reverse the stack so the first <base href> wins in document order.
65
- if ('childNodes' in node) {
66
- for (let i = node.childNodes.length - 1; i >= 0; i--) nodes.push(node.childNodes[i]);
67
- }
68
- }
68
+ if (INERT_ELEMENTS.has(tagName)) inert++;
69
+ },
70
+ onclosetag(tagName) {
71
+ if (INERT_ELEMENTS.has(tagName) && inert > 0) inert--;
72
+ },
73
+ });
74
+ parser.end(html);
69
75
  return page;
70
76
  };
71
77
 
@@ -212,7 +212,9 @@ export const getNodesAndEdges = async ({ id, version, entities, type = 'domains'
212
212
  height: 20,
213
213
  },
214
214
  });
215
- } else {
215
+ } else if (!entityMap.has(referencedEntityId)) {
216
+ // Only a reference to an entity missing from the catalog is broken. An external entity's own
217
+ // references can point further away than this map shows: those edges are left out.
216
218
  console.warn(`Referenced entity "${referencedEntityId}" not found for ${entity.data.name}.${referenceProperty.name}`);
217
219
  }
218
220
  }