@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
@@ -22,19 +22,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.7.0_postcss@8.5.15_tsx@4.21.0_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js
25
+ // ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.7.0_postcss@8.5.29_tsx@4.23.15_typescript@5.9.3_yaml@2.9.1/node_modules/tsup/assets/cjs_shims.js
26
26
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
27
27
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
28
28
 
29
29
  // src/eventcatalog.ts
30
30
  var import_commander = require("commander");
31
31
  var import_node_child_process2 = require("child_process");
32
- var import_node_path20 = require("path");
32
+ var import_node_path21 = require("path");
33
33
  var import_node_http = __toESM(require("http"), 1);
34
34
  var import_fs = __toESM(require("fs"), 1);
35
- var import_node_path21 = __toESM(require("path"), 1);
35
+ var import_node_path22 = __toESM(require("path"), 1);
36
36
  var import_node_url2 = require("url");
37
- var import_node_module2 = require("module");
37
+ var import_node_module3 = require("module");
38
38
 
39
39
  // src/generate.js
40
40
  var import_node_path3 = __toESM(require("path"), 1);
@@ -50,65 +50,58 @@ var import_promises = require("fs/promises");
50
50
  var import_node_fs = require("fs");
51
51
  var import_node_path = __toESM(require("path"), 1);
52
52
  var import_node_url = require("url");
53
- var import_node_os = require("os");
53
+ var import_node_module = require("module");
54
54
  async function cleanup(projectDirectory) {
55
55
  const filePath = import_node_path.default.join(projectDirectory, "eventcatalog.config.mjs");
56
56
  if ((0, import_node_fs.existsSync)(filePath)) {
57
57
  await (0, import_promises.rm)(filePath);
58
58
  }
59
59
  }
