@eventcatalog/core 3.0.0-beta.9 → 3.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 (148) hide show
  1. package/README.md +41 -98
  2. package/dist/__mocks__/astro-content.cjs +32 -0
  3. package/dist/__mocks__/astro-content.d.cts +13 -0
  4. package/dist/__mocks__/astro-content.d.ts +13 -0
  5. package/dist/__mocks__/astro-content.js +7 -0
  6. package/dist/analytics/analytics.cjs +1 -1
  7. package/dist/analytics/analytics.js +2 -2
  8. package/dist/analytics/log-build.cjs +1 -1
  9. package/dist/analytics/log-build.js +3 -3
  10. package/dist/catalog-to-astro-content-directory.cjs +2 -19
  11. package/dist/catalog-to-astro-content-directory.d.cts +1 -2
  12. package/dist/catalog-to-astro-content-directory.d.ts +1 -2
  13. package/dist/catalog-to-astro-content-directory.js +3 -5
  14. package/dist/{chunk-R2BJ7MJG.js → chunk-6Z6ARMQS.js} +1 -17
  15. package/dist/{chunk-A4MGWK5T.js → chunk-BYP43AAT.js} +1 -1
  16. package/dist/{chunk-RAJ7TGWN.js → chunk-E5Q7TZYT.js} +1 -1
  17. package/dist/{chunk-TT4LZO2Q.js → chunk-EKGR533N.js} +1 -1
  18. package/dist/{chunk-2VPX4WIJ.js → chunk-KF5PARQK.js} +1 -1
  19. package/dist/{chunk-TC3R47V6.js → chunk-VO5WYA44.js} +1 -1
  20. package/dist/constants.cjs +1 -1
  21. package/dist/constants.js +1 -1
  22. package/dist/eventcatalog.cjs +20 -64
  23. package/dist/eventcatalog.config.d.cts +4 -0
  24. package/dist/eventcatalog.config.d.ts +4 -0
  25. package/dist/eventcatalog.js +26 -52
  26. package/dist/generate.cjs +1 -1
  27. package/dist/generate.js +3 -3
  28. package/dist/utils/cli-logger.cjs +1 -1
  29. package/dist/utils/cli-logger.js +2 -2
  30. package/eventcatalog/astro.config.mjs +4 -1
  31. package/eventcatalog/integrations/eventcatalog-features.ts +69 -0
  32. package/eventcatalog/public/icons/asyncapi-black.svg +2 -0
  33. package/eventcatalog/public/icons/graphql-black.svg +1 -0
  34. package/eventcatalog/public/icons/openapi-black.svg +1 -0
  35. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +994 -0
  36. package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +24 -0
  37. package/eventcatalog/src/components/Grids/DomainGrid.tsx +310 -173
  38. package/eventcatalog/src/components/Grids/MessageGrid.tsx +299 -180
  39. package/eventcatalog/src/components/Grids/specification-utils.ts +106 -0
  40. package/eventcatalog/src/components/Header.astro +25 -5
  41. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +14 -3
  42. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +95 -90
  43. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +144 -0
  44. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +34 -8
  45. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -2
  46. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +140 -109
  47. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +5 -14
  48. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +247 -59
  49. package/eventcatalog/src/components/SchemaExplorer/SchemaFilters.tsx +64 -126
  50. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +41 -43
  51. package/eventcatalog/src/components/Search/Search.astro +2 -2
  52. package/eventcatalog/src/components/Search/SearchDataLoader.astro +25 -0
  53. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +6 -3
  54. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +44 -16
  55. package/eventcatalog/src/components/SideNav/SideNav.astro +0 -15
  56. package/eventcatalog/src/components/Tables/Table.tsx +96 -77
  57. package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +108 -74
  58. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +74 -55
  59. package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +36 -36
  60. package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +110 -77
  61. package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +105 -94
  62. package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +31 -26
  63. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +115 -215
  64. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +145 -243
  65. package/eventcatalog/src/content.config.ts +1 -13
  66. package/eventcatalog/src/enterprise/ai/chat-api.ts +360 -0
  67. package/eventcatalog/src/enterprise/auth/[...auth].ts +3 -0
  68. package/eventcatalog/src/enterprise/auth/login.astro +420 -0
  69. package/eventcatalog/src/enterprise/collections/index.ts +0 -1
  70. package/eventcatalog/src/layouts/Footer.astro +8 -5
  71. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +133 -117
  72. package/eventcatalog/src/pages/_index.astro +243 -559
  73. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +8 -2
  74. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +9 -5
  75. package/eventcatalog/src/pages/directory/[type]/index.astro +6 -0
  76. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +19 -3
  77. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +7 -7
  78. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
  79. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +10 -7
  80. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +194 -121
  81. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +94 -70
  82. package/eventcatalog/src/pages/docs/teams/[id].mdx.ts +36 -0
  83. package/eventcatalog/src/pages/docs/users/[id]/index.astro +56 -45
  84. package/eventcatalog/src/pages/docs/users/[id].mdx.ts +36 -0
  85. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +178 -0
  86. package/eventcatalog/src/pages/schemas/explorer/index.astro +7 -157
  87. package/eventcatalog/src/pages/studio.astro +124 -72
  88. package/eventcatalog/src/remark-plugins/directives.ts +30 -9
  89. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/container.ts +10 -1
  90. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/domain.ts +17 -7
  91. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/message.ts +10 -1
  92. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/service.ts +11 -4
  93. package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/shared.ts +14 -0
  94. package/eventcatalog/src/stores/{sidebar-store.ts → sidebar-store/index.ts} +1 -1
  95. package/eventcatalog/src/utils/collections/channels.ts +0 -2
  96. package/eventcatalog/src/utils/collections/commands.ts +0 -2
  97. package/eventcatalog/src/utils/collections/containers.ts +0 -2
  98. package/eventcatalog/src/utils/collections/domains.ts +0 -2
  99. package/eventcatalog/src/utils/collections/entities.ts +0 -2
  100. package/eventcatalog/src/utils/collections/events.ts +0 -2
  101. package/eventcatalog/src/utils/collections/flows.ts +0 -2
  102. package/eventcatalog/src/utils/collections/queries.ts +0 -2
  103. package/eventcatalog/src/utils/collections/schemas.ts +45 -7
  104. package/eventcatalog/src/utils/collections/services.ts +0 -2
  105. package/eventcatalog/src/utils/feature.ts +9 -5
  106. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +1 -1
  107. package/eventcatalog/src/utils/resource-files.ts +86 -0
  108. package/package.json +12 -15
  109. package/default-files-for-collections/changelogs.md +0 -5
  110. package/default-files-for-collections/channels.md +0 -8
  111. package/default-files-for-collections/commands.md +0 -8
  112. package/default-files-for-collections/domains.md +0 -8
  113. package/default-files-for-collections/events.md +0 -8
  114. package/default-files-for-collections/flows.md +0 -11
  115. package/default-files-for-collections/queries.md +0 -8
  116. package/default-files-for-collections/services.md +0 -8
  117. package/default-files-for-collections/ubiquitousLanguages.md +0 -7
  118. package/eventcatalog/src/enterprise/collections/chat-prompts.ts +0 -32
  119. package/eventcatalog/src/enterprise/eventcatalog-chat/components/Chat.tsx +0 -60
  120. package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatMessage.tsx +0 -414
  121. package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatSidebar.tsx +0 -169
  122. package/eventcatalog/src/enterprise/eventcatalog-chat/components/InputModal.tsx +0 -244
  123. package/eventcatalog/src/enterprise/eventcatalog-chat/components/MentionInput.tsx +0 -211
  124. package/eventcatalog/src/enterprise/eventcatalog-chat/components/WelcomePromptArea.tsx +0 -176
  125. package/eventcatalog/src/enterprise/eventcatalog-chat/components/default-prompts.ts +0 -93
  126. package/eventcatalog/src/enterprise/eventcatalog-chat/components/hooks/ChatProvider.tsx +0 -143
  127. package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx +0 -387
  128. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/api/chat.ts +0 -59
  129. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +0 -104
  130. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/ai-provider.ts +0 -140
  131. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/anthropic.ts +0 -28
  132. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/google.ts +0 -41
  133. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/index.ts +0 -26
  134. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/openai.ts +0 -61
  135. package/eventcatalog/src/enterprise/eventcatalog-chat/utils/chat-prompts.ts +0 -50
  136. package/eventcatalog/src/pages/auth/login.astro +0 -280
  137. package/eventcatalog/src/pages/chat/feature.astro +0 -179
  138. package/eventcatalog/src/pages/chat/index.astro +0 -10
  139. package/eventcatalog/src/pages/docs/_default-docs.mdx +0 -25
  140. package/eventcatalog/src/pages/docs/index.astro +0 -33
  141. package/eventcatalog/src/pages/nav-index.json.ts +0 -30
  142. /package/eventcatalog/src/{pages → enterprise}/auth/error.astro +0 -0
  143. /package/eventcatalog/src/{middleware-auth.ts → enterprise/auth/middleware/middleware-auth.ts} +0 -0
  144. /package/eventcatalog/src/{middleware.ts → enterprise/auth/middleware/middleware.ts} +0 -0
  145. /package/eventcatalog/src/{pages/unauthorized/index.astro → enterprise/auth/unauthorized.astro} +0 -0
  146. /package/eventcatalog/src/{pages → enterprise}/plans/index.astro +0 -0
  147. /package/eventcatalog/src/{components/SideNav/NestedSideBar → stores/sidebar-store}/builders/flow.ts +0 -0
  148. /package/eventcatalog/src/{components/SideNav/NestedSideBar/sidebar-builder.ts → stores/sidebar-store/state.ts} +0 -0
