@eventcatalog/core 2.33.11 → 2.34.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 (36) 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-WHJEWUMZ.js → chunk-FSNOP5RV.js} +1 -1
  6. package/dist/{chunk-FKC4UAA6.js → chunk-SP3CDAMI.js} +1 -1
  7. package/dist/{chunk-2NTEYUNI.js → chunk-XKIQJQIS.js} +1 -1
  8. package/dist/constants.cjs +1 -1
  9. package/dist/constants.js +1 -1
  10. package/dist/eventcatalog.cjs +1 -1
  11. package/dist/eventcatalog.js +3 -3
  12. package/eventcatalog/src/components/Grids/DomainGrid.tsx +52 -0
  13. package/eventcatalog/src/components/Grids/ServiceGrid.tsx +198 -168
  14. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +40 -16
  15. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Channel.tsx +3 -1
  16. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Command.tsx +3 -1
  17. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Custom.tsx +1 -1
  18. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Event.tsx +13 -2
  19. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Query.tsx +3 -1
  20. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Service.tsx +3 -1
  21. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/User.tsx +1 -1
  22. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewerRoot.astro +0 -3
  23. package/eventcatalog/src/components/SideBars/DomainSideBar.astro +47 -2
  24. package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +22 -0
  25. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +11 -1
  26. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +1 -0
  27. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +1 -0
  28. package/eventcatalog/src/content.config.ts +1 -0
  29. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +0 -3
  30. package/eventcatalog/src/pages/architecture/architecture.astro +17 -6
  31. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +2 -7
  32. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +100 -102
  33. package/eventcatalog/src/pages/docs/users/[id]/index.astro +4 -12
  34. package/eventcatalog/src/utils/collections/domains.ts +32 -2
  35. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +31 -2
  36. package/package.json +1 -1
@@ -55,7 +55,7 @@ const ownedServicesList = services.map((p) => ({
55
55
  tag: `v${p.data.version}`,
56
56
  }));
57
57
 
