@eventcatalog/core 4.6.0 → 4.6.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/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-BYW3E5I3.js → chunk-MTXVQ4VP.js} +1 -1
- package/dist/{chunk-DIVHIZPM.js → chunk-N3YKQTGX.js} +1 -1
- package/dist/{chunk-SXQSNSUH.js → chunk-U6VOVEVZ.js} +1 -1
- package/dist/{chunk-XBFXBRPC.js → chunk-X7XI7NEP.js} +1 -1
- package/dist/{chunk-VD4WSIHN.js → chunk-Y7JJ2B3L.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +5 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +2 -8
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.spec.ts +4 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +2 -2
- package/eventcatalog/src/components/Tables/SystemResources/SystemResourcesTable.tsx +29 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +28 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +7 -22
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.spec.ts +65 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.ts +46 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +7 -29
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -3
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -4
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +1 -0
- package/eventcatalog/src/stores/sidebar-store/state.ts +1 -0
- package/package.json +10 -10
|
@@ -140,7 +140,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
140
140
|
var import_os = __toESM(require("os"), 1);
|
|
141
141
|
|
|
142
142
|
// package.json
|
|
143
|
-
var version = "4.6.
|
|
143
|
+
var version = "4.6.1";
|
|
144
144
|
|
|
145
145
|
// src/constants.ts
|
|
146
146
|
var VERSION = version;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-Y7JJ2B3L.js";
|
|
4
4
|
import "../chunk-K2XIENVT.js";
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
import "../chunk-U6VOVEVZ.js";
|
|
6
|
+
import "../chunk-X7XI7NEP.js";
|
|
7
7
|
import "../chunk-6QENHZZP.js";
|
|
8
8
|
export {
|
|
9
9
|
log_build_default as default
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
|
@@ -144,7 +144,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
144
144
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
145
145
|
|
|
146
146
|
// package.json
|
|
147
|
-
var version = "4.6.
|
|
147
|
+
var version = "4.6.1";
|
|
148
148
|
|
|
149
149
|
// src/constants.ts
|
|
150
150
|
var VERSION = version;
|
package/dist/eventcatalog.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y7JJ2B3L.js";
|
|
4
4
|
import "./chunk-K2XIENVT.js";
|
|
5
5
|
import {
|
|
6
6
|
runMigrations
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
} from "./chunk-B7HCX5HM.js";
|
|
15
15
|
import {
|
|
16
16
|
generate
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-N3YKQTGX.js";
|
|
18
18
|
import {
|
|
19
19
|
logger
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-MTXVQ4VP.js";
|
|
21
21
|
import {
|
|
22
22
|
resolve_catalog_dependencies_default
|
|
23
23
|
} from "./chunk-LHR4G2UO.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
watch
|
|
29
29
|
} from "./chunk-CAJUIMDJ.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-U6VOVEVZ.js";
|
|
31
31
|
import {
|
|
32
32
|
createAstroDevLineFilter,
|
|
33
33
|
createAstroLineFilter
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
import "./chunk-W5JQON7Z.js";
|
|
39
39
|
import {
|
|
40
40
|
VERSION
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-X7XI7NEP.js";
|
|
42
42
|
import {
|
|
43
43
|
linkCoreNodeModules,
|
|
44
44
|
resolveInstalledCoreNodeModules
|
package/dist/generate.cjs
CHANGED
|
@@ -108,7 +108,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
|
|
|
108
108
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
109
109
|
|
|
110
110
|
// package.json
|
|
111
|
-
var version = "4.6.
|
|
111
|
+
var version = "4.6.1";
|
|
112
112
|
|
|
113
113
|
// src/constants.ts
|
|
114
114
|
var VERSION = version;
|
package/dist/generate.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generate
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-N3YKQTGX.js";
|
|
4
|
+
import "./chunk-MTXVQ4VP.js";
|
|
5
|
+
import "./chunk-X7XI7NEP.js";
|
|
6
6
|
import "./chunk-6QENHZZP.js";
|
|
7
7
|
export {
|
|
8
8
|
generate
|
package/dist/utils/cli-logger.js
CHANGED
|
@@ -749,7 +749,7 @@ export default function NestedSideBar() {
|
|
|
749
749
|
}) ?? [];
|
|
750
750
|
|
|
751
751
|
const groupId = groupKey || group.collapseKey || `${currentLevel.key ?? 'root'}:group:${group.title}`;
|
|
752
|
-
const canCollapse = canCollapseGroup(visibleChildren.length, isTopLevel);
|
|
752
|
+
const canCollapse = canCollapseGroup(visibleChildren.length, isTopLevel, group.collapsible);
|
|
753
753
|
const isCollapsed = isGroupCollapsed(canCollapse, groupId, sectionCollapsePreferences);
|
|
754
754
|
|
|
755
755
|
// When a group's children are subtle subgroups (e.g. Resources > Services/Flows/Data Stores),
|
|
@@ -866,12 +866,6 @@ export default function NestedSideBar() {
|
|
|
866
866
|
// a custom icon (item.leftIcon) is always still shown.
|
|
867
867
|
const IconComponent =
|
|
868
868
|
item.icon && !suppressDefaultIcon ? (LucideIcons as unknown as Record<string, LucideIcons.LucideIcon>)[item.icon] : null;
|
|
869
|
-
// Some glyphs fill their box more than others, so they read larger at the shared
|
|
870
|
-
// item size. Render these ~25% smaller (matching the ADR icon) to visually balance:
|
|
871
|
-
// ClipboardList (ADRs) and the message glyphs (events/commands/queries).
|
|
872
|
-
const smallerIcons = ['ClipboardList', 'Zap', 'MessageSquare', 'Search', 'Mail'];
|
|
873
|
-
const iconSizeClass = item.icon && smallerIcons.includes(item.icon) ? 'w-3 h-3' : 'w-4 h-4';
|
|
874
|
-
|
|
875
869
|
const handleStarClick = (e: React.MouseEvent) => {
|
|
876
870
|
e.preventDefault();
|
|
877
871
|
e.stopPropagation();
|
|
@@ -888,7 +882,7 @@ export default function NestedSideBar() {
|
|
|
888
882
|
isActive ? 'text-[rgb(var(--ec-accent-text))]' : 'text-[rgb(var(--ec-content-text-muted))]'
|
|
889
883
|
)}
|
|
890
884
|
>
|
|
891
|
-
<IconComponent className=
|
|
885
|
+
<IconComponent className="w-4 h-4" />
|
|
892
886
|
</span>
|
|
893
887
|
)}
|
|
894
888
|
{item.leftIcon && <img src={resolveIconUrl(item.leftIcon)} alt="" loading="lazy" className="w-4 h-4 flex-shrink-0" />}
|
|
@@ -22,6 +22,10 @@ describe('sidebar group presentation', () => {
|
|
|
22
22
|
expect(canCollapseGroup(5, false)).toBe(false);
|
|
23
23
|
expect(canCollapseGroup(6, false)).toBe(true);
|
|
24
24
|
});
|
|
25
|
+
|
|
26
|
+
it('keeps groups marked as non-collapsible expanded regardless of their size', () => {
|
|
27
|
+
expect(canCollapseGroup(100, false, false)).toBe(false);
|
|
28
|
+
});
|
|
25
29
|
});
|
|
26
30
|
|
|
27
31
|
describe('isGroupCollapsed', () => {
|
|
@@ -7,8 +7,8 @@ export type SectionCollapsePreferences = {
|
|
|
7
7
|
expanded: Set<string>;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export const canCollapseGroup = (childCount: number, isTopLevel: boolean): boolean =>
|
|
11
|
-
!isTopLevel && childCount > SIDEBAR_GROUP_COLLAPSE_THRESHOLD;
|
|
10
|
+
export const canCollapseGroup = (childCount: number, isTopLevel: boolean, collapsible = true): boolean =>
|
|
11
|
+
collapsible && !isTopLevel && childCount > SIDEBAR_GROUP_COLLAPSE_THRESHOLD;
|
|
12
12
|
|
|
13
13
|
export const getGroupLabel = (title: string, childCount: number): string =>
|
|
14
14
|
GROUP_TITLES_WITHOUT_COUNT.has(title) ? title : `${title} (${childCount})`;
|
|
@@ -12,7 +12,18 @@ import { getColorAndIconForCollection } from '@utils/collections/icons';
|
|
|
12
12
|
import { getCollectionTextColorClass } from '@utils/collection-colors';
|
|
13
13
|
import { isIconPath, resolveIconUrl } from '@utils/icon';
|
|
14
14
|
|
|
15
|
-
export type SystemResourceCollection =
|
|
15
|
+
export type SystemResourceCollection =
|
|
16
|
+
| 'domains'
|
|
17
|
+
| 'systems'
|
|
18
|
+
| 'agents'
|
|
19
|
+
| 'services'
|
|
20
|
+
| 'flows'
|
|
21
|
+
| 'entities'
|
|
22
|
+
| 'data-products'
|
|
23
|
+
| 'containers'
|
|
24
|
+
| 'events'
|
|
25
|
+
| 'commands'
|
|
26
|
+
| 'queries';
|
|
16
27
|
|
|
17
28
|
export interface SystemResourceItem {
|
|
18
29
|
collection: SystemResourceCollection;
|
|
@@ -29,9 +40,13 @@ interface SystemResourcesTableProps {
|
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
const TYPE_LABELS: Record<SystemResourceCollection, string> = {
|
|
43
|
+
domains: 'Subdomains',
|
|
44
|
+
systems: 'Systems',
|
|
45
|
+
agents: 'Agents',
|
|
32
46
|
services: 'Services',
|
|
33
47
|
flows: 'Flows',
|
|
34
48
|
entities: 'Entities',
|
|
49
|
+
'data-products': 'Data Products',
|
|
35
50
|
containers: 'Data Stores',
|
|
36
51
|
events: 'Events',
|
|
37
52
|
commands: 'Commands',
|
|
@@ -39,7 +54,19 @@ const TYPE_LABELS: Record<SystemResourceCollection, string> = {
|
|
|
39
54
|
};
|
|
40
55
|
|
|
41
56
|
// Order the type filter pills follow on the page.
|
|
42
|
-
const TYPE_ORDER: SystemResourceCollection[] = [
|
|
57
|
+
const TYPE_ORDER: SystemResourceCollection[] = [
|
|
58
|
+
'domains',
|
|
59
|
+
'systems',
|
|
60
|
+
'agents',
|
|
61
|
+
'services',
|
|
62
|
+
'flows',
|
|
63
|
+
'entities',
|
|
64
|
+
'data-products',
|
|
65
|
+
'containers',
|
|
66
|
+
'events',
|
|
67
|
+
'commands',
|
|
68
|
+
'queries',
|
|
69
|
+
];
|
|
43
70
|
|
|
44
71
|
// Small icon for a collection type (used in filter pills and the type column).
|
|
45
72
|
const CollectionTypeIcon = ({ collection, className }: { collection: SystemResourceCollection; className?: string }) => {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { loadResourceOwner } from './_index.data';
|
|
3
|
+
|
|
4
|
+
const collectionMocks = vi.hoisted(() => ({
|
|
5
|
+
getDomains: vi.fn(() => Promise.resolve([])),
|
|
6
|
+
getSystems: vi.fn(() => Promise.resolve([])),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
vi.mock('@utils/collections/domains', () => ({ getDomains: collectionMocks.getDomains }));
|
|
10
|
+
vi.mock('@utils/collections/systems', () => ({ getSystems: collectionMocks.getSystems }));
|
|
11
|
+
|
|
12
|
+
describe('Resources page owner loader', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.clearAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('loads domains without flattening child-subdomain services and agents', async () => {
|
|
18
|
+
await loadResourceOwner('domains');
|
|
19
|
+
|
|
20
|
+
expect(collectionMocks.getDomains).toHaveBeenCalledWith({ includeServicesInSubdomains: false });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('keeps the system loader unchanged', async () => {
|
|
24
|
+
await loadResourceOwner('systems');
|
|
25
|
+
|
|
26
|
+
expect(collectionMocks.getSystems).toHaveBeenCalledWith();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -1,36 +1,21 @@
|
|
|
1
1
|
import { isSSR } from '@utils/feature';
|
|
2
2
|
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
+
import { hasResources } from './_resources';
|
|
3
4
|
|
|
4
|
-
// The Resources page lists the
|
|
5
|
-
//
|
|
6
|
-
// systems and domains — every other resource type 404s.
|
|
5
|
+
// The Resources page lists the resources directly attached to a single system or
|
|
6
|
+
// domain. It is only available for systems and domains — every other resource type 404s.
|
|
7
7
|
const SUPPORTED_TYPES = ['systems', 'domains'] as const;
|
|
8
8
|
type SupportedType = (typeof SUPPORTED_TYPES)[number];
|
|
9
9
|
|
|
10
10
|
const isSupportedType = (type: string): type is SupportedType => SUPPORTED_TYPES.includes(type as SupportedType);
|
|
11
11
|
|
|
12
|
-
const loadResourceOwner = async (type: SupportedType) => {
|
|
12
|
+
export const loadResourceOwner = async (type: SupportedType) => {
|
|
13
13
|
if (type === 'systems') {
|
|
14
14
|
const { getSystems } = await import('@utils/collections/systems');
|
|
15
15
|
return getSystems();
|
|
16
16
|
}
|
|
17
17
|
const { getDomains } = await import('@utils/collections/domains');
|
|
18
|
-
return getDomains();
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// A system/domain only gets a Resources page when it actually has resources attached.
|
|
22
|
-
// Mirrors what the page renders: services, flows, entities, data stores and (domains
|
|
23
|
-
// only) the domain's own messages.
|
|
24
|
-
const hasResources = (owner: any): boolean => {
|
|
25
|
-
const data = owner?.data ?? {};
|
|
26
|
-
return (
|
|
27
|
-
(data.services || []).length > 0 ||
|
|
28
|
-
(data.flows || []).length > 0 ||
|
|
29
|
-
(data.entities || []).length > 0 ||
|
|
30
|
-
(data.containers || []).length > 0 ||
|
|
31
|
-
(data.sends || []).length > 0 ||
|
|
32
|
-
(data.receives || []).length > 0
|
|
33
|
-
);
|
|
18
|
+
return getDomains({ includeServicesInSubdomains: false });
|
|
34
19
|
};
|
|
35
20
|
|
|
36
21
|
export class Page extends HybridPage {
|
|
@@ -47,7 +32,7 @@ export class Page extends HybridPage {
|
|
|
47
32
|
|
|
48
33
|
return SUPPORTED_TYPES.flatMap((type, index) =>
|
|
49
34
|
owners[index]
|
|
50
|
-
.filter((owner) => hasResources(owner))
|
|
35
|
+
.filter((owner) => hasResources(owner, type))
|
|
51
36
|
.map((owner) => ({
|
|
52
37
|
params: {
|
|
53
38
|
type,
|
|
@@ -71,7 +56,7 @@ export class Page extends HybridPage {
|
|
|
71
56
|
const owners = await loadResourceOwner(type);
|
|
72
57
|
const owner = owners.find((o) => o.data.id === id && o.data.version === version);
|
|
73
58
|
|
|
74
|
-
if (!owner || !hasResources(owner)) {
|
|
59
|
+
if (!owner || !hasResources(owner, type)) {
|
|
75
60
|
return null;
|
|
76
61
|
}
|
|
77
62
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getResourceGroups, hasResources } from './_resources';
|
|
3
|
+
|
|
4
|
+
const resource = (id: string, version = '1.0.0') => ({ data: { id, name: id, version } });
|
|
5
|
+
const message = (collection: 'events' | 'commands' | 'queries', id: string, version = '1.0.0') => ({
|
|
6
|
+
collection,
|
|
7
|
+
data: { id, name: id, version },
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('resource page groups', () => {
|
|
11
|
+
it('includes every resource directly attached to a domain', () => {
|
|
12
|
+
const sharedEvent = message('events', 'OrderPlaced');
|
|
13
|
+
const groups = getResourceGroups(
|
|
14
|
+
{
|
|
15
|
+
domains: [resource('Fulfilment')],
|
|
16
|
+
systems: [resource('OrderingSystem')],
|
|
17
|
+
agents: [resource('OrderAgent')],
|
|
18
|
+
'data-products': [resource('OrderAnalytics')],
|
|
19
|
+
services: [resource('OrdersService')],
|
|
20
|
+
flows: [resource('PlaceOrder')],
|
|
21
|
+
entities: [resource('Order')],
|
|
22
|
+
sends: [sharedEvent, message('commands', 'PlaceOrder')],
|
|
23
|
+
receives: [sharedEvent, message('queries', 'GetOrder')],
|
|
24
|
+
},
|
|
25
|
+
'domains'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(Object.fromEntries(groups.map(({ collection, items }) => [collection, items.map((item) => item.data.id)]))).toEqual({
|
|
29
|
+
domains: ['Fulfilment'],
|
|
30
|
+
systems: ['OrderingSystem'],
|
|
31
|
+
agents: ['OrderAgent'],
|
|
32
|
+
'data-products': ['OrderAnalytics'],
|
|
33
|
+
services: ['OrdersService'],
|
|
34
|
+
flows: ['PlaceOrder'],
|
|
35
|
+
entities: ['Order'],
|
|
36
|
+
containers: [],
|
|
37
|
+
events: ['OrderPlaced'],
|
|
38
|
+
commands: ['PlaceOrder'],
|
|
39
|
+
queries: ['GetOrder'],
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('keeps domain-only resources off system resource pages', () => {
|
|
44
|
+
const collections = getResourceGroups(
|
|
45
|
+
{
|
|
46
|
+
domains: [resource('Fulfilment')],
|
|
47
|
+
systems: [resource('OrderingSystem')],
|
|
48
|
+
agents: [resource('OrderAgent')],
|
|
49
|
+
'data-products': [resource('OrderAnalytics')],
|
|
50
|
+
services: [resource('OrdersService')],
|
|
51
|
+
containers: [resource('OrdersDatabase')],
|
|
52
|
+
},
|
|
53
|
+
'systems'
|
|
54
|
+
).map(({ collection }) => collection);
|
|
55
|
+
|
|
56
|
+
expect(collections).toEqual(['services', 'flows', 'entities', 'containers', 'events', 'commands', 'queries']);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it.each(['domains', 'systems', 'agents', 'data-products'] as const)(
|
|
60
|
+
'makes a domain with only %s eligible for a Resources page',
|
|
61
|
+
(collection) => {
|
|
62
|
+
expect(hasResources({ data: { [collection]: [resource('direct-resource')] } }, 'domains')).toBe(true);
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SystemResourceCollection } from '@components/Tables/SystemResources/SystemResourcesTable';
|
|
2
|
+
|
|
3
|
+
export type ResourceOwnerCollection = 'systems' | 'domains';
|
|
4
|
+
|
|
5
|
+
export interface ResourceGroup {
|
|
6
|
+
collection: SystemResourceCollection;
|
|
7
|
+
items: any[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const getDomainMessages = (data: any) => {
|
|
11
|
+
const seen = new Map<string, any>();
|
|
12
|
+
|
|
13
|
+
for (const message of [...(data.sends || []), ...(data.receives || [])]) {
|
|
14
|
+
if (!message?.data?.id || !message?.collection) continue;
|
|
15
|
+
seen.set(`${message.collection}:${message.data.id}:${message.data.version}`, message);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return Array.from(seen.values());
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getResourceGroups = (data: any, ownerCollection: ResourceOwnerCollection): ResourceGroup[] => {
|
|
22
|
+
const domainMessages = ownerCollection === 'domains' ? getDomainMessages(data) : [];
|
|
23
|
+
const domainOnlyGroups: ResourceGroup[] =
|
|
24
|
+
ownerCollection === 'domains'
|
|
25
|
+
? [
|
|
26
|
+
{ collection: 'domains', items: data.domains || [] },
|
|
27
|
+
{ collection: 'systems', items: data.systems || [] },
|
|
28
|
+
{ collection: 'agents', items: data.agents || [] },
|
|
29
|
+
{ collection: 'data-products', items: data['data-products'] || [] },
|
|
30
|
+
]
|
|
31
|
+
: [];
|
|
32
|
+
|
|
33
|
+
return [
|
|
34
|
+
...domainOnlyGroups,
|
|
35
|
+
{ collection: 'services', items: data.services || [] },
|
|
36
|
+
{ collection: 'flows', items: data.flows || [] },
|
|
37
|
+
{ collection: 'entities', items: data.entities || [] },
|
|
38
|
+
{ collection: 'containers', items: data.containers || [] },
|
|
39
|
+
{ collection: 'events', items: domainMessages.filter((message) => message.collection === 'events') },
|
|
40
|
+
{ collection: 'commands', items: domainMessages.filter((message) => message.collection === 'commands') },
|
|
41
|
+
{ collection: 'queries', items: domainMessages.filter((message) => message.collection === 'queries') },
|
|
42
|
+
];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const hasResources = (owner: any, ownerCollection: ResourceOwnerCollection): boolean =>
|
|
46
|
+
getResourceGroups(owner?.data ?? {}, ownerCollection).some(({ items }) => items.length > 0);
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type SystemResourceItem,
|
|
8
8
|
type SystemResourceCollection,
|
|
9
9
|
} from '@components/Tables/SystemResources/SystemResourcesTable';
|
|
10
|
+
import { getResourceGroups, type ResourceOwnerCollection } from './_resources';
|
|
10
11
|
|
|
11
12
|
import { Page } from './_index.data';
|
|
12
13
|
|
|
@@ -15,35 +16,11 @@ export const getStaticPaths = Page.getStaticPaths;
|
|
|
15
16
|
|
|
16
17
|
const resourceOwner = await Page.getData(Astro);
|
|
17
18
|
const { data } = resourceOwner;
|
|
18
|
-
const ownerCollection = resourceOwner.collection as
|
|
19
|
+
const ownerCollection = resourceOwner.collection as ResourceOwnerCollection;
|
|
19
20
|
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
const messageEntries = (() => {
|
|
24
|
-
const seen = new Map<string, any>();
|
|
25
|
-
for (const message of [...(data.sends || []), ...(data.receives || [])]) {
|
|
26
|
-
if (!message?.data?.id || !message?.collection) continue;
|
|
27
|
-
seen.set(`${message.collection}:${message.data.id}:${message.data.version}`, message);
|
|
28
|
-
}
|
|
29
|
-
return Array.from(seen.values());
|
|
30
|
-
})();
|
|
31
|
-
|
|
32
|
-
const messagesByCollection = (collection: SystemResourceCollection) =>
|
|
33
|
-
messageEntries.filter((message: any) => message.collection === collection);
|
|
34
|
-
|
|
35
|
-
// Only show resources that are directly attached to the system/domain — not resources
|
|
36
|
-
// nested further downstream. Domains can't hold containers directly, so a domain's
|
|
37
|
-
// Resources page shows services, flows, entities and its own messages.
|
|
38
|
-
const resourceGroups: Array<{ collection: SystemResourceCollection; items: any[] }> = [
|
|
39
|
-
{ collection: 'services', items: data.services || [] },
|
|
40
|
-
{ collection: 'flows', items: data.flows || [] },
|
|
41
|
-
{ collection: 'entities', items: data.entities || [] },
|
|
42
|
-
{ collection: 'containers', items: data.containers || [] },
|
|
43
|
-
{ collection: 'events', items: messagesByCollection('events') },
|
|
44
|
-
{ collection: 'commands', items: messagesByCollection('commands') },
|
|
45
|
-
{ collection: 'queries', items: messagesByCollection('queries') },
|
|
46
|
-
];
|
|
21
|
+
// Only show resources directly attached to this system/domain. Domain child resources
|
|
22
|
+
// are not flattened, so services inside a child system remain on that system's page.
|
|
23
|
+
const resourceGroups = getResourceGroups(data, ownerCollection);
|
|
47
24
|
|
|
48
25
|
const hrefForResource = (collection: SystemResourceCollection, id: string, version: string) => {
|
|
49
26
|
if (collection === 'entities') {
|
|
@@ -72,7 +49,8 @@ const resources: SystemResourceItem[] = resourceGroups.flatMap(({ collection, it
|
|
|
72
49
|
<div class="border-b border-[rgb(var(--ec-page-border))] pb-4">
|
|
73
50
|
<h2 class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{data.name} Resources</h2>
|
|
74
51
|
<h2 class="text-lg pt-2 text-[rgb(var(--ec-page-text-muted))] font-light">
|
|
75
|
-
A group of resources that are mapped to the {data.name}
|
|
52
|
+
A group of resources that are mapped to the {data.name}{' '}
|
|
53
|
+
{ownerCollection === 'domains' ? 'domain' : 'system'}.
|
|
76
54
|
</h2>
|
|
77
55
|
</div>
|
|
78
56
|
|
|
@@ -81,10 +81,14 @@ export const buildDomainNode = (domain: CollectionEntry<'domains'>, owners: any[
|
|
|
81
81
|
const sortedReceivesMessages = [...receivesMessages].sort(byResourceName);
|
|
82
82
|
const renderMessages = shouldRenderSideBarSection(domain, 'messages');
|
|
83
83
|
|
|
84
|
-
// The Resources page/link only makes sense when the domain
|
|
85
|
-
//
|
|
84
|
+
// The Resources page/link only makes sense when the domain has direct resources.
|
|
85
|
+
// Keep this aligned with the resource groups rendered by the page.
|
|
86
86
|
const hasResources =
|
|
87
|
-
|
|
87
|
+
subDomains.length > 0 ||
|
|
88
|
+
systemsInDomain.length > 0 ||
|
|
89
|
+
agentsInDomain.length > 0 ||
|
|
90
|
+
dataProductsInDomain.length > 0 ||
|
|
91
|
+
allServicesInDomain.length > 0 ||
|
|
88
92
|
domainFlows.length > 0 ||
|
|
89
93
|
entitiesInDomain.length > 0 ||
|
|
90
94
|
sendsMessages.length > 0 ||
|
|
@@ -58,15 +58,13 @@ export const buildServiceNode = (
|
|
|
58
58
|
const renderEntities = serviceEntities.length > 0 && shouldRenderSideBarSection(service, 'entities');
|
|
59
59
|
const renderOwners = owners.length > 0 && shouldRenderSideBarSection(service, 'owners');
|
|
60
60
|
const renderRepository = service.data.repository && shouldRenderSideBarSection(service, 'repository');
|
|
61
|
-
const
|
|
62
|
-
const docsBasePath = `/docs/services/${service.data.id}${isLatestVersion ? '' : `/${service.data.version}`}`;
|
|
61
|
+
const docsBasePath = `/docs/services/${service.data.id}/${service.data.version}`;
|
|
63
62
|
const docsSection = buildResourceDocsSection(
|
|
64
63
|
'services',
|
|
65
64
|
service.data.id,
|
|
66
65
|
service.data.version,
|
|
67
66
|
context.resourceDocs,
|
|
68
|
-
context.resourceDocCategories
|
|
69
|
-
{ includeVersionInUrl: !isLatestVersion }
|
|
67
|
+
context.resourceDocCategories
|
|
70
68
|
);
|
|
71
69
|
|
|
72
70
|
// Diagrams
|
|
@@ -24,6 +24,7 @@ export type NavNode = {
|
|
|
24
24
|
type: 'group' | 'item';
|
|
25
25
|
title: string;
|
|
26
26
|
collapseKey?: string; // Stable key used to persist collapse state for inline groups
|
|
27
|
+
collapsible?: boolean; // Set to false to keep a group expanded regardless of its size
|
|
27
28
|
icon?: string; // Lucide icon name
|
|
28
29
|
subtle?: boolean; // Render lightweight styling for nested subgroup headers
|
|
29
30
|
leftIcon?: string; // Path to SVG icon shown on the left of the label
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "4.6.
|
|
10
|
+
"version": "4.6.1",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@ai-sdk/react": "^3.0.17",
|
|
35
|
-
"@astrojs/markdown-remark": "^7.2.
|
|
36
|
-
"@astrojs/mdx": "^7.0.
|
|
37
|
-
"@astrojs/node": "^11.0
|
|
38
|
-
"@astrojs/react": "^6.0.
|
|
35
|
+
"@astrojs/markdown-remark": "^7.2.2",
|
|
36
|
+
"@astrojs/mdx": "^7.0.5",
|
|
37
|
+
"@astrojs/node": "^11.1.0",
|
|
38
|
+
"@astrojs/react": "^6.0.2",
|
|
39
39
|
"@astrojs/rss": "^4.0.19",
|
|
40
40
|
"@asyncapi/avro-schema-parser": "3.0.24",
|
|
41
41
|
"@asyncapi/parser": "^3.6.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@tanstack/react-table": "^8.17.3",
|
|
62
62
|
"@xyflow/react": "^12.3.6",
|
|
63
63
|
"ai": "^6.0.17",
|
|
64
|
-
"astro": "^7.
|
|
64
|
+
"astro": "^7.2.0",
|
|
65
65
|
"astro-expressive-code": "^0.44.0",
|
|
66
66
|
"astro-seo": "^0.8.4",
|
|
67
67
|
"auth-astro": "^4.2.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"gray-matter": "^4.0.3",
|
|
82
82
|
"hono": "4.12.27",
|
|
83
83
|
"html-to-image": "^1.11.11",
|
|
84
|
-
"js-yaml": "^4.3.
|
|
84
|
+
"js-yaml": "^4.3.1",
|
|
85
85
|
"jsonpath-plus": "^10.4.0",
|
|
86
86
|
"jsonwebtoken": "^9.0.2",
|
|
87
87
|
"lodash.debounce": "^4.0.8",
|
|
@@ -120,11 +120,11 @@
|
|
|
120
120
|
"uuid": "^10.0.0",
|
|
121
121
|
"zod": "^4.3.6",
|
|
122
122
|
"@eventcatalog/linter": "1.1.10",
|
|
123
|
-
"@eventcatalog/
|
|
124
|
-
"@eventcatalog/
|
|
123
|
+
"@eventcatalog/sdk": "2.27.1",
|
|
124
|
+
"@eventcatalog/visualiser": "^4.1.1"
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
127
|
-
"@astrojs/check": "^0.9.
|
|
127
|
+
"@astrojs/check": "^0.9.10",
|
|
128
128
|
"@types/d3-drag": "^3.0.7",
|
|
129
129
|
"@types/d3-force": "^3.0.10",
|
|
130
130
|
"@types/d3-selection": "^3.0.11",
|