60
- var findNodeModulesDirectory = (directory) => {
61
- let currentDirectory = directory;
62
- while (true) {
63
- const nodeModulesDirectory = import_node_path.default.join(currentDirectory, "node_modules");
64
- if ((0, import_node_fs.existsSync)(nodeModulesDirectory)) {
65
- return nodeModulesDirectory;
66
- }
67
- const parentDirectory = import_node_path.default.dirname(currentDirectory);
68
- if (parentDirectory === currentDirectory) {
69
- return void 0;
70
- }
71
- currentDirectory = parentDirectory;
72
- }
73
- };
74
- var linkNodeModulesIntoTempDirectory = async ({ projectDirectory, tempDir }) => {
75
- const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
76
- if (!nodeModulesDirectory) {
77
- return;
78
- }
79
- await (0, import_promises.symlink)(nodeModulesDirectory, import_node_path.default.join(tempDir, "node_modules"), "dir");
60
+ var hidesConfigModuleTypeWarning = false;
61
+ var loads = 0;
62
+ var hideConfigModuleTypeWarning = () => {
63
+ if (hidesConfigModuleTypeWarning) return;
64
+ hidesConfigModuleTypeWarning = true;
65
+ const emitWarning = process.emitWarning;
66
+ process.emitWarning = function(warning, ...args) {
67
+ const code = typeof args[0] === "object" ? args[0]?.code : args[1];
68
+ const message2 = typeof warning === "string" ? warning : warning?.message;
69
+ if (code === "MODULE_TYPELESS_PACKAGE_JSON" && message2?.includes("eventcatalog.config.js")) return;
70
+ return emitWarning.call(this, warning, ...args);
71
+ };
80
72
  };
81
- var createTemporaryConfigDirectory = async (projectDirectory) => {
82
- const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
83
- if (nodeModulesDirectory) {
84
- return (0, import_promises.mkdtemp)(import_node_path.default.join(nodeModulesDirectory, ".eventcatalog-config-"));
73
+ var AS_MODULE_QUERY = "eventcatalog-config-as-module";
74
+ var loadsMarkedConfigsAsModules = false;
75
+ var loadMarkedConfigsAsModules = () => {
76
+ if (loadsMarkedConfigsAsModules) return;
77
+ loadsMarkedConfigsAsModules = true;
78
+ const hook = `export async function load(url, context, nextLoad) {
79
+ return nextLoad(url, url.includes('${AS_MODULE_QUERY}=') ? { ...context, format: 'module' } : context);
80
+ }`;
81
+ (0, import_node_module.register)(`data:text/javascript,${encodeURIComponent(hook)}`);
82
+ };
83
+ var isCommonJSPackage = async (projectDirectory) => {
84
+ try {
85
+ const packageJson = JSON.parse(await (0, import_promises.readFile)(import_node_path.default.join(projectDirectory, "package.json"), "utf-8"));
86
+ return packageJson?.type === "commonjs";
87
+ } catch {
88
+ return false;
85
89
  }
86
- const tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
87
- await linkNodeModulesIntoTempDirectory({ projectDirectory, tempDir });
88
- return tempDir;
89
90
  };
90
91
  var getEventCatalogConfigFile = async (projectDirectory) => {
91
- let tempDir;
92
92
  try {
93
- let configFilePath = import_node_path.default.join(projectDirectory, "eventcatalog.config.js");
94
- const filePath = import_node_path.default.join(projectDirectory, "package.json");
95
- const packageJson = JSON.parse(await (0, import_promises.readFile)(filePath, "utf-8"));
96
- if (packageJson?.type !== "module") {
97
- tempDir = await createTemporaryConfigDirectory(projectDirectory);
98
- configFilePath = import_node_path.default.join(tempDir, "eventcatalog.config.mjs");
99
- await (0, import_promises.copyFile)(import_node_path.default.join(projectDirectory, "eventcatalog.config.js"), configFilePath);
100
- }
101
- const configFileURL = `${(0, import_node_url.pathToFileURL)(configFilePath).href}?t=${Date.now()}`;
93
+ hideConfigModuleTypeWarning();
94
+ const asModule = await isCommonJSPackage(projectDirectory);
95
+ if (asModule) loadMarkedConfigsAsModules();
96
+ const configFileURL = (0, import_node_url.pathToFileURL)(import_node_path.default.join(projectDirectory, "eventcatalog.config.js")).href;
97
+ const query = `${asModule ? AS_MODULE_QUERY : "loaded"}=${Date.now()}-${loads++}`;
102
98
  const config = await import(
103
99
  /* @vite-ignore */
104
- configFileURL
100
+ `${configFileURL}?${query}`
105
101
  );
106
102
  return config.default;
107
103
  } finally {
108
104
  await cleanup(projectDirectory);
109
- if (tempDir) {
110
- await (0, import_promises.rm)(tempDir, { recursive: true, force: true });
111
- }
112
105
  }
113
106
  };
114
107
 
@@ -181,7 +174,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
181
174
  var import_picocolors = __toESM(require("picocolors"), 1);
182
175
 
183
176
  // package.json
184
- var version = "5.0.0-beta.9";
177
+ var version = "5.0.0";
185
178
 
186
179
  // src/constants.ts
187
180
  var VERSION = version;
@@ -295,10 +288,12 @@ var generate = async (PROJECT_DIRECTORY) => {
295
288
  for (const { plugin } of errors) {
296
289
  logger.error(` - ${plugin}`, "generator");
297
290
  }
291
+ process.exitCode = 1;
298
292
  }
299
293
  } catch (error) {
300
294
  console.error(error);
301
295
  await cleanup(PROJECT_DIRECTORY);
296
+ process.exitCode = 1;
302
297
  }
303
298
  };
304
299
 
@@ -427,6 +422,9 @@ var import_license2 = require("@eventcatalog/license");
427
422
  var TRIAL_LENGTH_DAYS = 60;
428
423
  var LICENSE_FAQ_URL = "https://www.eventcatalog.dev/license-faq";
429
424
  var LICENSE_RENEW_URL = "https://eventcatalog.cloud";
425
+ var BUY_BUSINESS_URL = "https://www.eventcatalog.dev/buy?source=cli";
426
+ var PRICING_URL = "https://www.eventcatalog.dev/pricing";
427
+ var FREE_USE_NOTE = "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.";
430
428
  var DAY_IN_MS = 24 * 60 * 60 * 1e3;
431
429
  var getTrialStatus = (tsd, now = Date.now()) => {
432
430
  if (typeof tsd !== "number" || !Number.isFinite(tsd) || tsd <= 0) return;
@@ -545,15 +543,17 @@ var formatDate = (date) => date.toLocaleDateString(void 0, { dateStyle: "medium"
545
543
  var formatDays = (days) => `${days} ${days === 1 ? "day" : "days"}`;
546
544
  var PLAIN = { bold: (text) => text, dim: (text) => text, link: (text) => text };
547
545
  var COLOURS = { bold: import_picocolors2.default.bold, dim: import_picocolors2.default.dim, link: (text) => import_picocolors2.default.cyan(text) };
548
- var render = ({ headline, rows, links }, colours) => {
546
+ var render = ({ headline, rows, links, note }, colours) => {
549
547
  const width = Math.max(0, ...[...rows, ...links].map(([label]) => label.length));
550
548
  const row = ([label, value]) => `${colours.dim(label.padEnd(width))} ${value}`;
551
549
  return [
552
550
  colours.bold(headline),
553
551
  ...rows.length ? ["", ...rows.map(row)] : [],
554
- ...links.length ? ["", ...links.map(([label, url]) => row([label, colours.link(url)]))] : []
552
+ ...links.length ? ["", ...links.map(([label, url]) => row([label, colours.link(url)]))] : [],
553
+ ...note?.length ? ["", ...note.map(colours.dim)] : []
555
554
  ].join("\n");
556
555
  };
556
+ var FREE_USE_LINES = FREE_USE_NOTE.split(/(?<=\?) /);
557
557
  var message = (content) => ({
558
558
  ...content,
559
559
  text: render(content, PLAIN)
@@ -600,7 +600,8 @@ var getLicenseStatusMessage = (license, tsd, now = Date.now()) => {
600
600
  color: trial.ended ? "yellow" : "green",
601
601
  headline: trial.ended ? "Your EventCatalog trial has ended" : `You're on the ${TRIAL_LENGTH_DAYS}-day EventCatalog trial`,
602
602
  rows: trialRows,
603
- links: trial.ended ? [["Get a license", LICENSE_RENEW_URL], licensing] : [licensing]
603
+ links: trial.ended ? [["Get a license", LICENSE_RENEW_URL], ["Buy Business", BUY_BUSINESS_URL], licensing] : [["Buy a license", PRICING_URL], licensing],
604
+ note: trial.ended ? FREE_USE_LINES : void 0
604
605
  });
605
606
  }
606
607
  if (license.state === "expired") {
@@ -614,7 +615,8 @@ var getLicenseStatusMessage = (license, tsd, now = Date.now()) => {
614
615
  title: "EventCatalog license",
615
616
  color: "yellow",
616
617
  headline: "Your commercial license has expired",
617
- rows: [...licensedTo, ...expiredOn, ...trialRows],
618
+ // A catalog has a license or is on the trial: an expired license is renewed, not replaced by the trial
619
+ rows: [...licensedTo, ...expiredOn],
618
620
  links: [renew, licensing]
619
621
  });
620
622
  }
@@ -641,6 +643,55 @@ var printLicenseStatus = (license, tsd) => {
641
643
  );
642
644
  };
643
645
 
646
+ // src/analytics/studio-usage.js
647
+ var import_node_fs3 = __toESM(require("fs"), 1);
648
+ var import_node_path6 = __toESM(require("path"), 1);
649
+ var DAY_IN_MS3 = 24 * 60 * 60 * 1e3;
650
+ var DEFAULT_DATABASE_PATH = ".eventcatalog/eventcatalog.db";
651
+ var getStudioMode = (configFile) => {
652
+ const enabled = configFile.studio?.enabled;
653
+ if (enabled === false) return "off";
654
+ return configFile.output === "server" && enabled === true ? "server" : "dev";
655
+ };
656
+ var getStorageType = (configFile) => configFile.storage?.type || "memory";
657
+ var loadSqlite = () => {
658
+ const emitWarning = process.emitWarning;
659
+ process.emitWarning = function(warning, ...args) {
660
+ const type = typeof args[0] === "object" ? args[0]?.type : args[0];
661
+ const message2 = typeof warning === "string" ? warning : warning?.message;
662
+ if (type === "ExperimentalWarning" && message2?.startsWith("SQLite")) return;
663
+ return emitWarning.call(this, warning, ...args);
664
+ };
665
+ try {
666
+ return process.getBuiltinModule?.("node:sqlite");
667
+ } catch {
668
+ return void 0;
669
+ } finally {
670
+ process.emitWarning = emitWarning;
671
+ }
672
+ };
673
+ var UNKNOWN = "canvases:unknown";
674
+ var serializeStudioUsage = (projectDirectory, configFile, now = Date.now()) => {
675
+ if (getStudioMode(configFile) === "off" || getStorageType(configFile) !== "sqlite") return UNKNOWN;
676
+ const file = import_node_path6.default.resolve(projectDirectory, configFile.storage.path ?? DEFAULT_DATABASE_PATH);
677
+ if (!import_node_fs3.default.existsSync(file)) return "canvases:0,changed7d:0,changed30d:0,deleted:0";
678
+ let database;
679
+ try {
680
+ const sqlite = loadSqlite();
681
+ if (!sqlite?.DatabaseSync) return UNKNOWN;
682
+ database = new sqlite.DatabaseSync(file, { readOnly: true });
683
+ const canvases = database.prepare(
684
+ "SELECT COUNT(*) AS total, SUM(updated_at >= ?) AS changed7d, SUM(updated_at >= ?) AS changed30d FROM studio_canvases"
685
+ ).get(now - 7 * DAY_IN_MS3, now - 30 * DAY_IN_MS3);
686
+ const { deleted } = database.prepare("SELECT COUNT(*) AS deleted FROM studio_deleted_canvases").get();
687
+ return `canvases:${canvases.total},changed7d:${canvases.changed7d ?? 0},changed30d:${canvases.changed30d ?? 0},deleted:${deleted}`;
688
+ } catch {
689
+ return UNKNOWN;
690
+ } finally {
691
+ database?.close();
692
+ }
693
+ };
694
+
644
695
  // src/analytics/log-build.js
645
696
  var isMCPEnabled = (configFile) => configFile.output === "server" && (configFile.mcp?.enabled ?? true);
646
697
  var getFeatures = async (configFile) => {
@@ -654,7 +705,9 @@ var getFeatures = async (configFile) => {
654
705
  environments: Array.isArray(configFile.environments) && configFile.environments.length > 0,
655
706
  output: configFile.output || "static",
656
707
  mcp,
657
- mcpAuth: mcp && (configFile.mcp?.auth?.enabled ?? false)
708
+ mcpAuth: mcp && (configFile.mcp?.auth?.enabled ?? false),
709
+ studio: getStudioMode(configFile),
710
+ storage: getStorageType(configFile)
658
711
  };
659
712
  };
660
713
  var getDirectoryProvider = (source) => {
@@ -755,7 +808,8 @@ var main = async (projectDir, { command = "build", license } = {}) => {
755
808
  generators: generatorNames.toString(),
756
809
  features: Object.keys(features).map((feature) => `${feature}:${features[feature]}`).join(","),
757
810
  directorySources: serializeDirectorySources(configFile),
758
- resources: serializeCounts(resourceCounts)
811
+ resources: serializeCounts(resourceCounts),
812
+ studio: serializeStudioUsage(projectDir, configFile)
759
813
  },
760
814
  configFile
761
815
  );
@@ -776,8 +830,8 @@ async function watch(projectDirectory, catalogDirectory, callback = () => {
776
830
  }
777
831
 
778
832
  // src/resolve-catalog-dependencies.js
779
- var import_node_path6 = __toESM(require("path"), 1);
780
- var import_node_fs3 = __toESM(require("fs"), 1);
833
+ var import_node_path7 = __toESM(require("path"), 1);
834
+ var import_node_fs4 = __toESM(require("fs"), 1);
781
835
  var import_gray_matter2 = __toESM(require("gray-matter"), 1);
782
836
  var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
783
837
  const catalogConfig = await getEventCatalogConfigFile(catalogDir);
@@ -785,11 +839,11 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
785
839
  if (!dependencies) {
786
840
  return;
787
841
  }
788
- const dependenciesDir = import_node_path6.default.join(catalogDir, "dependencies");
789
- if (import_node_fs3.default.existsSync(dependenciesDir)) {
790
- import_node_fs3.default.rmSync(dependenciesDir, { recursive: true, force: true });
842
+ const dependenciesDir = import_node_path7.default.join(catalogDir, "dependencies");
843
+ if (import_node_fs4.default.existsSync(dependenciesDir)) {
844
+ import_node_fs4.default.rmSync(dependenciesDir, { recursive: true, force: true });
791
845
  }
792
- import_node_fs3.default.mkdirSync(dependenciesDir, { recursive: true });
846
+ import_node_fs4.default.mkdirSync(dependenciesDir, { recursive: true });
793
847
  const resourceTypes = Object.keys(dependencies);
794
848
  for (const resourceType of resourceTypes) {
795
849
  for (const dependency of dependencies[resourceType]) {
@@ -809,9 +863,9 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
809
863
  },
810
864
  frontmatter
811
865
  );
812
- const resourceFile = import_node_path6.default.join(dependenciesDir, resourceType, dependency.id, `index.md`);
813
- import_node_fs3.default.mkdirSync(import_node_path6.default.dirname(resourceFile), { recursive: true });
814
- import_node_fs3.default.writeFileSync(resourceFile, markdown);
866
+ const resourceFile = import_node_path7.default.join(dependenciesDir, resourceType, dependency.id, `index.md`);
867
+ import_node_fs4.default.mkdirSync(import_node_path7.default.dirname(resourceFile), { recursive: true });
868
+ import_node_fs4.default.writeFileSync(resourceFile, markdown);
815
869
  }
816
870
  }
817
871
  return;
@@ -821,8 +875,8 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
821
875
  var import_boxen2 = __toESM(require("boxen"), 1);
822
876
 
823
877
  // src/features.ts
824
- var import_node_path7 = require("path");
825
- var import_node_fs4 = __toESM(require("fs"), 1);
878
+ var import_node_path8 = require("path");
879
+ var import_node_fs5 = __toESM(require("fs"), 1);
826
880
  var getProjectOutDir = async () => {
827
881
  const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
828
882
  return config?.outDir || "dist";
@@ -831,17 +885,13 @@ var isOutputServer = async () => {
831
885
  const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
832
886
  return config?.output === "server";
833
887
  };
834
- var isStudioEnabled = async () => {
835
- const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
836
- return config?.output === "server" && config?.studio?.enabled === true;
837
- };
838
888
  var isIndexedSearchEnabled = async () => {
839
889
  const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
840
890
  return config?.search?.type === "indexed";
841
891
  };
842
892
  var isAuthEnabled = async () => {
843
893
  const directory = process.env.PROJECT_DIR || process.cwd();
844
- const hasAuthConfig = import_node_fs4.default.existsSync((0, import_node_path7.join)(directory, "eventcatalog.auth.js"));
894
+ const hasAuthConfig = import_node_fs5.default.existsSync((0, import_node_path8.join)(directory, "eventcatalog.auth.js"));
845
895
  return hasAuthConfig;
846
896
  };
847
897
 
@@ -850,11 +900,11 @@ var import_update_notifier = __toESM(require("update-notifier"), 1);
850
900
  var import_dotenv = __toESM(require("dotenv"), 1);
851
901
 
852
902
  // src/migrations/message-channels-to-service-channels.ts
853
- var import_node_fs5 = __toESM(require("fs"), 1);
903
+ var import_node_fs6 = __toESM(require("fs"), 1);
854
904
  var import_glob2 = require("glob");
855
- var import_node_os2 = __toESM(require("os"), 1);
905
+ var import_node_os = __toESM(require("os"), 1);
856
906
  var import_gray_matter3 = __toESM(require("gray-matter"), 1);
857
- var import_node_path8 = __toESM(require("path"), 1);
907
+ var import_node_path9 = __toESM(require("path"), 1);
858
908
  var DISABLE_CHANNEL_MIGRATION_ENV = "EVENTCATALOG_DISABLE_CHANNEL_MIGRATION";
859
909
  var isChannelMigrationDisabled = () => {
860
910
  return ["true", "1", "yes"].includes((process.env[DISABLE_CHANNEL_MIGRATION_ENV] ?? "").toLowerCase());
@@ -863,7 +913,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
863
913
  if (isChannelMigrationDisabled()) {
864
914
  return { status: "skipped", message: `Channel migration disabled by ${DISABLE_CHANNEL_MIGRATION_ENV}` };
865
915
  }
866
- const PROJECT_DIR = import_node_path8.default.join(dir2 || process.env.PROJECT_DIR);
916
+ const PROJECT_DIR = import_node_path9.default.join(dir2 || process.env.PROJECT_DIR);
867
917
  const messages = await (0, import_glob2.glob)(
868
918
  [
869
919
  "**/events/*/index.mdx",
@@ -886,7 +936,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
886
936
  cwd: PROJECT_DIR,
887
937
  absolute: true,
888
938
  nodir: true,
889
- windowsPathsNoEscape: import_node_os2.default.platform() == "win32",
939
+ windowsPathsNoEscape: import_node_os.default.platform() == "win32",
890
940
  ignore: ["node_modules/**", "**/dist/**", "**/teams", "**/users", "**/package.json", "**/Dockerfile"]
891
941
  }
892
942
  );
@@ -903,7 +953,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
903
953
  }
904
954
  );
905
955
  const messagesWithChannels = messages.reduce((acc, message2) => {
906
- const file = import_node_fs5.default.readFileSync(message2, "utf8");
956
+ const file = import_node_fs6.default.readFileSync(message2, "utf8");
907
957
  const { data } = (0, import_gray_matter3.default)(file);
908
958
  if (data.channels?.length > 0) {
909
959
  acc.push({
@@ -917,7 +967,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
917
967
  return { status: "success", message: "No messages with channels found in the catalog" };
918
968
  }
919
969
  const servicesWithChannels = services.reduce((acc, service) => {
920
- const file = import_node_fs5.default.readFileSync(service, "utf8");
970
+ const file = import_node_fs6.default.readFileSync(service, "utf8");
921
971
  const { data } = (0, import_gray_matter3.default)(file);
922
972
  const isSending = data.sends?.some((send) => messagesWithChannels.some((message2) => message2.id === send.id));
923
973
  const isReceiving = data.receives?.some(
@@ -932,7 +982,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
932
982
  return acc;
933
983
  }, []);
934
984
  for (const service of servicesWithChannels) {
935
- const file = import_node_fs5.default.readFileSync(service.path, "utf8");
985
+ const file = import_node_fs6.default.readFileSync(service.path, "utf8");
936
986
  const { data } = (0, import_gray_matter3.default)(file);
937
987
  const messagesTheServiceSendsThatNeedUpdating = data.sends?.filter((send) => messagesWithChannels.some((message2) => message2.id === send.id)) ?? [];
938
988
  const messagesTheServiceReceivesThatNeedUpdating = data.receives?.filter((receive) => messagesWithChannels.some((message2) => message2.id === receive.id)) ?? [];
@@ -952,14 +1002,14 @@ var message_channels_to_service_channels_default = async (dir2) => {
952
1002
  ...newSends.length > 0 ? { sends: newSends } : {},
953
1003
  ...newReceives.length > 0 ? { receives: newReceives } : {}
954
1004
  };
955
- import_node_fs5.default.writeFileSync(service.path, import_gray_matter3.default.stringify(file, newData));
1005
+ import_node_fs6.default.writeFileSync(service.path, import_gray_matter3.default.stringify(file, newData));
956
1006
  }
957
1007
  }
958
1008
  for (const message2 of messagesWithChannels) {
959
- const file = import_node_fs5.default.readFileSync(message2.path, "utf8");
1009
+ const file = import_node_fs6.default.readFileSync(message2.path, "utf8");
960
1010
  const parsed = (0, import_gray_matter3.default)(file);
961
1011
  const { channels, ...newData } = parsed.data;
962
- import_node_fs5.default.writeFileSync(message2.path, import_gray_matter3.default.stringify(parsed.content, newData));
1012
+ import_node_fs6.default.writeFileSync(message2.path, import_gray_matter3.default.stringify(parsed.content, newData));
963
1013
  }
964
1014
  console.log("\u2714 Channels migrated to new services API");
965
1015
  };
@@ -969,13 +1019,39 @@ var runMigrations = async (dir2) => {
969
1019
  await message_channels_to_service_channels_default(dir2);
970
1020
  };
971
1021
 
1022
+ // src/utils/child-process-signals.ts
1023
+ var import_node_os2 = require("os");
1024
+ var FORWARDED_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
1025
+ var isRunning = (child) => child.exitCode === null && child.signalCode === null;
1026
+ var stopChildWithParent = (child, parent = process) => {
1027
+ let received;
1028
+ const onSignal = (signal) => {
1029
+ received = signal;
1030
+ if (isRunning(child)) child.kill(signal);
1031
+ };
1032
+ const onExit = () => {
1033
+ if (isRunning(child)) child.kill("SIGTERM");
1034
+ };
1035
+ for (const signal of FORWARDED_SIGNALS) parent.on(signal, onSignal);
1036
+ parent.on("exit", onExit);
1037
+ return {
1038
+ childClosed: () => {
1039
+ for (const signal of FORWARDED_SIGNALS) parent.off(signal, onSignal);
1040
+ parent.off("exit", onExit);
1041
+ if (!received) return false;
1042
+ parent.exit(128 + import_node_os2.constants.signals[received]);
1043
+ return true;
1044
+ }
1045
+ };
1046
+ };
1047
+
972
1048
  // eventcatalog/src/features/fields/field-indexer.ts
973
- var import_node_path10 = __toESM(require("path"), 1);
974
- var import_node_fs7 = __toESM(require("fs"), 1);
1049
+ var import_node_path11 = __toESM(require("path"), 1);
1050
+ var import_node_fs8 = __toESM(require("fs"), 1);
975
1051
 
976
1052
  // eventcatalog/src/features/fields/fields-db.ts
977
1053
  var import_sql = __toESM(require("sql.js"), 1);
978
- var import_node_fs6 = __toESM(require("fs"), 1);
1054
+ var import_node_fs7 = __toESM(require("fs"), 1);
979
1055
  var SCHEMA_SQL = `
980
1056
  CREATE TABLE IF NOT EXISTS fields (
981
1057
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -1044,13 +1120,13 @@ var FieldsDatabase = class _FieldsDatabase {
1044
1120
  this.dbPath = dbPath;
1045
1121
  }
1046
1122
  static async create(dbPath, options) {
1047
- if (options?.recreate && import_node_fs6.default.existsSync(dbPath)) {
1048
- import_node_fs6.default.unlinkSync(dbPath);
1123
+ if (options?.recreate && import_node_fs7.default.existsSync(dbPath)) {
1124
+ import_node_fs7.default.unlinkSync(dbPath);
1049
1125
  }
1050
1126
  const SQL = await (0, import_sql.default)();
1051
1127
  let db;
1052
- if (!options?.recreate && import_node_fs6.default.existsSync(dbPath)) {
1053
- const buffer = import_node_fs6.default.readFileSync(dbPath);
1128
+ if (!options?.recreate && import_node_fs7.default.existsSync(dbPath)) {
1129
+ const buffer = import_node_fs7.default.readFileSync(dbPath);
1054
1130
  db = new SQL.Database(buffer);
1055
1131
  } else {
1056
1132
  db = new SQL.Database();
@@ -1111,7 +1187,7 @@ var FieldsDatabase = class _FieldsDatabase {
1111
1187
  save() {
1112
1188
  const data = this.db.export();
1113
1189
  const buffer = Buffer.from(data);
1114
- import_node_fs6.default.writeFileSync(this.dbPath, buffer);
1190
+ import_node_fs7.default.writeFileSync(this.dbPath, buffer);
1115
1191
  }
1116
1192
  queryFields(params) {
1117
1193
  const {
@@ -1336,22 +1412,22 @@ function getAvroTypeName(type) {
1336
1412
  function walkAvroRecord(schema, prefix, fields) {
1337
1413
  if (!schema.fields || !Array.isArray(schema.fields)) return;
1338
1414
  for (const field of schema.fields) {
1339
- const path20 = prefix ? `${prefix}.${field.name}` : field.name;
1415
+ const path21 = prefix ? `${prefix}.${field.name}` : field.name;
1340
1416
  const isOptional = Array.isArray(field.type) && field.type.includes("null");
1341
1417
  const typeName = getAvroTypeName(field.type);
1342
1418
  fields.push({
1343
- path: path20,
1419
+ path: path21,
1344
1420
  type: typeName,
1345
1421
  description: field.doc || "",
1346
1422
  required: !isOptional
1347
1423
  });
1348
1424
  const innerType = Array.isArray(field.type) ? field.type.find((t) => typeof t === "object" && t.type === "record") : typeof field.type === "object" && field.type.type === "record" ? field.type : null;
1349
1425
  if (innerType) {
1350
- walkAvroRecord(innerType, path20, fields);
1426
+ walkAvroRecord(innerType, path21, fields);
1351
1427
  }
1352
1428
  const arrayType = Array.isArray(field.type) ? field.type.find((t) => typeof t === "object" && t.type === "array") : typeof field.type === "object" && field.type.type === "array" ? field.type : null;
1353
1429
  if (arrayType && typeof arrayType.items === "object" && arrayType.items.type === "record") {
1354
- walkAvroRecord(arrayType.items, `${path20}[]`, fields);
1430
+ walkAvroRecord(arrayType.items, `${path21}[]`, fields);
1355
1431
  }
1356
1432
  }
1357
1433
  }
@@ -1382,32 +1458,32 @@ function walkJsonSchema(node, prefix, requiredList, rootSchema, fields) {
1382
1458
  }
1383
1459
  if (!node.properties) return;
1384
1460
  for (const [name, prop] of Object.entries(node.properties)) {
1385
- const path20 = prefix ? `${prefix}.${name}` : name;
1461
+ const path21 = prefix ? `${prefix}.${name}` : name;
1386
1462
  const isRequired = requiredList.includes(name);
1387
1463
  if (prop.$ref) {
1388
1464
  const resolved = resolveLocalRef(prop.$ref, rootSchema);
1389
1465
  if (resolved) {
1390
1466
  const rawRefType = resolved.type || "object";
1391
1467
  const type2 = Array.isArray(rawRefType) ? [...rawRefType].sort().join(" | ") : rawRefType;
1392
- fields.push({ path: path20, type: type2, description: resolved.description || "", required: isRequired });
1468
+ fields.push({ path: path21, type: type2, description: resolved.description || "", required: isRequired });
1393
1469
  if (resolved.properties) {
1394
- walkJsonSchema(resolved, path20, resolved.required || [], rootSchema, fields);
1470
+ walkJsonSchema(resolved, path21, resolved.required || [], rootSchema, fields);
1395
1471
  }
1396
1472
  } else {
1397
- fields.push({ path: path20, type: "$ref", description: "", required: isRequired });
1473
+ fields.push({ path: path21, type: "$ref", description: "", required: isRequired });
1398
1474
  }
1399
1475
  continue;
1400
1476
  }
1401
1477
  const rawType = prop.type || (prop.enum ? "enum" : prop.$ref ? "$ref" : "object");
1402
1478
  const typeList = Array.isArray(rawType) ? rawType : [rawType];
1403
1479
  const type = Array.isArray(rawType) ? [...rawType].sort().join(" | ") : rawType;
1404
- fields.push({ path: path20, type, description: prop.description || "", required: isRequired });
1480
+ fields.push({ path: path21, type, description: prop.description || "", required: isRequired });
1405
1481
  if (typeList.includes("object") && prop.properties) {
1406
- walkJsonSchema(prop, path20, prop.required || [], rootSchema, fields);
1482
+ walkJsonSchema(prop, path21, prop.required || [], rootSchema, fields);
1407
1483
  }
1408
1484
  if (typeList.includes("array") && prop.items) {
1409
1485
  if (prop.items.type === "object" && prop.items.properties) {
1410
- walkJsonSchema(prop.items, `${path20}[]`, prop.items.required || [], rootSchema, fields);
1486
+ walkJsonSchema(prop.items, `${path21}[]`, prop.items.required || [], rootSchema, fields);
1411
1487
  }
1412
1488
  }
1413
1489
  }
@@ -1424,22 +1500,22 @@ function resolveLocalRef(ref, rootSchema) {
1424
1500
  }
1425
1501
 
1426
1502
  // eventcatalog/integrations/runtime-paths.mjs
1427
- var import_node_path9 = __toESM(require("path"), 1);
1503
+ var import_node_path10 = __toESM(require("path"), 1);
1428
1504
  function getRuntimePaths(projectDirectory, runtimeDirectory) {
1429
- const project = import_node_path9.default.resolve(projectDirectory);
1430
- const cacheDirectory = import_node_path9.default.join(project, ".astro");
1431
- const runtime = runtimeDirectory ? import_node_path9.default.resolve(runtimeDirectory) : import_node_path9.default.join(cacheDirectory, "eventcatalog");
1505
+ const project = import_node_path10.default.resolve(projectDirectory);
1506
+ const cacheDirectory = import_node_path10.default.join(project, ".astro");
1507
+ const runtime = runtimeDirectory ? import_node_path10.default.resolve(runtimeDirectory) : import_node_path10.default.join(cacheDirectory, "eventcatalog");
1432
1508
  return {
1433
1509
  projectDirectory: project,
1434
1510
  cacheDirectory,
1435
1511
  runtimeDirectory: runtime,
1436
- fieldsDatabasePath: import_node_path9.default.join(runtime, ".eventcatalog", "fields.db")
1512
+ fieldsDatabasePath: import_node_path10.default.join(runtime, ".eventcatalog", "fields.db")
1437
1513
  };
1438
1514
  }
1439
1515
 
1440
1516
  // eventcatalog/src/features/fields/field-indexer.ts
1441
1517
  function detectFormat(fileName) {
1442
- const ext = import_node_path10.default.extname(fileName).toLowerCase();
1518
+ const ext = import_node_path11.default.extname(fileName).toLowerCase();
1443
1519
  if (ext === ".proto") return "proto";
1444
1520
  if (ext === ".avro" || ext === ".avsc") return "avro";
1445
1521
  return "json-schema";
@@ -1448,9 +1524,9 @@ async function buildFieldsIndex(catalogDir, outputDir) {
1448
1524
  const sdkModule = await import("@eventcatalog/sdk");
1449
1525
  const sdk = sdkModule.default(catalogDir);
1450
1526
  const { fieldsDatabasePath: dbPath } = getRuntimePaths(catalogDir, outputDir || catalogDir);
1451
- const dbDir = import_node_path10.default.dirname(dbPath);
1452
- if (!import_node_fs7.default.existsSync(dbDir)) {
1453
- import_node_fs7.default.mkdirSync(dbDir, { recursive: true });
1527
+ const dbDir = import_node_path11.default.dirname(dbPath);
1528
+ if (!import_node_fs8.default.existsSync(dbDir)) {
1529
+ import_node_fs8.default.mkdirSync(dbDir, { recursive: true });
1454
1530
  }
1455
1531
  const db = await FieldsDatabase.create(dbPath, { recreate: true });
1456
1532
  const warnings = [];
@@ -1534,7 +1610,7 @@ async function buildFieldsIndex(catalogDir, outputDir) {
1534
1610
 
1535
1611
  // src/search-indexer.ts
1536
1612
  var import_promises4 = __toESM(require("fs/promises"), 1);
1537
- var import_node_path11 = __toESM(require("path"), 1);
1613
+ var import_node_path12 = __toESM(require("path"), 1);
1538
1614
  var import_glob3 = require("glob");
1539
1615
  var import_gray_matter4 = __toESM(require("gray-matter"), 1);
1540
1616
  var RESOURCE_COLLECTIONS = {
@@ -1598,9 +1674,9 @@ var markdownToSearchText = (content) => {
1598
1674
  };
1599
1675
  var inferDocIdFromFile = (relativePath, frontmatterId) => {
1600
1676
  if (frontmatterId) return frontmatterId;
1601
- const fileName = import_node_path11.default.posix.basename(removeExtension(relativePath));
1677
+ const fileName = import_node_path12.default.posix.basename(removeExtension(relativePath));
1602
1678
  if (fileName.toLowerCase() === "index") {
1603
- return import_node_path11.default.posix.basename(import_node_path11.default.posix.dirname(relativePath));
1679
+ return import_node_path12.default.posix.basename(import_node_path12.default.posix.dirname(relativePath));
1604
1680
  }
1605
1681
  return stripNumericPrefix(fileName);
1606
1682
  };
@@ -1618,7 +1694,7 @@ var findResourceSegment = (segments) => {
1618
1694
  return match;
1619
1695
  };
1620
1696
  var readResourceFrontmatter = async (projectDir, resourcePath) => {
1621
- const candidates = [import_node_path11.default.join(projectDir, resourcePath, "index.mdx"), import_node_path11.default.join(projectDir, resourcePath, "index.md")];
1697
+ const candidates = [import_node_path12.default.join(projectDir, resourcePath, "index.mdx"), import_node_path12.default.join(projectDir, resourcePath, "index.md")];
1622
1698
  for (const candidate of candidates) {
1623
1699
  try {
1624
1700
  const file = await import_promises4.default.readFile(candidate, "utf8");
@@ -1643,7 +1719,7 @@ var deriveRecordFromPath = async ({
1643
1719
  }
1644
1720
  if (segments[0] === "docs") {
1645
1721
  const customPath = normalizeUrlPath(removeExtension(segments.slice(1).join("/")));
1646
- const title = data.title || data.label || import_node_path11.default.posix.basename(customPath) || "Custom docs";
1722
+ const title = data.title || data.label || import_node_path12.default.posix.basename(customPath) || "Custom docs";
1647
1723
  return {
1648
1724
  url: buildUrl(`/docs/custom/${customPath}`, config),
1649
1725
  title,
@@ -1761,7 +1837,7 @@ var collectSearchRecords = async ({
1761
1837
  files.map(async (file) => {
1762
1838
  const raw = await import_promises4.default.readFile(file, "utf8");
1763
1839
  const parsed = (0, import_gray_matter4.default)(raw);
1764
- const relativePath = normalizePath(import_node_path11.default.relative(projectDir, file));
1840
+ const relativePath = normalizePath(import_node_path12.default.relative(projectDir, file));
1765
1841
  const baseRecord = await deriveRecordFromPath({
1766
1842
  projectDir,
1767
1843
  relativePath,
@@ -1809,7 +1885,7 @@ var getSearchOutputPath = ({
1809
1885
  if (searchOutputPath) {
1810
1886
  return searchOutputPath;
1811
1887
  }
1812
- return import_node_path11.default.join(outDir, isServer ? "client" : "", "pagefind");
1888
+ return import_node_path12.default.join(outDir, isServer ? "client" : "", "pagefind");
1813
1889
  };
1814
1890
  var buildSearchIndex = async ({ projectDir, outDir, config, isServer, searchOutputPath }) => {
1815
1891
  const records = await collectSearchRecords({ projectDir, config });
@@ -1863,74 +1939,74 @@ ${errors.join("\n")}`);
1863
1939
  };
1864
1940
 
1865
1941
  // src/catalog-runtime.ts
1866
- var import_node_fs8 = __toESM(require("fs"), 1);
1867
- var import_node_path12 = __toESM(require("path"), 1);
1868
- var import_node_module = require("module");
1869
- var require2 = (0, import_node_module.createRequire)(importMetaUrl);
1942
+ var import_node_fs9 = __toESM(require("fs"), 1);
1943
+ var import_node_path13 = __toESM(require("path"), 1);
1944
+ var import_node_module2 = require("module");
1945
+ var require2 = (0, import_node_module2.createRequire)(importMetaUrl);
1870
1946
  var writeIfChanged = (file, content) => {
1871
- if (import_node_fs8.default.existsSync(file) && import_node_fs8.default.readFileSync(file, "utf8") === content) return;
1872
- import_node_fs8.default.mkdirSync(import_node_path12.default.dirname(file), { recursive: true });
1873
- import_node_fs8.default.writeFileSync(file, content);
1947
+ if (import_node_fs9.default.existsSync(file) && import_node_fs9.default.readFileSync(file, "utf8") === content) return;
1948
+ import_node_fs9.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
1949
+ import_node_fs9.default.writeFileSync(file, content);
1874
1950
  };
1875
1951
  var importPath = (file) => file.replace(/\\/g, "/");
1876
- var hasLegacyCatalogRuntime = (projectDirectory) => import_node_fs8.default.existsSync(import_node_path12.default.join(projectDirectory, ".eventcatalog-core"));
1952
+ var hasLegacyCatalogRuntime = (projectDirectory) => import_node_fs9.default.existsSync(import_node_path13.default.join(projectDirectory, ".eventcatalog-core"));
1877
1953
  var clearCatalogCache = (projectDirectory) => {
1878
1954
  const { cacheDirectory } = getRuntimePaths(projectDirectory);
1879
- import_node_fs8.default.rmSync(cacheDirectory, { recursive: true, force: true });
1955
+ import_node_fs9.default.rmSync(cacheDirectory, { recursive: true, force: true });
1880
1956
  };
1881
1957
  var prepareCatalogRuntime = ({ projectDirectory, catalogDirectory, packageDirectory }) => {
1882
- const runtime = import_node_path12.default.resolve(catalogDirectory);
1883
- const source = import_node_path12.default.resolve(packageDirectory);
1884
- const project = import_node_path12.default.resolve(projectDirectory);
1958
+ const runtime = import_node_path13.default.resolve(catalogDirectory);
1959
+ const source = import_node_path13.default.resolve(packageDirectory);
1960
+ const project = import_node_path13.default.resolve(projectDirectory);
1885
1961
  if (runtime === source || runtime === project) {
1886
1962
  throw new Error("The catalog runtime must be separate from the project and installed application directories.");
1887
1963
  }
1888
- import_node_fs8.default.mkdirSync(runtime, { recursive: true });
1964
+ import_node_fs9.default.mkdirSync(runtime, { recursive: true });
1889
1965
  writeIfChanged(
1890
- import_node_path12.default.join(runtime, "content.config.ts"),
1891
- `export { collections } from ${JSON.stringify(importPath(import_node_path12.default.join(source, "src/content.config.ts")))};
1966
+ import_node_path13.default.join(runtime, "content.config.ts"),
1967
+ `export { collections } from ${JSON.stringify(importPath(import_node_path13.default.join(source, "src/content.config.ts")))};
1892
1968
  `
1893
1969
  );
1894
- const packageTsconfig = JSON.parse(import_node_fs8.default.readFileSync(import_node_path12.default.join(source, "tsconfig.json"), "utf8"));
1970
+ const packageTsconfig = JSON.parse(import_node_fs9.default.readFileSync(import_node_path13.default.join(source, "tsconfig.json"), "utf8"));
1895
1971
  const paths = Object.fromEntries(
1896
1972
  Object.entries(packageTsconfig.compilerOptions.paths).map(([alias, targets]) => [
1897
1973
  alias,
1898
- targets.map((target) => importPath(import_node_path12.default.resolve(source, target)))
1974
+ targets.map((target) => importPath(import_node_path13.default.resolve(source, target)))
1899
1975
  ])
1900
1976
  );
1901
- paths["@config"] = [importPath(import_node_path12.default.join(project, "eventcatalog.config.js"))];
1902
- paths["@catalog/styles"] = [importPath(import_node_path12.default.join(project, "eventcatalog.styles.css"))];
1977
+ paths["@config"] = [importPath(import_node_path13.default.join(project, "eventcatalog.config.js"))];
1978
+ paths["@catalog/styles"] = [importPath(import_node_path13.default.join(project, "eventcatalog.styles.css"))];
1903
1979
  paths["@catalog/components/*"] = [
1904
- importPath(import_node_path12.default.join(project, "components/*")),
1905
- importPath(import_node_path12.default.join(project, "federated/components/*"))
1980
+ importPath(import_node_path13.default.join(project, "components/*")),
1981
+ importPath(import_node_path13.default.join(project, "federated/components/*"))
1906
1982
  ];
1907
- paths["@catalog/snippets/*"] = [importPath(import_node_path12.default.join(project, "snippets/*"))];
1983
+ paths["@catalog/snippets/*"] = [importPath(import_node_path13.default.join(project, "snippets/*"))];
1908
1984
  for (const specifier of ["astro", "astro/zod", "astro/loaders", "astro/runtime/server/index.js"]) {
1909
1985
  paths[specifier] = [importPath(require2.resolve(specifier).replace(/\.js$/, ".d.ts"))];
1910
1986
  }
1911
1987
  writeIfChanged(
1912
- import_node_path12.default.join(runtime, "tsconfig.json"),
1988
+ import_node_path13.default.join(runtime, "tsconfig.json"),
1913
1989
  JSON.stringify(
1914
1990
  {
1915
- extends: importPath(import_node_path12.default.join(source, "tsconfig.json")),
1991
+ extends: importPath(import_node_path13.default.join(source, "tsconfig.json")),
1916
1992
  compilerOptions: {
1917
1993
  baseUrl: ".",
1918
1994
  paths,
1919
1995
  typeRoots: [
1920
- importPath(import_node_path12.default.join(project, "node_modules/@types")),
1921
- importPath(import_node_path12.default.join(source, "../node_modules/@types")),
1922
- importPath(import_node_path12.default.join(source, "../node_modules")),
1923
- importPath(import_node_path12.default.join(project, "node_modules"))
1996
+ importPath(import_node_path13.default.join(project, "node_modules/@types")),
1997
+ importPath(import_node_path13.default.join(source, "../node_modules/@types")),
1998
+ importPath(import_node_path13.default.join(source, "../node_modules")),
1999
+ importPath(import_node_path13.default.join(project, "node_modules"))
1924
2000
  ]
1925
2001
  },
1926
2002
  include: [
1927
- importPath(import_node_path12.default.join(project, ".astro/types.d.ts")),
2003
+ importPath(import_node_path13.default.join(project, ".astro/types.d.ts")),
1928
2004
  "content.config.ts",
1929
- importPath(import_node_path12.default.join(project, "components/**/*")),
1930
- importPath(import_node_path12.default.join(source, "src/**/*"))
2005
+ importPath(import_node_path13.default.join(project, "components/**/*")),
2006
+ importPath(import_node_path13.default.join(source, "src/**/*"))
1931
2007
  ],
1932
2008
  // Keep legacy generated files out of checks on an existing checkout.
1933
- exclude: (packageTsconfig.exclude ?? []).map((entry) => importPath(import_node_path12.default.resolve(source, entry)))
2009
+ exclude: (packageTsconfig.exclude ?? []).map((entry) => importPath(import_node_path13.default.resolve(source, entry)))
1934
2010
  },
1935
2011
  null,
1936
2012
  2
@@ -2010,8 +2086,8 @@ var createAstroDevLineFilter = () => {
2010
2086
  };
2011
2087
 
2012
2088
  // src/astro-config-path.ts
2013
- var import_node_path13 = __toESM(require("path"), 1);
2014
- var getAstroConfigPath = (projectDirectory, configFile, paths = import_node_path13.default) => {
2089
+ var import_node_path14 = __toESM(require("path"), 1);
2090
+ var getAstroConfigPath = (projectDirectory, configFile, paths = import_node_path14.default) => {
2015
2091
  const relative = paths.relative(projectDirectory, configFile);
2016
2092
  const projectRoot = paths.parse(paths.resolve(projectDirectory)).root.toLowerCase();
2017
2093
  const configRoot = paths.parse(paths.resolve(configFile)).root.toLowerCase();
@@ -2026,18 +2102,18 @@ var getAstroConfigPath = (projectDirectory, configFile, paths = import_node_path
2026
2102
  // src/federation/federate.ts
2027
2103
  var import_node_crypto5 = require("crypto");
2028
2104
  var import_promises10 = __toESM(require("fs/promises"), 1);
2029
- var import_node_path19 = __toESM(require("path"), 1);
2105
+ var import_node_path20 = __toESM(require("path"), 1);
2030
2106
  var import_sdk3 = __toESM(require("@eventcatalog/sdk"), 1);
2031
2107
 
2032
2108
  // src/federation/content-cache.ts
2033
2109
  var import_node_crypto2 = require("crypto");
2034
2110
  var import_promises5 = __toESM(require("fs/promises"), 1);
2035
- var import_node_path14 = __toESM(require("path"), 1);
2111
+ var import_node_path15 = __toESM(require("path"), 1);
2036
2112
  var getContentHash = (content) => `sha256:${(0, import_node_crypto2.createHash)("sha256").update(content).digest("hex")}`;
2037
2113
  var isContentHash = (key) => /^sha256:[a-f0-9]{64}$/i.test(key);
2038
2114
  var createFederationContentCache = (projectDirectory, options = {}) => {
2039
- const cacheDirectory = import_node_path14.default.join(projectDirectory, ".eventcatalog-cache", "federation", "content");
2040
- const getCachePath = (key) => import_node_path14.default.join(cacheDirectory, encodeURIComponent(key));
2115
+ const cacheDirectory = import_node_path15.default.join(projectDirectory, ".eventcatalog-cache", "federation", "content");
2116
+ const getCachePath = (key) => import_node_path15.default.join(cacheDirectory, encodeURIComponent(key));
2041
2117
  return {
2042
2118
  async get(key) {
2043
2119
  if (options.read === false || !isContentHash(key)) return void 0;
@@ -2224,20 +2300,20 @@ var getVisibleFederationDiagnostics = (diagnostics, verbose) => diagnostics.filt
2224
2300
 
2225
2301
  // src/federation/output-transaction.ts
2226
2302
  var import_promises6 = __toESM(require("fs/promises"), 1);
2227
- var import_node_path15 = __toESM(require("path"), 1);
2303
+ var import_node_path16 = __toESM(require("path"), 1);
2228
2304
  var getSafePublicPath = (publicDirectory, relativePath) => {
2229
- const normalizedPath = import_node_path15.default.posix.normalize(relativePath);
2230
- const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path15.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2305
+ const normalizedPath = import_node_path16.default.posix.normalize(relativePath);
2306
+ const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path16.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2231
2307
  if (unsafe) return void 0;
2232
- const destinationPath = import_node_path15.default.resolve(publicDirectory, relativePath);
2233
- const relativeDestinationPath = import_node_path15.default.relative(publicDirectory, destinationPath);
2234
- return relativeDestinationPath !== "" && relativeDestinationPath !== ".." && !relativeDestinationPath.startsWith(`..${import_node_path15.default.sep}`) && !import_node_path15.default.isAbsolute(relativeDestinationPath) ? destinationPath : void 0;
2308
+ const destinationPath = import_node_path16.default.resolve(publicDirectory, relativePath);
2309
+ const relativeDestinationPath = import_node_path16.default.relative(publicDirectory, destinationPath);
2310
+ return relativeDestinationPath !== "" && relativeDestinationPath !== ".." && !relativeDestinationPath.startsWith(`..${import_node_path16.default.sep}`) && !import_node_path16.default.isAbsolute(relativeDestinationPath) ? destinationPath : void 0;
2235
2311
  };
2236
2312
  var beginFederationOutputTransaction = async (projectDirectory, outDir, relativePublicPaths) => {
2237
- const transactionDirectory = await import_promises6.default.mkdtemp(import_node_path15.default.join(projectDirectory, ".eventcatalog-federation-transaction-"));
2238
- const previousOutDir = import_node_path15.default.join(transactionDirectory, "federated");
2239
- const publicBackupDirectory = import_node_path15.default.join(transactionDirectory, "public");
2240
- const publicDirectory = import_node_path15.default.resolve(projectDirectory, "public");
2313
+ const transactionDirectory = await import_promises6.default.mkdtemp(import_node_path16.default.join(projectDirectory, ".eventcatalog-federation-transaction-"));
2314
+ const previousOutDir = import_node_path16.default.join(transactionDirectory, "federated");
2315
+ const publicBackupDirectory = import_node_path16.default.join(transactionDirectory, "public");
2316
+ const publicDirectory = import_node_path16.default.resolve(projectDirectory, "public");
2241
2317
  const publicSnapshots = [];
2242
2318
  const missingPublicDirectories = /* @__PURE__ */ new Set();
2243
2319
  let hadPreviousOutDir = false;
@@ -2248,8 +2324,8 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2248
2324
  try {
2249
2325
  const stat = await import_promises6.default.lstat(destinationPath);
2250
2326
  if (!stat.isFile()) continue;
2251
- const backupPath = import_node_path15.default.join(publicBackupDirectory, `${publicSnapshots.length}`);
2252
- await import_promises6.default.mkdir(import_node_path15.default.dirname(backupPath), { recursive: true });
2327
+ const backupPath = import_node_path16.default.join(publicBackupDirectory, `${publicSnapshots.length}`);
2328
+ await import_promises6.default.mkdir(import_node_path16.default.dirname(backupPath), { recursive: true });
2253
2329
  await import_promises6.default.copyFile(destinationPath, backupPath);
2254
2330
  publicSnapshots.push({ backupPath, destinationPath, state: "file" });
2255
2331
  } catch (error) {
@@ -2257,7 +2333,7 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2257
2333
  if (code === "ENOTDIR") continue;
2258
2334
  if (code !== "ENOENT") throw error;
2259
2335
  publicSnapshots.push({ destinationPath, state: "missing" });
2260
- let directory = import_node_path15.default.dirname(destinationPath);
2336
+ let directory = import_node_path16.default.dirname(destinationPath);
2261
2337
  while (directory !== publicDirectory) {
2262
2338
  try {
2263
2339
  await import_promises6.default.lstat(directory);
@@ -2267,7 +2343,7 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2267
2343
  if (directoryCode === "ENOTDIR") break;
2268
2344
  if (directoryCode !== "ENOENT") throw directoryError;
2269
2345
  missingPublicDirectories.add(directory);
2270
- directory = import_node_path15.default.dirname(directory);
2346
+ directory = import_node_path16.default.dirname(directory);
2271
2347
  }
2272
2348
  }
2273
2349
  }
@@ -2303,7 +2379,7 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2303
2379
  continue;
2304
2380
  }
2305
2381
  await attempt(async () => {
2306
- await import_promises6.default.mkdir(import_node_path15.default.dirname(snapshot.destinationPath), { recursive: true });
2382
+ await import_promises6.default.mkdir(import_node_path16.default.dirname(snapshot.destinationPath), { recursive: true });
2307
2383
  await import_promises6.default.copyFile(snapshot.backupPath, snapshot.destinationPath);
2308
2384
  });
2309
2385
  }
@@ -2340,7 +2416,7 @@ var withFederationOutputTransaction = async (projectDirectory, outDir, relativeP
2340
2416
  // src/federation/public-assets.ts
2341
2417
  var import_node_crypto3 = require("crypto");
2342
2418
  var import_promises7 = __toESM(require("fs/promises"), 1);
2343
- var import_node_path16 = __toESM(require("path"), 1);
2419
+ var import_node_path17 = __toESM(require("path"), 1);
2344
2420
  var getContentHash2 = (content) => `sha256:${(0, import_node_crypto3.createHash)("sha256").update(content).digest("hex")}`;
2345
2421
  var getFileHash = async (filePath) => {
2346
2422
  try {
@@ -2352,13 +2428,13 @@ var getFileHash = async (filePath) => {
2352
2428
  }
2353
2429
  };
2354
2430
  var getSafePath = (directory, relativePath) => {
2355
- const normalizedPath = import_node_path16.default.posix.normalize(relativePath);
2356
- const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path16.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2431
+ const normalizedPath = import_node_path17.default.posix.normalize(relativePath);
2432
+ const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path17.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2357
2433
  if (unsafe) return void 0;
2358
- const resolvedDirectory = import_node_path16.default.resolve(directory);
2359
- const resolvedPath = import_node_path16.default.resolve(resolvedDirectory, relativePath);
2360
- const relativeResolvedPath = import_node_path16.default.relative(resolvedDirectory, resolvedPath);
2361
- if (relativeResolvedPath === "" || relativeResolvedPath === ".." || relativeResolvedPath.startsWith(`..${import_node_path16.default.sep}`) || import_node_path16.default.isAbsolute(relativeResolvedPath)) {
2434
+ const resolvedDirectory = import_node_path17.default.resolve(directory);
2435
+ const resolvedPath = import_node_path17.default.resolve(resolvedDirectory, relativePath);
2436
+ const relativeResolvedPath = import_node_path17.default.relative(resolvedDirectory, resolvedPath);
2437
+ if (relativeResolvedPath === "" || relativeResolvedPath === ".." || relativeResolvedPath.startsWith(`..${import_node_path17.default.sep}`) || import_node_path17.default.isAbsolute(relativeResolvedPath)) {
2362
2438
  return void 0;
2363
2439
  }
2364
2440
  return resolvedPath;
@@ -2366,16 +2442,16 @@ var getSafePath = (directory, relativePath) => {
2366
2442
  var listFiles = async (directory, relativeDirectory = "") => {
2367
2443
  let entries;
2368
2444
  try {
2369
- entries = await import_promises7.default.readdir(import_node_path16.default.join(directory, relativeDirectory), { withFileTypes: true });
2445
+ entries = await import_promises7.default.readdir(import_node_path17.default.join(directory, relativeDirectory), { withFileTypes: true });
2370
2446
  } catch (error) {
2371
2447
  if (error.code === "ENOENT") return [];
2372
2448
  throw error;
2373
2449
  }
2374
2450
  const files = await Promise.all(
2375
2451
  entries.map(async (entry) => {
2376
- const relativePath = import_node_path16.default.join(relativeDirectory, entry.name);
2452
+ const relativePath = import_node_path17.default.join(relativeDirectory, entry.name);
2377
2453
  if (entry.isDirectory()) return listFiles(directory, relativePath);
2378
- return entry.isFile() ? [relativePath.split(import_node_path16.default.sep).join("/")] : [];
2454
+ return entry.isFile() ? [relativePath.split(import_node_path17.default.sep).join("/")] : [];
2379
2455
  })
2380
2456
  );
2381
2457
  return files.flat().sort();
@@ -2390,19 +2466,19 @@ var pathExists = async (filePath) => {
2390
2466
  }
2391
2467
  };
2392
2468
  var hasBlockingParent = async (publicDirectory, destinationPath) => {
2393
- let currentPath = import_node_path16.default.dirname(destinationPath);
2469
+ let currentPath = import_node_path17.default.dirname(destinationPath);
2394
2470
  while (currentPath !== publicDirectory) {
2395
2471
  try {
2396
2472
  if (!(await import_promises7.default.lstat(currentPath)).isDirectory()) return true;
2397
2473
  } catch (error) {
2398
2474
  if (error.code !== "ENOENT") throw error;
2399
2475
  }
2400
- currentPath = import_node_path16.default.dirname(currentPath);
2476
+ currentPath = import_node_path17.default.dirname(currentPath);
2401
2477
  }
2402
2478
  return false;
2403
2479
  };
2404
2480
  var pruneEmptyDirectories = async (publicDirectory, filePath) => {
2405
- let currentPath = import_node_path16.default.dirname(filePath);
2481
+ let currentPath = import_node_path17.default.dirname(filePath);
2406
2482
  while (currentPath !== publicDirectory) {
2407
2483
  try {
2408
2484
  await import_promises7.default.rmdir(currentPath);
@@ -2410,7 +2486,7 @@ var pruneEmptyDirectories = async (publicDirectory, filePath) => {
2410
2486
  if (!["ENOENT", "ENOTEMPTY"].includes(error.code ?? "")) throw error;
2411
2487
  if (error.code === "ENOTEMPTY") return;
2412
2488
  }
2413
- currentPath = import_node_path16.default.dirname(currentPath);
2489
+ currentPath = import_node_path17.default.dirname(currentPath);
2414
2490
  }
2415
2491
  };
2416
2492
  var composePublicAssets = async ({
@@ -2420,8 +2496,8 @@ var composePublicAssets = async ({
2420
2496
  previousFiles = {},
2421
2497
  collisionPaths = /* @__PURE__ */ new Set()
2422
2498
  }) => {
2423
- const publicDirectory = import_node_path16.default.resolve(projectDirectory, "public");
2424
- const federatedPublicDirectory = import_node_path16.default.resolve(federatedDirectory, "public");
2499
+ const publicDirectory = import_node_path17.default.resolve(projectDirectory, "public");
2500
+ const federatedPublicDirectory = import_node_path17.default.resolve(federatedDirectory, "public");
2425
2501
  const sourceFiles = await listFiles(federatedPublicDirectory);
2426
2502
  const sourceFileSet = new Set(sourceFiles);
2427
2503
  const managedFiles = /* @__PURE__ */ new Set();
@@ -2457,7 +2533,7 @@ var composePublicAssets = async ({
2457
2533
  const asset = publicAssetsByPath.get(relativePath);
2458
2534
  if (!asset) throw new Error(`Cannot identify the source of federated public asset "${relativePath}"`);
2459
2535
  const content = await import_promises7.default.readFile(sourcePath);
2460
- await import_promises7.default.mkdir(import_node_path16.default.dirname(destinationPath), { recursive: true });
2536
+ await import_promises7.default.mkdir(import_node_path17.default.dirname(destinationPath), { recursive: true });
2461
2537
  await import_promises7.default.writeFile(destinationPath, content);
2462
2538
  files[relativePath] = { source: asset.resolvedFrom.source, hash: getContentHash2(content) };
2463
2539
  copied += 1;
@@ -2470,17 +2546,17 @@ var composePublicAssets = async ({
2470
2546
  // src/federation/filesystem-source-provider.ts
2471
2547
  var import_node_crypto4 = require("crypto");
2472
2548
  var import_promises8 = __toESM(require("fs/promises"), 1);
2473
- var import_node_path17 = __toESM(require("path"), 1);
2549
+ var import_node_path18 = __toESM(require("path"), 1);
2474
2550
  var import_sdk = __toESM(require("@eventcatalog/sdk"), 1);
2475
2551
  var FILESYSTEM_SOURCE_PREFIX = "file:";
2476
2552
  var isWithinDirectory = (directory, target) => {
2477
- const relativePath = import_node_path17.default.relative(directory, target);
2478
- return relativePath === "" || !relativePath.startsWith(`..${import_node_path17.default.sep}`) && relativePath !== ".." && !import_node_path17.default.isAbsolute(relativePath);
2553
+ const relativePath = import_node_path18.default.relative(directory, target);
2554
+ return relativePath === "" || !relativePath.startsWith(`..${import_node_path18.default.sep}`) && relativePath !== ".." && !import_node_path18.default.isAbsolute(relativePath);
2479
2555
  };
2480
2556
  var assertPortableRelativePath = (filePath, label, allowRoot = true) => {
2481
2557
  const portablePath = filePath.replaceAll("\\", "/");
2482
- const normalizedPath = import_node_path17.default.posix.normalize(portablePath);
2483
- const isUnsafe = filePath.includes("\\") || filePath.includes("\0") || import_node_path17.default.posix.isAbsolute(normalizedPath) || /^[a-zA-Z]:\//.test(normalizedPath) || normalizedPath === ".." || normalizedPath.startsWith("../") || !allowRoot && (normalizedPath === "." || normalizedPath === "");
2558
+ const normalizedPath = import_node_path18.default.posix.normalize(portablePath);
2559
+ const isUnsafe = filePath.includes("\\") || filePath.includes("\0") || import_node_path18.default.posix.isAbsolute(normalizedPath) || /^[a-zA-Z]:\//.test(normalizedPath) || normalizedPath === ".." || normalizedPath.startsWith("../") || !allowRoot && (normalizedPath === "." || normalizedPath === "");
2484
2560
  if (isUnsafe) throw new Error(`${label} "${filePath}" escapes its filesystem source`);
2485
2561
  return normalizedPath;
2486
2562
  };
@@ -2490,13 +2566,13 @@ var getSourceRoot = (projectDirectory, source) => {
2490
2566
  }
2491
2567
  const locator = source.source.slice(FILESYSTEM_SOURCE_PREFIX.length);
2492
2568
  if (!locator.trim()) throw new Error(`Filesystem federation source "${source.id}" requires a path after "file:".`);
2493
- return import_node_path17.default.resolve(projectDirectory, locator);
2569
+ return import_node_path18.default.resolve(projectDirectory, locator);
2494
2570
  };
2495
2571
  var getCatalogDirectory = async (projectDirectory, source) => {
2496
2572
  if (source.ref) throw new Error(`Filesystem federation source "${source.id}" does not support "ref".`);
2497
2573
  const sourceRoot = getSourceRoot(projectDirectory, source);
2498
2574
  const catalogPath = assertPortableRelativePath(source.path ?? ".", "Catalog path");
2499
- const catalogDirectory = import_node_path17.default.resolve(sourceRoot, ...catalogPath.split("/"));
2575
+ const catalogDirectory = import_node_path18.default.resolve(sourceRoot, ...catalogPath.split("/"));
2500
2576
  if (!isWithinDirectory(sourceRoot, catalogDirectory)) {
2501
2577
  throw new Error(`Catalog path "${source.path}" escapes source "${source.id}"`);
2502
2578
  }
@@ -2518,7 +2594,7 @@ var getCatalogDirectory = async (projectDirectory, source) => {
2518
2594
  };
2519
2595
  var getArtifactPath = async (catalogDirectory, source, artifactPath) => {
2520
2596
  const normalizedPath = assertPortableRelativePath(artifactPath, "Federated artifact path", false);
2521
- const filePath = import_node_path17.default.resolve(catalogDirectory, ...normalizedPath.split("/"));
2597
+ const filePath = import_node_path18.default.resolve(catalogDirectory, ...normalizedPath.split("/"));
2522
2598
  if (!isWithinDirectory(catalogDirectory, filePath)) {
2523
2599
  throw new Error(`Federated artifact path "${artifactPath}" escapes source "${source.id}"`);
2524
2600
  }
@@ -2558,7 +2634,7 @@ var createFileSystemSourceProvider = (projectDirectory) => ({
2558
2634
  var import_node_child_process = require("child_process");
2559
2635
  var import_promises9 = __toESM(require("fs/promises"), 1);
2560
2636
  var import_node_os3 = __toESM(require("os"), 1);
2561
- var import_node_path18 = __toESM(require("path"), 1);
2637
+ var import_node_path19 = __toESM(require("path"), 1);
2562
2638
  var import_node_util = require("util");
2563
2639
  var import_sdk2 = __toESM(require("@eventcatalog/sdk"), 1);
2564
2640
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
@@ -2569,8 +2645,8 @@ var parseGitHubSource = (source) => {
2569
2645
  };
2570
2646
  var assertSafeCatalogPath = (source) => {
2571
2647
  const catalogPath = source.path ?? ".";
2572
- const normalized = import_node_path18.default.posix.normalize(catalogPath.replaceAll("\\", "/"));
2573
- if (catalogPath.includes("\\") || import_node_path18.default.posix.isAbsolute(normalized) || normalized === ".." || normalized.startsWith("../")) {
2648
+ const normalized = import_node_path19.default.posix.normalize(catalogPath.replaceAll("\\", "/"));
2649
+ if (catalogPath.includes("\\") || import_node_path19.default.posix.isAbsolute(normalized) || normalized === ".." || normalized.startsWith("../")) {
2574
2650
  throw new Error(`Catalog path "${catalogPath}" escapes source "${source.id}"`);
2575
2651
  }
2576
2652
  };
@@ -2613,8 +2689,8 @@ var getGitEnvironment = (token) => {
2613
2689
  };
2614
2690
  var createCheckout = (executeFile, token) => async (source, ref, callback) => {
2615
2691
  const { owner, repository } = parseGitHubSource(source);
2616
- const catalogPath = import_node_path18.default.posix.normalize(source.path ?? ".");
2617
- const directory = await import_promises9.default.mkdtemp(import_node_path18.default.join(import_node_os3.default.tmpdir(), "eventcatalog-federation-"));
2692
+ const catalogPath = import_node_path19.default.posix.normalize(source.path ?? ".");
2693
+ const directory = await import_promises9.default.mkdtemp(import_node_path19.default.join(import_node_os3.default.tmpdir(), "eventcatalog-federation-"));
2618
2694
  const env = getGitEnvironment(token);
2619
2695
  try {
2620
2696
  const git = (args) => executeFile("git", args, { cwd: directory, env, encoding: "utf8" });
@@ -2634,16 +2710,16 @@ var createCheckout = (executeFile, token) => async (source, ref, callback) => {
2634
2710
  var generateIndex = async (source, ref, checkout, executeFile) => checkout(source, ref, async (directory) => {
2635
2711
  const { stdout } = await executeFile("git", ["rev-parse", "HEAD"], { cwd: directory, encoding: "utf8" });
2636
2712
  const commit = stdout.trim();
2637
- const catalogDirectory = import_node_path18.default.resolve(directory, source.path ?? ".");
2638
- const relativeCatalogDirectory = import_node_path18.default.relative(directory, catalogDirectory);
2639
- if (relativeCatalogDirectory.startsWith("..") || import_node_path18.default.isAbsolute(relativeCatalogDirectory)) {
2713
+ const catalogDirectory = import_node_path19.default.resolve(directory, source.path ?? ".");
2714
+ const relativeCatalogDirectory = import_node_path19.default.relative(directory, catalogDirectory);
2715
+ if (relativeCatalogDirectory.startsWith("..") || import_node_path19.default.isAbsolute(relativeCatalogDirectory)) {
2640
2716
  throw new Error(`Catalog path "${source.path}" escapes source "${source.id}"`);
2641
2717
  }
2642
2718
  const index = await (0, import_sdk2.default)(catalogDirectory).buildIndex({ source: source.id, commit });
2643
2719
  return { bytes: Buffer.from(JSON.stringify(index)), index, commit, generated: true };
2644
2720
  });
2645
2721
  var fetchPublishedIndex = async (source, ref, fetcher, token) => {
2646
- const indexPath = import_node_path18.default.posix.join(source.path ?? ".", "catalog.index.json");
2722
+ const indexPath = import_node_path19.default.posix.join(source.path ?? ".", "catalog.index.json");
2647
2723
  const bytes = await fetchBytes(source, ref, indexPath, fetcher, token);
2648
2724
  if (!bytes) return void 0;
2649
2725
  const index = (0, import_sdk2.parseIndex)(JSON.parse(bytes.toString("utf8")));
@@ -2666,7 +2742,7 @@ var createGitHubSourceProvider = (options = {}) => {
2666
2742
  },
2667
2743
  async fetchContent({ source, commit, path: artifactPath }) {
2668
2744
  assertSafeCatalogPath(source);
2669
- const catalogPath = import_node_path18.default.posix.join(source.path ?? ".", artifactPath);
2745
+ const catalogPath = import_node_path19.default.posix.join(source.path ?? ".", artifactPath);
2670
2746
  const content = await fetchBytes(source, commit, catalogPath, fetcher, token);
2671
2747
  if (!content) throw new Error(`Federated artifact not found for "${source.id}": ${artifactPath}`);
2672
2748
  return content;
@@ -2777,8 +2853,8 @@ var pathExists2 = async (filePath) => {
2777
2853
  }
2778
2854
  };
2779
2855
  var cleanupPreviousFederation = async (projectDirectory, onProgress) => {
2780
- const outDir = import_node_path19.default.join(projectDirectory, "federated");
2781
- const lockPath = import_node_path19.default.join(projectDirectory, "eventcatalog.lock");
2856
+ const outDir = import_node_path20.default.join(projectDirectory, "federated");
2857
+ const lockPath = import_node_path20.default.join(projectDirectory, "eventcatalog.lock");
2782
2858
  const previousLock = await readLock(lockPath);
2783
2859
  const hadFederatedOutput = await pathExists2(outDir);
2784
2860
  const hadLock = previousLock !== void 0;
@@ -2838,8 +2914,8 @@ var federateCatalog = async (projectDirectory, options = {}) => {
2838
2914
  throw new Error(`Failed to federate source "${source.id}": ${message2}`, { cause: error });
2839
2915
  }
2840
2916
  }
2841
- const outDir = import_node_path19.default.join(projectDirectory, "federated");
2842
- const lockPath = import_node_path19.default.join(projectDirectory, "eventcatalog.lock");
2917
+ const outDir = import_node_path20.default.join(projectDirectory, "federated");
2918
+ const lockPath = import_node_path20.default.join(projectDirectory, "eventcatalog.lock");
2843
2919
  const previousLock = await readLock(lockPath);
2844
2920
  const resources = resolvedSources.reduce((total, source) => total + source.resolved.index.resources.length, 0);
2845
2921
  const remoteIndexes = resolvedSources.map(({ resolved }) => resolved.index);
@@ -2951,16 +3027,17 @@ Run npm i @eventcatalog/core to update`;
2951
3027
  };
2952
3028
 
2953
3029
  // src/eventcatalog.ts
2954
- var currentDir = import_node_path21.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
2955
- var astroCli = import_node_path21.default.join(import_node_path21.default.dirname((0, import_node_module2.createRequire)(importMetaUrl).resolve("astro/package.json")), "bin/astro.mjs");
3030
+ var currentDir = import_node_path22.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
3031
+ var astroCli = import_node_path22.default.join(import_node_path22.default.dirname((0, import_node_module3.createRequire)(importMetaUrl).resolve("astro/package.json")), "bin/astro.mjs");
3032
+ var ASTRO_IN_FOREGROUND = { ASTRO_DEV_BACKGROUND: "1", ASTRO_PREVIEW_BACKGROUND: "1" };
2956
3033
  var program = new import_commander.Command().version(VERSION);
2957
- var dir = import_node_path21.default.resolve(process.env.PROJECT_DIR || process.cwd());
2958
- var eventCatalogDir = import_node_path21.default.resolve((0, import_node_path20.join)(currentDir, "../eventcatalog/"));
2959
- var astroConfigPath = () => getAstroConfigPath(dir, (0, import_node_path20.join)(eventCatalogDir, "astro.config.mjs"));
3034
+ var dir = import_node_path22.default.resolve(process.env.PROJECT_DIR || process.cwd());
3035
+ var eventCatalogDir = import_node_path22.default.resolve((0, import_node_path21.join)(currentDir, "../eventcatalog/"));
3036
+ var astroConfigPath = () => getAstroConfigPath(dir, (0, import_node_path21.join)(eventCatalogDir, "astro.config.mjs"));
2960
3037
  var { runtimeDirectory: core } = getRuntimePaths(dir);
2961
3038
  var getInstalledEventCatalogVersion = () => {
2962
3039
  try {
2963
- const pkg = import_fs.default.readFileSync((0, import_node_path20.join)(dir, "package.json"), "utf8");
3040
+ const pkg = import_fs.default.readFileSync((0, import_node_path21.join)(dir, "package.json"), "utf8");
2964
3041
  const json = JSON.parse(pkg);
2965
3042
  return json.dependencies["@eventcatalog/core"];
2966
3043
  } catch (error) {
@@ -2984,7 +3061,7 @@ var resolveDevPort = async ({ projectDir }) => {
2984
3061
  };
2985
3062
  var startDevPrewarm = ({
2986
3063
  port = 3e3,
2987
- paths = ["/ping", "/"],
3064
+ paths = ["/"],
2988
3065
  retries = 80,
2989
3066
  intervalMs = 250,
2990
3067
  initialDelayMs = 500
@@ -2993,10 +3070,13 @@ var startDevPrewarm = ({
2993
3070
  const hit = (requestPath) => new Promise((resolve2) => {
2994
3071
  const req = import_node_http.default.get(
2995
3072
  {
2996
- hostname: "127.0.0.1",
3073
+ // Not 127.0.0.1: the dev server can listen on IPv6 only ([::1]), which refused
3074
+ // every prewarm request
3075
+ hostname: "localhost",
2997
3076
  port,
2998
3077
  path: requestPath,
2999
- timeout: 1200
3078
+ // A refused connection fails at once; once connected, let the first render finish
3079
+ timeout: 3e4
3000
3080
  },
3001
3081
  (res) => {
3002
3082
  res.resume();
@@ -3026,12 +3106,12 @@ var startDevPrewarm = ({
3026
3106
  var buildDevSearchIndex = async ({ config }) => {
3027
3107
  const result = await buildSearchIndex({
3028
3108
  projectDir: dir,
3029
- outDir: import_node_path21.default.join(core, "public"),
3030
- searchOutputPath: import_node_path21.default.join(core, "public", "pagefind"),
3109
+ outDir: import_node_path22.default.join(core, "public"),
3110
+ searchOutputPath: import_node_path22.default.join(core, "public", "pagefind"),
3031
3111
  config,
3032
3112
  isServer: false
3033
3113
  });
3034
- logger.info(`Indexed ${result.records} page(s) into ${import_node_path21.default.relative(core, result.outputPath)}`, "search");
3114
+ logger.info(`Indexed ${result.records} page(s) into ${import_node_path22.default.relative(core, result.outputPath)}`, "search");
3035
3115
  };
3036
3116
  var warnIfIndexedSearchUsesAuth = async () => {
3037
3117
  if (!await isAuthEnabled()) {
@@ -3094,10 +3174,14 @@ var runCommandWithFilteredOutput = async ({
3094
3174
  cwd,
3095
3175
  env: {
3096
3176
  ...process.env,
3177
+ // Astro sends usage data (commands, config, machine details) to Astro by default: turn it off
3178
+ // for everyone using EventCatalog
3179
+ ASTRO_TELEMETRY_DISABLED: "1",
3097
3180
  ...env
3098
3181
  },
3099
3182
  stdio: ["inherit", "pipe", "pipe"]
3100
3183
  });
3184
+ const signals = stopChildWithParent(child);
3101
3185
  let stdoutBuffer = "";
3102
3186
  let stderrBuffer = "";
3103
3187
  const flush = (buffer, writer, isFinal = false) => {
@@ -3125,11 +3209,13 @@ var runCommandWithFilteredOutput = async ({
3125
3209
  stderrBuffer = flush(stderrBuffer, process.stderr);
3126
3210
  });
3127
3211
  child.on("error", (error) => {
3212
+ signals.childClosed();
3128
3213
  reject(error);
3129
3214
  });
3130
3215
  child.on("close", (code) => {
3131
3216
  stdoutBuffer = flush(stdoutBuffer, process.stdout, true);
3132
3217
  stderrBuffer = flush(stderrBuffer, process.stderr, true);
3218
+ if (signals.childClosed()) return;
3133
3219
  if (code === 0) {
3134
3220
  resolve2();
3135
3221
  return;
@@ -3207,8 +3293,8 @@ program.command("dev").description("Run development server of EventCatalog").opt
3207
3293
  logger.info("Setting up EventCatalog...", "eventcatalog");
3208
3294
  const isServer = await isOutputServer();
3209
3295
  logger.info(isServer ? "EventCatalog is running in Server Mode" : "EventCatalog is running in Static Mode", "config");
3210
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3211
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3296
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3297
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3212
3298
  }
3213
3299
  if (options.debug) {
3214
3300
  logger.info("Debug mode enabled", "debug");
@@ -3255,7 +3341,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
3255
3341
  });
3256
3342
  startDevPrewarm({
3257
3343
  port: prewarmPort,
3258
- paths: ["/ping", "/"]
3344
+ // Renders the homepage before anyone opens it. Requests stop at the first response,
3345
+ // so a probe path like /ping first would leave the homepage cold.
3346
+ paths: ["/"]
3259
3347
  });
3260
3348
  }
3261
3349
  await runCommandWithFilteredOutput({
@@ -3267,7 +3355,8 @@ program.command("dev").description("Run development server of EventCatalog").opt
3267
3355
  CATALOG_DIR: core,
3268
3356
  EVENTCATALOG_DEV_MODE: "true",
3269
3357
  IGNORE_BUILD_ARTIFACTS: "true",
3270
- NODE_NO_WARNINGS: "1"
3358
+ NODE_NO_WARNINGS: "1",
3359
+ ...ASTRO_IN_FOREGROUND
3271
3360
  },
3272
3361
  shouldFilterLine: createAstroDevLineFilter(),
3273
3362
  transformLine: replaceAstroReadyVersionLine
@@ -3283,8 +3372,8 @@ program.command("build").description("Run build of EventCatalog").action(async (
3283
3372
  logger.info("Building EventCatalog...", "build");
3284
3373
  const isServer = await isOutputServer();
3285
3374
  logger.info(isServer ? "EventCatalog is running in Server Mode" : "EventCatalog is running in Static Mode", "config");
3286
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3287
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3375
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3376
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3288
3377
  }
3289
3378
  await verifyRequiredFieldsAreInCatalogConfigFile(dir);
3290
3379
  const config = await getEventCatalogConfigFile(dir);
@@ -3321,7 +3410,7 @@ program.command("build").description("Run build of EventCatalog").action(async (
3321
3410
  });
3322
3411
  if (await isIndexedSearchEnabled()) {
3323
3412
  await warnIfIndexedSearchUsesAuth();
3324
- const outDir = import_node_path21.default.resolve(dir, await getProjectOutDir());
3413
+ const outDir = import_node_path22.default.resolve(dir, await getProjectOutDir());
3325
3414
  logger.info("Building indexed search...", "search");
3326
3415
  const result = await buildSearchIndex({
3327
3416
  projectDir: dir,
@@ -3329,7 +3418,7 @@ program.command("build").description("Run build of EventCatalog").action(async (
3329
3418
  config,
3330
3419
  isServer
3331
3420
  });
3332
- logger.info(`Indexed ${result.records} page(s) into ${import_node_path21.default.relative(dir, result.outputPath)}`, "search");
3421
+ logger.info(`Indexed ${result.records} page(s) into ${import_node_path22.default.relative(dir, result.outputPath)}`, "search");
3333
3422
  }
3334
3423
  });
3335
3424
  var previewCatalog = async ({ command }) => {
@@ -3339,7 +3428,8 @@ var previewCatalog = async ({ command }) => {
3339
3428
  cwd: dir,
3340
3429
  env: {
3341
3430
  PROJECT_DIR: dir,
3342
- CATALOG_DIR: core
3431
+ CATALOG_DIR: core,
3432
+ ...ASTRO_IN_FOREGROUND
3343
3433
  },
3344
3434
  shouldFilterLine: createAstroLineFilter()
3345
3435
  });
@@ -3348,18 +3438,18 @@ var SERVER_BOOTSTRAP = `
3348
3438
  const entry = await import(process.argv[1]);
3349
3439
  const { server } = entry.startServer();
3350
3440
  globalThis[Symbol.for('eventcatalog.http-server')] = server.server;
3351
- const wake = process.env.EVENTCATALOG_STUDIO_WAKE_PATH;
3352
- if (wake) {
3441
+ const start = process.env.EVENTCATALOG_START_PATH;
3442
+ if (start) {
3353
3443
  server.server.once('listening', () => {
3354
3444
  // Where the server listens (HOST can be one address only); loopback when it listens on every address
3355
3445
  const { address, port } = server.server.address();
3356
3446
  const host = ['0.0.0.0', '::'].includes(address) ? '127.0.0.1' : address.includes(':') ? '[' + address + ']' : address;
3357
- fetch('http://' + host + ':' + port + wake).catch((error) => console.error('[studio] Could not start Studio:', error.message));
3447
+ fetch('http://' + host + ':' + port + start).catch((error) => console.error('[eventcatalog] Could not start the server:', error.message));
3358
3448
  });
3359
3449
  }
3360
3450
  `;
3361
3451
  var startServerCatalog = async () => {
3362
- const serverEntryPath = import_node_path21.default.join(dir, "dist", "server", "entry.mjs");
3452
+ const serverEntryPath = import_node_path22.default.join(dir, "dist", "server", "entry.mjs");
3363
3453
  const config = await getEventCatalogConfigFile(dir);
3364
3454
  const base = (config?.base || "/").replace(/\/$/, "");
3365
3455
  await runCommandWithFilteredOutput({
@@ -3370,7 +3460,7 @@ var startServerCatalog = async () => {
3370
3460
  PROJECT_DIR: dir,
3371
3461
  CATALOG_DIR: core,
3372
3462
  ASTRO_NODE_AUTOSTART: "disabled",
3373
- ...await isStudioEnabled() && { EVENTCATALOG_STUDIO_WAKE_PATH: `${base}/_eventcatalog/studio/wake` }
3463
+ EVENTCATALOG_START_PATH: `${base}/_eventcatalog/start`
3374
3464
  },
3375
3465
  shouldFilterLine: createAstroLineFilter()
3376
3466
  });
@@ -3378,20 +3468,21 @@ var startServerCatalog = async () => {
3378
3468
  program.command("preview").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
3379
3469
  logger.welcome();
3380
3470
  logger.info("Starting preview of your build...", "preview");
3381
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3382
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3471
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3472
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3383
3473
  }
3384
3474
  await previewCatalog({ command });
3385
3475
  });
3386
3476
  program.command("start").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
3387
3477
  logger.welcome();
3388
3478
  logger.info("Starting preview of your build...", "preview");
3389
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3390
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3479
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3480
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3391
3481
  }
3392
3482
  const isServerOutput = await isOutputServer();
3393
3483
  if (isServerOutput) {
3394
- await getLicenseStatus2(dir);
3484
+ const license = await getLicenseStatus2(dir);
3485
+ void log_build_default(dir, { command: "start", license });
3395
3486
  await startServerCatalog();
3396
3487
  } else {
3397
3488
  await previewCatalog({ command });
@@ -3400,22 +3491,22 @@ program.command("start").description("Serves the contents of your eventcatalog b
3400
3491
  program.command("export").description("Export your EventCatalog using the SDK dumpCatalog function").option("--include-markdown", "Include markdown content in the export", false).action(async (options) => {
3401
3492
  logger.welcome();
3402
3493
  logger.info("Exporting EventCatalog...", "export");
3403
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3404
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3494
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3495
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3405
3496
  }
3406
3497
  const { default: initSDK } = await import("@eventcatalog/sdk");
3407
3498
  const sdk = initSDK(dir);
3408
3499
  const catalog = await sdk.dumpCatalog({ includeMarkdown: options.includeMarkdown });
3409
- const exportsDir = import_node_path21.default.join(dir, "exports");
3500
+ const exportsDir = import_node_path22.default.join(dir, "exports");
3410
3501
  ensureDir(exportsDir);
3411
3502
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
3412
- const exportFile = import_node_path21.default.join(exportsDir, `catalog-${date}.json`);
3503
+ const exportFile = import_node_path22.default.join(exportsDir, `catalog-${date}.json`);
3413
3504
  import_fs.default.writeFileSync(exportFile, JSON.stringify(catalog, null, 2), "utf-8");
3414
3505
  logger.info(`Catalog exported to ${exportFile}`, "export");
3415
3506
  });
3416
3507
  program.command("generate [siteDir]").description("Start the generator scripts.").action(async () => {
3417
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3418
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3508
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3509
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3419
3510
  }
3420
3511
  await generate(dir);
3421
3512
  });
@@ -3488,7 +3579,7 @@ var reportFederationProgress = (event, verbose = false) => {
3488
3579
  }
3489
3580
  return;
3490
3581
  case "hydrating":
3491
- logger.info(`Hydrating federated content into ${import_node_path21.default.relative(dir, event.outDir)}/...`, "federation");
3582
+ logger.info(`Hydrating federated content into ${import_node_path22.default.relative(dir, event.outDir)}/...`, "federation");
3492
3583
  return;
3493
3584
  case "hydrate:cache":
3494
3585
  if (event.files === 1 || event.files % 25 === 0) {
@@ -3511,13 +3602,13 @@ var reportFederationProgress = (event, verbose = false) => {
3511
3602
  `Federation complete: ${event.result.sources} sources, ${event.result.resources} remote resources, ${event.result.hydrate.written} files written (${event.result.hydrate.fetched} downloaded, ${event.result.hydrate.written - event.result.hydrate.fetched} cached)`,
3512
3603
  "federation"
3513
3604
  );
3514
- logger.info(`Recorded resolved source state in ${import_node_path21.default.relative(dir, event.result.lockPath)}`, "federation");
3605
+ logger.info(`Recorded resolved source state in ${import_node_path22.default.relative(dir, event.result.lockPath)}`, "federation");
3515
3606
  }
3516
3607
  };
3517
3608
  program.command("federate").description("Fetch, resolve, and hydrate the catalogs configured in federation.sources.").option("--no-cache", "Download all federation content and refresh the cache.").option("-v, --verbose", "Show detailed federation diagnostics.").action(async (commandOptions) => {
3518
3609
  logger.welcome();
3519
- if (import_fs.default.existsSync(import_node_path21.default.join(dir, ".env"))) {
3520
- import_dotenv.default.config({ path: import_node_path21.default.join(dir, ".env") });
3610
+ if (import_fs.default.existsSync(import_node_path22.default.join(dir, ".env"))) {
3611
+ import_dotenv.default.config({ path: import_node_path22.default.join(dir, ".env") });
3521
3612
  }
3522
3613
  logger.info("Starting federation...", "federation");
3523
3614
  let cleanedPreviousOutput = false;
@@ -3538,7 +3629,7 @@ program.addHelpText(
3538
3629
  Example: npx eventcatalog dev --debug -- --env=production --port=3000
3539
3630
  `
3540
3631
  );
3541
- program.parseAsync().then(() => process.exit(0)).catch((err) => {
3632
+ program.parseAsync().then(() => process.exit()).catch((err) => {
3542
3633
  if (!(err instanceof FederationConflictError) && !(err instanceof FederationDiagnosticError)) console.error(err);
3543
3634
  process.exit(1);
3544
3635
  });