58
- const ownedEventsList = [...events, ...commands].map((p) => ({
58
+ const ownedMessagesList = [...events, ...commands, ...queries].map((p) => ({
59
59
  label: `${p.data.name}`,
60
60
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
61
61
  color: p.collection === 'events' ? 'orange' : 'blue',
@@ -63,116 +63,114 @@ const ownedEventsList = [...events, ...commands].map((p) => ({
63
63
  tag: `v${p.data.version}`,
64
64
  }));
65
65
 
66
- const ownedQueriesList = queries.map((p) => ({
67
- label: `${p.data.name}`,
68
- href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
69
- collection: p.collection,
70
- tag: `v${p.data.version}`,
71
- }));
72
-
73
66
  const pageTitle = `Team | ${props.data.name}`;
74
67
  ---
75
68
 
76
69
  <VerticalSideBarLayout title={pageTitle} description={props.data.summary}>
77
- <div class="flex min-h-screen docs-layout sm:px-8">
78
- <main class="flex-1 w-full pr-10 pt-4" data-pagefind-body data-pagefind-meta={`title:${pageTitle}`}>
79
- <!-- <span class="text-purple-500 bg-purple-100 px-2 py-1 rounded-md">v{props.data.version}</span> -->
80
-
81
- <div class="border-b border-gray-200 py-4 pb-2">
82
- <div class="flex justify-start">
83
- <!-- <span class="shadow-md text-center flex items-center justify-center text-white text-4xl bg-red-500 h-28 w-28 rounded-full">{props.data.name.charAt(0)}</span> -->
84
- <div class="flex flex-col justify-between space-y-2">
85
- <div>
86
- <h2 class="text-4xl font-bold">{props.data.name} <span class="text-gray-300">(Team)</span></h2>
87
- </div>
88
- <div class="space-y-2">
89
- {
90
- props.data.email && (
91
- <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
92
- <EnvelopeIcon className="w-4 h-4 text-purple-400" />
93
- <a href={`mailto:${props.data.email}`}>Email</a>
94
- </div>
95
- )
96
- }
97
- {
98
- props.data.slackDirectMessageUrl && (
99
- <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
100
- <img src={buildUrl('/slack-icon.svg', true)} class="w-4 h-3" />
101
- <a href={`${props.data.slackDirectMessageUrl}`}>Send DM on Slack</a>
102
- </div>
103
- )
104
- }
105
- {
106
- props.data.msTeamsDirectMessageUrl && (
107
- <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
108
- <img src={buildUrl('/icons/ms-teams.svg', true)} class="w-4 h-4" />
109
- <a href={`${props.data.msTeamsDirectMessageUrl}`} target="_blank" rel="noopener noreferrer">
110
- Send DM on Teams
111
- </a>
112
- </div>
113
- )
114
- }
70
+ <main class="flex sm:px-8 docs-layout h-full" data-pagefind-body data-pagefind-meta={`title:${pageTitle}`}>
71
+ <div class="flex docs-layout w-full">
72
+ <div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
73
+ <div class="border-b border-gray-200 pb-4">
74
+ <div class="flex justify-start">
75
+ <div class="flex flex-col justify-between space-y-2">
76
+ <div>
77
+ <h2 class="text-4xl font-bold">{props.data.name} <span class="text-gray-300">(Team)</span></h2>
78
+ </div>
79
+ <div class="space-y-2">
80
+ {
81
+ props.data.email && (
82
+ <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
83
+ <EnvelopeIcon className="w-4 h-4 text-purple-400" />
84
+ <a href={`mailto:${props.data.email}`}>Email</a>
85
+ </div>
86
+ )
87
+ }
88
+ {
89
+ props.data.slackDirectMessageUrl && (
90
+ <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
91
+ <img src={buildUrl('/slack-icon.svg', true)} class="w-4 h-3" />
92
+ <a href={`${props.data.slackDirectMessageUrl}`}>Send DM on Slack</a>
93
+ </div>
94
+ )
95
+ }
96
+ {
97
+ props.data.msTeamsDirectMessageUrl && (
98
+ <div class="flex space-x-1 items-center text-xs text-gray-500 font-bold hover:underline hover:text-primary">
99
+ <img src={buildUrl('/icons/ms-teams.svg', true)} class="w-4 h-4" />
100
+ <a href={`${props.data.msTeamsDirectMessageUrl}`} target="_blank" rel="noopener noreferrer">
101
+ Send DM on Teams
102
+ </a>
103
+ </div>
104
+ )
105
+ }
106
+ </div>
115
107
  </div>
116
108
  </div>
109
+ <h2 class="text-xl py-2 text-gray-500">{props.data.summary}</h2>
117
110
  </div>
118
- <!-- {
119
- props.data.badges && (
120
- <div class="flex flex-wrap py-2">
121
- {props.data.badges.map((badge) => (
122
- <span class={`text-sm text-gray-500 px-2 py-1 rounded-md mr-2 bg-${badge.backgroundColor}-200 text-${badge.textColor}-800`}>{badge.content}</span>
123
- ))}
111
+ <div class="border-b border-gray-200" data-pagefind-ignore>
112
+ <div class="mx-auto max-w-7xl px-6 lg:px-8">
113
+ <div class="mx-auto max-w-2xl lg:max-w-none">
114
+ <dl
115
+ class="hidden lg:grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-4 lg:grid-cols-4"
116
+ >
117
+ <div class="flex flex-col p-8">
118
+ <dt class="text-sm font-semibold leading-6 text-gray-600"># owned domains</dt>
119
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedDomainsList.length}</dd>
120
+ </div>
121
+ <div class="flex flex-col p-8">
122
+ <dt class="text-sm font-semibold leading-6 text-gray-600"># owned services</dt>
123
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedServicesList.length}</dd>
124
+ </div>
125
+ <div class="flex flex-col p-8">
126
+ <dt class="text-sm font-semibold leading-6 text-gray-600"># owned messages</dt>
127
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedMessagesList.length}</dd>
128
+ </div>
129
+ <div class="flex flex-col p-8">
130
+ <dt class="text-sm font-semibold leading-6 text-gray-600"># team members</dt>
131
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{membersList.length}</dd>
132
+ </div>
133
+ </dl>
124
134
  </div>
125
- )
126
- } -->
127
- <h2 class="text-xl py-2 text-gray-500">{props.data.summary}</h2>
128
- </div>
129
- <div class="prose prose-md py-4 w-full">
130
- <Content components={components(props)} />
131
- </div>
132
- <!-- <div class="h-full w-full">
133
- <NodeGraph id={props.data.id} type={props?.catalog?.type} nodes={props.nodes} masterNode={{ name: props.data.name, id: props.data.id }} client:load />
134
- </div> -->
135
- </main>
136
- <aside class="sticky top-20 h-[calc(100vh-theme(spacing.16))] w-72 overflow-y-auto" data-pagefind-ignore>
137
- <div class="divide-y-2 divide-gray-100">
138
- <PillListFlat
139
- color="pink"
140
- title={`Owned domains (${ownedDomainsList.length})`}
141
- pills={ownedDomainsList}
142
- emptyMessage={`${props.data.name} does not own any domains.`}
143
- client:load
144
- />
145
- <PillListFlat
146
- color="blue"
147
- title={`Owned services (${ownedServicesList.length})`}
148
- pills={ownedServicesList}
149
- emptyMessage={`This team does not own any services .`}
150
- client:load
151
- />
152
- <PillListFlat
153
- color="red"
154
- title={`Owned messages (${ownedEventsList.length})`}
155
- pills={ownedEventsList}
156
- emptyMessage={`This team does not own any messages .`}
157
- client:load
158
- />
159
- <PillListFlat
160
- color="purple"
161
- title={`Owned queries (${ownedQueriesList.length})`}
162
- pills={ownedQueriesList}
163
- emptyMessage={`This team does not own any queries .`}
164
- client:load
165
- />
166
- <OwnersList
167
- title={`Team members (${membersList.length})`}
168
- owners={membersList}
169
- emptyMessage={`This team does not have any members.`}
170
- client:load
171
- />
135
+ </div>
136
+ </div>
137
+ <div class="prose prose-md py-4 w-full">
138
+ <Content components={components(props)} />
139
+ </div>
172
140
  </div>
173
- <!-- {props?.collection === 'events' && <MessageSideBar message={props} />} -->
174
- </aside>
175
- </div>
141
+ <aside class="hidden lg:block sticky top-0 pb-10 w-96 overflow-y-auto py-2" data-pagefind-ignore>
142
+ <div class="sticky top-28 left-0 h-full overflow-y-auto pr-6 py-4">
143
+ <PillListFlat
144
+ color="pink"
145
+ title={`Owned domains (${ownedDomainsList.length})`}
146
+ pills={ownedDomainsList}
147
+ emptyMessage={`${props.data.name} does not own any domains.`}
148
+ client:load
149
+ />
150
+ <PillListFlat
151
+ color="blue"
152
+ title={`Owned services (${ownedServicesList.length})`}
153
+ pills={ownedServicesList}
154
+ emptyMessage={`This team does not own any services .`}
155
+ client:load
156
+ />
157
+ <PillListFlat
158
+ color="red"
159
+ title={`Owned messages (${ownedMessagesList.length})`}
160
+ pills={ownedMessagesList}
161
+ emptyMessage={`This team does not own any messages .`}
162
+ client:load
163
+ />
164
+ <OwnersList
165
+ title={`Team members (${membersList.length})`}
166
+ owners={membersList}
167
+ emptyMessage={`This team does not have any members.`}
168
+ client:load
169
+ />
170
+ </div>
171
+ </aside>
172
+ </div>
173
+ </main>
176
174
  </VerticalSideBarLayout>
177
175
 
178
176
  <style>
@@ -66,9 +66,8 @@ const pageTitle = `User | ${props.data.name}`;
66
66
  <VerticalSideBarLayout title={pageTitle}>
67
67
  <main class="flex sm:px-8 docs-layout h-full" data-pagefind-body data-pagefind-meta={`title:${pageTitle}`}>
68
68
  <div class="flex docs-layout w-full">
69
- <div class="w-full lg:mr-6 pr-8 overflow-y-auto py-4">
70
- <!-- <span class="text-purple-500 bg-purple-100 px-2 py-1 rounded-md">v{props.data.version}</span> -->
71
- <div class="border-b border-gray-200 pb-4 py-4">
69
+ <div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
70
+ <div class="border-b border-gray-200 pb-4">
72
71
  <div class="flex justify-start space-x-8">
73
72
  <img src={props.data.avatarUrl} alt="Profile picture" class="shadow-md w-28 rounded-md" />
74
73
  <div class="flex flex-col justify-between">
@@ -125,10 +124,6 @@ const pageTitle = `User | ${props.data.name}`;
125
124
  <dt class="text-sm font-semibold leading-6 text-gray-600"># owned messages</dt>
126
125
  <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedMessageList.length}</dd>
127
126
  </div>
128
- <!-- <div class="flex flex-col p-8">
129
- <dt class="text-sm font-semibold leading-6 text-gray-600"># owned domains</dt>
130
- <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">2</dd>
131
- </div> -->
132
127
  <div class="flex flex-col p-8">
133
128
  <dt class="text-sm font-semibold leading-6 text-gray-600"># teams joined</dt>
134
129
  <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{associatedTeams.length}</dd>
@@ -141,11 +136,8 @@ const pageTitle = `User | ${props.data.name}`;
141
136
  <Content components={components(props)} />
142
137
  </div>
143
138
  </div>
144
- <aside
145
- class="hidden lg:block sticky top-0 h-[calc(100vh-theme(spacing.16))] w-72 overflow-y-auto py-2"
146
- data-pagefind-ignore
147
- >
148
- <div class="divide-y-2 divide-gray-100 pr-6">
139
+ <aside class="hidden lg:block sticky top-0 pb-10 w-96 overflow-y-auto py-2" data-pagefind-ignore>
140
+ <div class="sticky top-28 left-0 h-full overflow-y-auto pr-6 py-4">
149
141
  {
150
142
  ownedDomainsList.length > 0 && (
151
143
  <PillListFlat
@@ -3,6 +3,7 @@ import { getCollection } from 'astro:content';
3
3
  import type { CollectionEntry } from 'astro:content';
4
4
  import path from 'path';
5
5
  import type { CollectionMessageTypes } from '@types';
6
+ import type { Service } from './services';
6
7
 
7
8
  const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
8
9
 
@@ -40,8 +41,20 @@ export const getDomains = async ({ getAllVersions = true }: Props = {}): Promise
40
41
 
41
42
  // const receives = service.data.receives || [];
42
43
  const servicesInDomain = domain.data.services || [];
44
+ const subDomainsInDomain = domain.data.domains || [];
43
45
 
44
- const services = servicesInDomain
46
+ const subDomains = subDomainsInDomain
47
+ .map((_subDomain: { id: string; version: string | undefined }) =>
48
+ getItemsFromCollectionByIdAndSemverOrLatest(domains, _subDomain.id, _subDomain.version)
49
+ )
50
+ .flat()
51
+ // Stop circular references
52
+ .filter((subDomain) => subDomain.data.id !== domain.data.id);
53
+
54
+ // Services in the sub domains
55
+ const subdomainServices = subDomains.flatMap((subDomain) => subDomain.data.services || []);
56
+
57
+ const services = [...servicesInDomain, ...subdomainServices]
45
58
  .map((_service: { id: string; version: string | undefined }) =>
46
59
  getItemsFromCollectionByIdAndSemverOrLatest(servicesCollection, _service.id, _service.version)
47
60
  )
@@ -51,7 +64,8 @@ export const getDomains = async ({ getAllVersions = true }: Props = {}): Promise
51
64
  ...domain,
52
65
  data: {
53
66
  ...domain.data,
54
- services,
67
+ services: services,
68
+ domains: subDomains,
55
69
  latestVersion,
56
70
  versions,
57
71
  },
@@ -109,3 +123,19 @@ export const getUbiquitousLanguage = async (domain: Domain): Promise<UbiquitousL
109
123
 
110
124
  return ubiquitousLanguages;
111
125
  };
126
+
127
+ export const getParentDomains = async (domain: Domain): Promise<Domain[]> => {
128
+ const domains = await getDomains({ getAllVersions: false });
129
+ return domains.filter((d) => {
130
+ const subDomains = (d.data.domains as unknown as Domain[]) || [];
131
+ return subDomains.some((d) => d.data.id === domain.data.id);
132
+ });
133
+ };
134
+
135
+ export const getDomainsForService = async (service: Service): Promise<Domain[]> => {
136
+ const domains = await getDomains({ getAllVersions: false });
137
+ return domains.filter((d) => {
138
+ const services = d.data.services as unknown as Service[];
139
+ return services.some((s) => s.data.id === service.data.id);
140
+ });
141
+ };
@@ -3,7 +3,6 @@ import {
3
3
  createDagreGraph,
4
4
  calculatedNodes,
5
5
  generateIdForNode,
6
- createNode,
7
6
  getEdgeLabelForServiceAsTarget,
8
7
  generatedIdForEdge,
9
8
  createEdge,
@@ -214,9 +213,10 @@ interface NodesAndEdgesProps {
214
213
  version: string;
215
214
  defaultFlow?: DagreGraph;
216
215
  mode: 'simple' | 'full';
216
+ group?: boolean;
217
217
  }
218
218
 
219
- export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple' }: NodesAndEdgesProps) => {
219
+ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple', group = false }: NodesAndEdgesProps) => {
220
220
  const flow = defaultFlow || createDagreGraph({ ranksep: 360, nodesep: 50, edgesep: 50 });
221
221
  let nodes = new Map(),
222
222
  edges = new Map();
@@ -234,6 +234,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
234
234
  }
235
235
 
236
236
  const rawServices = domain?.data.services || [];
237
+ const rawSubDomains = domain?.data.domains || [];
237
238
 
238
239
  const servicesCollection = await getCollection('services');
239
240
 
@@ -242,6 +243,11 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
242
243
  .flat()
243
244
  .map((svc) => ({ id: svc.data.id, version: svc.data.version }));
244
245
 
246
+ const domainSubDomainsWithVersion = rawSubDomains
247
+ .map((subDomain) => getItemsFromCollectionByIdAndSemverOrLatest(domains, subDomain.id, subDomain.version))
248
+ .flat()
249
+ .map((svc) => ({ id: svc.data.id, version: svc.data.version }));
250
+
245
251
  // Get all the nodes for everyhing
246
252
 
247
253
  for (const service of domainServicesWithVersion) {
@@ -267,6 +273,29 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
267
273
  serviceEdges.forEach((e) => edges.set(e.id, e));
268
274
  }
269
275
 
276
+ for (const subDomain of domainSubDomainsWithVersion) {
277
+ const { nodes: subDomainNodes, edges: subDomainEdges } = await getNodesAndEdges({
278
+ id: subDomain.id,
279
+ version: subDomain.version,
280
+ defaultFlow: flow,
281
+ mode,
282
+ group: true,
283
+ });
284
+ subDomainNodes.forEach((n) => {
285
+ nodes.set(n.id, nodes.has(n.id) ? merge(nodes.get(n.id), n) : n);
286
+ });
287
+
288
+ subDomainEdges.forEach((e) => edges.set(e.id, e));
289
+ }
290
+
291
+ // Add group node to the graph first before calculating positions
292
+ if (group) {
293
+ // Update the data of the node to add the group name and color
294
+ nodes.forEach((n) => {
295
+ nodes.set(n.id, { ...n, data: { ...n.data, group: { type: 'Domain', value: domain?.data.name, id: domain?.data.id } } });
296
+ });
297
+ }
298
+
270
299
  return {
271
300
  nodes: calculatedNodes(flow, Array.from(nodes.values())),
272
301
  edges: [...edges.values()],
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": "2.33.11",
9
+ "version": "2.34.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },