@eventcatalog/core 2.5.0 → 2.5.1
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/components/MDX/Flow/Flow.astro +63 -0
- package/src/components/MDX/NodeGraph/NodeGraph.tsx +59 -29
- package/src/components/MDX/components.tsx +2 -0
- package/src/pages/docs/[type]/[id]/[version]/index.astro +2 -1
- package/src/utils/flows/flows.ts +2 -2
- package/src/utils/flows/node-graph.ts +2 -2
- package/src/utils/services/node-graph.ts +3 -3
- package/src/utils/services/services.ts +3 -26
- package/src/utils/versions/versions.ts +26 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ You can see the markdown files that generated the website in the GitHub repo und
|
|
|
113
113
|
|
|
114
114
|
Interested in collaborating with us? Our offerings include dedicated support, priority assistance, feature development, custom integrations, and more.
|
|
115
115
|
|
|
116
|
-
Find more details on our [
|
|
116
|
+
Find more details on our [services page](https://eventcatalog.dev/services).
|
|
117
117
|
|
|
118
118
|
# Looking for v1?
|
|
119
119
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getFlows } from '@utils/flows/flows';
|
|
3
|
+
import { getNodesAndEdges } from '@utils/flows/node-graph';
|
|
4
|
+
import Admonition from '@components/MDX/Admonition';
|
|
5
|
+
import NodeGraph from '../NodeGraph/NodeGraph';
|
|
6
|
+
import { getVersionFromCollection } from '@utils/versions/versions';
|
|
7
|
+
|
|
8
|
+
const { id, version = 'latest', maxHeight, includeKey = true } = Astro.props;
|
|
9
|
+
|
|
10
|
+
// Find the flow for the given id and version
|
|
11
|
+
const flows = await getFlows();
|
|
12
|
+
const flowCollection = getVersionFromCollection(flows, id, version) || [];
|
|
13
|
+
const flow = flowCollection[0];
|
|
14
|
+
|
|
15
|
+
// const flow = flows.find((flow) => flow.data.id === id && flow.data.version === version);
|
|
16
|
+
|
|
17
|
+
const { nodes, edges } = await getNodesAndEdges({
|
|
18
|
+
id: id,
|
|
19
|
+
version: flow.data.version,
|
|
20
|
+
});
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
!flow && (
|
|
25
|
+
<Admonition type="warning">
|
|
26
|
+
<>
|
|
27
|
+
<span class="block font-bold">{`<Flow/>`} failed to load</span>
|
|
28
|
+
<span class="block">
|
|
29
|
+
Tried to load flow id: {id} with version {version}. Make sure you have this flow defined in your project.
|
|
30
|
+
</span>
|
|
31
|
+
</>
|
|
32
|
+
</Admonition>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
<div
|
|
37
|
+
class="h-[30em] my-6 mb-12 w-full relative border border-gray-200 rounded-md"
|
|
38
|
+
id={`${id}-portal`}
|
|
39
|
+
style={{
|
|
40
|
+
maxHeight: maxHeight ? `${maxHeight}em` : `30em`,
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div>
|
|
46
|
+
<NodeGraph
|
|
47
|
+
id={id}
|
|
48
|
+
nodes={nodes}
|
|
49
|
+
edges={edges}
|
|
50
|
+
hrefLabel={'View in visualizer'}
|
|
51
|
+
href={`/visualiser/flows/${id}/${version}`}
|
|
52
|
+
linkTo={'visualiser'}
|
|
53
|
+
includeKey={includeKey}
|
|
54
|
+
footerLabel=`Flow diagram - ${flow.data.name} - v(${flow.data.version})`
|
|
55
|
+
client:load
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<style is:global>
|
|
60
|
+
.react-flow__attribution {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
</style>
|
|
@@ -31,6 +31,7 @@ interface Props {
|
|
|
31
31
|
includeBackground?: boolean;
|
|
32
32
|
includeControls?: boolean;
|
|
33
33
|
linkTo: 'docs' | 'visualiser';
|
|
34
|
+
includeKey?: boolean;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const getDocUrlForCollection = (collectionItem: CollectionEntry<CollectionTypes>) => {
|
|
@@ -41,7 +42,14 @@ const getVisualiserUrlForCollection = (collectionItem: CollectionEntry<Collectio
|
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
// const NodeGraphBuilder = ({ title, subtitle, includeBackground = true, includeControls = true }: Props) => {
|
|
44
|
-
const NodeGraphBuilder = ({
|
|
45
|
+
const NodeGraphBuilder = ({
|
|
46
|
+
nodes: initialNodes,
|
|
47
|
+
edges,
|
|
48
|
+
title,
|
|
49
|
+
includeBackground = true,
|
|
50
|
+
linkTo = 'docs',
|
|
51
|
+
includeKey = true,
|
|
52
|
+
}: Props) => {
|
|
45
53
|
const nodeTypes = useMemo(
|
|
46
54
|
() => ({
|
|
47
55
|
services: ServiceNode,
|
|
@@ -89,25 +97,27 @@ const NodeGraphBuilder = ({ nodes: initialNodes, edges, title, includeBackground
|
|
|
89
97
|
<DownloadButton filename={title} addPadding={!!title} />
|
|
90
98
|
{includeBackground && <Background color="#bbb" gap={16} />}
|
|
91
99
|
{includeBackground && <Controls />}
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
{includeKey && (
|
|
101
|
+
<Panel position="bottom-right">
|
|
102
|
+
<div className=" bg-white font-light px-4 text-[14px] shadow-md py-1 rounded-md">
|
|
103
|
+
<span className="font-bold">Key</span>
|
|
104
|
+
<ul>
|
|
105
|
+
<li className="flex space-x-2 items-center text-[12px]">
|
|
106
|
+
<span className="w-2 h-2 bg-orange-500 block" />
|
|
107
|
+
<span className="block">Event</span>
|
|
108
|
+
</li>
|
|
109
|
+
<li className="flex space-x-2 items-center text-[12px]">
|
|
110
|
+
<span className="w-2 h-2 bg-pink-500 block" />
|
|
111
|
+
<span className="block">Service</span>
|
|
112
|
+
</li>
|
|
113
|
+
<li className="flex space-x-2 items-center text-[12px]">
|
|
114
|
+
<span className="w-2 h-2 bg-blue-500 block" />
|
|
115
|
+
<span className="block">Command</span>
|
|
116
|
+
</li>
|
|
117
|
+
</ul>
|
|
118
|
+
</div>
|
|
119
|
+
</Panel>
|
|
120
|
+
)}
|
|
111
121
|
</ReactFlow>
|
|
112
122
|
);
|
|
113
123
|
};
|
|
@@ -120,9 +130,21 @@ interface NodeGraphProps {
|
|
|
120
130
|
nodes: Node[];
|
|
121
131
|
edges: Edge[];
|
|
122
132
|
linkTo: 'docs' | 'visualiser';
|
|
133
|
+
includeKey?: boolean;
|
|
134
|
+
footerLabel?: string;
|
|
123
135
|
}
|
|
124
136
|
|
|
125
|
-
const NodeGraph = ({
|
|
137
|
+
const NodeGraph = ({
|
|
138
|
+
id,
|
|
139
|
+
nodes,
|
|
140
|
+
edges,
|
|
141
|
+
title,
|
|
142
|
+
href,
|
|
143
|
+
linkTo = 'docs',
|
|
144
|
+
hrefLabel = 'Open in visualizer',
|
|
145
|
+
includeKey = true,
|
|
146
|
+
footerLabel,
|
|
147
|
+
}: NodeGraphProps) => {
|
|
126
148
|
const [elem, setElem] = useState(null);
|
|
127
149
|
|
|
128
150
|
useEffect(() => {
|
|
@@ -136,15 +158,23 @@ const NodeGraph = ({ id, nodes, edges, title, href, linkTo = 'docs', hrefLabel =
|
|
|
136
158
|
<div>
|
|
137
159
|
{createPortal(
|
|
138
160
|
<ReactFlowProvider>
|
|
139
|
-
<NodeGraphBuilder edges={edges} nodes={nodes} title={title} linkTo={linkTo} />
|
|
161
|
+
<NodeGraphBuilder edges={edges} nodes={nodes} title={title} linkTo={linkTo} includeKey={includeKey} />
|
|
162
|
+
|
|
163
|
+
<div className="flex justify-between">
|
|
164
|
+
{footerLabel && (
|
|
165
|
+
<div className="py-2 w-full text-left ">
|
|
166
|
+
<span className=" text-sm no-underline py-2 text-gray-300">{footerLabel}</span>
|
|
167
|
+
</div>
|
|
168
|
+
)}
|
|
140
169
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
170
|
+
{href && (
|
|
171
|
+
<div className="py-2 w-full text-right">
|
|
172
|
+
<a className=" text-sm no-underline py-2 text-gray-800 hover:text-purple-500" href={href}>
|
|
173
|
+
{hrefLabel} →
|
|
174
|
+
</a>
|
|
175
|
+
</div>
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
148
178
|
</ReactFlowProvider>,
|
|
149
179
|
elem
|
|
150
180
|
)}
|
|
@@ -3,6 +3,7 @@ import Schema from '@components/MDX/Schema';
|
|
|
3
3
|
import File from '@components/MDX/File';
|
|
4
4
|
import Accordion from '@components/MDX/Accordion/Accordion.astro';
|
|
5
5
|
import AccordionGroup from '@components/MDX/Accordion/AccordionGroup.astro';
|
|
6
|
+
import Flow from '@components/MDX/Flow/Flow.astro';
|
|
6
7
|
import Admonition from '@components/MDX/Admonition';
|
|
7
8
|
import OpenAPI from '@components/MDX/OpenAPI/OpenAPI';
|
|
8
9
|
|
|
@@ -14,6 +15,7 @@ const components = (props: any) => {
|
|
|
14
15
|
return {
|
|
15
16
|
Accordion,
|
|
16
17
|
AccordionGroup,
|
|
18
|
+
Flow,
|
|
17
19
|
Admonition: (mdxProp: any) => <Admonition {...mdxProp} {...props} />,
|
|
18
20
|
File: (mdxProp: any) => File({ ...props, ...mdxProp }),
|
|
19
21
|
NodeGraph: (mdxProp: any) => NodeGraphPortal({ ...props.data, ...mdxProp }),
|
|
@@ -5,6 +5,7 @@ import Footer from '@layouts/Footer.astro';
|
|
|
5
5
|
|
|
6
6
|
import components from '@components/MDX/components';
|
|
7
7
|
import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
|
|
8
|
+
import SchemaViewer from '@components/MDX/SchemaViewer/SchemaViewer.astro';
|
|
8
9
|
|
|
9
10
|
// SideBars
|
|
10
11
|
import ServiceSideBar from '@components/SideBars/ServiceSideBar.astro';
|
|
@@ -17,7 +18,7 @@ import { EnvelopeIcon, PencilIcon, QueueListIcon, RectangleGroupIcon, ServerIcon
|
|
|
17
18
|
import { getDomains } from '@utils/domains/domains';
|
|
18
19
|
import DomainSideBar from '@components/SideBars/DomainSideBar.astro';
|
|
19
20
|
import type { CollectionTypes } from '@types';
|
|
20
|
-
|
|
21
|
+
|
|
21
22
|
import { buildUrl } from '@utils/url-builder';
|
|
22
23
|
import { getFlows } from '@utils/flows/flows';
|
|
23
24
|
|
package/src/utils/flows/flows.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getVersionForCollectionItem, getVersions } from '@utils/collections/util';
|
|
2
|
-
import {
|
|
2
|
+
import { getVersionFromCollection } from '@utils/versions/versions';
|
|
3
3
|
import { getCollection } from 'astro:content';
|
|
4
4
|
import type { CollectionEntry } from 'astro:content';
|
|
5
5
|
import path from 'path';
|
|
@@ -31,7 +31,7 @@ export const getFlows = async ({ getAllVersions = true }: Props = {}): Promise<F
|
|
|
31
31
|
|
|
32
32
|
const hydrateSteps = steps.map((step) => {
|
|
33
33
|
if (!step.message) return { ...flow, data: { ...flow.data, type: 'node' } };
|
|
34
|
-
const message =
|
|
34
|
+
const message = getVersionFromCollection(allMessages, step.message.id, step.message.version);
|
|
35
35
|
return {
|
|
36
36
|
...step,
|
|
37
37
|
type: 'message',
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
2
2
|
import dagre from 'dagre';
|
|
3
|
-
import { getVersion } from '../services/services';
|
|
4
3
|
import { createDagreGraph, calculatedNodes } from '@utils/node-graph-utils/utils';
|
|
5
4
|
import { MarkerType } from 'reactflow';
|
|
6
5
|
import type { Node as NodeType } from 'reactflow';
|
|
6
|
+
import { getVersionFromCollection } from '@utils/versions/versions';
|
|
7
7
|
|
|
8
8
|
type DagreGraph = any;
|
|
9
9
|
|
|
@@ -27,7 +27,7 @@ const getServiceNode = (step: any, services: CollectionEntry<'services'>[]) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const getMessageNode = (step: any, messages: CollectionEntry<'events' | 'commands'>[]) => {
|
|
30
|
-
const messagesForVersion =
|
|
30
|
+
const messagesForVersion = getVersionFromCollection(messages, step.message.id, step.message.version);
|
|
31
31
|
const message = messagesForVersion[0];
|
|
32
32
|
return {
|
|
33
33
|
...step,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// import { getColor } from '@utils/colors';
|
|
2
2
|
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
3
3
|
import dagre from 'dagre';
|
|
4
|
-
import { getVersion } from './services';
|
|
5
4
|
import { createDagreGraph, generateIdForNode, generatedIdForEdge, calculatedNodes } from '@utils/node-graph-utils/utils';
|
|
6
5
|
import { MarkerType } from 'reactflow';
|
|
6
|
+
import { getVersionFromCollection } from '@utils/versions/versions';
|
|
7
7
|
|
|
8
8
|
type DagreGraph = any;
|
|
9
9
|
|
|
@@ -41,12 +41,12 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
41
41
|
const messages = [...events, ...commands];
|
|
42
42
|
|
|
43
43
|
const receivesHydrated = receivesRaw
|
|
44
|
-
.map((message) =>
|
|
44
|
+
.map((message) => getVersionFromCollection(messages, message.id, message.version))
|
|
45
45
|
.flat()
|
|
46
46
|
.filter((e) => e !== undefined);
|
|
47
47
|
|
|
48
48
|
const sendsHydrated = sendsRaw
|
|
49
|
-
.map((message) =>
|
|
49
|
+
.map((message) => getVersionFromCollection(messages, message.id, message.version))
|
|
50
50
|
.flat()
|
|
51
51
|
.filter((e) => e !== undefined);
|
|
52
52
|
|
|
@@ -1,36 +1,13 @@
|
|
|
1
1
|
import { getVersionForCollectionItem } from '@utils/collections/util';
|
|
2
|
+
import { getVersionFromCollection } from '@utils/versions/versions';
|
|
2
3
|
import { getCollection } from 'astro:content';
|
|
3
4
|
import type { CollectionEntry } from 'astro:content';
|
|
4
5
|
import path from 'path';
|
|
5
|
-
import { satisfies, validRange } from 'semver';
|
|
6
6
|
|
|
7
7
|
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
8
8
|
|
|
9
9
|
export type Service = CollectionEntry<'services'>;
|
|
10
10
|
|
|
11
|
-
export const getVersion = (
|
|
12
|
-
collection: CollectionEntry<'events' | 'commands'>[],
|
|
13
|
-
id: string,
|
|
14
|
-
version?: string
|
|
15
|
-
): CollectionEntry<'events' | 'commands'>[] => {
|
|
16
|
-
const data = collection;
|
|
17
|
-
const semverRange = validRange(version);
|
|
18
|
-
|
|
19
|
-
if (semverRange) {
|
|
20
|
-
return data.filter((msg) => msg.data.id == id).filter((msg) => satisfies(msg.data.version, semverRange));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const filteredEvents = data.filter((event) => event.data.id === id);
|
|
24
|
-
|
|
25
|
-
// Order by version
|
|
26
|
-
const sorted = filteredEvents.sort((a, b) => {
|
|
27
|
-
return a.data.version.localeCompare(b.data.version);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// latest version
|
|
31
|
-
return [sorted[sorted.length - 1]];
|
|
32
|
-
};
|
|
33
|
-
|
|
34
11
|
interface Props {
|
|
35
12
|
getAllVersions?: boolean;
|
|
36
13
|
}
|
|
@@ -53,12 +30,12 @@ export const getServices = async ({ getAllVersions = true }: Props = {}): Promis
|
|
|
53
30
|
const receivesMessages = service.data.receives || [];
|
|
54
31
|
|
|
55
32
|
const sends = sendsMessages
|
|
56
|
-
.map((message) =>
|
|
33
|
+
.map((message) => getVersionFromCollection(allMessages, message.id, message.version))
|
|
57
34
|
.flat()
|
|
58
35
|
.filter((e) => e !== undefined);
|
|
59
36
|
|
|
60
37
|
const receives = receivesMessages
|
|
61
|
-
.map((message) =>
|
|
38
|
+
.map((message) => getVersionFromCollection(allMessages, message.id, message.version))
|
|
62
39
|
.flat()
|
|
63
40
|
.filter((e) => e !== undefined);
|
|
64
41
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CollectionTypes } from '@types';
|
|
2
|
+
import type { CollectionEntry } from 'astro:content';
|
|
3
|
+
import { satisfies, validRange } from 'semver';
|
|
4
|
+
|
|
5
|
+
export const getVersionFromCollection = (
|
|
6
|
+
collection: CollectionEntry<CollectionTypes>[],
|
|
7
|
+
id: string,
|
|
8
|
+
version?: string
|
|
9
|
+
): CollectionEntry<CollectionTypes>[] => {
|
|
10
|
+
const data = collection;
|
|
11
|
+
const semverRange = validRange(version);
|
|
12
|
+
|
|
13
|
+
if (semverRange) {
|
|
14
|
+
return data.filter((msg) => msg.data.id == id).filter((msg) => satisfies(msg.data.version, semverRange));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const filteredEvents = data.filter((event) => event.data.id === id);
|
|
18
|
+
|
|
19
|
+
// Order by version
|
|
20
|
+
const sorted = filteredEvents.sort((a, b) => {
|
|
21
|
+
return a.data.version.localeCompare(b.data.version);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// latest version
|
|
25
|
+
return [sorted[sorted.length - 1]];
|
|
26
|
+
};
|