@eventcatalog/core 5.0.0-beta.2 → 5.0.0-beta.21

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 (209) hide show
  1. package/LICENSE +234 -134
  2. package/README.md +5 -5
  3. package/dist/analytics/analytics.cjs +18 -3
  4. package/dist/analytics/analytics.d.cts +1 -1
  5. package/dist/analytics/analytics.d.ts +1 -1
  6. package/dist/analytics/analytics.js +3 -2
  7. package/dist/analytics/log-build.cjs +71 -35
  8. package/dist/analytics/log-build.js +5 -4
  9. package/dist/analytics/telemetry.cjs +42 -0
  10. package/dist/analytics/telemetry.d.cts +20 -0
  11. package/dist/analytics/telemetry.d.ts +20 -0
  12. package/dist/analytics/telemetry.js +8 -0
  13. package/dist/catalog-runtime.cjs +1 -1
  14. package/dist/{chunk-TQLRG35T.js → chunk-AWOO63ME.js} +71 -45
  15. package/dist/chunk-CPW6G62V.js +17 -0
  16. package/dist/{chunk-KIDISU6X.js → chunk-I7F7CPDC.js} +56 -33
  17. package/dist/{chunk-HGRFXTFC.js → chunk-OVWDUANF.js} +1 -1
  18. package/dist/{chunk-62EV4IJA.js → chunk-RIRRWE7D.js} +1 -1
  19. package/dist/chunk-S5GWAUG5.js +29 -0
  20. package/dist/{chunk-4J2ZM2HX.js → chunk-W6KDW6ZC.js} +1 -1
  21. package/dist/{chunk-XARPIXWF.js → chunk-WHYRRLHE.js} +9 -3
  22. package/dist/constants.cjs +1 -1
  23. package/dist/constants.js +1 -1
  24. package/dist/eventcatalog.cjs +245 -131
  25. package/dist/eventcatalog.config.d.cts +59 -1
  26. package/dist/eventcatalog.config.d.ts +59 -1
  27. package/dist/eventcatalog.js +45 -15
  28. package/dist/federation/federate.js +2 -2
  29. package/dist/generate.cjs +1 -1
  30. package/dist/generate.js +3 -3
  31. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
  32. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
  33. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
  34. package/dist/runtime-dependencies/@hocuspocus__provider.mjs +3 -0
  35. package/dist/runtime-dependencies/@hocuspocus__server.mjs +3 -0
  36. package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +3 -0
  37. package/dist/runtime-dependencies/@mcp-b__webmcp-polyfill.mjs +3 -0
  38. package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
  39. package/dist/runtime-dependencies/manifest.json +13 -1
  40. package/dist/runtime-dependencies/react-hotkeys-hook.mjs +3 -0
  41. package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
  42. package/dist/runtime-dependencies/y-protocols.mjs +3 -0
  43. package/dist/runtime-dependencies/y-protocols__awareness.mjs +3 -0
  44. package/dist/runtime-dependencies/yjs.mjs +3 -0
  45. package/dist/utils/child-process-signals.cjs +53 -0
  46. package/dist/utils/child-process-signals.d.cts +19 -0
  47. package/dist/utils/child-process-signals.d.ts +19 -0
  48. package/dist/utils/child-process-signals.js +6 -0
  49. package/dist/utils/cli-logger.cjs +1 -1
  50. package/dist/utils/cli-logger.js +2 -2
  51. package/dist/utils/license-status.cjs +71 -45
  52. package/dist/utils/license-status.d.cts +14 -5
  53. package/dist/utils/license-status.d.ts +14 -5
  54. package/dist/utils/license-status.js +1 -1
  55. package/eventcatalog/astro.config.mjs +23 -1
  56. package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
  57. package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
  58. package/eventcatalog/integrations/storage.mjs +20 -0
  59. package/eventcatalog/integrations/studio-server.mjs +32 -0
  60. package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
  61. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
  62. package/eventcatalog/src/components/Grids/utils.tsx +0 -23
  63. package/eventcatalog/src/components/Header.astro +3 -3
  64. package/eventcatalog/src/components/MDX/CodeGroup/CodeGroup.tsx +6 -1
  65. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +42 -3
  66. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
  67. package/eventcatalog/src/components/NavigationProgress.astro +7 -0
  68. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
  69. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
  70. package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
  71. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
  72. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +12 -4
  73. package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
  74. package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
  75. package/eventcatalog/src/components/Search/search-utils.ts +26 -0
  76. package/eventcatalog/src/components/Seo.astro +5 -1
  77. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +53 -83
  78. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
  79. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +131 -0
  80. package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
  81. package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +4 -62
  82. package/eventcatalog/src/components/Tables/Discover/columns.tsx +17 -150
  83. package/eventcatalog/src/components/Tables/Resources/ResourcesTable.tsx +425 -0
  84. package/eventcatalog/src/components/Tables/RowActionsMenu.tsx +157 -0
  85. package/eventcatalog/src/components/Tables/TablePagination.tsx +82 -0
  86. package/eventcatalog/src/features/ai/chat-api.ts +3 -3
  87. package/eventcatalog/src/features/auth/error.astro +4 -2
  88. package/eventcatalog/src/features/auth/login.astro +2 -1
  89. package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +10 -0
  90. package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
  91. package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
  92. package/eventcatalog/src/features/integrations/eventcatalog-features.ts +34 -1
  93. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
  94. package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +47 -0
  95. package/eventcatalog/src/features/mcp/apps/canvas/styles.css +24 -0
  96. package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +278 -0
  97. package/eventcatalog/src/features/mcp/apps/generated/canvas.html +272 -0
  98. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +77 -76
  99. package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +2 -1
  100. package/eventcatalog/src/features/mcp/mcp-apps.ts +6 -3
  101. package/eventcatalog/src/features/mcp/mcp-server.ts +36 -5
  102. package/eventcatalog/src/features/server/start.ts +25 -0
  103. package/eventcatalog/src/features/storage/database.ts +88 -0
  104. package/eventcatalog/src/features/storage/migrations.ts +85 -0
  105. package/eventcatalog/src/features/storage/sql/database.sql +5 -0
  106. package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
  107. package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
  108. package/eventcatalog/src/features/storage/sql.ts +28 -0
  109. package/eventcatalog/src/features/studio/agent-choreography.ts +384 -0
  110. package/eventcatalog/src/features/studio/agents.ts +28 -0
  111. package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
  112. package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
  113. package/eventcatalog/src/features/studio/api/client.ts +40 -0
  114. package/eventcatalog/src/features/studio/canvas-actions.ts +540 -0
  115. package/eventcatalog/src/features/studio/canvas-preview.ts +52 -0
  116. package/eventcatalog/src/features/studio/catalog-resources.ts +155 -0
  117. package/eventcatalog/src/features/studio/catalog.ts +173 -0
  118. package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +518 -0
  119. package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +118 -0
  120. package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +434 -0
  121. package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +143 -0
  122. package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
  123. package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
  124. package/eventcatalog/src/features/studio/components/JoinForm.tsx +109 -0
  125. package/eventcatalog/src/features/studio/components/LeftPanel.tsx +203 -0
  126. package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
  127. package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
  128. package/eventcatalog/src/features/studio/components/Presence.tsx +293 -0
  129. package/eventcatalog/src/features/studio/components/ShareDialog.tsx +396 -0
  130. package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
  131. package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +2091 -0
  132. package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
  133. package/eventcatalog/src/features/studio/document-name.ts +7 -0
  134. package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
  135. package/eventcatalog/src/features/studio/hooks/presence-sender.ts +63 -0
  136. package/eventcatalog/src/features/studio/hooks/presence-store.ts +119 -0
  137. package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +353 -0
  138. package/eventcatalog/src/features/studio/hooks/use-comments.ts +54 -0
  139. package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +109 -0
  140. package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +782 -0
  141. package/eventcatalog/src/features/studio/identity.ts +59 -0
  142. package/eventcatalog/src/features/studio/limits.ts +2 -0
  143. package/eventcatalog/src/features/studio/pages/[id].astro +69 -0
  144. package/eventcatalog/src/features/studio/pages/index.astro +784 -0
  145. package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +27 -0
  146. package/eventcatalog/src/features/studio/server/canvas-mcp.ts +495 -0
  147. package/eventcatalog/src/features/studio/server/runtime.ts +498 -0
  148. package/eventcatalog/src/features/studio/server/sign-in.ts +18 -0
  149. package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
  150. package/eventcatalog/src/features/studio/server/storage.ts +90 -0
  151. package/eventcatalog/src/features/studio/server/tool-icons.ts +30 -0
  152. package/eventcatalog/src/features/studio/tool-sync.ts +75 -0
  153. package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
  154. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +13 -7
  155. package/eventcatalog/src/pages/_index.astro +1 -1
  156. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +52 -63
  157. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +34 -46
  158. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +11 -29
  159. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_ResourcesPage.astro +79 -0
  160. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +32 -14
  161. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +63 -58
  162. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +2 -62
  163. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +1 -1
  164. package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +13 -0
  165. package/eventcatalog/src/pages/index.astro +1 -1
  166. package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -1
  167. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +1 -1
  168. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +24 -42
  169. package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +2 -0
  170. package/eventcatalog/src/stores/sidebar-store/builders/message.ts +2 -0
  171. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +23 -23
  172. package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +13 -0
  173. package/eventcatalog/src/stores/sidebar-store/builders/system.ts +18 -27
  174. package/eventcatalog/src/stores/sidebar-store/state.ts +5 -0
  175. package/eventcatalog/src/styles/tailwind.css +2 -2
  176. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
  177. package/eventcatalog/src/utils/collections/channels.ts +56 -1
  178. package/eventcatalog/src/utils/collections/flows.ts +50 -1
  179. package/eventcatalog/src/utils/collections/message-connections.ts +60 -0
  180. package/eventcatalog/src/utils/collections/message-triggers.ts +2 -1
  181. package/eventcatalog/src/utils/collections/resource-owners.ts +193 -0
  182. package/eventcatalog/src/utils/collections/resources.ts +310 -0
  183. package/eventcatalog/src/utils/collections/util.ts +31 -0
  184. package/eventcatalog/src/utils/feature.ts +8 -0
  185. package/eventcatalog/src/utils/git.ts +11 -5
  186. package/eventcatalog/src/utils/link-validation.ts +25 -19
  187. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
  188. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
  189. package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +0 -2
  190. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
  191. package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
  192. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
  193. package/eventcatalog/src/utils/page-title.ts +15 -0
  194. package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
  195. package/eventcatalog/src/utils/trial.ts +1 -1
  196. package/package.json +22 -16
  197. package/dist/runtime-dependencies/shelljs.mjs +0 -3
  198. package/eventcatalog/public/studio-bg.png +0 -0
  199. package/eventcatalog/src/components/Grids/DomainGrid.tsx +0 -838
  200. package/eventcatalog/src/components/Grids/MessageGrid.tsx +0 -344
  201. package/eventcatalog/src/components/Grids/SystemGrid.tsx +0 -185
  202. package/eventcatalog/src/components/Grids/components.tsx +0 -170
  203. package/eventcatalog/src/components/Grids/message-link.ts +0 -38
  204. package/eventcatalog/src/components/Studio/StudioPageModal.tsx +0 -150
  205. package/eventcatalog/src/components/Tables/SystemResources/SystemResourcesTable.tsx +0 -294
  206. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.spec.ts +0 -65
  207. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.ts +0 -46
  208. package/eventcatalog/src/pages/studio.astro +0 -316
  209. package/dist/{chunk-AYNZXUB5.js → chunk-KHACCTW2.js} +3 -3
