@eventcatalog/core 2.3.4 → 2.5.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/CHANGELOG.md +19 -0
- package/README.md +7 -0
- package/bin/dist/eventcatalog.cjs +5 -4
- package/bin/dist/eventcatalog.js +5 -4
- package/package.json +9 -6
- package/scripts/catalog-to-astro-content-directory.js +32 -1
- package/scripts/default-files-for-collections/flows.md +11 -0
- package/scripts/default-files-for-collections/pages.md +1 -0
- package/scripts/watcher.js +1 -2
- package/src/components/DocsNavigation.astro +5 -1
- package/src/components/MDX/NodeGraph/NodeGraph.astro +12 -0
- package/src/components/MDX/NodeGraph/NodeGraph.tsx +16 -4
- package/src/components/MDX/NodeGraph/Nodes/ExternalSystem.tsx +79 -0
- package/src/components/MDX/NodeGraph/Nodes/Service.tsx +0 -12
- package/src/components/MDX/NodeGraph/Nodes/Step.tsx +69 -0
- package/src/components/MDX/NodeGraph/Nodes/User.tsx +79 -0
- package/src/components/SideBars/DomainSideBar.astro +1 -1
- package/src/components/Tables/columns/FlowTableColumns.tsx +82 -0
- package/src/components/Tables/columns/index.tsx +3 -0
- package/src/content/config.ts +65 -5
- package/src/layouts/DiscoverLayout.astro +11 -1
- package/src/layouts/VisualiserLayout.astro +33 -22
- package/src/pages/discover/[type]/index.astro +3 -0
- package/src/pages/docs/[type]/[id]/[version]/index.astro +10 -2
- package/src/pages/docs/teams/[id]/index.astro +14 -0
- package/src/pages/docs/users/[id]/index.astro +23 -4
- package/src/pages/visualiser/[type]/[id]/[version]/index.astro +9 -2
- package/src/types/index.ts +1 -1
- package/src/utils/collections/util.ts +22 -0
- package/src/utils/commands/node-graph.ts +13 -2
- package/src/utils/commands.ts +5 -4
- package/src/utils/config/catalog.ts +1 -0
- package/src/utils/domains/domains.ts +3 -5
- package/src/utils/domains/node-graph.ts +28 -9
- package/src/utils/events/node-graph.ts +13 -2
- package/src/utils/events.ts +3 -2
- package/src/utils/flows/flows.ts +59 -0
- package/src/utils/flows/node-graph.ts +153 -0
- package/src/utils/services/node-graph.ts +17 -9
- package/src/utils/services/services.ts +16 -16
- package/src/utils/teams.ts +7 -1
- package/src/utils/users.ts +8 -0
- package/tailwind.config.mjs +1 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ServerIcon } from '@heroicons/react/20/solid';
|
|
2
|
+
import { RectangleGroupIcon } from '@heroicons/react/20/solid';
|
|
3
|
+
import { createColumnHelper } from '@tanstack/react-table';
|
|
4
|
+
import type { CollectionEntry } from 'astro:content';
|
|
5
|
+
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
|
|
6
|
+
import { buildUrl } from '@utils/url-builder';
|
|
7
|
+
import { QueueListIcon } from '@heroicons/react/24/solid';
|
|
8
|
+
|
|
9
|
+
const columnHelper = createColumnHelper<CollectionEntry<'flows'>>();
|
|
10
|
+
|
|
11
|
+
export const columns = () => [
|
|
12
|
+
columnHelper.accessor('data.name', {
|
|
13
|
+
id: 'name',
|
|
14
|
+
header: () => <span>Flow</span>,
|
|
15
|
+
cell: (info) => {
|
|
16
|
+
const flowRaw = info.row.original;
|
|
17
|
+
const color = 'teal';
|
|
18
|
+
return (
|
|
19
|
+
<div className=" group ">
|
|
20
|
+
<a
|
|
21
|
+
href={buildUrl(`/docs/${flowRaw.collection}/${flowRaw.data.id}/${flowRaw.data.version}`)}
|
|
22
|
+
className={`group-hover:text-${color}-500 flex space-x-1 items-center`}
|
|
23
|
+
>
|
|
24
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md group-hover:border-${color}-400`}>
|
|
25
|
+
<span className="flex items-center">
|
|
26
|
+
<span className={`bg-${color}-500 group-hover:bg-${color}-600 h-full rounded-tl rounded-bl p-1`}>
|
|
27
|
+
<QueueListIcon className="h-4 w-4 text-white" />
|
|
28
|
+
</span>
|
|
29
|
+
<span className="leading-none px-2 group-hover:underline group-hover:text-purple-500 font-light">
|
|
30
|
+
{flowRaw.data.name} (v{flowRaw.data.version})
|
|
31
|
+
</span>
|
|
32
|
+
</span>
|
|
33
|
+
</div>
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
footer: (info) => info.column.id,
|
|
39
|
+
meta: {
|
|
40
|
+
filterVariant: 'name',
|
|
41
|
+
},
|
|
42
|
+
filterFn: filterByName,
|
|
43
|
+
}),
|
|
44
|
+
columnHelper.accessor('data.version', {
|
|
45
|
+
header: () => <span>Version</span>,
|
|
46
|
+
cell: (info) => {
|
|
47
|
+
const service = info.row.original;
|
|
48
|
+
return (
|
|
49
|
+
<div className="text-left font-light">{`v${info.getValue()} ${service.data.latestVersion === service.data.version ? '(latest)' : ''}`}</div>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
footer: (info) => info.column.id,
|
|
53
|
+
}),
|
|
54
|
+
columnHelper.accessor('data.summary', {
|
|
55
|
+
id: 'summary',
|
|
56
|
+
header: () => 'Summary',
|
|
57
|
+
cell: (info) => <span className="font-light ">{info.renderValue()}</span>,
|
|
58
|
+
footer: (info) => info.column.id,
|
|
59
|
+
meta: {
|
|
60
|
+
showFilter: false,
|
|
61
|
+
className: 'max-w-md',
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
columnHelper.accessor('data.name', {
|
|
65
|
+
header: () => <span />,
|
|
66
|
+
cell: (info) => {
|
|
67
|
+
const domain = info.row.original;
|
|
68
|
+
return (
|
|
69
|
+
<a
|
|
70
|
+
className="hover:text-purple-500 hover:underline px-4 font-light"
|
|
71
|
+
href={buildUrl(`/visualiser/${domain.collection}/${domain.data.id}/${domain.data.version}`)}
|
|
72
|
+
>
|
|
73
|
+
Visualiser →
|
|
74
|
+
</a>
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
id: 'actions',
|
|
78
|
+
meta: {
|
|
79
|
+
showFilter: false,
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { columns as MessageTableColumns } from './MessageTableColumns';
|
|
2
2
|
import { columns as ServiceTableColumns } from './ServiceTableColumns';
|
|
3
3
|
import { columns as DomainTableColumns } from './DomainTableColumns';
|
|
4
|
+
import { columns as FlowTableColumns } from './FlowTableColumns';
|
|
4
5
|
|
|
5
6
|
export const getColumnsByCollection = (collection: string): any => {
|
|
6
7
|
switch (collection) {
|
|
@@ -11,6 +12,8 @@ export const getColumnsByCollection = (collection: string): any => {
|
|
|
11
12
|
return ServiceTableColumns();
|
|
12
13
|
case 'domains':
|
|
13
14
|
return DomainTableColumns();
|
|
15
|
+
case 'flows':
|
|
16
|
+
return FlowTableColumns();
|
|
14
17
|
default:
|
|
15
18
|
return [];
|
|
16
19
|
}
|
package/src/content/config.ts
CHANGED
|
@@ -13,6 +13,11 @@ const pages = defineCollection({
|
|
|
13
13
|
}),
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
+
const pointer = z.object({
|
|
17
|
+
id: z.string(),
|
|
18
|
+
version: z.string().optional().default('latest'),
|
|
19
|
+
});
|
|
20
|
+
|
|
16
21
|
const changelogs = defineCollection({
|
|
17
22
|
type: 'content',
|
|
18
23
|
schema: z.object({
|
|
@@ -58,6 +63,63 @@ const baseSchema = z.object({
|
|
|
58
63
|
.optional(),
|
|
59
64
|
});
|
|
60
65
|
|
|
66
|
+
const flowStep = z
|
|
67
|
+
.union([
|
|
68
|
+
// Can be a string or a number just to reference a step
|
|
69
|
+
z.union([z.string(), z.number()]),
|
|
70
|
+
z
|
|
71
|
+
.object({
|
|
72
|
+
id: z.union([z.string(), z.number()]),
|
|
73
|
+
label: z.string().optional(),
|
|
74
|
+
})
|
|
75
|
+
.optional(),
|
|
76
|
+
])
|
|
77
|
+
.optional();
|
|
78
|
+
|
|
79
|
+
const flows = defineCollection({
|
|
80
|
+
type: 'content',
|
|
81
|
+
schema: z
|
|
82
|
+
.object({
|
|
83
|
+
steps: z.array(
|
|
84
|
+
z
|
|
85
|
+
.object({
|
|
86
|
+
id: z.union([z.string(), z.number()]),
|
|
87
|
+
type: z.enum(['node', 'message', 'user', 'actor']).optional(),
|
|
88
|
+
title: z.string(),
|
|
89
|
+
summary: z.string().optional(),
|
|
90
|
+
message: pointer.optional(),
|
|
91
|
+
service: pointer.optional(),
|
|
92
|
+
actor: z
|
|
93
|
+
.object({
|
|
94
|
+
name: z.string(),
|
|
95
|
+
})
|
|
96
|
+
.optional(),
|
|
97
|
+
externalSystem: z
|
|
98
|
+
.object({
|
|
99
|
+
name: z.string(),
|
|
100
|
+
summary: z.string().optional(),
|
|
101
|
+
url: z.string().url().optional(),
|
|
102
|
+
})
|
|
103
|
+
.optional(),
|
|
104
|
+
next_step: flowStep,
|
|
105
|
+
next_steps: z.array(flowStep).optional(),
|
|
106
|
+
})
|
|
107
|
+
.refine((data) => {
|
|
108
|
+
if (!data.message && !data.service && !data.actor) return true;
|
|
109
|
+
// Cant have both next_steps and next_steps
|
|
110
|
+
if (data.next_step && data.next_steps) return false;
|
|
111
|
+
// Either message or service or actor must be present, but not all
|
|
112
|
+
return (
|
|
113
|
+
(data.message && !data.service && !data.actor) ||
|
|
114
|
+
(!data.message && data.service) ||
|
|
115
|
+
(data.actor && !data.message && !data.service)
|
|
116
|
+
);
|
|
117
|
+
})
|
|
118
|
+
),
|
|
119
|
+
})
|
|
120
|
+
.merge(baseSchema),
|
|
121
|
+
});
|
|
122
|
+
|
|
61
123
|
const events = defineCollection({
|
|
62
124
|
type: 'content',
|
|
63
125
|
schema: z
|
|
@@ -78,11 +140,6 @@ const commands = defineCollection({
|
|
|
78
140
|
.merge(baseSchema),
|
|
79
141
|
});
|
|
80
142
|
|
|
81
|
-
const pointer = z.object({
|
|
82
|
-
id: z.string(),
|
|
83
|
-
version: z.string(),
|
|
84
|
-
});
|
|
85
|
-
|
|
86
143
|
const services = defineCollection({
|
|
87
144
|
type: 'content',
|
|
88
145
|
schema: z
|
|
@@ -112,6 +169,7 @@ const users = defineCollection({
|
|
|
112
169
|
hidden: z.boolean().optional(),
|
|
113
170
|
email: z.string().optional(),
|
|
114
171
|
slackDirectMessageUrl: z.string().optional(),
|
|
172
|
+
ownedDomains: z.array(reference('domains')).optional(),
|
|
115
173
|
ownedServices: z.array(reference('services')).optional(),
|
|
116
174
|
ownedEvents: z.array(reference('events')).optional(),
|
|
117
175
|
ownedCommands: z.array(reference('commands')).optional(),
|
|
@@ -130,6 +188,7 @@ const teams = defineCollection({
|
|
|
130
188
|
slackDirectMessageUrl: z.string().optional(),
|
|
131
189
|
members: z.array(reference('users')).optional(),
|
|
132
190
|
ownedCommands: z.array(reference('commands')).optional(),
|
|
191
|
+
ownedDomains: z.array(reference('domains')).optional(),
|
|
133
192
|
ownedServices: z.array(reference('services')).optional(),
|
|
134
193
|
ownedEvents: z.array(reference('events')).optional(),
|
|
135
194
|
}),
|
|
@@ -142,6 +201,7 @@ export const collections = {
|
|
|
142
201
|
users,
|
|
143
202
|
teams,
|
|
144
203
|
domains,
|
|
204
|
+
flows,
|
|
145
205
|
pages,
|
|
146
206
|
changelogs,
|
|
147
207
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Table } from '@components/Tables/Table';
|
|
3
|
-
import { RectangleGroupIcon } from '@heroicons/react/24/outline';
|
|
3
|
+
import { QueueListIcon, RectangleGroupIcon } from '@heroicons/react/24/outline';
|
|
4
4
|
import EnvelopeIcon from '@heroicons/react/24/outline/EnvelopeIcon';
|
|
5
5
|
import ServerIcon from '@heroicons/react/24/outline/ServerIcon';
|
|
6
6
|
import PlainPage from '@layouts/PlainPage.astro';
|
|
7
7
|
import { getCommands } from '@utils/commands';
|
|
8
8
|
import { getDomains } from '@utils/domains/domains';
|
|
9
|
+
import { getFlows } from '@utils/flows/flows';
|
|
9
10
|
import { getEvents } from '@utils/events';
|
|
10
11
|
import { getServices } from '@utils/services/services';
|
|
11
12
|
import { buildUrl } from '@utils/url-builder';
|
|
@@ -14,6 +15,7 @@ const events = await getEvents();
|
|
|
14
15
|
const commands = await getCommands();
|
|
15
16
|
const services = await getServices();
|
|
16
17
|
const domains = await getDomains();
|
|
18
|
+
const flows = await getFlows();
|
|
17
19
|
|
|
18
20
|
const { title, subtitle, data, type } = Astro.props;
|
|
19
21
|
const currentPath = Astro.url.pathname;
|
|
@@ -51,6 +53,14 @@ const tabs = [
|
|
|
51
53
|
activeColor: 'yellow',
|
|
52
54
|
enabled: domains.length > 0,
|
|
53
55
|
},
|
|
56
|
+
{
|
|
57
|
+
label: `Flows (${flows.length})`,
|
|
58
|
+
href: buildUrl('/discover/flows'),
|
|
59
|
+
isActive: currentPath === '/discover/flows',
|
|
60
|
+
icon: QueueListIcon,
|
|
61
|
+
activeColor: 'teal',
|
|
62
|
+
enabled: flows.length > 0,
|
|
63
|
+
},
|
|
54
64
|
];
|
|
55
65
|
---
|
|
56
66
|
|
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
import BasicList from '@components/Lists/BasicList';
|
|
3
3
|
import PlainPage from '@layouts/PlainPage.astro';
|
|
4
|
-
import type { CollectionTypes } from '@types';
|
|
5
4
|
import { getCommands } from '@utils/commands';
|
|
6
5
|
import { getDomains } from '@utils/domains/domains';
|
|
7
6
|
import { getEvents } from '@utils/events';
|
|
7
|
+
import { getFlows } from '@utils/flows/flows';
|
|
8
8
|
import { getServices } from '@utils/services/services';
|
|
9
9
|
import { buildUrl } from '@utils/url-builder';
|
|
10
|
-
import type { CollectionEntry } from 'astro:content';
|
|
11
10
|
import { ViewTransitions } from 'astro:transitions';
|
|
12
11
|
|
|
13
|
-
const [services, events, commands, domains] = await Promise.all([
|
|
12
|
+
const [services, events, commands, domains, flows] = await Promise.all([
|
|
13
|
+
getServices(),
|
|
14
|
+
getEvents(),
|
|
15
|
+
getCommands(),
|
|
16
|
+
getDomains(),
|
|
17
|
+
getFlows(),
|
|
18
|
+
]);
|
|
14
19
|
|
|
15
20
|
// @ts-ignore for large catalogs https://github.com/event-catalog/eventcatalog/issues/552
|
|
16
|
-
const navItems = [...domains, ...services, ...events, ...commands];
|
|
21
|
+
const navItems = [...domains, ...services, ...events, ...commands, ...flows];
|
|
17
22
|
|
|
18
|
-
const navigation = navItems
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
const navigation = navItems
|
|
24
|
+
.filter((item) => item.data.version === item.data.latestVersion)
|
|
25
|
+
.reduce((acc, item) => {
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
const group = acc[item.collection] || [];
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}, {}) as any;
|
|
29
|
+
return {
|
|
30
|
+
...acc,
|
|
31
|
+
[item.collection]: [...group, item],
|
|
32
|
+
};
|
|
33
|
+
}, {}) as any;
|
|
27
34
|
|
|
28
35
|
const currentPath = Astro.url.pathname;
|
|
29
36
|
const { title, description } = Astro.props;
|
|
@@ -53,16 +60,20 @@ const getColor = (collection: string) => {
|
|
|
53
60
|
>
|
|
54
61
|
{
|
|
55
62
|
Object.keys(navigation).map((key: any) => {
|
|
56
|
-
const items = navigation[key]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const items = navigation[key]
|
|
64
|
+
.map((item: any) => {
|
|
65
|
+
const isCurrent = currentPath.includes(`${item.collection}/${item.data.id}/${item.data.version}`);
|
|
66
|
+
const isLatest = item.data.version === item.data.latestVersion;
|
|
67
|
+
if (!isLatest) return null;
|
|
68
|
+
return {
|
|
69
|
+
label: item.data.name,
|
|
70
|
+
version: item.data.version,
|
|
71
|
+
color: getColor(item.collection),
|
|
72
|
+
href: buildUrl(`/visualiser/${item.collection}/${item.data.id}/${item.data.version}`),
|
|
73
|
+
active: isCurrent,
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
.filter((n: any) => n !== null);
|
|
66
77
|
return (
|
|
67
78
|
<BasicList
|
|
68
79
|
title={`${key} (${navigation[key].length})`}
|
|
@@ -6,12 +6,14 @@ import type { CollectionTypes } from '@types';
|
|
|
6
6
|
import { getCommands } from '@utils/commands';
|
|
7
7
|
import { getServices } from '@utils/services/services';
|
|
8
8
|
import { getDomains } from '@utils/domains/domains';
|
|
9
|
+
import { getFlows } from '@utils/flows/flows';
|
|
9
10
|
|
|
10
11
|
export async function getStaticPaths() {
|
|
11
12
|
const events = await getEvents();
|
|
12
13
|
const commands = await getCommands();
|
|
13
14
|
const services = await getServices();
|
|
14
15
|
const domains = await getDomains();
|
|
16
|
+
const flows = await getFlows();
|
|
15
17
|
|
|
16
18
|
const buildPage = (type: string, collection: CollectionEntry<CollectionTypes>[]) => {
|
|
17
19
|
return {
|
|
@@ -30,6 +32,7 @@ export async function getStaticPaths() {
|
|
|
30
32
|
buildPage('commands', commands),
|
|
31
33
|
buildPage('services', services),
|
|
32
34
|
buildPage('domains', domains),
|
|
35
|
+
buildPage('flows', flows),
|
|
33
36
|
];
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -13,18 +13,20 @@ import MessageSideBar from '@components/SideBars/MessageSideBar.astro';
|
|
|
13
13
|
import { getEvents } from '@utils/events';
|
|
14
14
|
import { getServices } from '@utils/services/services';
|
|
15
15
|
import { getCommands } from '@utils/commands';
|
|
16
|
-
import { EnvelopeIcon, PencilIcon, RectangleGroupIcon, ServerIcon } from '@heroicons/react/24/outline';
|
|
16
|
+
import { EnvelopeIcon, PencilIcon, QueueListIcon, RectangleGroupIcon, ServerIcon } from '@heroicons/react/24/outline';
|
|
17
17
|
import { getDomains } from '@utils/domains/domains';
|
|
18
18
|
import DomainSideBar from '@components/SideBars/DomainSideBar.astro';
|
|
19
19
|
import type { CollectionTypes } from '@types';
|
|
20
20
|
import SchemaViewer from '@components/MDX/SchemaViewer/SchemaViewer.astro';
|
|
21
21
|
import { buildUrl } from '@utils/url-builder';
|
|
22
|
+
import { getFlows } from '@utils/flows/flows';
|
|
22
23
|
|
|
23
24
|
export async function getStaticPaths() {
|
|
24
25
|
const events = await getEvents();
|
|
25
26
|
const commands = await getCommands();
|
|
26
27
|
const services = await getServices();
|
|
27
28
|
const domains = await getDomains();
|
|
29
|
+
const flows = await getFlows();
|
|
28
30
|
|
|
29
31
|
const buildPages = (collection: CollectionEntry<CollectionTypes>[]) => {
|
|
30
32
|
return collection.map((item) => ({
|
|
@@ -40,7 +42,7 @@ export async function getStaticPaths() {
|
|
|
40
42
|
}));
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
return [...buildPages(domains), ...buildPages(events), ...buildPages(services), ...buildPages(commands)];
|
|
45
|
+
return [...buildPages(domains), ...buildPages(events), ...buildPages(services), ...buildPages(commands), ...buildPages(flows)];
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
const props = Astro.props;
|
|
@@ -70,6 +72,12 @@ const getBadge = () => {
|
|
|
70
72
|
class: 'text-yellow-400',
|
|
71
73
|
};
|
|
72
74
|
}
|
|
75
|
+
|
|
76
|
+
if (props.collection === 'flows') {
|
|
77
|
+
return { backgroundColor: 'teal', textColor: 'teal', content: 'Flow', icon: QueueListIcon, class: 'text-gray' };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { backgroundColor: 'teal', textColor: 'teal', content: '', icon: QueueListIcon, class: 'text-gray' };
|
|
73
81
|
};
|
|
74
82
|
|
|
75
83
|
const badges = [getBadge(), ...contentBadges];
|
|
@@ -34,6 +34,7 @@ const { Content } = await render();
|
|
|
34
34
|
const membersRaw = props.data.members || [];
|
|
35
35
|
const members = await Promise.all(membersRaw.map((m) => getEntry(m)));
|
|
36
36
|
|
|
37
|
+
const domains = props.data.ownedDomains as CollectionEntry<'domains'>[];
|
|
37
38
|
const services = props.data.ownedServices as CollectionEntry<'services'>[];
|
|
38
39
|
const events = props.data.ownedEvents as CollectionEntry<'events'>[];
|
|
39
40
|
const commands = props.data.ownedCommands as CollectionEntry<'commands'>[];
|
|
@@ -46,6 +47,12 @@ const membersList = members.map((o) => ({
|
|
|
46
47
|
href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
|
|
47
48
|
}));
|
|
48
49
|
|
|
50
|
+
const ownedDomainsList = domains.map((p) => ({
|
|
51
|
+
label: `${p.data.name}`,
|
|
52
|
+
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
53
|
+
tag: `v${p.data.version}`,
|
|
54
|
+
}));
|
|
55
|
+
|
|
49
56
|
const ownedServicesList = services.map((p) => ({
|
|
50
57
|
label: `${p.data.name} (service)`,
|
|
51
58
|
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
@@ -112,6 +119,13 @@ const ownedEventsList = [...events, ...commands].map((p) => ({
|
|
|
112
119
|
</main>
|
|
113
120
|
<aside class="sticky top-20 h-[calc(100vh-theme(spacing.16))] w-56 overflow-y-auto">
|
|
114
121
|
<div class="divide-y-2 divide-gray-100">
|
|
122
|
+
<PillList
|
|
123
|
+
color="pink"
|
|
124
|
+
title={`Owned domains (${ownedDomainsList.length})`}
|
|
125
|
+
pills={ownedDomainsList}
|
|
126
|
+
emptyMessage={`${props.data.name} does not own any domains.`}
|
|
127
|
+
client:load
|
|
128
|
+
/>
|
|
115
129
|
<PillList
|
|
116
130
|
color="blue"
|
|
117
131
|
title={`Owned services (${ownedServicesList.length})`}
|
|
@@ -29,11 +29,18 @@ const { render, ...props } = Astro.props;
|
|
|
29
29
|
|
|
30
30
|
const { Content } = await render();
|
|
31
31
|
|
|
32
|
+
const domains = props.data.ownedDomains as CollectionEntry<'domains'>[];
|
|
32
33
|
const services = props.data.ownedServices as CollectionEntry<'services'>[];
|
|
33
34
|
const events = props.data.ownedEvents as CollectionEntry<'events'>[];
|
|
34
35
|
const commands = props.data.ownedCommands as CollectionEntry<'commands'>[];
|
|
35
36
|
const teams = props.data.associatedTeams as CollectionEntry<'teams'>[];
|
|
36
37
|
|
|
38
|
+
const ownedDomainsList = domains.map((p) => ({
|
|
39
|
+
label: `${p.data.name}`,
|
|
40
|
+
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
41
|
+
tag: `v${p.data.version}`,
|
|
42
|
+
}));
|
|
43
|
+
|
|
37
44
|
const ownedServicesList = services.map((p) => ({
|
|
38
45
|
label: `${p.data.name} (service)`,
|
|
39
46
|
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
@@ -41,7 +48,8 @@ const ownedServicesList = services.map((p) => ({
|
|
|
41
48
|
}));
|
|
42
49
|
|
|
43
50
|
const ownedMessageList = [...events, ...commands].map((p) => ({
|
|
44
|
-
label: `${p.data.name}
|
|
51
|
+
label: `${p.data.name}`,
|
|
52
|
+
badge: p.collection,
|
|
45
53
|
color: p.collection === 'events' ? 'orange' : 'blue',
|
|
46
54
|
tag: `v${p.data.version}`,
|
|
47
55
|
href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
|
|
@@ -91,7 +99,11 @@ const associatedTeams = teams.map((o) => ({
|
|
|
91
99
|
<div class="border-b border-gray-200">
|
|
92
100
|
<div class="mx-auto max-w-7xl px-6 lg:px-8">
|
|
93
101
|
<div class="mx-auto max-w-2xl lg:max-w-none">
|
|
94
|
-
<dl class="hidden lg:grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-
|
|
102
|
+
<dl class="hidden lg:grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-4 lg:grid-cols-4">
|
|
103
|
+
<div class="flex flex-col p-8">
|
|
104
|
+
<dt class="text-sm font-semibold leading-6 text-gray-600"># owned domains</dt>
|
|
105
|
+
<dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedDomainsList.length}</dd>
|
|
106
|
+
</div>
|
|
95
107
|
<div class="flex flex-col p-8">
|
|
96
108
|
<dt class="text-sm font-semibold leading-6 text-gray-600"># owned services</dt>
|
|
97
109
|
<dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">{ownedServicesList.length}</dd>
|
|
@@ -118,18 +130,25 @@ const associatedTeams = teams.map((o) => ({
|
|
|
118
130
|
</main>
|
|
119
131
|
<aside class="sticky top-20 h-[calc(100vh-theme(spacing.16))] w-56 overflow-y-auto">
|
|
120
132
|
<div class="divide-y-2 divide-gray-100">
|
|
133
|
+
<PillList
|
|
134
|
+
color="pink"
|
|
135
|
+
title={`Owned domains (${ownedDomainsList.length})`}
|
|
136
|
+
pills={ownedDomainsList}
|
|
137
|
+
emptyMessage={`${props.data.name} does not own any domains.`}
|
|
138
|
+
client:load
|
|
139
|
+
/>
|
|
121
140
|
<PillList
|
|
122
141
|
color="pink"
|
|
123
142
|
title={`Owned services (${ownedServicesList.length})`}
|
|
124
143
|
pills={ownedServicesList}
|
|
125
|
-
emptyMessage={`${props.data.name} does not own any services
|
|
144
|
+
emptyMessage={`${props.data.name} does not own any services.`}
|
|
126
145
|
client:load
|
|
127
146
|
/>
|
|
128
147
|
<PillList
|
|
129
148
|
color="orange"
|
|
130
149
|
title={`Owned messages (${ownedMessageList.length})`}
|
|
131
150
|
pills={ownedMessageList}
|
|
132
|
-
emptyMessage={`${props.data.name} does not own any messages
|
|
151
|
+
emptyMessage={`${props.data.name} does not own any messages.`}
|
|
133
152
|
client:load
|
|
134
153
|
/>
|
|
135
154
|
<OwnersList
|
|
@@ -5,12 +5,19 @@ import type { CollectionTypes } from '@types';
|
|
|
5
5
|
import { getCommands } from '@utils/commands';
|
|
6
6
|
import { getDomains } from '@utils/domains/domains';
|
|
7
7
|
import { getEvents } from '@utils/events';
|
|
8
|
+
import { getFlows } from '@utils/flows/flows';
|
|
8
9
|
import { getServices } from '@utils/services/services';
|
|
9
10
|
import { buildUrl } from '@utils/url-builder';
|
|
10
11
|
import type { CollectionEntry } from 'astro:content';
|
|
11
12
|
|
|
12
13
|
export async function getStaticPaths() {
|
|
13
|
-
const [services, events, commands, domains] = await Promise.all([
|
|
14
|
+
const [services, events, commands, domains, flows] = await Promise.all([
|
|
15
|
+
getServices(),
|
|
16
|
+
getEvents(),
|
|
17
|
+
getCommands(),
|
|
18
|
+
getDomains(),
|
|
19
|
+
getFlows(),
|
|
20
|
+
]);
|
|
14
21
|
|
|
15
22
|
const buildPages = (collection: CollectionEntry<CollectionTypes>[]) => {
|
|
16
23
|
return collection.map((item) => ({
|
|
@@ -26,7 +33,7 @@ export async function getStaticPaths() {
|
|
|
26
33
|
}));
|
|
27
34
|
};
|
|
28
35
|
|
|
29
|
-
return [...buildPages(services), ...buildPages(events), ...buildPages(commands), ...buildPages(domains)];
|
|
36
|
+
return [...buildPages(services), ...buildPages(events), ...buildPages(commands), ...buildPages(domains), ...buildPages(flows)];
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
const props = Astro.props;
|
package/src/types/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type CollectionTypes = 'commands' | 'events' | 'domains' | 'services';
|
|
1
|
+
export type CollectionTypes = 'commands' | 'events' | 'domains' | 'services' | 'flows';
|
|
2
2
|
export type CollectionMessageTypes = 'commands' | 'events';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CollectionTypes } from '@types';
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
|
+
import { satisfies, validRange } from 'semver';
|
|
3
4
|
|
|
4
5
|
export const getVersions = (data: CollectionEntry<CollectionTypes>[]) => {
|
|
5
6
|
const allVersions = data.map((item) => item.data.version).sort();
|
|
@@ -20,3 +21,24 @@ export const getVersionForCollectionItem = (
|
|
|
20
21
|
const latestVersion = versions[0];
|
|
21
22
|
return { versions, latestVersion };
|
|
22
23
|
};
|
|
24
|
+
|
|
25
|
+
export const getItemsFromCollectionByIdAndSemverOrLatest = <T extends { data: { id: string; version: string } }>(
|
|
26
|
+
collection: T[],
|
|
27
|
+
id: string,
|
|
28
|
+
version?: string
|
|
29
|
+
): T[] => {
|
|
30
|
+
const semverRange = validRange(version);
|
|
31
|
+
const filteredCollection = collection.filter((c) => c.data.id == id);
|
|
32
|
+
|
|
33
|
+
if (semverRange) {
|
|
34
|
+
return filteredCollection.filter((c) => satisfies(c.data.version, semverRange));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Order by version
|
|
38
|
+
const sorted = filteredCollection.sort((a, b) => {
|
|
39
|
+
return a.data.version.localeCompare(b.data.version);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// latest version
|
|
43
|
+
return sorted.length > 0 ? [sorted[sorted.length - 1]] : [];
|
|
44
|
+
};
|
|
@@ -2,6 +2,7 @@ import { getCommands } from '@utils/commands';
|
|
|
2
2
|
import { calculatedNodes, createDagreGraph, generateIdForNode, generatedIdForEdge } from '@utils/node-graph-utils/utils';
|
|
3
3
|
import { type CollectionEntry } from 'astro:content';
|
|
4
4
|
import dagre from 'dagre';
|
|
5
|
+
import { MarkerType } from 'reactflow';
|
|
5
6
|
|
|
6
7
|
type DagreGraph = any;
|
|
7
8
|
|
|
@@ -50,7 +51,12 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
50
51
|
label: 'invokes',
|
|
51
52
|
animated: false,
|
|
52
53
|
markerEnd: {
|
|
53
|
-
type:
|
|
54
|
+
type: MarkerType.ArrowClosed,
|
|
55
|
+
width: 40,
|
|
56
|
+
height: 40,
|
|
57
|
+
},
|
|
58
|
+
style: {
|
|
59
|
+
strokeWidth: 1,
|
|
54
60
|
},
|
|
55
61
|
});
|
|
56
62
|
});
|
|
@@ -84,7 +90,12 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
84
90
|
label: 'accepts',
|
|
85
91
|
animated: false,
|
|
86
92
|
markerEnd: {
|
|
87
|
-
type:
|
|
93
|
+
type: MarkerType.ArrowClosed,
|
|
94
|
+
width: 40,
|
|
95
|
+
height: 40,
|
|
96
|
+
},
|
|
97
|
+
style: {
|
|
98
|
+
strokeWidth: 1,
|
|
88
99
|
},
|
|
89
100
|
});
|
|
90
101
|
});
|
package/src/utils/commands.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { getCollection } from 'astro:content';
|
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { getVersionForCollectionItem } from './collections/util';
|
|
5
|
+
import { satisfies } from 'semver';
|
|
5
6
|
|
|
6
7
|
const PROJECT_DIR = process.env.PROJECT_DIR || process.cwd();
|
|
7
8
|
|
|
@@ -29,16 +30,16 @@ export const getCommands = async ({ getAllVersions = true }: Props = {}): Promis
|
|
|
29
30
|
const producers = services.filter((service) => {
|
|
30
31
|
if (!service.data.sends) return false;
|
|
31
32
|
return service.data.sends.find((item) => {
|
|
32
|
-
if (item.version) return item.id === command.data.id &&
|
|
33
|
-
return item.id == command.data.id;
|
|
33
|
+
if (item.version) return item.id === command.data.id && satisfies(command.data.version, item.version);
|
|
34
|
+
return item.id == command.data.id; // ??
|
|
34
35
|
});
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
const consumers = services.filter((service) => {
|
|
38
39
|
if (!service.data.receives) return false;
|
|
39
40
|
return service.data.receives.find((item) => {
|
|
40
|
-
if (item.version) return item.id === command.data.id &&
|
|
41
|
-
return item.id == command.data.id;
|
|
41
|
+
if (item.version) return item.id === command.data.id && satisfies(command.data.version, item.version);
|
|
42
|
+
return item.id == command.data.id; // ??
|
|
42
43
|
});
|
|
43
44
|
});
|
|
44
45
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getItemsFromCollectionByIdAndSemverOrLatest, getVersionForCollectionItem } from '@utils/collections/util';
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
3
|
import type { CollectionEntry } from 'astro:content';
|
|
4
4
|
import path from 'path';
|
|
@@ -28,10 +28,8 @@ export const getDomains = async ({ getAllVersions = true }: Props = {}): Promise
|
|
|
28
28
|
const servicesInDomain = domain.data.services || [];
|
|
29
29
|
|
|
30
30
|
const services = servicesInDomain
|
|
31
|
-
.map((_service) =>
|
|
32
|
-
|
|
33
|
-
})
|
|
34
|
-
.filter((e) => e !== undefined);
|
|
31
|
+
.map((_service) => getItemsFromCollectionByIdAndSemverOrLatest(servicesCollection, _service.id, _service.version))
|
|
32
|
+
.flat();
|
|
35
33
|
|
|
36
34
|
return {
|
|
37
35
|
...domain,
|