@eventcatalog/core 3.6.1 → 3.7.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.
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "3.6.1";
40
+ var version = "3.7.0";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-N2VBSHPU.js";
4
- import "../chunk-SI6IEUYS.js";
3
+ } from "../chunk-6DINZHVK.js";
4
+ import "../chunk-WFIM5UXN.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "3.6.1";
109
+ var version = "3.7.0";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-XRLZZXIS.js";
4
- import "../chunk-N2VBSHPU.js";
5
- import "../chunk-SI6IEUYS.js";
3
+ } from "../chunk-2CIYDOFG.js";
4
+ import "../chunk-6DINZHVK.js";
5
+ import "../chunk-WFIM5UXN.js";
6
6
  import "../chunk-UPONRQSN.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-N2VBSHPU.js";
3
+ } from "./chunk-6DINZHVK.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-SI6IEUYS.js";
3
+ } from "./chunk-WFIM5UXN.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-SI6IEUYS.js";
3
+ } from "./chunk-WFIM5UXN.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-OFHFRJ42.js";
3
+ } from "./chunk-TWL75YK3.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "3.6.1";
2
+ var version = "3.7.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "3.6.1";
28
+ var version = "3.7.0";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-SI6IEUYS.js";
3
+ } from "./chunk-WFIM5UXN.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -109,7 +109,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
109
109
  var import_picocolors = __toESM(require("picocolors"), 1);
110
110
 
111
111
  // package.json
112
- var version = "3.6.1";
112
+ var version = "3.7.0";
113
113
 
114
114
  // src/constants.ts
115
115
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-XRLZZXIS.js";
10
- import "./chunk-N2VBSHPU.js";
9
+ } from "./chunk-2CIYDOFG.js";
10
+ import "./chunk-6DINZHVK.js";
11
11
  import {
12
12
  runMigrations
13
13
  } from "./chunk-BH3JMNAV.js";
@@ -21,13 +21,13 @@ import {
21
21
  } from "./chunk-5VBIXL6C.js";
22
22
  import {
23
23
  generate
24
- } from "./chunk-FCIJEGOL.js";
24
+ } from "./chunk-VA6OWAKW.js";
25
25
  import {
26
26
  logger
27
- } from "./chunk-OFHFRJ42.js";
27
+ } from "./chunk-TWL75YK3.js";
28
28
  import {
29
29
  VERSION
30
- } from "./chunk-SI6IEUYS.js";
30
+ } from "./chunk-WFIM5UXN.js";
31
31
  import "./chunk-UPONRQSN.js";
32
32
 
33
33
  // src/eventcatalog.ts
package/dist/generate.cjs CHANGED
@@ -73,7 +73,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
73
73
  var import_picocolors = __toESM(require("picocolors"), 1);
74
74
 
75
75
  // package.json
76
- var version = "3.6.1";
76
+ var version = "3.7.0";
77
77
 
78
78
  // src/constants.ts
79
79
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-FCIJEGOL.js";
4
- import "./chunk-OFHFRJ42.js";
5
- import "./chunk-SI6IEUYS.js";
3
+ } from "./chunk-VA6OWAKW.js";
4
+ import "./chunk-TWL75YK3.js";
5
+ import "./chunk-WFIM5UXN.js";
6
6
  import "./chunk-UPONRQSN.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.6.1";
39
+ var version = "3.7.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-OFHFRJ42.js";
4
- import "../chunk-SI6IEUYS.js";
3
+ } from "../chunk-TWL75YK3.js";
4
+ import "../chunk-WFIM5UXN.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -96,7 +96,7 @@ try {
96
96
  throw new Error(`Unknown resource type: ${type}`);
97
97
  }
98
98
 
99
- const resourcesCollection = await getCollection(collection as any);
99
+ const resourcesCollection = (await getCollection(collection as any)) as { data: { id: string; version: string } }[];
100
100
  const resources = getItemsFromCollectionByIdAndSemverOrLatest(resourcesCollection, resourceId, version);
101
101
 