@@ -22,7 +22,7 @@ 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
 
@@ -181,7 +181,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
181
181
  var import_picocolors = __toESM(require("picocolors"), 1);
182
182
 
183
183
  // package.json
184
- var version = "5.0.0-beta.2";
184
+ var version = "5.0.0-beta.21";
185
185
 
186
186
  // src/constants.ts
187
187
  var VERSION = version;
@@ -191,8 +191,8 @@ var getTimestamp = () => {
191
191
  const now = /* @__PURE__ */ new Date();
192
192
  return now.toLocaleTimeString("en-US", { hour12: false });
193
193
  };
194
- var formatMessage = (tag, message, tagColor) => {
195
- return `${import_picocolors.default.dim(getTimestamp())} ${tagColor(`[${tag}]`)} ${message}`;
194
+ var formatMessage = (tag, message2, tagColor) => {
195
+ return `${import_picocolors.default.dim(getTimestamp())} ${tagColor(`[${tag}]`)} ${message2}`;
196
196
  };
197
197
  var logger = {
198
198
  welcome: () => {
@@ -208,28 +208,28 @@ var logger = {
208
208
  );
209
209
  console.log();
210
210
  },
211
- info: (message, tag = "info") => {
212
- console.log(formatMessage(tag, message, import_picocolors.default.blue));
211
+ info: (message2, tag = "info") => {
212
+ console.log(formatMessage(tag, message2, import_picocolors.default.blue));
213
213
  },
214
- success: (message, tag = "success") => {
215
- console.log(formatMessage(tag, message, import_picocolors.default.green));
214
+ success: (message2, tag = "success") => {
215
+ console.log(formatMessage(tag, message2, import_picocolors.default.green));
216
216
  },
217
- error: (message, tag = "error") => {
218
- console.log(formatMessage(tag, message, import_picocolors.default.red));
217
+ error: (message2, tag = "error") => {
218
+ console.log(formatMessage(tag, message2, import_picocolors.default.red));
219
219
  },
220
- warning: (message, tag = "warn") => {
221
- console.log(formatMessage(tag, message, import_picocolors.default.yellow));
220
+ warning: (message2, tag = "warn") => {
221
+ console.log(formatMessage(tag, message2, import_picocolors.default.yellow));
222
222
  },
223
- line: (message = "") => {
224
- console.log(message);
223
+ line: (message2 = "") => {
224
+ console.log(message2);
225
225
  },
226
- diagnostic: (severity, message, rule, attributes = []) => {
226
+ diagnostic: (severity, message2, rule, attributes = []) => {
227
227
  const isError = severity === "error";
228
228
  const color = isError ? import_picocolors.default.red : import_picocolors.default.yellow;
229
229
  const icon = isError ? "\u2716" : "\u26A0";
230
- const label = `${icon} ${severity.padEnd(7)} ${message}`;
230
+ const label = `${icon} ${severity.padEnd(7)} ${message2}`;
231
231
  const ruleSpacing = " ".repeat(Math.max(2, 72 - label.length));
232
- console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${message}${ruleSpacing}${import_picocolors.default.gray(rule)}`);
232
+ console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${message2}${ruleSpacing}${import_picocolors.default.gray(rule)}`);
233
233
  for (const attribute of attributes) {
234
234
  console.log(` - ${import_picocolors.default.dim(`${attribute.label}:`)} ${attribute.value}`);
235
235
  }
@@ -243,8 +243,8 @@ var logger = {
243
243
  const warningCount = `${warnings} warning${warnings === 1 ? "" : "s"}`;
244
244
  console.log(color(`${icon} ${problems} (${errorCount}, ${warningCount})`));
245
245
  },
246
- dim: (message) => {
247
- console.log(import_picocolors.default.dim(message));
246
+ dim: (message2) => {
247
+ console.log(import_picocolors.default.dim(message2));
248
248
  }
249
249
  };
250
250
 
@@ -304,7 +304,23 @@ var generate = async (PROJECT_DIRECTORY) => {
304
304
 
305
305
  // src/analytics/analytics.js
306
306
  var import_os = __toESM(require("os"), 1);
307
- async function raiseEvent(eventData) {
307
+
308
+ // src/analytics/telemetry.ts
309
+ var TELEMETRY_REQUEST_TIMEOUT_MS = 2e3;
310
+ var isOptOutEnvValue = (value) => {
311
+ if (typeof value !== "string") return false;
312
+ const normalized = value.trim().toLowerCase();
313
+ return normalized === "1" || normalized === "true";
314
+ };
315
+ var isTelemetryDisabled = (config, env) => {
316
+ if (isOptOutEnvValue(env.EVENTCATALOG_TELEMETRY_DISABLED)) return true;
317
+ if (isOptOutEnvValue(env.DO_NOT_TRACK)) return true;
318
+ return config?.telemetry === false;
319
+ };
320
+
321
+ // src/analytics/analytics.js
322
+ async function raiseEvent(eventData, config) {
323
+ if (isTelemetryDisabled(config, process.env)) return;
308
324
  if (typeof eventData?.command !== "string" || typeof eventData?.cId !== "string") return;
309
325
  const url = "https://queue.simpleanalyticscdn.com/events";
310
326
  const userAgent = `@eventcatalog/eventcatalog@${VERSION} (${import_os.default.platform()}; ${import_os.default.arch()}; Node/${process.version})`;
@@ -326,7 +342,8 @@ async function raiseEvent(eventData) {
326
342
  const response = await fetch(url, {
327
343
  method: "POST",
328
344
  headers,
329
- body: JSON.stringify(payload)
345
+ body: JSON.stringify(payload),
346
+ signal: AbortSignal.timeout(TELEMETRY_REQUEST_TIMEOUT_MS)
330
347
  });
331
348
  if (!response.ok) {
332
349
  throw new Error(`Failed to raise analytics event: ${response.status}`);
@@ -403,10 +420,11 @@ function serializeCounts(counts) {
403
420
 
404
421
  // src/utils/license-status.ts
405
422
  var import_boxen = __toESM(require("boxen"), 1);
423
+ var import_picocolors2 = __toESM(require("picocolors"), 1);
406
424
  var import_license2 = require("@eventcatalog/license");
407
425
 
408
426
  // eventcatalog/src/utils/trial.ts
409
- var TRIAL_LENGTH_DAYS = 90;
427
+ var TRIAL_LENGTH_DAYS = 60;
410
428
  var LICENSE_FAQ_URL = "https://www.eventcatalog.dev/license-faq";
411
429
  var LICENSE_RENEW_URL = "https://eventcatalog.cloud";
412
430
  var DAY_IN_MS = 24 * 60 * 60 * 1e3;
@@ -525,75 +543,100 @@ var getLicenseAnalytics = (license = { state: "none" }, tsd) => ({
525
543
  });
526
544
  var formatDate = (date) => date.toLocaleDateString(void 0, { dateStyle: "medium" });
527
545
  var formatDays = (days) => `${days} ${days === 1 ? "day" : "days"}`;
528
- var getTrialLine = (tsd, now) => {
546
+ var PLAIN = { bold: (text) => text, dim: (text) => text, link: (text) => text };
547
+ 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) => {
549
+ const width = Math.max(0, ...[...rows, ...links].map(([label]) => label.length));
550
+ const row = ([label, value]) => `${colours.dim(label.padEnd(width))} ${value}`;
551
+ return [
552
+ colours.bold(headline),
553
+ ...rows.length ? ["", ...rows.map(row)] : [],
554
+ ...links.length ? ["", ...links.map(([label, url]) => row([label, colours.link(url)]))] : []
555
+ ].join("\n");
556
+ };
557
+ var message = (content) => ({
558
+ ...content,
559
+ text: render(content, PLAIN)
560
+ });
561
+ var getTrialRow = (tsd, now) => {
529
562
  const trial = getTrialStatus(tsd, now);
530
563
  if (!trial) return;
531
- return trial.ended ? `Your ${TRIAL_LENGTH_DAYS}-day EventCatalog trial ended on ${formatDate(trial.endsAt)}.` : `${formatDays(trial.daysLeft)} left of your ${TRIAL_LENGTH_DAYS}-day EventCatalog trial (ends ${formatDate(trial.endsAt)}).`;
564
+ return [
565
+ "Trial",
566
+ trial.ended ? `Ended ${formatDate(trial.endsAt)}` : `${formatDays(trial.daysLeft)} left of ${TRIAL_LENGTH_DAYS} (ends ${formatDate(trial.endsAt)})`
567
+ ];
532
568
  };
533
569
  var getLicenseStatusMessage = (license, tsd, now = Date.now()) => {
570
+ const licensing = ["Licensing", LICENSE_FAQ_URL];
571
+ const renew = ["Renew", LICENSE_RENEW_URL];
572
+ const licensedTo = "org" in license && license.org ? [["Licensed to", license.org]] : [];
534
573
  if (license.state === "licensed") {
535
574
  const daysLeft = Math.max(0, Math.ceil((license.expiresAt.getTime() - now) / DAY_IN_MS2));
536
- const licensedTo = license.org ? `Licensed to ${license.org}` : "Licensed";
537
575
  if (daysLeft < LICENSE_REMINDER_DAYS) {
538
- return {
539
- title: "EventCatalog Commercial License",
576
+ return message({
577
+ title: "EventCatalog license",
540
578
  color: "yellow",
541
- text: [
542
- licensedTo,
543
- `Your license expires in ${formatDays(daysLeft)}, on ${formatDate(license.expiresAt)}.`,
544
- `Renew it to keep using EventCatalog commercially: ${LICENSE_RENEW_URL}`
545
- ].join("\n")
546
- };
579
+ headline: `Your commercial license expires in ${formatDays(daysLeft)}`,
580
+ rows: [...licensedTo, ["Expires", formatDate(license.expiresAt)]],
581
+ links: [renew]
582
+ });
547
583
  }
548
- return {
549
- title: "EventCatalog Commercial License",
584
+ return message({
585
+ title: "EventCatalog license",
550
586
  color: "green",
551
- text: `${licensedTo}
552
- Valid until ${formatDate(license.expiresAt)} (${formatDays(daysLeft)} left)`
553
- };
587
+ headline: "Commercial license active",
588
+ rows: [...licensedTo, ["Valid until", `${formatDate(license.expiresAt)} (${formatDays(daysLeft)} left)`]],
589
+ links: []
590
+ });
554
591
  }
555
592
  if (license.state === "plan") return;
556
- const trialLine = getTrialLine(tsd, now);
593
+ const trialRow = getTrialRow(tsd, now);
594
+ const trialRows = trialRow ? [trialRow] : [];
557
595
  if (license.state === "none") {
558
- if (!trialLine) return;
559
- const ended = getTrialStatus(tsd, now)?.ended;
560
- return {
596
+ const trial = getTrialStatus(tsd, now);
597
+ if (!trial || !trialRow) return;
598
+ return message({
561
599
  title: "EventCatalog trial",
562
- color: ended ? "yellow" : "green",
563
- text: `${trialLine}
564
- Learn about licensing: ${LICENSE_FAQ_URL}`
565
- };
600
+ color: trial.ended ? "yellow" : "green",
601
+ headline: trial.ended ? "Your EventCatalog trial has ended" : `You're on the ${TRIAL_LENGTH_DAYS}-day EventCatalog trial`,
602
+ rows: trialRows,
603
+ links: trial.ended ? [["Get a license", LICENSE_RENEW_URL], licensing] : [licensing]
604
+ });
566
605
  }
567
606
  if (license.state === "expired") {
568
- const expiredOn = license.expiresAt ? `expired on ${formatDate(license.expiresAt)} (${formatDays(Math.floor((now - license.expiresAt.getTime()) / DAY_IN_MS2))} ago)` : "has expired";
569
- return {
570
- title: "EventCatalog License Expired",
607
+ const expiredOn = license.expiresAt ? [
608
+ [
609
+ "Expired",
610
+ `${formatDate(license.expiresAt)} (${formatDays(Math.floor((now - license.expiresAt.getTime()) / DAY_IN_MS2))} ago)`
611
+ ]
612
+ ] : [];
613
+ return message({
614
+ title: "EventCatalog license",
571
615
  color: "yellow",
572
- text: [
573
- `Your EventCatalog commercial license${license.org ? ` for ${license.org}` : ""} ${expiredOn}.`,
574
- `Renew it to keep using EventCatalog commercially: ${LICENSE_RENEW_URL}`,
575
- trialLine,
576
- `Learn about licensing: ${LICENSE_FAQ_URL}`
577
- ].filter(Boolean).join("\n")
578
- };
616
+ headline: "Your commercial license has expired",
617
+ rows: [...licensedTo, ...expiredOn, ...trialRows],
618
+ links: [renew, licensing]
619
+ });
579
620
  }
580
- return {
621
+ return message({
581
622
  title: "EventCatalog license",
582
623
  color: "yellow",
583
- text: [`Your license.jwt could not be verified: ${license.reason}.`, trialLine, `Learn about licensing: ${LICENSE_FAQ_URL}`].filter(Boolean).join("\n")
584
- };
624
+ headline: "Your license.jwt couldn't be verified",
625
+ rows: [["Reason", license.reason.charAt(0).toUpperCase() + license.reason.slice(1)], ...trialRows],
626
+ links: [licensing]
627
+ });
585
628
  };
586
629
  var printLicenseStatus = (license, tsd) => {
587
- const message = getLicenseStatusMessage(license, tsd);
588
- if (!message) return;
630
+ const status = getLicenseStatusMessage(license, tsd);
631
+ if (!status) return;
589
632
  console.log(
590
- (0, import_boxen.default)(message.text, {
591
- padding: 1,
633
+ (0, import_boxen.default)(render(status, COLOURS), {
634
+ padding: { top: 1, bottom: 1, left: 2, right: 2 },
592
635
  margin: 1,
593
636
  borderStyle: "round",
594
- borderColor: message.color,
595
- title: message.title,
596
- titleAlignment: "center"
637
+ borderColor: status.color,
638
+ title: status.title,
639
+ titleAlignment: "left"
597
640
  })
598
641
  );
599
642
  };
@@ -653,50 +696,69 @@ var toCloudResourceCounts = (counts) => ({
653
696
  customPages: counts.customPages || 0,
654
697
  customApis: counts.customApis || 0
655
698
  });
656
- var reportCloudResourceInventory = async (configFile, resourceCounts) => {
699
+ var getEnabledCloudAnalytics = (configFile) => {
657
700
  const analytics = configFile.cloud?.analytics;
658
- if (!analytics?.enabled || !analytics.trackingId || !analytics.writeKey) return;
701
+ if (!analytics?.enabled || !analytics.trackingId || !analytics.writeKey) return null;
702
+ return analytics;
703
+ };
704
+ var reportCloudResourceInventory = async (configFile, resourceCounts) => {
705
+ const analytics = getEnabledCloudAnalytics(configFile);
706
+ if (!analytics) return;
659
707
  const endpoint = analytics.endpoint || CLOUD_ANALYTICS_ENDPOINT;
660
- await fetch(endpoint, {
661
- method: "POST",
662
- headers: {
663
- "Content-Type": "application/json",
664
- "X-EventCatalog-Analytics-Key": analytics.writeKey
665
- },
666
- body: JSON.stringify({
667
- trackingId: analytics.trackingId,
668
- event: "catalog.resource_inventory_reported",
669
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
670
- counts: toCloudResourceCounts(resourceCounts)
671
- })
672
- });
708
+ try {
709
+ await fetch(endpoint, {
710
+ method: "POST",
711
+ headers: {
712
+ "Content-Type": "application/json",
713
+ "X-EventCatalog-Analytics-Key": analytics.writeKey
714
+ },
715
+ body: JSON.stringify({
716
+ trackingId: analytics.trackingId,
717
+ event: "catalog.resource_inventory_reported",
718
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
719
+ counts: toCloudResourceCounts(resourceCounts)
720
+ }),
721
+ signal: AbortSignal.timeout(TELEMETRY_REQUEST_TIMEOUT_MS)
722
+ });
723
+ } catch {
724
+ }
673
725
  };
674
726
  var main = async (projectDir, { command = "build", license } = {}) => {
675
727
  try {
676
728
  await verifyRequiredFieldsAreInCatalogConfigFile(projectDir);
677
729
  const configFile = await getEventCatalogConfigFile(projectDir);
730
+ if (isTelemetryDisabled(configFile, process.env)) {
731
+ if (getEnabledCloudAnalytics(configFile)) {
732
+ const resourceCounts2 = await countResources(projectDir);
733
+ await reportCloudResourceInventory(configFile, resourceCounts2);
734
+ }
735
+ return;
736
+ }
678
737
  const { cId, tsd, organizationName, generators = [] } = configFile;
679
738
  const generatorNames = generators.length > 0 ? generators.map((generator) => generator[0]) : ["none"];
680
739
  const features = await getFeatures(configFile);
681
740
  const resourceCounts = await countResources(projectDir);
682
741
  const contentHash = await hashCatalogContent(projectDir);
683
742
  await reportCloudResourceInventory(configFile, resourceCounts);
684
- await raiseEvent({
685
- command,
686
- org: organizationName,
687
- cId,
688
- // Trial start date (unix ms) from eventcatalog.config.js
689
- tsd,
690
- // Commercial license or trial, and when each expires (unix ms)
691
- ...getLicenseAnalytics(license, tsd),
692
- // CI redeploys and human-run builds are different signals; tag rather than suppress
693
- ci: process.env.CI ? "true" : "false",
694
- contentHash,
695
- generators: generatorNames.toString(),
696
- features: Object.keys(features).map((feature) => `${feature}:${features[feature]}`).join(","),
697
- directorySources: serializeDirectorySources(configFile),
698
- resources: serializeCounts(resourceCounts)
699
- });
743
+ await raiseEvent(
744
+ {
745
+ command,
746
+ org: organizationName,
747
+ cId,
748
+ // Trial start date (unix ms) from eventcatalog.config.js
749
+ tsd,
750
+ // Commercial license or trial, and when each expires (unix ms)
751
+ ...getLicenseAnalytics(license, tsd),
752
+ // CI redeploys and human-run builds are different signals; tag rather than suppress
753
+ ci: process.env.CI ? "true" : "false",
754
+ contentHash,
755
+ generators: generatorNames.toString(),
756
+ features: Object.keys(features).map((feature) => `${feature}:${features[feature]}`).join(","),
757
+ directorySources: serializeDirectorySources(configFile),
758
+ resources: serializeCounts(resourceCounts)
759
+ },
760
+ configFile
761
+ );
700
762
  } catch (error) {
701
763
  }
702
764
  };
@@ -836,13 +898,13 @@ var message_channels_to_service_channels_default = async (dir2) => {
836
898
  absolute: true
837
899
  }
838
900
  );
839
- const messagesWithChannels = messages.reduce((acc, message) => {
840
- const file = import_node_fs5.default.readFileSync(message, "utf8");
901
+ const messagesWithChannels = messages.reduce((acc, message2) => {
902
+ const file = import_node_fs5.default.readFileSync(message2, "utf8");
841
903
  const { data } = (0, import_gray_matter3.default)(file);
842
904
  if (data.channels?.length > 0) {
843
905
  acc.push({
844
906
  ...data,
845
- path: message
907
+ path: message2
846
908
  });
847
909
  }
848
910
  return acc;
@@ -853,9 +915,9 @@ var message_channels_to_service_channels_default = async (dir2) => {
853
915
  const servicesWithChannels = services.reduce((acc, service) => {
854
916
  const file = import_node_fs5.default.readFileSync(service, "utf8");
855
917
  const { data } = (0, import_gray_matter3.default)(file);
856
- const isSending = data.sends?.some((send) => messagesWithChannels.some((message) => message.id === send.id));
918
+ const isSending = data.sends?.some((send) => messagesWithChannels.some((message2) => message2.id === send.id));
857
919
  const isReceiving = data.receives?.some(
858
- (receive) => messagesWithChannels.some((message) => message.id === receive.id)
920
+ (receive) => messagesWithChannels.some((message2) => message2.id === receive.id)
859
921
  );
860
922
  if (isSending || isReceiving) {
861
923
  acc.push({
@@ -868,16 +930,16 @@ var message_channels_to_service_channels_default = async (dir2) => {
868
930
  for (const service of servicesWithChannels) {
869
931
  const file = import_node_fs5.default.readFileSync(service.path, "utf8");
870
932
  const { data } = (0, import_gray_matter3.default)(file);
871
- const messagesTheServiceSendsThatNeedUpdating = data.sends?.filter((send) => messagesWithChannels.some((message) => message.id === send.id)) ?? [];
872
- const messagesTheServiceReceivesThatNeedUpdating = data.receives?.filter((receive) => messagesWithChannels.some((message) => message.id === receive.id)) ?? [];
933
+ const messagesTheServiceSendsThatNeedUpdating = data.sends?.filter((send) => messagesWithChannels.some((message2) => message2.id === send.id)) ?? [];
934
+ const messagesTheServiceReceivesThatNeedUpdating = data.receives?.filter((receive) => messagesWithChannels.some((message2) => message2.id === receive.id)) ?? [];
873
935
  if (messagesTheServiceSendsThatNeedUpdating.length > 0 || messagesTheServiceReceivesThatNeedUpdating.length > 0) {
874
936
  const newSends = (data.sends ?? []).map((send) => {
875
- const match = messagesWithChannels.find((message) => message.id === send.id);
937
+ const match = messagesWithChannels.find((message2) => message2.id === send.id);
876
938
  if (!match) return send;
877
939
  return { ...send, to: (match.channels ?? []).filter((channel) => channel !== null) };
878
940
  });
879
941
  const newReceives = (data.receives ?? []).map((receive) => {
880
- const match = messagesWithChannels.find((message) => message.id === receive.id);
942
+ const match = messagesWithChannels.find((message2) => message2.id === receive.id);
881
943
  if (!match) return receive;
882
944
  return { ...receive, from: (match.channels ?? []).filter((channel) => channel !== null) };
883
945
  });
@@ -889,11 +951,11 @@ var message_channels_to_service_channels_default = async (dir2) => {
889
951
  import_node_fs5.default.writeFileSync(service.path, import_gray_matter3.default.stringify(file, newData));
890
952
  }
891
953
  }
892
- for (const message of messagesWithChannels) {
893
- const file = import_node_fs5.default.readFileSync(message.path, "utf8");
954
+ for (const message2 of messagesWithChannels) {
955
+ const file = import_node_fs5.default.readFileSync(message2.path, "utf8");
894
956
  const parsed = (0, import_gray_matter3.default)(file);
895
957
  const { channels, ...newData } = parsed.data;
896
- import_node_fs5.default.writeFileSync(message.path, import_gray_matter3.default.stringify(parsed.content, newData));
958
+ import_node_fs5.default.writeFileSync(message2.path, import_gray_matter3.default.stringify(parsed.content, newData));
897
959
  }
898
960
  console.log("\u2714 Channels migrated to new services API");
899
961
  };
@@ -903,6 +965,32 @@ var runMigrations = async (dir2) => {
903
965
  await message_channels_to_service_channels_default(dir2);
904
966
  };
905
967
 
968
+ // src/utils/child-process-signals.ts
969
+ var import_node_os3 = require("os");
970
+ var FORWARDED_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
971
+ var isRunning = (child) => child.exitCode === null && child.signalCode === null;
972
+ var stopChildWithParent = (child, parent = process) => {
973
+ let received;
974
+ const onSignal = (signal) => {
975
+ received = signal;
976
+ if (isRunning(child)) child.kill(signal);
977
+ };
978
+ const onExit = () => {
979
+ if (isRunning(child)) child.kill("SIGTERM");
980
+ };
981
+ for (const signal of FORWARDED_SIGNALS) parent.on(signal, onSignal);
982
+ parent.on("exit", onExit);
983
+ return {
984
+ childClosed: () => {
985
+ for (const signal of FORWARDED_SIGNALS) parent.off(signal, onSignal);
986
+ parent.off("exit", onExit);
987
+ if (!received) return false;
988
+ parent.exit(128 + import_node_os3.constants.signals[received]);
989
+ return true;
990
+ }
991
+ };
992
+ };
993
+
906
994
  // eventcatalog/src/features/fields/field-indexer.ts
907
995
  var import_node_path10 = __toESM(require("path"), 1);
908
996
  var import_node_fs7 = __toESM(require("fs"), 1);
@@ -1055,7 +1143,7 @@ var FieldsDatabase = class _FieldsDatabase {
1055
1143
  format,
1056
1144
  type,
1057
1145
  messageType,
1058
- message,
1146
+ message: message2,
1059
1147
  producer,
1060
1148
  consumer,
1061
1149
  required,
@@ -1089,9 +1177,9 @@ var FieldsDatabase = class _FieldsDatabase {
1089
1177
  conditions.push(`f.message_type IN (${types2.map(() => "?").join(", ")})`);
1090
1178
  bindings.push(...types2);
1091
1179
  }
1092
- if (message) {
1180
+ if (message2) {
1093
1181
  conditions.push(`f.message_id = ?`);
1094
- bindings.push(message);
1182
+ bindings.push(message2);
1095
1183
  }
1096
1184
  if (required) {
1097
1185
  conditions.push(`f.required = 1`);
@@ -1904,8 +1992,8 @@ var KNOWN_EVENTCATALOG_COLLECTIONS = /* @__PURE__ */ new Set([
1904
1992
  var EMPTY_COLLECTION_MESSAGE = /^The collection ("(?:\\.|[^"\\])*") does not exist or is empty\. Please check your content config file for errors\.$/;
1905
1993
  var ANSI_PATTERN = /\u001B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
1906
1994
  var ASTRO_CONTENT_WARN_PREFIX = /^[^[\]]*\[WARN\]\s+\[content\](?:\s+\[[^\]]+\])*\s*$/;
1907
- function collectionNameFromEmptyWarning(message) {
1908
- const match = message.match(EMPTY_COLLECTION_MESSAGE);
1995
+ function collectionNameFromEmptyWarning(message2) {
1996
+ const match = message2.match(EMPTY_COLLECTION_MESSAGE);
1909
1997
  if (!match) return null;
1910
1998
  try {
1911
1999
  const name = JSON.parse(match[1]);
@@ -1914,8 +2002,8 @@ function collectionNameFromEmptyWarning(message) {
1914
2002
  return null;
1915
2003
  }
1916
2004
  }
1917
- function isIntentionalEmptyCollectionMessage(message) {
1918
- const name = collectionNameFromEmptyWarning(message);
2005
+ function isIntentionalEmptyCollectionMessage(message2) {
2006
+ const name = collectionNameFromEmptyWarning(message2);
1919
2007
  return name !== null && KNOWN_EVENTCATALOG_COLLECTIONS.has(name);
1920
2008
  }
1921
2009
  function isIntentionalEmptyCollectionLine(line) {
@@ -1923,8 +2011,8 @@ function isIntentionalEmptyCollectionLine(line) {
1923
2011
  const marker = 'The collection "';
1924
2012
  const start = plain.indexOf(marker);
1925
2013
  if (start === -1) return false;
1926
- const message = plain.slice(start).trim();
1927
- if (!isIntentionalEmptyCollectionMessage(message)) return false;
2014
+ const message2 = plain.slice(start).trim();
2015
+ if (!isIntentionalEmptyCollectionMessage(message2)) return false;
1928
2016
  const before = plain.slice(0, start).trim();
1929
2017
  return before.length === 0 || ASTRO_CONTENT_WARN_PREFIX.test(before);
1930
2018
  }
@@ -2491,7 +2579,7 @@ var createFileSystemSourceProvider = (projectDirectory) => ({
2491
2579
  // src/federation/github-source-provider.ts
2492
2580
  var import_node_child_process = require("child_process");
2493
2581
  var import_promises9 = __toESM(require("fs/promises"), 1);
2494
- var import_node_os3 = __toESM(require("os"), 1);
2582
+ var import_node_os4 = __toESM(require("os"), 1);
2495
2583
  var import_node_path18 = __toESM(require("path"), 1);
2496
2584
  var import_node_util = require("util");
2497
2585
  var import_sdk2 = __toESM(require("@eventcatalog/sdk"), 1);
@@ -2548,7 +2636,7 @@ var getGitEnvironment = (token) => {
2548
2636
  var createCheckout = (executeFile, token) => async (source, ref, callback) => {
2549
2637
  const { owner, repository } = parseGitHubSource(source);
2550
2638
  const catalogPath = import_node_path18.default.posix.normalize(source.path ?? ".");
2551
- const directory = await import_promises9.default.mkdtemp(import_node_path18.default.join(import_node_os3.default.tmpdir(), "eventcatalog-federation-"));
2639
+ const directory = await import_promises9.default.mkdtemp(import_node_path18.default.join(import_node_os4.default.tmpdir(), "eventcatalog-federation-"));
2552
2640
  const env = getGitEnvironment(token);
2553
2641
  try {
2554
2642
  const git = (args) => executeFile("git", args, { cwd: directory, env, encoding: "utf8" });
@@ -2768,8 +2856,8 @@ var federateCatalog = async (projectDirectory, options = {}) => {
2768
2856
  generated: resolved.generated
2769
2857
  });
2770
2858
  } catch (error) {
2771
- const message = error instanceof Error ? error.message : String(error);
2772
- throw new Error(`Failed to federate source "${source.id}": ${message}`, { cause: error });
2859
+ const message2 = error instanceof Error ? error.message : String(error);
2860
+ throw new Error(`Failed to federate source "${source.id}": ${message2}`, { cause: error });
2773
2861
  }
2774
2862
  }
2775
2863
  const outDir = import_node_path19.default.join(projectDirectory, "federated");
@@ -2918,7 +3006,7 @@ var resolveDevPort = async ({ projectDir }) => {
2918
3006
  };
2919
3007
  var startDevPrewarm = ({
2920
3008
  port = 3e3,
2921
- paths = ["/ping", "/"],
3009
+ paths = ["/"],
2922
3010
  retries = 80,
2923
3011
  intervalMs = 250,
2924
3012
  initialDelayMs = 500
@@ -2927,10 +3015,13 @@ var startDevPrewarm = ({
2927
3015
  const hit = (requestPath) => new Promise((resolve2) => {
2928
3016
  const req = import_node_http.default.get(
2929
3017
  {
2930
- hostname: "127.0.0.1",
3018
+ // Not 127.0.0.1: the dev server can listen on IPv6 only ([::1]), which refused
3019
+ // every prewarm request
3020
+ hostname: "localhost",
2931
3021
  port,
2932
3022
  path: requestPath,
2933
- timeout: 1200
3023
+ // A refused connection fails at once; once connected, let the first render finish
3024
+ timeout: 3e4
2934
3025
  },
2935
3026
  (res) => {
2936
3027
  res.resume();
@@ -3032,6 +3123,7 @@ var runCommandWithFilteredOutput = async ({
3032
3123
  },
3033
3124
  stdio: ["inherit", "pipe", "pipe"]
3034
3125
  });
3126
+ const signals = stopChildWithParent(child);
3035
3127
  let stdoutBuffer = "";
3036
3128
  let stderrBuffer = "";
3037
3129
  const flush = (buffer, writer, isFinal = false) => {
@@ -3059,11 +3151,13 @@ var runCommandWithFilteredOutput = async ({
3059
3151
  stderrBuffer = flush(stderrBuffer, process.stderr);
3060
3152
  });
3061
3153
  child.on("error", (error) => {
3154
+ signals.childClosed();
3062
3155
  reject(error);
3063
3156
  });
3064
3157
  child.on("close", (code) => {
3065
3158
  stdoutBuffer = flush(stdoutBuffer, process.stdout, true);
3066
3159
  stderrBuffer = flush(stderrBuffer, process.stderr, true);
3160
+ if (signals.childClosed()) return;
3067
3161
  if (code === 0) {
3068
3162
  resolve2();
3069
3163
  return;
@@ -3114,10 +3208,10 @@ Upgrade now: npm i @eventcatalog/core@beta`;
3114
3208
  if (!installedVersion) return;
3115
3209
  const pkg = { name: "@eventcatalog/core", version: installedVersion };
3116
3210
  const notifier = (0, import_update_notifier.default)({ pkg, updateCheckInterval: 0 });
3117
- const message = getEventCatalogUpdateMessage(installedVersion, notifier.update?.latest);
3118
- if (message) {
3211
+ const message2 = getEventCatalogUpdateMessage(installedVersion, notifier.update?.latest);
3212
+ if (message2) {
3119
3213
  console.log(
3120
- (0, import_boxen2.default)(message, {
3214
+ (0, import_boxen2.default)(message2, {
3121
3215
  padding: 1,
3122
3216
  margin: 1,
3123
3217
  align: "center",
@@ -3189,7 +3283,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
3189
3283
  });
3190
3284
  startDevPrewarm({
3191
3285
  port: prewarmPort,
3192
- paths: ["/ping", "/"]
3286
+ // Renders the homepage before anyone opens it. Requests stop at the first response,
3287
+ // so a probe path like /ping first would leave the homepage cold.
3288
+ paths: ["/"]
3193
3289
  });
3194
3290
  }
3195
3291
  await runCommandWithFilteredOutput({
@@ -3278,15 +3374,33 @@ var previewCatalog = async ({ command }) => {
3278
3374
  shouldFilterLine: createAstroLineFilter()
3279
3375
  });
3280
3376
  };
3377
+ var SERVER_BOOTSTRAP = `
3378
+ const entry = await import(process.argv[1]);
3379
+ const { server } = entry.startServer();
3380
+ globalThis[Symbol.for('eventcatalog.http-server')] = server.server;
3381
+ const start = process.env.EVENTCATALOG_START_PATH;
3382
+ if (start) {
3383
+ server.server.once('listening', () => {
3384
+ // Where the server listens (HOST can be one address only); loopback when it listens on every address
3385
+ const { address, port } = server.server.address();
3386
+ const host = ['0.0.0.0', '::'].includes(address) ? '127.0.0.1' : address.includes(':') ? '[' + address + ']' : address;
3387
+ fetch('http://' + host + ':' + port + start).catch((error) => console.error('[eventcatalog] Could not start the server:', error.message));
3388
+ });
3389
+ }
3390
+ `;
3281
3391
  var startServerCatalog = async () => {
3282
3392
  const serverEntryPath = import_node_path21.default.join(dir, "dist", "server", "entry.mjs");
3393
+ const config = await getEventCatalogConfigFile(dir);
3394
+ const base = (config?.base || "/").replace(/\/$/, "");
3283
3395
  await runCommandWithFilteredOutput({
3284
3396
  command: process.execPath,
3285
- args: [serverEntryPath],
3397
+ args: ["--input-type=module", "-e", SERVER_BOOTSTRAP, (0, import_node_url2.pathToFileURL)(serverEntryPath).href],
3286
3398
  cwd: dir,
3287
3399
  env: {
3288
3400
  PROJECT_DIR: dir,
3289
- CATALOG_DIR: core
3401
+ CATALOG_DIR: core,
3402
+ ASTRO_NODE_AUTOSTART: "disabled",
3403
+ EVENTCATALOG_START_PATH: `${base}/_eventcatalog/start`
3290
3404
  },
3291
3405
  shouldFilterLine: createAstroLineFilter()
3292
3406
  });