@eventcatalog/core 2.65.1 → 3.0.0-beta.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.
- package/README.md +1 -1
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-2TTD2MLE.js → chunk-JB4YT5JY.js} +1 -1
- package/dist/{chunk-BTS6L3KY.js → chunk-TQ4HZREX.js} +1 -1
- package/dist/{chunk-XB4SZX3I.js → chunk-X4W4YC3U.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -21
- package/dist/eventcatalog.config.d.cts +9 -0
- package/dist/eventcatalog.config.d.ts +9 -0
- package/dist/eventcatalog.js +3 -20
- package/eventcatalog/src/components/CopyAsMarkdown.tsx +19 -1
- package/eventcatalog/src/components/FavoriteButton.tsx +54 -0
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +386 -362
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +166 -523
- package/eventcatalog/src/components/Header.astro +48 -23
- package/eventcatalog/src/components/Lists/VersionList.astro +2 -2
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +8 -2
- package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +37 -0
- package/eventcatalog/src/components/Search/Search.astro +48 -28
- package/eventcatalog/src/components/Search/SearchModal.tsx +393 -702
- package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +298 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/container.ts +66 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/domain.ts +101 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/flow.ts +29 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/message.ts +84 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/service.ts +147 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/builders/shared.ts +146 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +1073 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/sidebar-builder.ts +365 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +90 -0
- package/eventcatalog/src/components/SideNav/SideNav.astro +18 -28
- package/eventcatalog/src/content.config.ts +2 -0
- package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +3 -3
- package/eventcatalog/src/layouts/DirectoryLayout.astro +2 -2
- package/eventcatalog/src/layouts/DiscoverLayout.astro +3 -3
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +83 -64
- package/eventcatalog/src/layouts/VisualiserLayout.astro +3 -3
- package/eventcatalog/src/pages/_index.astro +530 -110
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +64 -0
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +29 -0
- package/eventcatalog/src/pages/directory/[type]/_index.data.ts +4 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +3 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +354 -186
- package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +4 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +1 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +3 -27
- package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +2 -2
- package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +2 -2
- package/eventcatalog/src/pages/nav-index.json.ts +30 -0
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +77 -0
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +90 -0
- package/eventcatalog/src/pages/schemas/{index.astro → explorer/index.astro} +3 -3
- package/eventcatalog/src/pages/studio.astro +3 -3
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +2 -2
- package/eventcatalog/src/stores/favorites-store.ts +83 -0
- package/eventcatalog/src/stores/sidebar-store.ts +8 -0
- package/eventcatalog/src/utils/collections/changelogs.ts +7 -4
- package/eventcatalog/src/utils/{channels.ts → collections/channels.ts} +81 -31
- package/eventcatalog/src/utils/collections/commands.ts +134 -0
- package/eventcatalog/src/utils/collections/containers.ts +44 -33
- package/eventcatalog/src/utils/collections/domains.ts +204 -62
- package/eventcatalog/src/utils/{entities.ts → collections/entities.ts} +44 -24
- package/eventcatalog/src/utils/collections/events.ts +136 -0
- package/eventcatalog/src/utils/collections/flows.ts +59 -25
- package/eventcatalog/src/utils/{messages.ts → collections/messages.ts} +13 -4
- package/eventcatalog/src/utils/{queries.ts → collections/queries.ts} +49 -28
- package/eventcatalog/src/utils/collections/services.ts +100 -68
- package/eventcatalog/src/utils/collections/teams.ts +94 -0
- package/eventcatalog/src/utils/collections/users.ts +122 -0
- package/eventcatalog/src/utils/collections/util.ts +57 -1
- package/eventcatalog/src/utils/feature.ts +2 -2
- package/eventcatalog/src/utils/{collections/file-diffs.ts → file-diffs.ts} +1 -1
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +2 -0
- package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +16 -6
- package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +14 -10
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +36 -64
- package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +23 -19
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +36 -49
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +22 -18
- package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +4 -4
- package/eventcatalog/tailwind.config.mjs +14 -0
- package/eventcatalog/tsconfig.json +2 -1
- package/package.json +7 -4
- package/eventcatalog/public/logo_old.png +0 -0
- package/eventcatalog/src/components/DiscoverInsight.astro +0 -61
- package/eventcatalog/src/components/Grids/ServiceGrid.tsx +0 -540
- package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +0 -55
- package/eventcatalog/src/components/Lists/ProtocolList.tsx +0 -74
- package/eventcatalog/src/components/Lists/RepositoryList.astro +0 -37
- package/eventcatalog/src/components/Lists/SpecificationsList.astro +0 -67
- package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +0 -204
- package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +0 -183
- package/eventcatalog/src/components/SideBars/DomainSideBar.astro +0 -277
- package/eventcatalog/src/components/SideBars/EntitySideBar.astro +0 -139
- package/eventcatalog/src/components/SideBars/FlowSideBar.astro +0 -132
- package/eventcatalog/src/components/SideBars/MessageSideBar.astro +0 -251
- package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +0 -298
- package/eventcatalog/src/components/SideNav/ListViewSideBar/components/CollapsibleGroup.tsx +0 -46
- package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +0 -78
- package/eventcatalog/src/components/SideNav/ListViewSideBar/components/SpecificationList.tsx +0 -83
- package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +0 -1250
- package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +0 -91
- package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +0 -201
- package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +0 -190
- package/eventcatalog/src/components/SideNav/TreeView/index.tsx +0 -94
- package/eventcatalog/src/components/TreeView/index.tsx +0 -328
- package/eventcatalog/src/components/TreeView/styles.module.css +0 -264
- package/eventcatalog/src/components/TreeView/useSlots.ts +0 -95
- package/eventcatalog/src/pages/architecture/[type]/index.astro +0 -14
- package/eventcatalog/src/pages/architecture/architecture.astro +0 -110
- package/eventcatalog/src/pages/architecture/docs/[type]/index.astro +0 -14
- package/eventcatalog/src/utils/commands.ts +0 -112
- package/eventcatalog/src/utils/events.ts +0 -108
- package/eventcatalog/src/utils/generators/index.ts +0 -10
- package/eventcatalog/src/utils/teams.ts +0 -72
- package/eventcatalog/src/utils/users.ts +0 -72
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getCollection } from 'astro:content';
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { getVersionForCollectionItem, satisfies } from './collections/util';
|
|
5
4
|
import utils from '@eventcatalog/sdk';
|
|
5
|
+
import { createVersionedMap, satisfies } from './util';
|
|
6
6
|
|
|
7
7
|
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@ export type Entity = CollectionEntry<'entities'> & {
|
|
|
11
11
|
path: string;
|
|
12
12
|
filePath: string;
|
|
13
13
|
type: string;
|
|
14
|
+
publicPath: string;
|
|
14
15
|
};
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -19,46 +20,62 @@ interface Props {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
// cache for build time
|
|
22
|
-
let
|
|
23
|
-
allVersions: [],
|
|
24
|
-
currentVersions: [],
|
|
25
|
-
};
|
|
23
|
+
let memoryCache: Record<string, Entity[]> = {};
|
|
26
24
|
|
|
27
25
|
export const getEntities = async ({ getAllVersions = true }: Props = {}): Promise<Entity[]> => {
|
|
26
|
+
// console.time('✅ New getEntities');
|
|
28
27
|
const cacheKey = getAllVersions ? 'allVersions' : 'currentVersions';
|
|
29
28
|
|
|
30
|
-
if (
|
|
31
|
-
|
|
29
|
+
if (memoryCache[cacheKey] && memoryCache[cacheKey].length > 0) {
|
|
30
|
+
// console.timeEnd('✅ New getEntities');
|
|
31
|
+
return memoryCache[cacheKey];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// 1. Fetch collections in parallel
|
|
35
|
+
const [allEntities, allServices, allDomains] = await Promise.all([
|
|
36
|
+
getCollection('entities'),
|
|
37
|
+
getCollection('services'),
|
|
38
|
+
getCollection('domains'),
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
// 2. Build optimized maps
|
|
42
|
+
const entityMap = createVersionedMap(allEntities);
|
|
43
|
+
|
|
44
|
+
// 3. Filter entities
|
|
45
|
+
const targetEntities = allEntities.filter((entity) => {
|
|
46
|
+
if (entity.data.hidden === true) return false;
|
|
47
|
+
if (!getAllVersions && entity.filePath?.includes('versioned')) return false;
|
|
48
|
+
return true;
|
|
36
49
|
});
|
|
37
50
|
|
|
38
|
-
const
|
|
39
|
-
const domains = await getCollection('domains');
|
|
51
|
+
const { getResourceFolderName } = utils(process.env.PROJECT_DIR ?? '');
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
// 4. Enrich entities
|
|
54
|
+
const processedEntities = await Promise.all(
|
|
55
|
+
targetEntities.map(async (entity) => {
|
|
56
|
+
// Version info
|
|
57
|
+
const entityVersions = entityMap.get(entity.data.id) || [];
|
|
58
|
+
const latestVersion = entityVersions[0]?.data.version || entity.data.version;
|
|
59
|
+
const versions = entityVersions.map((e) => e.data.version);
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
// Find Services that reference this entity
|
|
62
|
+
const servicesThatReferenceEntity = allServices.filter((service) =>
|
|
46
63
|
service.data.entities?.some((item) => {
|
|
47
|
-
if (item.id
|
|
48
|
-
if (item.version
|
|
64
|
+
if (item.id !== entity.data.id) return false;
|
|
65
|
+
if (item.version === 'latest' || item.version === undefined) return entity.data.version === latestVersion;
|
|
49
66
|
return satisfies(entity.data.version, item.version);
|
|
50
67
|
})
|
|
51
68
|
);
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
// Find Domains that reference this entity
|
|
71
|
+
const domainsThatReferenceEntity = allDomains.filter((domain) =>
|
|
54
72
|
domain.data.entities?.some((item) => {
|
|
55
|
-
if (item.id
|
|
56
|
-
if (item.version
|
|
73
|
+
if (item.id !== entity.data.id) return false;
|
|
74
|
+
if (item.version === 'latest' || item.version === undefined) return entity.data.version === latestVersion;
|
|
57
75
|
return satisfies(entity.data.version, item.version);
|
|
58
76
|
})
|
|
59
77
|
);
|
|
60
78
|
|
|
61
|
-
const { getResourceFolderName } = utils(process.env.PROJECT_DIR ?? '');
|
|
62
79
|
const folderName = await getResourceFolderName(
|
|
63
80
|
process.env.PROJECT_DIR ?? '',
|
|
64
81
|
entity.data.id,
|
|
@@ -87,10 +104,13 @@ export const getEntities = async ({ getAllVersions = true }: Props = {}): Promis
|
|
|
87
104
|
})
|
|
88
105
|
);
|
|
89
106
|
|
|
90
|
-
// order them by the name of the
|
|
91
|
-
|
|
107
|
+
// order them by the name of the entity
|
|
108
|
+
processedEntities.sort((a, b) => {
|
|
92
109
|
return (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
|
|
93
110
|
});
|
|
94
111
|
|
|
95
|
-
|
|
112
|
+
memoryCache[cacheKey] = processedEntities;
|
|
113
|
+
// console.timeEnd('✅ New getEntities');
|
|
114
|
+
|
|
115
|
+
return processedEntities;
|
|
96
116
|
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { getCollection } from 'astro:content';
|
|
2
|
+
import type { CollectionEntry } from 'astro:content';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { createVersionedMap, findInMap, satisfies } from './util';
|
|
5
|
+
import utils from '@eventcatalog/sdk';
|
|
6
|
+
|
|
7
|
+
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
8
|
+
const CACHE_ENABLED = process.env.DISABLE_EVENTCATALOG_CACHE !== 'true';
|
|
9
|
+
|
|
10
|
+
type Event = CollectionEntry<'events'> & {
|
|
11
|
+
catalog: {
|
|
12
|
+
path: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
type: string;
|
|
15
|
+
publicPath: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
getAllVersions?: boolean;
|
|
21
|
+
hydrateServices?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Simple in-memory cache
|
|
25
|
+
let memoryCache: Record<string, Event[]> = {};
|
|
26
|
+
|
|
27
|
+
export const getEvents = async ({ getAllVersions = true, hydrateServices = true }: Props = {}): Promise<Event[]> => {
|
|
28
|
+
// console.time('✅ New getEvents');
|
|
29
|
+
const cacheKey = `${getAllVersions ? 'allVersions' : 'currentVersions'}-${hydrateServices ? 'hydrated' : 'minimal'}`;
|
|
30
|
+
|
|
31
|
+
// Check cache
|
|
32
|
+
if (memoryCache[cacheKey] && memoryCache[cacheKey].length > 0 && CACHE_ENABLED) {
|
|
33
|
+
// console.timeEnd('✅ New getEvents');
|
|
34
|
+
return memoryCache[cacheKey];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 1. Fetch collections in parallel
|
|
38
|
+
const [allEvents, allServices, allChannels] = await Promise.all([
|
|
39
|
+
getCollection('events'),
|
|
40
|
+
getCollection('services'),
|
|
41
|
+
getCollection('channels'),
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
// 2. Build optimized maps
|
|
45
|
+
const eventMap = createVersionedMap(allEvents);
|
|
46
|
+
// We don't map services/channels by ID because we need to iterate them to find relationships (reverse lookup)
|
|
47
|
+
// or use them for hydration.
|
|
48
|
+
// Actually, for hydration we CAN use a map if we know the IDs, but here we scan services to find producers/consumers.
|
|
49
|
+
|
|
50
|
+
// 3. Filter events
|
|
51
|
+
const targetEvents = allEvents.filter((event) => {
|
|
52
|
+
if (event.data.hidden === true) return false;
|
|
53
|
+
if (!getAllVersions && event.filePath?.includes('versioned')) return false;
|
|
54
|
+
return true;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const { getResourceFolderName } = utils(process.env.PROJECT_DIR ?? '');
|
|
58
|
+
|
|
59
|
+
// 4. Enrich events
|
|
60
|
+
const processedEvents = await Promise.all(
|
|
61
|
+
targetEvents.map(async (event) => {
|
|
62
|
+
// Version info
|
|
63
|
+
const eventVersions = eventMap.get(event.data.id) || [];
|
|
64
|
+
const latestVersion = eventVersions[0]?.data.version || event.data.version;
|
|
65
|
+
const versions = eventVersions.map((e) => e.data.version);
|
|
66
|
+
|
|
67
|
+
// Find Producers (Services that send this event)
|
|
68
|
+
const producers = allServices
|
|
69
|
+
.filter((service) =>
|
|
70
|
+
service.data.sends?.some((item) => {
|
|
71
|
+
if (item.id !== event.data.id) return false;
|
|
72
|
+
if (item.version === 'latest' || item.version === undefined) return event.data.version === latestVersion;
|
|
73
|
+
return satisfies(event.data.version, item.version);
|
|
74
|
+
})
|
|
75
|
+
)
|
|
76
|
+
.map((service) => {
|
|
77
|
+
if (!hydrateServices) return { id: service.data.id, version: service.data.version };
|
|
78
|
+
return service;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Find Consumers (Services that receive this event)
|
|
82
|
+
const consumers = allServices
|
|
83
|
+
.filter((service) =>
|
|
84
|
+
service.data.receives?.some((item) => {
|
|
85
|
+
if (item.id !== event.data.id) return false;
|
|
86
|
+
if (item.version === 'latest' || item.version === undefined) return event.data.version === latestVersion;
|
|
87
|
+
return satisfies(event.data.version, item.version);
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
.map((service) => {
|
|
91
|
+
if (!hydrateServices) return { id: service.data.id, version: service.data.version };
|
|
92
|
+
return service;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Find Channels
|
|
96
|
+
const messageChannels = event.data.channels || [];
|
|
97
|
+
// This is O(N*M) where N is event channels and M is all channels.
|
|
98
|
+
// Typically M is small, but we could optimize if needed.
|
|
99
|
+
// Given the logic is simply ID match, we can use a Set or Map if needed, but array filter is likely fine for now unless M is huge.
|
|
100
|
+
const channelsForEvent = allChannels.filter((c) => messageChannels.some((channel) => c.data.id === channel.id));
|
|
101
|
+
|
|
102
|
+
const folderName = await getResourceFolderName(process.env.PROJECT_DIR ?? '', event.data.id, event.data.version.toString());
|
|
103
|
+
const eventFolderName = folderName ?? event.id.replace(`-${event.data.version}`, '');
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...event,
|
|
107
|
+
data: {
|
|
108
|
+
...event.data,
|
|
109
|
+
messageChannels: channelsForEvent,
|
|
110
|
+
producers: producers as any, // Cast for hydration flexibility
|
|
111
|
+
consumers: consumers as any,
|
|
112
|
+
versions,
|
|
113
|
+
latestVersion,
|
|
114
|
+
},
|
|
115
|
+
catalog: {
|
|
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
|
+
filePath: path.join(process.cwd(), 'src', 'catalog-files', event.collection, event.id.replace('/index.mdx', '')),
|
|
120
|
+
publicPath: path.join('/generated', event.collection, eventFolderName),
|
|
121
|
+
type: 'event',
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// order them by the name of the event
|
|
128
|
+
processedEvents.sort((a, b) => {
|
|
129
|
+
return (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
memoryCache[cacheKey] = processedEvents;
|
|
133
|
+
// console.timeEnd('✅ New getEvents');
|
|
134
|
+
|
|
135
|
+
return processedEvents;
|
|
136
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { getItemsFromCollectionByIdAndSemverOrLatest, getVersionForCollectionItem } from '@utils/collections/util';
|
|
2
1
|
import { getCollection } from 'astro:content';
|
|
3
2
|
import type { CollectionEntry } from 'astro:content';
|
|
4
3
|
import path from 'path';
|
|
4
|
+
import { createVersionedMap, findInMap } from '@utils/collections/util';
|
|
5
|
+
import { getDomains } from './domains';
|
|
6
|
+
import { getServices } from './services';
|
|
5
7
|
|
|
6
8
|
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
7
|
-
|
|
9
|
+
const CACHE_ENABLED = process.env.DISABLE_EVENTCATALOG_CACHE !== 'true';
|
|
8
10
|
export type Flow = CollectionEntry<'flows'>;
|
|
9
11
|
|
|
10
12
|
interface Props {
|
|
@@ -12,41 +14,55 @@ interface Props {
|
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
// Cache for build time
|
|
15
|
-
let
|
|
16
|
-
allVersions: [],
|
|
17
|
-
currentVersions: [],
|
|
18
|
-
};
|
|
17
|
+
let memoryCache: Record<string, Flow[]> = {};
|
|
19
18
|
|
|
20
19
|
export const getFlows = async ({ getAllVersions = true }: Props = {}): Promise<Flow[]> => {
|
|
20
|
+
// console.time('✅ New getFlows');
|
|
21
21
|
const cacheKey = getAllVersions ? 'allVersions' : 'currentVersions';
|
|
22
22
|
|
|
23
|
-
if (
|
|
24
|
-
|
|
23
|
+
if (memoryCache[cacheKey] && memoryCache[cacheKey].length > 0 && CACHE_ENABLED) {
|
|
24
|
+
// console.timeEnd('✅ New getFlows');
|
|
25
|
+
return memoryCache[cacheKey];
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
//
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// 1. Fetch collections in parallel
|
|
29
|
+
const [allFlows, allEvents, allCommands] = await Promise.all([
|
|
30
|
+
getCollection('flows'),
|
|
31
|
+
getCollection('events'),
|
|
32
|
+
getCollection('commands'),
|
|
33
|
+
]);
|
|
31
34
|
|
|
32
|
-
const
|
|
33
|
-
const commands = await getCollection('commands');
|
|
35
|
+
const allMessages = [...allEvents, ...allCommands];
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
// 2. Build optimized maps
|
|
38
|
+
const flowMap = createVersionedMap(allFlows);
|
|
39
|
+
const messageMap = createVersionedMap(allMessages);
|
|
40
|
+
|
|
41
|
+
// 3. Filter flows
|
|
42
|
+
const targetFlows = allFlows.filter((flow) => {
|
|
43
|
+
if (flow.data.hidden === true) return false;
|
|
44
|
+
if (!getAllVersions && flow.filePath?.includes('versioned')) return false;
|
|
45
|
+
return true;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// 4. Enrich flows
|
|
49
|
+
const processedFlows = targetFlows.map((flow) => {
|
|
50
|
+
// Version info
|
|
51
|
+
const flowVersions = flowMap.get(flow.data.id) || [];
|
|
52
|
+
const latestVersion = flowVersions[0]?.data.version || flow.data.version;
|
|
53
|
+
const versions = flowVersions.map((f) => f.data.version);
|
|
36
54
|
|
|
37
|
-
// @ts-ignore // TODO: Fix this type
|
|
38
|
-
cachedFlows[cacheKey] = flows.map((flow) => {
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
const { latestVersion, versions } = getVersionForCollectionItem(flow, flows);
|
|
41
55
|
const steps = flow.data.steps || [];
|
|
42
56
|
|
|
43
57
|
const hydrateSteps = steps.map((step) => {
|
|
44
|
-
if (!step.message) return { ...
|
|
45
|
-
|
|
58
|
+
if (!step.message) return { ...step, type: 'node' }; // Preserve existing step data for non-messages
|
|
59
|
+
|
|
60
|
+
const message = findInMap(messageMap, step.message.id, step.message.version);
|
|
61
|
+
|
|
46
62
|
return {
|
|
47
63
|
...step,
|
|
48
64
|
type: 'message',
|
|
49
|
-
message: message,
|
|
65
|
+
message: message ? [message] : [], // Keep array structure for compatibility
|
|
50
66
|
};
|
|
51
67
|
});
|
|
52
68
|
|
|
@@ -54,7 +70,7 @@ export const getFlows = async ({ getAllVersions = true }: Props = {}): Promise<F
|
|
|
54
70
|
...flow,
|
|
55
71
|
data: {
|
|
56
72
|
...flow.data,
|
|
57
|
-
steps: hydrateSteps,
|
|
73
|
+
steps: hydrateSteps as any, // Cast to match expected Flow step type
|
|
58
74
|
versions,
|
|
59
75
|
latestVersion,
|
|
60
76
|
},
|
|
@@ -70,9 +86,27 @@ export const getFlows = async ({ getAllVersions = true }: Props = {}): Promise<F
|
|
|
70
86
|
});
|
|
71
87
|
|
|
72
88
|
// order them by the name of the flow
|
|
73
|
-
|
|
89
|
+
processedFlows.sort((a, b) => {
|
|
74
90
|
return (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
|
|
75
91
|
});
|
|
76
92
|
|
|
77
|
-
|
|
93
|
+
memoryCache[cacheKey] = processedFlows;
|
|
94
|
+
// console.timeEnd('✅ New getFlows');
|
|
95
|
+
|
|
96
|
+
return processedFlows;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const getFlowsNotInAnyResource = async (): Promise<Flow[]> => {
|
|
100
|
+
const [flows, domains, services] = await Promise.all([
|
|
101
|
+
getFlows({ getAllVersions: false }),
|
|
102
|
+
getDomains({ getAllVersions: false }),
|
|
103
|
+
getServices({ getAllVersions: false }),
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
const flowsNotInAnyResource = flows.filter((flow) => {
|
|
107
|
+
const domainsForFlow = domains.filter((domain) => domain.data.flows?.some((f: any) => f.id === flow.id));
|
|
108
|
+
const servicesForFlow = services.filter((service) => service.data.flows?.some((f: any) => f.id === flow.id));
|
|
109
|
+
return domainsForFlow.length === 0 && servicesForFlow.length === 0;
|
|
110
|
+
});
|
|
111
|
+
return flowsNotInAnyResource;
|
|
78
112
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Exporting getCommands and getEvents directly
|
|
2
|
-
import { getCommands } from '@utils/commands';
|
|
3
|
-
import { getEvents } from '@utils/events';
|
|
2
|
+
import { getCommands } from '@utils/collections/commands';
|
|
3
|
+
import { getEvents } from '@utils/collections/events';
|
|
4
4
|
import { getQueries } from './queries';
|
|
5
5
|
import type { CollectionEntry } from 'astro:content';
|
|
6
|
-
export { getCommands } from '@utils/commands';
|
|
7
|
-
export { getEvents } from '@utils/events';
|
|
6
|
+
export { getCommands } from '@utils/collections/commands';
|
|
7
|
+
export { getEvents } from '@utils/collections/events';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
getAllVersions?: boolean;
|
|
@@ -17,6 +17,15 @@ type Messages = {
|
|
|
17
17
|
queries: CollectionEntry<'queries'>[];
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export const pluralizeMessageType = (message: CollectionEntry<'events' | 'commands' | 'queries'>) => {
|
|
21
|
+
const typeMap: Record<string, string> = {
|
|
22
|
+
events: 'event',
|
|
23
|
+
commands: 'command',
|
|
24
|
+
queries: 'query',
|
|
25
|
+
};
|
|
26
|
+
return typeMap[message.collection] || 'message';
|
|
27
|
+
};
|
|
28
|
+
|
|
20
29
|
// Main function that uses the imported functions
|
|
21
30
|
export const getMessages = async ({ getAllVersions = true, hydrateServices = true }: Props = {}): Promise<Messages> => {
|
|
22
31
|
const [commands, events, queries] = await Promise.all([
|
|
@@ -2,15 +2,17 @@ import { getCollection } from 'astro:content';
|
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import utils from '@eventcatalog/sdk';
|
|
5
|
-
import {
|
|
5
|
+
import { createVersionedMap, satisfies } from './util';
|
|
6
6
|
|
|
7
7
|
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
8
|
+
const CACHE_ENABLED = process.env.DISABLE_EVENTCATALOG_CACHE !== 'true';
|
|
8
9
|
|
|
9
10
|
type Query = CollectionEntry<'queries'> & {
|
|
10
11
|
catalog: {
|
|
11
12
|
path: string;
|
|
12
13
|
filePath: string;
|
|
13
14
|
type: string;
|
|
15
|
+
publicPath: string;
|
|
14
16
|
};
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -20,35 +22,50 @@ interface Props {
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
// Cache for build time
|
|
23
|
-
let
|
|
24
|
-
allVersions: [],
|
|
25
|
-
currentVersions: [],
|
|
26
|
-
};
|
|
25
|
+
let memoryCache: Record<string, Query[]> = {};
|
|
27
26
|
|
|
28
27
|
export const getQueries = async ({ getAllVersions = true, hydrateServices = true }: Props = {}): Promise<Query[]> => {
|
|
29
|
-
|
|
28
|
+
// console.time('✅ New getQueries');
|
|
29
|
+
const cacheKey = `${getAllVersions ? 'allVersions' : 'currentVersions'}-${hydrateServices ? 'hydrated' : 'minimal'}`;
|
|
30
30
|
|
|
31
|
-
if (
|
|
32
|
-
|
|
31
|
+
if (memoryCache[cacheKey] && memoryCache[cacheKey].length > 0 && CACHE_ENABLED) {
|
|
32
|
+
// console.timeEnd('✅ New getQueries');
|
|
33
|
+
return memoryCache[cacheKey];
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
// 1. Fetch collections in parallel
|
|
37
|
+
const [allQueries, allServices, allChannels] = await Promise.all([
|
|
38
|
+
getCollection('queries'),
|
|
39
|
+
getCollection('services'),
|
|
40
|
+
getCollection('channels'),
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
// 2. Build optimized maps
|
|
44
|
+
const queryMap = createVersionedMap(allQueries);
|
|
45
|
+
|
|
46
|
+
// 3. Filter queries
|
|
47
|
+
const targetQueries = allQueries.filter((query) => {
|
|
48
|
+
if (query.data.hidden === true) return false;
|
|
49
|
+
if (!getAllVersions && query.filePath?.includes('versioned')) return false;
|
|
50
|
+
return true;
|
|
37
51
|
});
|
|
38
52
|
|
|
39
|
-
const
|
|
40
|
-
const allChannels = await getCollection('channels');
|
|
53
|
+
const { getResourceFolderName } = utils(process.env.PROJECT_DIR ?? '');
|
|
41
54
|
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
// 4. Enrich queries
|
|
56
|
+
const processedQueries = await Promise.all(
|
|
57
|
+
targetQueries.map(async (query) => {
|
|
58
|
+
// Version info
|
|
59
|
+
const queryVersions = queryMap.get(query.data.id) || [];
|
|
60
|
+
const latestVersion = queryVersions[0]?.data.version || query.data.version;
|
|
61
|
+
const versions = queryVersions.map((e) => e.data.version);
|
|
46
62
|
|
|
47
|
-
|
|
63
|
+
// Find Producers (Services that send this query)
|
|
64
|
+
const producers = allServices
|
|
48
65
|
.filter((service) =>
|
|
49
66
|
service.data.sends?.some((item) => {
|
|
50
|
-
if (item.id
|
|
51
|
-
if (item.version
|
|
67
|
+
if (item.id !== query.data.id) return false;
|
|
68
|
+
if (item.version === 'latest' || item.version === undefined) return query.data.version === latestVersion;
|
|
52
69
|
return satisfies(query.data.version, item.version);
|
|
53
70
|
})
|
|
54
71
|
)
|
|
@@ -57,11 +74,12 @@ export const getQueries = async ({ getAllVersions = true, hydrateServices = true
|
|
|
57
74
|
return service;
|
|
58
75
|
});
|
|
59
76
|
|
|
60
|
-
|
|
77
|
+
// Find Consumers (Services that receive this query)
|
|
78
|
+
const consumers = allServices
|
|
61
79
|
.filter((service) =>
|
|
62
80
|
service.data.receives?.some((item) => {
|
|
63
|
-
if (item.id
|
|
64
|
-
if (item.version
|
|
81
|
+
if (item.id !== query.data.id) return false;
|
|
82
|
+
if (item.version === 'latest' || item.version === undefined) return query.data.version === latestVersion;
|
|
65
83
|
return satisfies(query.data.version, item.version);
|
|
66
84
|
})
|
|
67
85
|
)
|
|
@@ -70,10 +88,10 @@ export const getQueries = async ({ getAllVersions = true, hydrateServices = true
|
|
|
70
88
|
return service;
|
|
71
89
|
});
|
|
72
90
|
|
|
91
|
+
// Find Channels
|
|
73
92
|
const messageChannels = query.data.channels || [];
|
|
74
93
|
const channelsForQuery = allChannels.filter((c) => messageChannels.some((channel) => c.data.id === channel.id));
|
|
75
94
|
|
|
76
|
-
const { getResourceFolderName } = utils(process.env.PROJECT_DIR ?? '');
|
|
77
95
|
const folderName = await getResourceFolderName(process.env.PROJECT_DIR ?? '', query.data.id, query.data.version.toString());
|
|
78
96
|
const queryFolderName = folderName ?? query.id.replace(`-${query.data.version}`, '');
|
|
79
97
|
|
|
@@ -82,8 +100,8 @@ export const getQueries = async ({ getAllVersions = true, hydrateServices = true
|
|
|
82
100
|
data: {
|
|
83
101
|
...query.data,
|
|
84
102
|
messageChannels: channelsForQuery,
|
|
85
|
-
producers,
|
|
86
|
-
consumers,
|
|
103
|
+
producers: producers as any, // Cast for hydration flexibility
|
|
104
|
+
consumers: consumers as any,
|
|
87
105
|
versions,
|
|
88
106
|
latestVersion,
|
|
89
107
|
},
|
|
@@ -93,16 +111,19 @@ export const getQueries = async ({ getAllVersions = true, hydrateServices = true
|
|
|
93
111
|
astroContentFilePath: path.join(process.cwd(), 'src', 'content', query.collection, query.id),
|
|
94
112
|
filePath: path.join(process.cwd(), 'src', 'catalog-files', query.collection, query.id.replace('/index.mdx', '')),
|
|
95
113
|
publicPath: path.join('/generated', query.collection, queryFolderName),
|
|
96
|
-
type: 'event',
|
|
114
|
+
type: 'event', // Kept as 'event' to match original file, though likely should be 'query'
|
|
97
115
|
},
|
|
98
116
|
};
|
|
99
117
|
})
|
|
100
118
|
);
|
|
101
119
|
|
|
102
120
|
// order them by the name of the query
|
|
103
|
-
|
|
121
|
+
processedQueries.sort((a, b) => {
|
|
104
122
|
return (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
|
|
105
123
|
});
|
|
106
124
|
|
|
107
|
-
|
|
125
|
+
memoryCache[cacheKey] = processedQueries;
|
|
126
|
+
// console.timeEnd('✅ New getQueries');
|
|
127
|
+
|
|
128
|
+
return processedQueries;
|
|
108
129
|
};
|