@@ -2,7 +2,13 @@ import type { CollectionEntry } from 'astro:content';
2
2
  import { buildUrl } from '@utils/url-builder';
3
3
  import { getSchemaFormatFromURL } from '@utils/collections/schemas';
4
4
  import type { NavNode, ChildRef } from './shared';
5
- import { buildQuickReferenceSection, buildOwnersSection, shouldRenderSideBarSection, buildRepositorySection } from './shared';
5
+ import {
6
+ buildQuickReferenceSection,
7
+ buildOwnersSection,
8
+ shouldRenderSideBarSection,
9
+ buildRepositorySection,
10
+ buildAttachmentsSection,
11
+ } from './shared';
6
12
  import { isVisualiserEnabled } from '@utils/feature';
7
13
 
8
14
  export const buildMessageNode = (message: CollectionEntry<'events' | 'commands' | 'queries'>, owners: any[]): NavNode => {
@@ -25,6 +31,8 @@ export const buildMessageNode = (message: CollectionEntry<'events' | 'commands'
25
31
  const hasSchema = message.data.schemaPath !== undefined;
26
32
  const renderVisualiser = isVisualiserEnabled();
27
33
 
34
+ const hasAttachments = message.data.attachments && message.data.attachments.length > 0;
35
+
28
36
  const renderOwners = owners.length > 0 && shouldRenderSideBarSection(message, 'owners');
29
37
 
30
38
  return {
@@ -79,6 +87,7 @@ export const buildMessageNode = (message: CollectionEntry<'events' | 'commands'
79
87
  },
80
88
  renderOwners && buildOwnersSection(owners),
81
89
  renderRepository && buildRepositorySection(message.data.repository as { url: string; language: string }),
90
+ hasAttachments && buildAttachmentsSection(message.data.attachments as any[]),
82
91
  ].filter(Boolean) as ChildRef[],
83
92
  };
84
93
  };