102
102
  if (resources.length === 0) {
@@ -153,7 +153,7 @@ const resolveMessage = async (msg: any): Promise<{ version: string | null; colle
153
153
  const collections = ['events', 'commands', 'queries'];
154
154
  for (const col of collections) {
155
155
  try {
156
- const items = await getCollection(col as any);
156
+ const items = (await getCollection(col as any)) as { data: { id: string; version: string } }[];
157
157
  const found = getItemsFromCollectionByIdAndSemverOrLatest(items, msg.id);
158
158
  if (found.length > 0 && found[0].data.version && found[0].data.version !== 'latest') {
159
159
  return { version: found[0].data.version, collection: col };
@@ -25,6 +25,7 @@ import {
25
25
  import { StarIcon as StarIconSolid, CircleStackIcon } from '@heroicons/react/24/solid';
26
26
  import { useStore } from '@nanostores/react';
27
27
  import { sidebarStore } from '../../stores/sidebar-store';
28
+ import type { NavNode } from '../../stores/sidebar-store/state';
28
29
  import { favoritesStore, toggleFavorite as toggleFavoriteAction } from '../../stores/favorites-store';
29
30
  import { buildUrl } from '@utils/url-builder';
30
31
 
@@ -490,6 +490,8 @@ const domains = defineCollection({
490
490
  domains: z.array(pointer).optional(),
491
491
  entities: z.array(pointer).optional(),
492
492
  flows: z.array(pointer).optional(),
493
+ sends: z.array(sendsPointer).optional(),
494
+ receives: z.array(receivesPointer).optional(),
493
495
  detailsPanel: z
494
496
  .object({
495
497
  parentDomains: detailPanelPropertySchema.optional(),
@@ -52,10 +52,17 @@ import { getQueries } from '@utils/collections/queries';
52
52
  import { hasLandingPageForDocs } from '@utils/pages';
53
53
 
54
54
  import { isEventCatalogUpgradeEnabled, isEmbedEnabled, isCustomStylesEnabled } from '@utils/feature';
55
+ import { getUsers } from '@utils/collections/users';
56
+ import { getTeams } from '@utils/collections/teams';
55
57
 
56
58
  const catalogHasDefaultLandingPageForDocs = await hasLandingPageForDocs();
57
59
  const customDocs = await getCollection('customPages');
58
60
 
61
+ // Get users and teams for directory navigation
62
+ const users = await getUsers();
63
+ const teams = await getTeams();
64
+ const directoryDefaultUrl = users.length > 0 ? '/directory/users' : teams.length > 0 ? '/directory/teams' : '/directory/users';
65
+
59
66
  let events: any[] = [];
60
67
  let commands: any[] = [];
61
68
  let queries: any[] = [];
@@ -145,7 +152,7 @@ const navigationItems = [
145
152
  id: '/directory',
146
153
  label: 'Users & Teams',
147
154
  icon: Users,
148
- href: buildUrl('/directory/users'),
155
+ href: buildUrl(directoryDefaultUrl),
149
156
  current: currentPath.includes('/directory'),
150
157
  },
151
158
  ].filter((item) => {
@@ -1,6 +1,8 @@
1
1
  import type { APIRoute } from 'astro';
2
2
  import { getNestedSideBarData } from '@stores/sidebar-store/state';
3
3
 
4
+ const isDev = import.meta.env.DEV;
5
+
4
6
  /**
5
7
  * API route that returns the sidebar navigation data as JSON.
6
8
  * This is pre-rendered in static mode to avoid embedding the data in every HTML page.
@@ -12,11 +14,14 @@ export const GET: APIRoute = async () => {
12
14
  return new Response(JSON.stringify(sidebarData), {
13
15
  headers: {
14
16
  'Content-Type': 'application/json',
15
- // Cache for 1 hour in browser, allow CDN to cache and revalidate
16
- 'Cache-Control': 'public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400',
17
+ // In dev mode, disable caching to ensure fresh data. In production, cache for 1 hour.
18
+ 'Cache-Control': isDev
19
+ ? 'no-cache, no-store, must-revalidate'
20
+ : 'public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400',
17
21
  },
18
22
  });
19
23
  };
20
24
 
21
25
  // Pre-render this route in static mode so it becomes a static JSON file
22
- export const prerender = true;
26
+ // In dev mode, don't pre-render to allow dynamic updates
27
+ export const prerender = !isDev;
@@ -11,6 +11,7 @@ import {
11
11
  buildDiagramNavItems,
12
12
  } from './shared';
13
13
  import { isVisualiserEnabled } from '@utils/feature';
14
+ import { pluralizeMessageType } from '@utils/collections/messages';
14
15
 
15
16
  export const buildDomainNode = (domain: CollectionEntry<'domains'>, owners: any[], context: ResourceGroupContext): NavNode => {
16
17
  const servicesInDomain = domain.data.services || [];
@@ -37,6 +38,11 @@ export const buildDomainNode = (domain: CollectionEntry<'domains'>, owners: any[
37
38
 
38
39
  const renderRepository = domain.data.repository && shouldRenderSideBarSection(domain, 'repository');
39
40
 
41
+ // Domain-level messages (sends/receives)
42
+ const sendsMessages = domain.data.sends || [];
43
+ const receivesMessages = domain.data.receives || [];
44
+ const renderMessages = shouldRenderSideBarSection(domain, 'messages');
45
+
40
46
  // Diagrams
41
47
  const domainDiagrams = domain.data.diagrams || [];
42
48
  const diagramNavItems = buildDiagramNavItems(domainDiagrams, context.diagrams);
@@ -111,6 +117,24 @@ export const buildDomainNode = (domain: CollectionEntry<'domains'>, owners: any[
111
117
  icon: 'Server',
112
118
  pages: servicesInDomain.map((service) => `service:${(service as any).data.id}:${(service as any).data.version}`),
113
119
  },
120
+ sendsMessages.length > 0 &&
121
+ renderMessages && {
122
+ type: 'group',
123
+ title: 'Domain Events',
124
+ icon: 'Mail',
125
+ pages: sendsMessages.map(
126
+ (message) => `${pluralizeMessageType(message as any)}:${(message as any).data.id}:${(message as any).data.version}`
127
+ ),
128
+ },
129
+ receivesMessages.length > 0 &&
130
+ renderMessages && {
131
+ type: 'group',
132
+ title: 'External Events',
133
+ icon: 'Mail',
134
+ pages: receivesMessages.map(
135
+ (receive) => `${pluralizeMessageType(receive as any)}:${(receive as any).data.id}:${(receive as any).data.version}`
136
+ ),
137
+ },
114
138
  renderOwners && buildOwnersSection(owners),
115
139
  renderRepository && buildRepositorySection(domain.data.repository as { url: string; language: string }),
116
140
  hasAttachments && buildAttachmentsSection(domain.data.attachments as any[]),
@@ -79,35 +79,21 @@ export const getDomains = async ({
79
79
  return memoryCache[cacheKey];
80
80
  }
81
81
 
82
- // 1. Fetch collections
83
- const collectionsToFetch: any[] = [
82
+ // 1. Fetch collections (always fetch messages to hydrate domain-level sends/receives)
83
+ const [allDomains, allServices, allEntities, allFlows, allEvents, allCommands, allQueries, allContainers] = await Promise.all([
84
84
  getCollection('domains'),
85
85
  getCollection('services'),
86
86
  getCollection('entities'),
87
87
  getCollection('flows'),
88
- ];
89
-
90
- if (enrichServices) {
91
- collectionsToFetch.push(
92
- getCollection('events'),
93
- getCollection('commands'),
94
- getCollection('queries'),
95
- getCollection('containers')
96
- );
97
- }
98
-
99
- const results = await Promise.all(collectionsToFetch);
100
- const [allDomains, allServices, allEntities, allFlows] = results;
101
-
102
- let messageMap = new Map();
103
- let containerMap = new Map();
88
+ getCollection('events'),
89
+ getCollection('commands'),
90
+ getCollection('queries'),
91
+ getCollection('containers'),
92
+ ]);
104
93
 
105
- if (enrichServices) {
106
- const [, , , , allEvents, allCommands, allQueries, allContainers] = results;
107
- const allMessages = [...allEvents, ...allCommands, ...allQueries];
108
- messageMap = createVersionedMap(allMessages);
109
- containerMap = createVersionedMap(allContainers);
110
- }
94
+ const allMessages = [...allEvents, ...allCommands, ...allQueries];
95
+ const messageMap = createVersionedMap(allMessages);
96
+ const containerMap = createVersionedMap(allContainers);
111
97
 
112
98
  // 2. Build optimized maps
113
99
  const domainMap = createVersionedMap(allDomains);
@@ -192,6 +178,15 @@ export const getDomains = async ({
192
178
  ? [...(hydratedMainServices as any), ...(hydratedSubdomainServices as any)]
193
179
  : (hydratedMainServices as any);
194
180
 
181
+ // Hydrate domain-level sends and receives
182
+ const domainSends = (domain.data.sends || [])
183
+ .map((m: { id: string; version: string | undefined }) => findInMap(messageMap, m.id, m.version))
184
+ .filter((e): e is CollectionEntry<CollectionMessageTypes> => !!e);
185
+
186
+ const domainReceives = (domain.data.receives || [])
187
+ .map((m: { id: string; version: string | undefined }) => findInMap(messageMap, m.id, m.version))
188
+ .filter((e): e is CollectionEntry<CollectionMessageTypes> => !!e);
189
+
195
190
  // Calculate folder paths
196
191
  const folderName = await getResourceFolderName(
197
192
  process.env.PROJECT_DIR ?? '',
@@ -208,6 +203,8 @@ export const getDomains = async ({
208
203
  domains: subDomains as any,
209
204
  entities: entities as any,
210
205
  flows: flows as any,
206
+ sends: domainSends as any,
207
+ receives: domainReceives as any,
211
208
  latestVersion,
212
209
  versions,
213
210
  },
@@ -249,20 +246,43 @@ export const getMessagesForDomain = async (
249
246
  const allMessages = [...events, ...commands, ...queries];
250
247
  const messageMap = createVersionedMap(allMessages);
251
248
 
252
- const sends = services.flatMap((service) => service.data.sends || []);
253
- const receives = services.flatMap((service) => service.data.receives || []);
249
+ // Get service-level sends/receives
250
+ const serviceSends = services.flatMap((service) => service.data.sends || []);
251
+ const serviceReceives = services.flatMap((service) => service.data.receives || []);
252
+
253
+ // Get domain-level sends/receives (already hydrated if domain came from getDomains)
254
+ const domainSends = domain.data.sends || [];
255
+ const domainReceives = domain.data.receives || [];
254
256
 
255
- const sendsMessages = sends
256
- .map((send) => findInMap(messageMap, send.id, send.version))
257
+ // Combine and deduplicate - domain-level messages take priority
258
+ const allSends = [...domainSends, ...serviceSends];
259
+ const allReceives = [...domainReceives, ...serviceReceives];
260
+
261
+ const sendsMessages = allSends
262
+ .map((send: any) => {
263
+ // If already hydrated (has data property), return as-is
264
+ if (send.data) return send;
265
+ // Otherwise, resolve from map
266
+ return findInMap(messageMap, send.id, send.version);
267
+ })
257
268
  .filter((msg): msg is CollectionEntry<CollectionMessageTypes> => !!msg);
258
269
 
259
- const receivesMessages = receives
260
- .map((receive) => findInMap(messageMap, receive.id, receive.version))
270
+ const receivesMessages = allReceives
271
+ .map((receive: any) => {
272
+ // If already hydrated (has data property), return as-is
273
+ if (receive.data) return receive;
274
+ // Otherwise, resolve from map
275
+ return findInMap(messageMap, receive.id, receive.version);
276
+ })
261
277
  .filter((msg): msg is CollectionEntry<CollectionMessageTypes> => !!msg);
262
278
 
279
+ // Deduplicate by id and version
280
+ const uniqueSends = Array.from(new Map(sendsMessages.map((msg) => [`${msg.data.id}-${msg.data.version}`, msg])).values());
281
+ const uniqueReceives = Array.from(new Map(receivesMessages.map((msg) => [`${msg.data.id}-${msg.data.version}`, msg])).values());
282
+
263
283
  return {
264
- sends: sendsMessages,
265
- receives: receivesMessages,
284
+ sends: uniqueSends,
285
+ receives: uniqueReceives,
266
286
  };
267
287
  };
268
288
 
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "3.6.1",
9
+ "version": "3.7.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -158,6 +158,7 @@
158
158
  "release": "changeset publish",
159
159
  "format": "prettier --config .prettierrc --write \"**/*.{js,jsx,ts,tsx,json,astro}\"",
160
160
  "format:diff": "prettier --config .prettierrc --list-different \"**/*.{js,jsx,ts,tsx,json,astro}\"",
161
- "lint:catalog": "pnpm dlx @eventcatalog/linter examples/default"
161
+ "lint:catalog": "pnpm dlx @eventcatalog/linter examples/default",
162
+ "check": "node scripts/check-types.js"
162
163
  }
163
164
  }