@eventcatalog/core 3.2.1 → 3.3.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 (49) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-VBEYXPR5.js → chunk-I4CMEOEN.js} +1 -1
  6. package/dist/{chunk-SYOF3QEG.js → chunk-NGKYYZZP.js} +1 -1
  7. package/dist/{chunk-SFQ3BU4M.js → chunk-OAUYXPXT.js} +1 -1
  8. package/dist/{chunk-7PHTRC72.js → chunk-QZF5ZYJB.js} +1 -1
  9. package/dist/{chunk-LWUJQOCC.js → chunk-UPSN5H7S.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +5 -5
  14. package/dist/generate.cjs +1 -1
  15. package/dist/generate.js +3 -3
  16. package/dist/utils/cli-logger.cjs +1 -1
  17. package/dist/utils/cli-logger.js +2 -2
  18. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +9 -0
  19. package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +11 -1
  20. package/eventcatalog/src/components/CopyAsMarkdown.tsx +47 -28
  21. package/eventcatalog/src/content.config.ts +18 -0
  22. package/eventcatalog/src/enterprise/ai/chat-api.ts +24 -2
  23. package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +57 -0
  24. package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +267 -0
  25. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +411 -0
  26. package/eventcatalog/src/pages/diagrams/[id]/[version].mdx.ts +47 -0
  27. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +28 -33
  28. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
  29. package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +3 -2
  30. package/eventcatalog/src/pages/docs/[type]/[id]/[version].mdx.ts +5 -1
  31. package/eventcatalog/src/pages/docs/[type]/[id]/language.mdx.ts +2 -1
  32. package/eventcatalog/src/pages/docs/custom/[...path].mdx.ts +2 -2
  33. package/eventcatalog/src/pages/docs/teams/[id].md.ts +3 -2
  34. package/eventcatalog/src/pages/docs/teams/[id].mdx.ts +3 -3
  35. package/eventcatalog/src/pages/docs/users/[id].md.ts +3 -2
  36. package/eventcatalog/src/pages/docs/users/[id].mdx.ts +3 -3
  37. package/eventcatalog/src/stores/sidebar-store/builders/container.ts +20 -4
  38. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +20 -12
  39. package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +1 -1
  40. package/eventcatalog/src/stores/sidebar-store/builders/message.ts +20 -4
  41. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +18 -6
  42. package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +20 -0
  43. package/eventcatalog/src/stores/sidebar-store/state.ts +34 -6
  44. package/eventcatalog/src/types/index.ts +4 -2
  45. package/eventcatalog/src/utils/collections/diagrams.ts +64 -0
  46. package/eventcatalog/src/utils/collections/util.ts +2 -0
  47. package/eventcatalog/src/utils/feature.ts +4 -2
  48. package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
  49. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import type { CollectionEntry } from 'astro:content';
2
2
  import { buildUrl } from '@utils/url-builder';
3
3
  import { getSpecificationsForService } from '@utils/collections/services';
4
- import type { NavNode, ChildRef } from './shared';
4
+ import type { NavNode, ChildRef, ResourceGroupContext } from './shared';
5
5
  import {
6
6
  uniqueBy,
7
7
  buildQuickReferenceSection,
@@ -10,11 +10,12 @@ import {
10
10
  buildResourceGroupSections,
11
11
  buildRepositorySection,
12
12
  buildAttachmentsSection,
13
+ buildDiagramNavItems,
13
14
  } from './shared';
14
15
  import { isVisualiserEnabled } from '@utils/feature';
15
16
  import { pluralizeMessageType } from '@utils/collections/messages';
16
17
 
17
- export const buildServiceNode = (service: CollectionEntry<'services'>, owners: any[], context: any): NavNode => {
18
+ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: any[], context: ResourceGroupContext): NavNode => {
18
19
  const sendsMessages = service.data.sends || [];
19
20
  const receivesMessages = service.data.receives || [];
20
21
  const serviceEntities = service.data.entities || [];
@@ -44,6 +45,11 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
44
45
  const renderOwners = owners.length > 0 && shouldRenderSideBarSection(service, 'owners');
45
46
  const renderRepository = service.data.repository && shouldRenderSideBarSection(service, 'repository');
46
47
 
48
+ // Diagrams
49
+ const serviceDiagrams = service.data.diagrams || [];
50
+ const diagramNavItems = buildDiagramNavItems(serviceDiagrams, context.diagrams);
51
+ const hasDiagrams = diagramNavItems.length > 0;
52
+
47
53
  return {
48
54
  type: 'item',
49
55
  title: service.data.name,
@@ -55,17 +61,17 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
55
61
  ]),
56
62
  {
57
63
  type: 'group',
58
- title: 'Architecture & Design',
64
+ title: 'Architecture',
59
65
  icon: 'Workflow',
60
66
  pages: [
61
67
  {
62
68
  type: 'item',
63
- title: 'Architecture Overview',
69
+ title: 'Overview',
64
70
  href: buildUrl(`/architecture/services/${service.data.id}/${service.data.version}`),
65
71
  },
66
72
  renderVisualiser && {
67
73
  type: 'item',
68
- title: 'Interaction Map',
74
+ title: 'Map',
69
75
  href: buildUrl(`/visualiser/services/${service.data.id}/${service.data.version}`),
70
76
  },
71
77
  renderVisualiser &&
@@ -74,7 +80,13 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
74
80
  title: 'Data Map',
75
81
  href: buildUrl(`/visualiser/services/${service.data.id}/${service.data.version}/data`),
76
82
  },
77
- ],
83
+ ].filter(Boolean) as ChildRef[],
84
+ },
85
+ hasDiagrams && {
86
+ type: 'group',
87
+ title: 'Diagrams',
88
+ icon: 'FileImage',
89
+ pages: diagramNavItems,
78
90
  },
79
91
  renderSpecifications && {
80
92
  type: 'group',
@@ -54,6 +54,7 @@ export type ResourceGroupContext = {
54
54
  queries: CollectionEntry<'queries'>[];
55
55
  flows: CollectionEntry<'flows'>[];
56
56
  containers: CollectionEntry<'containers'>[];
57
+ diagrams: CollectionEntry<'diagrams'>[];
57
58
  };
58
59
 
59
60
  export const buildQuickReferenceSection = (items: { title: string; href: string }[]): NavNode => ({
@@ -158,3 +159,22 @@ export const shouldRenderSideBarSection = (resource: any, section: string) => {
158
159
  }
159
160
  return resource.data.detailsPanel[section]?.visible ?? true;
160
161
  };
162
+
163
+ export const buildDiagramNavItems = (
164
+ diagrams: Array<{ id: string; version?: string }> | undefined,
165
+ allDiagrams: CollectionEntry<'diagrams'>[]
166
+ ): NavNode[] => {
167
+ if (!diagrams || diagrams.length === 0) return [];
168
+
169
+ return diagrams.map((ref) => {
170
+ const diagram = allDiagrams.find(
171
+ (d) => d.data.id === ref.id && (ref.version === 'latest' || !ref.version || d.data.version === ref.version)
172
+ );
173
+ const version = diagram?.data.version || ref.version || 'latest';
174
+ return {
175
+ type: 'item' as const,
176
+ title: diagram?.data.name || ref.id,
177
+ href: buildUrl(`/diagrams/${ref.id}/${version}`),
178
+ };
179
+ });
180
+ };
@@ -6,6 +6,7 @@ import { getOwner } from '@utils/collections/owners';
6
6
  import { getFlows } from '@utils/collections/flows';
7
7
  import { getUsers } from '@utils/collections/users';
8
8
  import { getTeams } from '@utils/collections/teams';
9
+ import { getDiagrams } from '@utils/collections/diagrams';
9
10
  import { buildUrl } from '@utils/url-builder';
10
11
  import type { NavigationData, NavNode, ChildRef } from './builders/shared';
11
12
  import { buildDomainNode } from './builders/domain';
@@ -30,7 +31,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
30
31
  return memoryCache;
31
32
  }
32
33
 
33
- const [domains, services, { events, commands, queries }, containers, flows, users, teams, designs, channels] =
34
+ const [domains, services, { events, commands, queries }, containers, flows, users, teams, designs, channels, diagrams] =
34
35
  await Promise.all([
35
36
  getDomains({ getAllVersions: false, includeServicesInSubdomains: false }),
36
37
  getServices({ getAllVersions: false }),
@@ -41,6 +42,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
41
42
  getTeams(),
42
43
  getDesigns(),
43
44
  getChannels({ getAllVersions: false }),
45
+ getDiagrams({ getAllVersions: false }),
44
46
  ]);
45
47
 
46
48
  // Calculate derived lists to avoid extra fetches
@@ -57,6 +59,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
57
59
  queries,
58
60
  flows,
59
61
  containers,
62
+ diagrams,
60
63
  };
61
64
 
62
65
  // Process all domains with their owners first (async)
@@ -136,9 +139,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
136
139
  (acc, { message, owners }) => {
137
140
  const type = pluralizeMessageType(message as any);
138
141
 
139
- acc[`${type}:${message.data.id}:${message.data.version}`] = buildMessageNode(message, owners);
142
+ acc[`${type}:${message.data.id}:${message.data.version}`] = buildMessageNode(message, owners, context);
140
143
  if (message.data.latestVersion === message.data.version) {
141
- acc[`${type}:${message.data.id}`] = buildMessageNode(message, owners);
144
+ acc[`${type}:${message.data.id}`] = buildMessageNode(message, owners, context);
142
145
  }
143
146
  return acc;
144
147
  },
@@ -147,9 +150,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
147
150
 
148
151
  const containerNodes = containerWithOwners.reduce(
149
152
  (acc, { container, owners }) => {
150
- acc[`container:${container.data.id}:${container.data.version}`] = buildContainerNode(container, owners);
153
+ acc[`container:${container.data.id}:${container.data.version}`] = buildContainerNode(container, owners, context);
151
154
  if (container.data.latestVersion === container.data.version) {
152
- acc[`container:${container.data.id}`] = buildContainerNode(container, owners);
155
+ acc[`container:${container.data.id}`] = buildContainerNode(container, owners, context);
153
156
  }
154
157
  return acc;
155
158
  },
@@ -383,6 +386,25 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
383
386
  ...(allList ? { 'list:all': allList as NavNode } : {}),
384
387
  };
385
388
 
389
+ // System-level views (only show if visualiser is enabled and there are domains)
390
+ const systemNode: Record<string, NavNode> = {};
391
+ const visualiserEnabled = config?.visualiser?.enabled !== false;
392
+
393
+ if (visualiserEnabled && domains.length > 0) {
394
+ systemNode['list:system'] = {
395
+ type: 'group',
396
+ title: 'System',
397
+ icon: 'Globe',
398
+ pages: [
399
+ {
400
+ type: 'item',
401
+ title: 'Domain Map',
402
+ href: buildUrl('/visualiser/domain-integrations'),
403
+ },
404
+ ],
405
+ };
406
+ }
407
+
386
408
  const allGeneratedNodes = {
387
409
  ...rootDomainsNodes,
388
410
  ...domainNodes,
@@ -394,11 +416,17 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
394
416
  ...userNodes,
395
417
  ...teamNodes,
396
418
  ...designNodes,
419
+ ...systemNode,
397
420
  ...allNodes,
398
421
  };
399
422
 
400
423
  // only filter if child is string
401
- const rootNavigationConfig = config?.navigation?.pages || ['list:top-level-domains', 'list:all'];
424
+ const defaultPages = ['list:top-level-domains', 'list:all'];
425
+ // Add system section if it exists
426
+ if (systemNode['list:system']) {
427
+ defaultPages.push('list:system');
428
+ }
429
+ const rootNavigationConfig = config?.navigation?.pages || defaultPages;
402
430
 
403
431
  const navigationConfig = {
404
432
  roots: rootNavigationConfig,
@@ -7,7 +7,8 @@ export type CollectionTypes =
7
7
  | 'flows'
8
8
  | 'channels'
9
9
  | 'entities'
10
- | 'containers';
10
+ | 'containers'
11
+ | 'diagrams';
11
12
  export type CollectionMessageTypes = 'commands' | 'events' | 'queries';
12
13
  export type CollectionUserTypes = 'users';
13
14
  export type PageTypes =
@@ -19,7 +20,8 @@ export type PageTypes =
19
20
  | 'channels'
20
21
  | 'flows'
21
22
  | 'entities'
22
- | 'containers';
23
+ | 'containers'
24
+ | 'diagrams';
23
25
 
24
26
  export type TableConfiguration = {
25
27
  columns: {
@@ -0,0 +1,64 @@
1
+ import { getCollection } from 'astro:content';
2
+ import type { CollectionEntry } from 'astro:content';
3
+ import path from 'path';
4
+ import { createVersionedMap } from '@utils/collections/util';
5
+
6
+ const CACHE_ENABLED = process.env.DISABLE_EVENTCATALOG_CACHE !== 'true';
7
+ export type Diagram = CollectionEntry<'diagrams'>;
8
+
9
+ interface Props {
10
+ getAllVersions?: boolean;
11
+ }
12
+
13
+ // Cache for build time
14
+ let memoryCache: Record<string, Diagram[]> = {};
15
+
16
+ export const getDiagrams = async ({ getAllVersions = true }: Props = {}): Promise<Diagram[]> => {
17
+ const cacheKey = getAllVersions ? 'allVersions' : 'currentVersions';
18
+
19
+ if (memoryCache[cacheKey] && memoryCache[cacheKey].length > 0 && CACHE_ENABLED) {
20
+ return memoryCache[cacheKey];
21
+ }
22
+
23
+ const allDiagrams = await getCollection('diagrams');
24
+
25
+ // Build optimized map for version lookups
26
+ const diagramMap = createVersionedMap(allDiagrams);
27
+
28
+ // Filter diagrams
29
+ const targetDiagrams = allDiagrams.filter((diagram) => {
30
+ if (!getAllVersions && diagram.filePath?.includes('versioned')) return false;
31
+ return true;
32
+ });
33
+
34
+ // Enrich diagrams with version info
35
+ const processedDiagrams = targetDiagrams.map((diagram) => {
36
+ const diagramVersions = diagramMap.get(diagram.data.id) || [];
37
+ const latestVersion = diagramVersions[0]?.data.version || diagram.data.version;
38
+ const versions = diagramVersions.map((d) => d.data.version);
39
+
40
+ return {
41
+ ...diagram,
42
+ data: {
43
+ ...diagram.data,
44
+ versions,
45
+ latestVersion,
46
+ },
47
+ catalog: {
48
+ path: path.join(diagram.collection, diagram.id.replace('/index.mdx', '')),
49
+ filePath: path.join(process.cwd(), 'src', 'catalog-files', diagram.collection, diagram.id.replace('/index.mdx', '')),
50
+ publicPath: path.join('/generated', diagram.collection),
51
+ type: 'diagram',
52
+ },
53
+ };
54
+ });
55
+
56
+ // Sort by name
57
+ processedDiagrams.sort((a, b) => {
58
+ return (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
59
+ });
60
+
61
+ memoryCache[cacheKey] = processedDiagrams;
62
+
63
+ return processedDiagrams;
64
+ };
@@ -117,6 +117,7 @@ export const resourceToCollectionMap = {
117
117
  team: 'teams',
118
118
  container: 'containers',
119
119
  entity: 'entities',
120
+ diagram: 'diagrams',
120
121
  } as const;
121
122
 
122
123
  export const collectionToResourceMap = {
@@ -131,6 +132,7 @@ export const collectionToResourceMap = {
131
132
  teams: 'team',
132
133
  containers: 'container',
133
134
  entities: 'entity',
135
+ diagrams: 'diagram',
134
136
  } as const;
135
137
 
136
138
  export const getDeprecatedDetails = (item: CollectionEntry<CollectionTypes>) => {
@@ -50,8 +50,8 @@ export const isEventCatalogChatEnabled = () => {
50
50
  export const isEventCatalogUpgradeEnabled = () => !isEventCatalogStarterEnabled() && !isEventCatalogScaleEnabled();
51
51
  export const isCustomLandingPageEnabled = () => isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
52
52
 
53
- export const isMarkdownDownloadEnabled = () => config?.llmsTxt?.enabled ?? false;
54
- export const isLLMSTxtEnabled = () => (config?.llmsTxt?.enabled || isEventCatalogChatEnabled()) ?? true;
53
+ export const isMarkdownDownloadEnabled = () => config?.llmsTxt?.enabled ?? true;
54
+ export const isLLMSTxtEnabled = () => config?.llmsTxt?.enabled ?? true;
55
55
 
56
56
  export const isAuthEnabled = () => {
57
57
  const isAuthEnabledInCatalog = config?.auth?.enabled ?? false;
@@ -67,3 +67,5 @@ export const isVisualiserEnabled = () => config?.visualiser?.enabled ?? true;
67
67
  export const isCustomStylesEnabled = () => {
68
68
  return isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
69
69
  };
70
+
71
+ export const isDiagramComparisonEnabled = () => isEventCatalogScaleEnabled();
@@ -7,6 +7,7 @@ import { getServices } from '@utils/collections/services';
7
7
  import { getFlows } from '@utils/collections/flows';
8
8
  import { getEntities } from '@utils/collections/entities';
9
9
  import { getContainers } from '@utils/collections/containers';
10
+ import { getDiagrams } from '@utils/collections/diagrams';
10
11
  import type { CollectionEntry } from 'astro:content';
11
12
 
12
13
  export const pageDataLoader: Record<PageTypes, () => Promise<CollectionEntry<CollectionTypes>[]>> = {
@@ -19,4 +20,5 @@ export const pageDataLoader: Record<PageTypes, () => Promise<CollectionEntry<Col
19
20
  flows: getFlows,
20
21
  entities: getEntities,
21
22
  containers: getContainers,
23
+ diagrams: getDiagrams,
22
24
  };
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.2.1",
9
+ "version": "3.3.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -34,7 +34,7 @@
34
34
  "@eventcatalog/generator-ai": "^1.1.0",
35
35
  "@eventcatalog/license": "^0.0.7",
36
36
  "@eventcatalog/linter": "^0.0.2",
37
- "@eventcatalog/sdk": "^2.9.9",
37
+ "@eventcatalog/sdk": "^2.10.0",
38
38
  "@eventcatalog/visualizer": "^0.0.6",
39
39
  "@fontsource/inter": "^5.2.5",
40
40
  "@headlessui/react": "^2.0.3",