@@ -9,6 +9,7 @@ import {
9
9
  shouldRenderSideBarSection,
10
10
  buildResourceGroupSections,
11
11
  buildRepositorySection,
12
+ buildAttachmentsSection,
12
13
  } from './shared';
13
14
  import { isVisualiserEnabled } from '@utils/feature';
14
15
  import { pluralizeMessageType } from '@utils/collections/messages';
@@ -29,6 +30,8 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
29
30
  const serviceFlows = service.data.flows || [];
30
31
  const hasFlows = serviceFlows.length > 0;
31
32
 
33
+ const hasAttachments = service.data.attachments && service.data.attachments.length > 0;
34
+
32
35
  const hasDataStores = dataStoresInService.length > 0;
33
36
  const resourceGroups = service.data.resourceGroups || [];
34
37
  const hasResourceGroups = resourceGroups.length > 0;
@@ -57,7 +60,7 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
57
60
  pages: [
58
61
  {
59
62
  type: 'item',
60
- title: 'Architecture Diagram',
63
+ title: 'Architecture Overview',
61
64
  href: buildUrl(`/architecture/services/${service.data.id}/${service.data.version}`),
62
65
  },
63
66
  renderVisualiser && {
@@ -80,21 +83,24 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
80
83
  pages: [
81
84
  ...openAPISpecifications.map((specification) => ({
82
85
  type: 'item',
83
- title: `${specification.name} (OpenAPI)`,
86
+ title: `${specification.name}`,
87
+ leftIcon: '/icons/openapi-black.svg',
84
88
  href: buildUrl(
85
89
  `/docs/services/${service.data.id}/${service.data.version}/spec/${specification.filenameWithoutExtension}`
86
90
  ),
87
91
  })),
88
92
  ...asyncAPISpecifications.map((specification) => ({
89
93
  type: 'item',
90
- title: `${specification.name} (AsyncAPI)`,
94
+ title: `${specification.name}`,
95
+ leftIcon: '/icons/asyncapi-black.svg',
91
96
  href: buildUrl(
92
97
  `/docs/services/${service.data.id}/${service.data.version}/asyncapi/${specification.filenameWithoutExtension}`
93
98
  ),
94
99
  })),
95
100
  ...graphQLSpecifications.map((specification) => ({
96
101
  type: 'item',
97
- title: `${specification.name} (GraphQL)`,
102
+ title: `${specification.name}`,
103
+ leftIcon: '/icons/graphql-black.svg',
98
104
  href: buildUrl(
99
105
  `/docs/services/${service.data.id}/${service.data.version}/graphql/${specification.filenameWithoutExtension}`
100
106
  ),
@@ -142,6 +148,7 @@ export const buildServiceNode = (service: CollectionEntry<'services'>, owners: a
142
148
  },
143
149
  renderOwners && buildOwnersSection(owners),
144
150
  renderRepository && buildRepositorySection(service.data.repository as { url: string; language: string }),
151
+ hasAttachments && buildAttachmentsSection(service.data.attachments as any[]),
145
152
  ].filter(Boolean) as ChildRef[],
146
153
  };
147
154
  };
@@ -17,6 +17,7 @@ export type NavNode = {
17
17
  type: 'group' | 'item';
18
18
  title: string;
19
19
  icon?: string; // Lucide icon name
20
+ leftIcon?: string; // Path to SVG icon shown on the left of the label
20
21
  href?: string; // URL (for leaf items)
21
22
  external?: boolean; // If true, the item will open in a new tab
22
23
  pages?: ChildRef[]; // Can mix keys and inline nodes
@@ -97,6 +98,19 @@ export const buildRepositorySection = (repository: { url: string; language: stri
97
98
  };
98
99
  };
99
100
 
101
+ export const buildAttachmentsSection = (attachments: any[]): NavNode | null => {
102
+ if (!attachments) return null;
103
+ return {
104
+ type: 'group',
105
+ title: 'Attachments',
106
+ icon: 'File',
107
+ pages: attachments.map((attachment) => ({
108
+ type: 'item',
109
+ title: attachment.title,
110
+ href: attachment.url,
111
+ })),
112
+ };
113
+ };
100
114
  export const buildResourceGroupSections = (resourceGroups: ResourceGroup[], context: ResourceGroupContext) => {
101
115
  return resourceGroups.map((resourceGroup) => buildResourceGroupSection(resourceGroup, context));
102
116
  };
@@ -1,5 +1,5 @@
1
1
  import { atom } from 'nanostores';
2
- import type { NavigationData } from '../components/SideNav/NestedSideBar/sidebar-builder';
2
+ import type { NavigationData } from './state';
3
3
 
4
4
  export const sidebarStore = atom<NavigationData | null>(null);
5
5
 
@@ -122,8 +122,6 @@ export const getChannels = async ({ getAllVersions = true }: Props = {}): Promis
122
122
  },
123
123
  catalog: {
124
124
  path: path.join(channel.collection, channel.id.replace('/index.mdx', '')),
125
- absoluteFilePath: path.join(PROJECT_DIR, channel.collection, channel.id.replace('/index.mdx', '/index.md')),
126
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', channel.collection, channel.id),
127
125
  filePath: path.join(process.cwd(), 'src', 'catalog-files', channel.collection, channel.id.replace('/index.mdx', '')),
128
126
  publicPath: path.join('/generated', channel.collection, channelFolderName),
129
127
  type: 'event',
@@ -112,8 +112,6 @@ export const getCommands = async ({ getAllVersions = true, hydrateServices = tru
112
112
  },
113
113
  catalog: {
114
114
  path: path.join(command.collection, command.id.replace('/index.mdx', '')),
115
- absoluteFilePath: path.join(PROJECT_DIR, command.collection, command.id.replace('/index.mdx', '/index.md')),
116
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', command.collection, command.id),
117
115
  filePath: path.join(process.cwd(), 'src', 'catalog-files', command.collection, command.id.replace('/index.mdx', '')),
118
116
  publicPath: path.join('/generated', command.collection, commandFolderName),
119
117
  type: 'command',
@@ -94,8 +94,6 @@ export const getContainers = async ({ getAllVersions = true }: Props = {}): Prom
94
94
  },
95
95
  catalog: {
96
96
  path: path.join(container.collection, container.id.replace('/index.mdx', '')),
97
- absoluteFilePath: path.join(PROJECT_DIR, container.collection, container.id.replace('/index.mdx', '/index.md')),
98
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', container.collection, container.id),
99
97
  filePath: path.join(
100
98
  process.cwd(),
101
99
  'src',
@@ -213,8 +213,6 @@ export const getDomains = async ({
213
213
  },
214
214
  catalog: {
215
215
  path: path.join(domain.collection, domain.id.replace('/index.mdx', '')),
216
- absoluteFilePath: path.join(PROJECT_DIR, domain.collection, domain.id.replace('/index.mdx', '/index.md')),
217
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', domain.collection, domain.id),
218
216
  filePath: path.join(process.cwd(), 'src', 'catalog-files', domain.collection, domain.id.replace('/index.mdx', '')),
219
217
  publicPath: path.join('/generated', domain.collection, domainFolderName),
220
218
  type: 'service',
@@ -94,8 +94,6 @@ export const getEntities = async ({ getAllVersions = true }: Props = {}): Promis
94
94
  },
95
95
  catalog: {
96
96
  path: path.join(entity.collection, entity.id.replace('/index.mdx', '')),
97
- absoluteFilePath: path.join(PROJECT_DIR, entity.collection, entity.id.replace('/index.mdx', '/index.md')),
98
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', entity.collection, entity.id),
99
97
  filePath: path.join(process.cwd(), 'src', 'catalog-files', entity.collection, entity.id.replace('/index.mdx', '')),
100
98
  publicPath: path.join('/generated', entity.collection, entityFolderName),
101
99
  type: 'entity',
@@ -114,8 +114,6 @@ export const getEvents = async ({ getAllVersions = true, hydrateServices = true
114
114
  },
115
115
  catalog: {
116
116
  path: path.join(event.collection, event.id.replace('/index.mdx', '')),
117
- absoluteFilePath: path.join(PROJECT_DIR, event.collection, event.id.replace('/index.mdx', '/index.md')),
118
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', event.collection, event.id),
119
117
  filePath: path.join(process.cwd(), 'src', 'catalog-files', event.collection, event.id.replace('/index.mdx', '')),
120
118
  publicPath: path.join('/generated', event.collection, eventFolderName),
121
119
  type: 'event',
@@ -76,8 +76,6 @@ export const getFlows = async ({ getAllVersions = true }: Props = {}): Promise<F
76
76
  },
77
77
  catalog: {
78
78
  path: path.join(flow.collection, flow.id.replace('/index.mdx', '')),
79
- absoluteFilePath: path.join(PROJECT_DIR, flow.collection, flow.id.replace('/index.mdx', '/index.md')),
80
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', flow.collection, flow.id),
81
79
  filePath: path.join(process.cwd(), 'src', 'catalog-files', flow.collection, flow.id.replace('/index.mdx', '')),
82
80
  publicPath: path.join('/generated', flow.collection),
83
81
  type: 'flow',
@@ -107,8 +107,6 @@ export const getQueries = async ({ getAllVersions = true, hydrateServices = true
107
107
  },
108
108
  catalog: {
109
109
  path: path.join(query.collection, query.id.replace('/index.mdx', '')),
110
- absoluteFilePath: path.join(PROJECT_DIR, query.collection, query.id.replace('/index.mdx', '/index.md')),
111
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', query.collection, query.id),
112
110
  filePath: path.join(process.cwd(), 'src', 'catalog-files', query.collection, query.id.replace('/index.mdx', '')),
113
111
  publicPath: path.join('/generated', query.collection, queryFolderName),
114
112
  type: 'event', // Kept as 'event' to match original file, though likely should be 'query'
@@ -2,6 +2,7 @@ import type { CollectionEntry } from 'astro:content';
2
2
  import type { PageTypes } from '@types';
3
3
  import path from 'path';
4
4
  import { buildUrl } from '@utils/url-builder';
5
+ import { getAbsoluteFilePathForAstroFile } from '@utils/files';
5
6
 
6
7
  export type Schema = {
7
8
  url: string;
@@ -13,12 +14,23 @@ export const getSchemaURL = (resource: CollectionEntry<PageTypes>) => {
13
14
  const publicPath = resource?.catalog?.publicPath;
14
15
  const schemaFilePath = resource?.data?.schemaPath;
15
16
 
16
- if (!publicPath || !schemaFilePath) {
17
+ // No schema file path, return an empty string
18
+ if (!schemaFilePath) {
19
+ return;
20
+ }
21
+
22
+ if (!publicPath) {
23
+ // Then we try and get the absolute file path from the resource
24
+ const absoluteFilePath = getAbsoluteFilePathForAstroFile(resource.filePath ?? '', schemaFilePath ?? '');
25
+ if (absoluteFilePath) {
26
+ return absoluteFilePath;
27
+ }
28
+ // Can't find the schema file, return an empty string
17
29
  return;
18
30
  }
19
31
 
20
32
  // new URL
21
- return path.join(publicPath, schemaFilePath);
33
+ return path.join(publicPath, schemaFilePath ?? '');
22
34
  };
23
35
 
24
36
  export const getSchemaFormatFromURL = (url: string) => {
@@ -42,18 +54,44 @@ export const getSchemasFromResource = (resource: CollectionEntry<PageTypes>): Sc
42
54
  const openapiPath = Array.isArray(specifications)
43
55
  ? specifications.find((spec) => spec.type === 'openapi')?.path
44
56
  : specifications?.openapiPath;
57
+ const graphqlPath = Array.isArray(specifications)
58
+ ? specifications.find((spec) => spec.type === 'graphql')?.path
59
+ : specifications?.graphqlPath;
45
60
  // @ts-ignore
46
- const publicPath = resource?.catalog?.publicPath;
61
+ let publicPath = resource?.catalog?.publicPath;
47
62
  const schemas = [];
48
63
 
49
64
  if (asyncapiPath) {
50
- const asyncapiUrl = path.join(publicPath, asyncapiPath);
51
- schemas.push({ url: buildUrl(asyncapiUrl), format: 'asyncapi' });
65
+ if (!publicPath) {
66
+ // We try and get the absoulate file path from the resource
67
+ const absoluteFilePath = getAbsoluteFilePathForAstroFile(resource.filePath ?? '', asyncapiPath ?? '');
68
+ schemas.push({ url: buildUrl(absoluteFilePath), format: 'asyncapi' });
69
+ } else {
70
+ // The resource has the public path, so we can use it to build the URL
71
+ schemas.push({ url: buildUrl(path.join(publicPath, asyncapiPath)), format: 'asyncapi' });
72
+ }
52
73
  }
53
74
 
54
75
  if (openapiPath) {
55
- const openapiUrl = path.join(publicPath, openapiPath);
56
- schemas.push({ url: buildUrl(openapiUrl), format: 'openapi' });
76
+ if (!publicPath) {
77
+ // We try and get the absoulate file path from the resource
78
+ const absoluteFilePath = getAbsoluteFilePathForAstroFile(resource.filePath ?? '', openapiPath ?? '');
79
+ schemas.push({ url: buildUrl(absoluteFilePath), format: 'openapi' });
80
+ } else {
81
+ // The resource has the public path, so we can use it to build the URL
82
+ schemas.push({ url: buildUrl(path.join(publicPath, openapiPath)), format: 'openapi' });
83
+ }
84
+ }
85
+
86
+ if (graphqlPath) {
87
+ if (!publicPath) {
88
+ // We try and get the absoulate file path from the resource
89
+ const absoluteFilePath = getAbsoluteFilePathForAstroFile(resource.filePath ?? '', graphqlPath ?? '');
90
+ schemas.push({ url: buildUrl(absoluteFilePath), format: 'graphql' });
91
+ } else {
92
+ // The resource has the public path, so we can use it to build the URL
93
+ schemas.push({ url: buildUrl(path.join(publicPath, graphqlPath)), format: 'graphql' });
94
+ }
57
95
  }
58
96
 
59
97
  return schemas;
@@ -118,8 +118,6 @@ export const getServices = async ({ getAllVersions = true, returnBody = false }:
118
118
  catalog: {
119
119
  // TODO: avoid use string replace at path due to win32
120
120
  path: path.join(service.collection, service.id.replace('/index.mdx', '')),
121
- absoluteFilePath: path.join(PROJECT_DIR, service.collection, service.id.replace('/index.mdx', '/index.md')),
122
- astroContentFilePath: path.join(process.cwd(), 'src', 'content', service.collection, service.id),
123
121
  filePath: path.join(process.cwd(), 'src', 'catalog-files', service.collection, service.id.replace('/index.mdx', '')),
124
122
  // service will be MySerive-0.0.1 remove the version
125
123
  publicPath: path.join('/generated', service.collection, serviceFolderName),
@@ -11,9 +11,9 @@
11
11
  * 3. Follow the official activation instructions
12
12
  */
13
13
 
14
- import config from '@config';
15
14
  import fs from 'fs';
16
15
  import { join } from 'path';
16
+ import config from '../../eventcatalog.config.js';
17
17
 
18
18
  // These functions check for valid, legally obtained access to premium features
19
19
  export const isEventCatalogStarterEnabled = () => process.env.EVENTCATALOG_STARTER === 'true';
@@ -39,21 +39,25 @@ export const showCustomBranding = () => {
39
39
  export const isChangelogEnabled = () => config?.changelog?.enabled ?? false;
40
40
 
41
41
  export const isCustomDocsEnabled = () => isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
42
+
42
43
  export const isEventCatalogChatEnabled = () => {
43
44
  const isFeatureEnabledFromPlan = isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
44
- return isFeatureEnabledFromPlan && config?.chat?.enabled && isSSR();
45
+ const directory = process.env.PROJECT_DIR || process.cwd();
46
+ const hasChatConfigurationFile = fs.existsSync(join(directory, 'eventcatalog.chat.js'));
47
+ return isFeatureEnabledFromPlan && hasChatConfigurationFile && isSSR();
45
48
  };
46
49
 
47
50
  export const isEventCatalogUpgradeEnabled = () => !isEventCatalogStarterEnabled() && !isEventCatalogScaleEnabled();
48
51
  export const isCustomLandingPageEnabled = () => isEventCatalogStarterEnabled() || isEventCatalogScaleEnabled();
49
52
 
50
53
  export const isMarkdownDownloadEnabled = () => config?.llmsTxt?.enabled ?? false;
51
- export const isLLMSTxtEnabled = () => (config?.llmsTxt?.enabled || isEventCatalogChatEnabled()) ?? false;
54
+ export const isLLMSTxtEnabled = () => (config?.llmsTxt?.enabled || isEventCatalogChatEnabled()) ?? true;
52
55
 
53
56
  export const isAuthEnabled = () => {
57
+ const isAuthEnabledInCatalog = config?.auth?.enabled ?? false;
54
58
  const directory = process.env.PROJECT_DIR || process.cwd();
55
- const hasAuthConfig = fs.existsSync(join(directory, 'eventcatalog.auth.js'));
56
- return (hasAuthConfig && isSSR() && isEventCatalogScaleEnabled()) || false;
59
+ const hasAuthConfigurationFile = fs.existsSync(join(directory, 'eventcatalog.auth.js'));
60
+ return (isAuthEnabledInCatalog && hasAuthConfigurationFile && isSSR() && isEventCatalogScaleEnabled()) || false;
57
61
  };
58
62
 
59
63
  export const isSSR = () => config?.output === 'server';
@@ -292,7 +292,7 @@ export const getNodesAndEdges = async ({
292
292
  const uniqueEdges = edges.reduce((acc: any[], edge: any) => {
293
293
  const existingEdge = acc.find((e: any) => e.id === edge.id);
294
294
  if (existingEdge) {
295
- existingEdge.label = `${existingEdge.label} & ${edge.label}`;
295
+ // existingEdge.label = `${existingEdge.label} & ${edge.label}`;
296
296
  // Add the custom colors to the existing edge which can be an array of strings
297
297
  const value = Array.isArray(edge.data.customColor) ? edge.data.customColor : [edge.data.customColor];
298
298
  const existingValue = Array.isArray(existingEdge.data.customColor)
@@ -0,0 +1,86 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { isSSR } from '@utils/feature';
4
+
5
+ /**
6
+ * Get the absolute base path for a resource item.
7
+ *
8
+ * In SSR mode, filePath is relative to the Astro core directory (e.g., "../examples/default/domains/...").
9
+ * We need to resolve it using PROJECT_DIR to get the correct absolute path.
10
+ *
11
+ * In static mode, filePath is resolved correctly by Astro's build context.
12
+ *
13
+ * @param item - The resource item with a filePath property
14
+ * @returns The absolute path to the directory containing the resource
15
+ */
16
+ export function getResourceBasePath(item: { filePath?: string }): string {
17
+ if (!item.filePath) {
18
+ return '';
19
+ }
20
+
21
+ const filePath = item.filePath;
22
+
23
+ // In SSR mode, we need to resolve the relative path using PROJECT_DIR
24
+ if (isSSR()) {
25
+ const PROJECT_DIR = process.env.PROJECT_DIR || '';
26
+
27
+ if (PROJECT_DIR) {
28
+ // Get the project folder name from PROJECT_DIR (e.g., "default" from ".../examples/default")
29
+ const projectFolderName = path.basename(PROJECT_DIR);
30
+
31
+ // Find the project folder in the relative path and extract everything after it
32
+ // Pattern: ../examples/default/domains/... -> domains/...
33
+ const regex = new RegExp(`.*?${projectFolderName}/(.+)$`);
34
+ const match = filePath.match(regex);
35
+
36
+ if (match && match[1]) {
37
+ // Join PROJECT_DIR with the relative path within the project
38
+ return path.join(PROJECT_DIR, path.dirname(match[1]));
39
+ }
40
+ }
41
+ }
42
+
43
+ // Static mode: resolve directly using Astro's build context
44
+ return path.dirname(path.resolve(filePath));
45
+ }
46
+
47
+ /**
48
+ * Get the absolute path to a file within a resource directory.
49
+ *
50
+ * @param item - The resource item with a filePath property
51
+ * @param relativePath - The relative path to the file (e.g., "schema.json")
52
+ * @returns The absolute path to the file
53
+ */
54
+ export function getResourceFilePath(item: { filePath?: string }, relativePath: string): string {
55
+ const basePath = getResourceBasePath(item);
56
+ return path.join(basePath, relativePath);
57
+ }
58
+
59
+ /**
60
+ * Check if a file exists within a resource directory.
61
+ *
62
+ * @param item - The resource item with a filePath property
63
+ * @param relativePath - The relative path to the file (e.g., "schema.json")
64
+ * @returns True if the file exists, false otherwise
65
+ */
66
+ export function resourceFileExists(item: { filePath?: string }, relativePath: string): boolean {
67
+ const filePath = getResourceFilePath(item, relativePath);
68
+ return fs.existsSync(filePath);
69
+ }
70
+
71
+ /**
72
+ * Read a file from a resource directory.
73
+ *
74
+ * @param item - The resource item with a filePath property
75
+ * @param relativePath - The relative path to the file (e.g., "schema.json")
76
+ * @returns The file content as a string, or null if the file doesn't exist
77
+ */
78
+ export function readResourceFile(item: { filePath?: string }, relativePath: string): string | null {
79
+ const filePath = getResourceFilePath(item, relativePath);
80
+
81
+ if (!fs.existsSync(filePath)) {
82
+ return null;
83
+ }
84
+
85
+ return fs.readFileSync(filePath, 'utf-8');
86
+ }
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.0.0-beta.9",
9
+ "version": "3.0.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -17,16 +17,12 @@
17
17
  "eventcatalog/",
18
18
  "!eventcatalog/**/__tests__/",
19
19
  "bin/",
20
- "dist/",
21
- "default-files-for-collections/"
20
+ "dist/"
22
21
  ],
23
22
  "dependencies": {
24
- "@ai-sdk/anthropic": "^2.0.23",
25
- "@ai-sdk/google": "^2.0.17",
26
- "@ai-sdk/openai": "^2.0.42",
27
23
  "@ai-sdk/react": "^2.0.60",
28
- "@astrojs/markdown-remark": "^6.3.9",
29
- "@astrojs/mdx": "^4.3.12",
24
+ "@astrojs/markdown-remark": "^6.3.10",
25
+ "@astrojs/mdx": "^4.3.13",
30
26
  "@astrojs/node": "^9.5.1",
31
27
  "@astrojs/react": "^4.4.2",
32
28
  "@astrojs/rss": "^4.0.14",
@@ -38,7 +34,7 @@
38
34
  "@eventcatalog/generator-ai": "^1.1.0",
39
35
  "@eventcatalog/license": "^0.0.7",
40
36
  "@eventcatalog/linter": "^0.0.2",
41
- "@eventcatalog/sdk": "^2.9.2",
37
+ "@eventcatalog/sdk": "^2.9.9",
42
38
  "@eventcatalog/visualizer": "^0.0.6",
43
39
  "@fontsource/inter": "^5.2.5",
44
40
  "@headlessui/react": "^2.0.3",
@@ -50,6 +46,7 @@
50
46
  "@radix-ui/react-context-menu": "^2.2.6",
51
47
  "@radix-ui/react-dialog": "^1.1.6",
52
48
  "@radix-ui/react-dropdown-menu": "^2.1.12",
49
+ "@radix-ui/react-popover": "^1.1.15",
53
50
  "@radix-ui/react-tooltip": "^1.1.8",
54
51
  "@scalar/api-reference-react": "^0.4.37",
55
52
  "@tailwindcss/typography": "^0.5.13",
@@ -57,7 +54,7 @@
57
54
  "@tanstack/react-table": "^8.17.3",
58
55
  "@xyflow/react": "^12.3.6",
59
56
  "ai": "^5.0.60",
60
- "astro": "^5.16.4",
57
+ "astro": "^5.16.6",
61
58
  "astro-compress": "^2.3.8",
62
59
  "astro-expressive-code": "^0.41.3",
63
60
  "astro-seo": "^0.8.4",
@@ -76,16 +73,15 @@
76
73
  "glob": "^10.5.0",
77
74
  "gray-matter": "^4.0.3",
78
75
  "html-to-image": "^1.11.11",
79
- "js-yaml": "^4.1.0",
76
+ "js-yaml": "^4.1.1",
80
77
  "jsonpath": "^1.1.1",
81
78
  "jsonwebtoken": "^9.0.2",
82
79
  "lodash.debounce": "^4.0.8",
83
80
  "lodash.merge": "4.6.2",
84
81
  "lucide-react": "^0.453.0",
85
82
  "marked": "^15.0.6",
86
- "mermaid": "^11.4.1",
83
+ "mermaid": "^11.12.1",
87
84
  "nanostores": "^1.1.0",
88
- "pagefind": "^1.3.0",
89
85
  "pako": "^2.1.0",
90
86
  "picocolors": "^1.1.1",
91
87
  "react": "^18.3.1",
@@ -94,13 +90,14 @@
94
90
  "react-syntax-highlighter": "^16.1.0",
95
91
  "rehype-autolink-headings": "^7.1.0",
96
92
  "rehype-expressive-code": "^0.41.3",
93
+ "rehype-raw": "^7.0.0",
97
94
  "rehype-slug": "^6.0.0",
98
95
  "remark-comment": "^1.0.0",
99
96
  "remark-directive": "^3.0.0",
100
97
  "remark-gfm": "^3.0.1",
101
98
  "rimraf": "^5.0.7",
102
99
  "semver": "7.6.3",
103
- "shelljs": "^0.8.5",
100
+ "shelljs": "^0.9.0",
104
101
  "tailwindcss": "^3.4.3",
105
102
  "tw-animate-css": "^1.4.0",
106
103
  "typescript": "^5.4.5",
@@ -147,7 +144,7 @@
147
144
  "preview": "astro preview",
148
145
  "astro": "astro",
149
146
  "start:catalog": "node scripts/start-catalog-locally.js",
150
- "pagefind": "node scripts/pagefind.js",
147
+ "start:catalog:server": "node scripts/start-server-locally.js",
151
148
  "preview:catalog": "node scripts/preview-catalog-locally.js",
152
149
  "generate:catalog": "node scripts/generate-catalog-locally.js",
153
150
  "verify-build:catalog": "rimraf dist && pnpm run build:cd",
@@ -1,5 +0,0 @@
1
- ---
2
- id: empty
3
- ---
4
-
5
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,11 +0,0 @@
1
- ---
2
- id: empty
3
- steps:
4
- - id: "empty"
5
- title: "empty"
6
- name: empty
7
- version: 0.0.1
8
- hidden: true
9
- ---
10
-
11
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,8 +0,0 @@
1
- ---
2
- id: empty
3
- name: empty
4
- version: 0.0.1
5
- hidden: true
6
- ---
7
-
8
- <!-- Do not delete this file, required for EC, you an ignore this file -->
@@ -1,7 +0,0 @@
1
- ---
2
- id: ubiquitous-language
3
- name: Ubiquitous Language
4
- summary: A shared language used by all team members to communicate about the system.
5
- description: A shared language used by all team members to communicate about the system.
6
- ---
7
- <!-- Do not delete this file, required for EC, you an ignore this file -->