@eventcatalog/core 4.5.2 → 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-KUDNNV6Z.js → chunk-MTXVQ4VP.js} +1 -1
- package/dist/{chunk-L7KILCHA.js → chunk-N3YKQTGX.js} +1 -1
- package/dist/{chunk-WLKAMUKO.js → chunk-U6VOVEVZ.js} +1 -1
- package/dist/{chunk-ER7ASBD5.js → chunk-X7XI7NEP.js} +1 -1
- package/dist/{chunk-TH7CEKTM.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/content.config.ts +59 -52
- package/eventcatalog/src/enterprise/auth/login.astro +1 -1
- 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/eventcatalog/src/utils/collections/glob-loader.spec.ts +20 -0
- package/eventcatalog/src/utils/collections/glob-loader.ts +11 -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.
|
|
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.
|
|
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.
|
|
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 }) => {
|
|
@@ -9,7 +9,7 @@ import path from 'path';
|
|
|
9
9
|
import { userTeamDirectoryLoader } from './enterprise/directory/user-team-directory';
|
|
10
10
|
import config from '@config';
|
|
11
11
|
import { schemaLoader } from './utils/collections/schema-loader';
|
|
12
|
-
import { globWithSafeWatcher, withIgnoredBuildArtifacts } from './utils/collections/glob-loader';
|
|
12
|
+
import { globWithSafeWatcher, withFederatedContent, withIgnoredBuildArtifacts } from './utils/collections/glob-loader';
|
|
13
13
|
import { withExtensionProperties } from './utils/collections/extension-properties';
|
|
14
14
|
|
|
15
15
|
// Enterprise Collections
|
|
@@ -494,24 +494,26 @@ const dataProducts = defineCollection({
|
|
|
494
494
|
|
|
495
495
|
const services = defineCollection({
|
|
496
496
|
loader: globWithSafeWatcher({
|
|
497
|
-
pattern: withIgnoredBuildArtifacts(
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
497
|
+
pattern: withIgnoredBuildArtifacts(
|
|
498
|
+
withFederatedContent([
|
|
499
|
+
'domains/*/services/*/index.(md|mdx)',
|
|
500
|
+
'domains/*/services/*/versioned/*/index.(md|mdx)',
|
|
501
|
+
|
|
502
|
+
// Capture subdomain folders
|
|
503
|
+
'domains/*/subdomains/*/services/*/index.(md|mdx)',
|
|
504
|
+
'domains/*/subdomains/*/services/*/versioned/*/index.(md|mdx)',
|
|
505
|
+
|
|
506
|
+
// Capture services inside systems
|
|
507
|
+
'systems/*/services/*/index.(md|mdx)',
|
|
508
|
+
'systems/*/services/*/versioned/*/index.(md|mdx)',
|
|
509
|
+
'domains/*/systems/*/services/*/index.(md|mdx)',
|
|
510
|
+
'domains/*/systems/*/services/*/versioned/*/index.(md|mdx)',
|
|
511
|
+
|
|
512
|
+
// Capture services in the root
|
|
513
|
+
'services/*/index.(md|mdx)', // ✅ Capture only services markdown files
|
|
514
|
+
'services/*/versioned/*/index.(md|mdx)', // ✅ Capture versioned files inside services
|
|
515
|
+
])
|
|
516
|
+
),
|
|
515
517
|
base: projectDirBase,
|
|
516
518
|
generateId: ({ data, ...rest }) => {
|
|
517
519
|
return `${data.id}-${data.version}`;
|
|
@@ -730,14 +732,16 @@ const resourceDocs = defineCollection({
|
|
|
730
732
|
loader: globWithSafeWatcher({
|
|
731
733
|
// Resource-level docs are restricted to known resource paths.
|
|
732
734
|
// This avoids scanning external docs such as node_modules/**/docs.
|
|
733
|
-
pattern: withIgnoredBuildArtifacts(
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
735
|
+
pattern: withIgnoredBuildArtifacts(
|
|
736
|
+
withFederatedContent([
|
|
737
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/docs/**/*.@(md|mdx)',
|
|
738
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/docs/*.@(md|mdx)',
|
|
739
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/versioned/*/docs/**/*.@(md|mdx)',
|
|
740
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/versioned/*/docs/*.@(md|mdx)',
|
|
741
|
+
'domains/**/docs/**/*.@(md|mdx)',
|
|
742
|
+
'domains/**/docs/*.@(md|mdx)',
|
|
743
|
+
])
|
|
744
|
+
),
|
|
741
745
|
base: projectDirBase,
|
|
742
746
|
}),
|
|
743
747
|
schema: resourceDocsSchema,
|
|
@@ -745,16 +749,18 @@ const resourceDocs = defineCollection({
|
|
|
745
749
|
|
|
746
750
|
const resourceDocCategories = defineCollection({
|
|
747
751
|
loader: globWithSafeWatcher({
|
|
748
|
-
pattern: withIgnoredBuildArtifacts(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
752
|
+
pattern: withIgnoredBuildArtifacts(
|
|
753
|
+
withFederatedContent([
|
|
754
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/docs/**/category.json',
|
|
755
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/docs/**/_category_.json',
|
|
756
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/versioned/*/docs/**/category.json',
|
|
757
|
+
'{agents,events,commands,queries,services,flows,containers,channels,entities,data-products,systems}/**/versioned/*/docs/**/_category_.json',
|
|
758
|
+
'domains/**/docs/**/category.json',
|
|
759
|
+
'domains/**/docs/**/_category_.json',
|
|
760
|
+
'domains/**/docs/category.json',
|
|
761
|
+
'domains/**/docs/_category_.json',
|
|
762
|
+
])
|
|
763
|
+
),
|
|
758
764
|
base: projectDirBase,
|
|
759
765
|
}),
|
|
760
766
|
schema: resourceDocCategoriesSchema,
|
|
@@ -762,15 +768,17 @@ const resourceDocCategories = defineCollection({
|
|
|
762
768
|
|
|
763
769
|
const domains = defineCollection({
|
|
764
770
|
loader: globWithSafeWatcher({
|
|
765
|
-
pattern: withIgnoredBuildArtifacts(
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
771
|
+
pattern: withIgnoredBuildArtifacts(
|
|
772
|
+
withFederatedContent([
|
|
773
|
+
// ✅ Strictly include only index.md at the expected levels
|
|
774
|
+
'domains/*/index.(md|mdx)',
|
|
775
|
+
'domains/*/versioned/*/index.(md|mdx)',
|
|
776
|
+
|
|
777
|
+
// Capture subdomain folders
|
|
778
|
+
'domains/*/subdomains/*/index.(md|mdx)',
|
|
779
|
+
'domains/*/subdomains/*/versioned/*/index.(md|mdx)',
|
|
780
|
+
])
|
|
781
|
+
),
|
|
774
782
|
base: projectDirBase,
|
|
775
783
|
generateId: ({ data, ...rest }) => {
|
|
776
784
|
return `${data.id}-${data.version}`;
|
|
@@ -938,10 +946,9 @@ const channels = defineCollection({
|
|
|
938
946
|
|
|
939
947
|
const ubiquitousLanguages = defineCollection({
|
|
940
948
|
loader: globWithSafeWatcher({
|
|
941
|
-
pattern: withIgnoredBuildArtifacts(
|
|
942
|
-
'domains/*/ubiquitous-language.(md|mdx)',
|
|
943
|
-
|
|
944
|
-
]),
|
|
949
|
+
pattern: withIgnoredBuildArtifacts(
|
|
950
|
+
withFederatedContent(['domains/*/ubiquitous-language.(md|mdx)', 'domains/*/subdomains/*/ubiquitous-language.(md|mdx)'])
|
|
951
|
+
),
|
|
945
952
|
base: projectDirBase,
|
|
946
953
|
generateId: ({ data }) => {
|
|
947
954
|
// File has no id, so we need to generate one
|
|
@@ -1039,7 +1046,7 @@ const users = defineCollection({
|
|
|
1039
1046
|
sources: config.directory?.sources,
|
|
1040
1047
|
conflictStrategy: config.directory?.conflictStrategy,
|
|
1041
1048
|
local: {
|
|
1042
|
-
pattern: withIgnoredBuildArtifacts('users/*.(md|mdx)'),
|
|
1049
|
+
pattern: withIgnoredBuildArtifacts(withFederatedContent('users/*.(md|mdx)')),
|
|
1043
1050
|
base: projectDirBase,
|
|
1044
1051
|
generateId: ({ data }) => data.id as string,
|
|
1045
1052
|
},
|
|
@@ -1071,7 +1078,7 @@ const teams = defineCollection({
|
|
|
1071
1078
|
sources: config.directory?.sources,
|
|
1072
1079
|
conflictStrategy: config.directory?.conflictStrategy,
|
|
1073
1080
|
local: {
|
|
1074
|
-
pattern: withIgnoredBuildArtifacts('teams/*.(md|mdx)'),
|
|
1081
|
+
pattern: withIgnoredBuildArtifacts(withFederatedContent('teams/*.(md|mdx)')),
|
|
1075
1082
|
base: projectDirBase,
|
|
1076
1083
|
generateId: ({ data }) => data.id as string,
|
|
1077
1084
|
},
|
|
@@ -5,6 +5,7 @@ const { title, logo } = config;
|
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { isAuthEnabled, isSSR } from '@utils/feature';
|
|
7
7
|
import { buildUrl } from '@utils/url-builder';
|
|
8
|
+
import { getSession } from 'auth-astro/server';
|
|
8
9
|
|
|
9
10
|
const catalogDirectory = process.env.PROJECT_DIR || process.cwd();
|
|
10
11
|
|
|
@@ -32,7 +33,6 @@ if (!isSSR() || !isAuthEnabled()) {
|
|
|
32
33
|
|
|
33
34
|
// If we are in SSR mode, check if the user is already logged in
|
|
34
35
|
if (isSSR() && isAuthEnabled()) {
|
|
35
|
-
const { getSession } = await import(/* @vite-ignore */ 'auth-astro/server');
|
|
36
36
|
const session = await getSession(Astro.request);
|
|
37
37
|
if (session) {
|
|
38
38
|
return Astro.redirect('/');
|
|
@@ -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
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import picomatch from 'picomatch';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { withFederatedContent } from './glob-loader';
|
|
4
|
+
|
|
5
|
+
describe('withFederatedContent', () => {
|
|
6
|
+
it('loads root catalog content from every federated source directory', () => {
|
|
7
|
+
const patterns = withFederatedContent(['services/*/index.(md|mdx)', 'domains/*/index.(md|mdx)', '!domains/*/services/**']);
|
|
8
|
+
|
|
9
|
+
expect(patterns).toEqual([
|
|
10
|
+
'services/*/index.(md|mdx)',
|
|
11
|
+
'domains/*/index.(md|mdx)',
|
|
12
|
+
'!domains/*/services/**',
|
|
13
|
+
'federated/*/services/*/index.(md|mdx)',
|
|
14
|
+
'federated/*/domains/*/index.(md|mdx)',
|
|
15
|
+
'!federated/*/domains/*/services/**',
|
|
16
|
+
]);
|
|
17
|
+
expect(picomatch.isMatch('federated/team-payments--abc123/services/payment-service/index.mdx', patterns)).toBe(true);
|
|
18
|
+
expect(picomatch.isMatch('federated/team-payments--abc123/domains/payments/index.mdx', patterns)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -15,6 +15,17 @@ export const withIgnoredBuildArtifacts = (patterns: string | string[]) => {
|
|
|
15
15
|
|
|
16
16
|
const toPatterns = (patterns: string | string[]) => (Array.isArray(patterns) ? patterns : [patterns]);
|
|
17
17
|
|
|
18
|
+
export const withFederatedContent = (patterns: string | string[]) => {
|
|
19
|
+
const patternList = toPatterns(patterns);
|
|
20
|
+
const federatedPatterns = patternList.map((pattern) => {
|
|
21
|
+
const isNegative = pattern.startsWith('!');
|
|
22
|
+
const catalogPattern = isNegative ? pattern.slice(1) : pattern;
|
|
23
|
+
return `${isNegative ? '!' : ''}federated/*/${catalogPattern}`;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return [...patternList, ...federatedPatterns];
|
|
27
|
+
};
|
|
28
|
+
|
|
18
29
|
const matchesGlobPattern = (entry: string, patterns: string | string[]) => {
|
|
19
30
|
const patternList = toPatterns(patterns);
|
|
20
31
|
const positivePatterns = patternList.filter((pattern) => !pattern.startsWith('!'));
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"license": "SEE LICENSE IN LICENSE",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "4.
|
|
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",
|
|
@@ -119,12 +119,12 @@
|
|
|
119
119
|
"update-notifier": "^7.3.1",
|
|
120
120
|
"uuid": "^10.0.0",
|
|
121
121
|
"zod": "^4.3.6",
|
|
122
|
-
"@eventcatalog/linter": "1.1.
|
|
123
|
-
"@eventcatalog/sdk": "2.27.
|
|
122
|
+
"@eventcatalog/linter": "1.1.10",
|
|
123
|
+
"@eventcatalog/sdk": "2.27.1",
|
|
124
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",
|