@eventcatalog/core 3.41.4 → 3.43.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/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/count-resources.cjs +1 -0
- package/dist/analytics/count-resources.js +1 -1
- package/dist/analytics/log-build.cjs +3 -1
- package/dist/analytics/log-build.js +4 -4
- package/dist/{chunk-VQLDZRHC.js → chunk-2EI3M7OO.js} +1 -1
- package/dist/{chunk-COPXPOV2.js → chunk-7M5IQL3J.js} +1 -1
- package/dist/{chunk-3DVHEVHQ.js → chunk-DAOXTQVS.js} +1 -0
- package/dist/{chunk-OH2U6UEJ.js → chunk-KY74BE42.js} +1 -1
- package/dist/{chunk-LYRAK5LI.js → chunk-QV2PKXZM.js} +3 -2
- package/dist/{chunk-QMORF42U.js → chunk-ZONBICNH.js} +8 -0
- package/dist/{chunk-YWG7CCN7.js → chunk-ZQHBDPIY.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/development/developer-tools/api-catalog.md +114 -0
- package/dist/eventcatalog.cjs +11 -1
- package/dist/eventcatalog.js +7 -7
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/search-indexer.cjs +8 -0
- package/dist/search-indexer.js +1 -1
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/MDX/Attachments.astro +3 -3
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +11 -2
- package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +100 -2
- package/eventcatalog/src/components/Tables/Discover/columns.tsx +53 -1
- package/eventcatalog/src/content.config.ts +61 -0
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +19 -0
- package/eventcatalog/src/layouts/DiscoverLayout.astro +12 -1
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +98 -46
- package/eventcatalog/src/pages/.well-known/api-catalog.ts +191 -0
- package/eventcatalog/src/pages/api-catalog/specifications/[collection]/[id]/[version]/[specification].ts +109 -0
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -0
- package/eventcatalog/src/pages/discover/[type]/index.astro +17 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +68 -2
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +1 -0
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +26 -1
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +26 -1
- package/eventcatalog/src/stores/sidebar-store/builders/adr.ts +150 -0
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +2 -0
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +50 -0
- package/eventcatalog/src/stores/sidebar-store/state.ts +209 -68
- package/eventcatalog/src/types/index.ts +2 -0
- package/eventcatalog/src/utils/collection-colors.ts +2 -0
- package/eventcatalog/src/utils/collections/adr-constants.ts +53 -0
- package/eventcatalog/src/utils/collections/adrs.ts +146 -0
- package/eventcatalog/src/utils/collections/icons.ts +2 -0
- package/eventcatalog/src/utils/collections/teams.ts +6 -1
- package/eventcatalog/src/utils/collections/users.ts +17 -10
- package/eventcatalog/src/utils/collections/util.ts +2 -0
- package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +2 -0
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getCollection } from 'astro:content';
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import { getAgents } from '@utils/collections/agents';
|
|
4
|
+
import { getAdrAliasNodeKey, getAdrNodeKey, getAdrs, type Adr } from '@utils/collections/adrs';
|
|
5
|
+
import { ADR_STATUS_VALUES, formatAdrStatus } from '@utils/collections/adr-constants';
|
|
4
6
|
import { getContainers } from '@utils/collections/containers';
|
|
5
7
|
import { getDomains } from '@utils/collections/domains';
|
|
6
8
|
import { getServices } from '@utils/collections/services';
|
|
@@ -22,12 +24,18 @@ import { buildMessageNode } from './builders/message';
|
|
|
22
24
|
import { buildContainerNode } from './builders/container';
|
|
23
25
|
import { buildFlowNode } from './builders/flow';
|
|
24
26
|
import { buildDataProductNode } from './builders/data-product';
|
|
27
|
+
import { buildAdrNode } from './builders/adr';
|
|
25
28
|
import config from '@config';
|
|
26
29
|
import { getDesigns } from '@utils/collections/designs';
|
|
27
30
|
import { getChannels } from '@utils/collections/channels';
|
|
28
31
|
import { createVersionedMap, findInMap } from '@utils/collections/util';
|
|
29
32
|
import { iconFieldsForResource } from '@utils/icon';
|
|
30
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
buildQuickReferenceSection,
|
|
35
|
+
buildResourceDocsSection,
|
|
36
|
+
shouldRenderSideBarSection,
|
|
37
|
+
withArchitectureDecisionsSection,
|
|
38
|
+
} from './builders/shared';
|
|
31
39
|
import { isChangelogEnabled } from '@utils/feature';
|
|
32
40
|
|
|
33
41
|
export type { NavigationData, NavNode, ChildRef };
|
|
@@ -41,6 +49,35 @@ type ServiceEntry = CollectionEntry<'services'>;
|
|
|
41
49
|
type ContainerEntry = CollectionEntry<'containers'>;
|
|
42
50
|
type DataProductEntry = CollectionEntry<'data-products'>;
|
|
43
51
|
|
|
52
|
+
const byResourceName = <T extends { data: { name?: string; id: string } }>(a: T, b: T) => {
|
|
53
|
+
const name = (a.data.name || a.data.id).localeCompare(b.data.name || b.data.id);
|
|
54
|
+
if (name !== 0) return name;
|
|
55
|
+
return a.data.id.localeCompare(b.data.id);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const sortByResourceName = <T extends { data: { name?: string; id: string } }>(items: T[]) => [...items].sort(byResourceName);
|
|
59
|
+
|
|
60
|
+
const byAdrDateDesc = (a: Adr, b: Adr) => {
|
|
61
|
+
const date = new Date(b.data.date).getTime() - new Date(a.data.date).getTime();
|
|
62
|
+
if (date !== 0) return date;
|
|
63
|
+
return byResourceName(a, b);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const groupAdrsByStatus = (adrs: Adr[]): NavNode[] =>
|
|
67
|
+
ADR_STATUS_VALUES.reduce<NavNode[]>((groups, status) => {
|
|
68
|
+
const adrsForStatus = adrs.filter((adr) => adr.data.status === status);
|
|
69
|
+
if (adrsForStatus.length === 0) return groups;
|
|
70
|
+
|
|
71
|
+
groups.push({
|
|
72
|
+
type: 'group',
|
|
73
|
+
title: `${formatAdrStatus(status)} (${adrsForStatus.length})`,
|
|
74
|
+
subtle: true,
|
|
75
|
+
pages: [...adrsForStatus].sort(byAdrDateDesc).map(getAdrNodeKey),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return groups;
|
|
79
|
+
}, []);
|
|
80
|
+
|
|
44
81
|
const getMessageNodeKey = (message: MessageEntry) =>
|
|
45
82
|
`${pluralizeMessageType(message)}:${message.data.id}:${message.data.version}`;
|
|
46
83
|
|
|
@@ -254,6 +291,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
254
291
|
diagrams,
|
|
255
292
|
dataProducts,
|
|
256
293
|
entities,
|
|
294
|
+
adrs,
|
|
257
295
|
resourceDocs,
|
|
258
296
|
resourceDocCategories,
|
|
259
297
|
] = await Promise.all([
|
|
@@ -270,6 +308,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
270
308
|
getDiagrams({ getAllVersions: false }),
|
|
271
309
|
getDataProducts({ getAllVersions: false }),
|
|
272
310
|
getEntities({ getAllVersions: false }),
|
|
311
|
+
getAdrs({ getAllVersions: false }),
|
|
273
312
|
getResourceDocs(),
|
|
274
313
|
getResourceDocCategories(),
|
|
275
314
|
]);
|
|
@@ -289,9 +328,13 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
289
328
|
queries,
|
|
290
329
|
flows,
|
|
291
330
|
containers,
|
|
331
|
+
channels,
|
|
292
332
|
diagrams,
|
|
293
333
|
dataProducts,
|
|
294
334
|
entities,
|
|
335
|
+
adrs,
|
|
336
|
+
users,
|
|
337
|
+
teams,
|
|
295
338
|
resourceDocs,
|
|
296
339
|
resourceDocCategories,
|
|
297
340
|
};
|
|
@@ -348,9 +391,25 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
348
391
|
})
|
|
349
392
|
);
|
|
350
393
|
|
|
394
|
+
const adrsWithOwners = await Promise.all(
|
|
395
|
+
adrs.map(async (adr) => {
|
|
396
|
+
const owners = await Promise.all((adr.data.owners || []).map((owner) => getOwner(owner)));
|
|
397
|
+
const decisionMakers = await Promise.all((adr.data.decisionMakers || []).map((owner) => getOwner(owner)));
|
|
398
|
+
return {
|
|
399
|
+
adr,
|
|
400
|
+
owners: owners.filter((o) => o !== undefined),
|
|
401
|
+
decisionMakers: decisionMakers.filter((o) => o !== undefined),
|
|
402
|
+
};
|
|
403
|
+
})
|
|
404
|
+
);
|
|
405
|
+
|
|
351
406
|
const flowNodes = flows.reduce(
|
|
352
407
|
(acc, flow) => {
|
|
353
|
-
acc[`flow:${flow.data.id}:${flow.data.version}`] =
|
|
408
|
+
acc[`flow:${flow.data.id}:${flow.data.version}`] = withArchitectureDecisionsSection(
|
|
409
|
+
buildFlowNode(flow, context),
|
|
410
|
+
flow,
|
|
411
|
+
adrs
|
|
412
|
+
);
|
|
354
413
|
return acc;
|
|
355
414
|
},
|
|
356
415
|
{} as Record<string, NavNode>
|
|
@@ -359,7 +418,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
359
418
|
const domainNodes = domainsWithOwners.reduce(
|
|
360
419
|
(acc, { domain, owners }) => {
|
|
361
420
|
const versionedKey = `domain:${domain.data.id}:${domain.data.version}`;
|
|
362
|
-
acc[versionedKey] = buildDomainNode(domain, owners, context);
|
|
421
|
+
acc[versionedKey] = withArchitectureDecisionsSection(buildDomainNode(domain, owners, context), domain, adrs);
|
|
363
422
|
if (domain.data.latestVersion === domain.data.version) {
|
|
364
423
|
// Store reference to versioned key instead of duplicating the full node
|
|
365
424
|
acc[`domain:${domain.data.id}`] = versionedKey;
|
|
@@ -447,7 +506,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
447
506
|
(acc, { agent, owners }) => {
|
|
448
507
|
const versionedKey = `agent:${agent.data.id}:${agent.data.version}`;
|
|
449
508
|
const agentChannels = agentChannelsMap.get(`${agent.data.id}:${agent.data.version}`) || [];
|
|
450
|
-
acc[versionedKey] =
|
|
509
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
510
|
+
buildAgentNode(agent, owners, context, agentChannels, flowRefsByAgent.get(versionedKey) || []),
|
|
511
|
+
agent,
|
|
512
|
+
adrs
|
|
513
|
+
);
|
|
451
514
|
if (agent.data.latestVersion === agent.data.version) {
|
|
452
515
|
acc[`agent:${agent.data.id}`] = versionedKey;
|
|
453
516
|
}
|
|
@@ -460,7 +523,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
460
523
|
(acc, { service, owners }) => {
|
|
461
524
|
const versionedKey = `service:${service.data.id}:${service.data.version}`;
|
|
462
525
|
const serviceChannels = serviceChannelsMap.get(`${service.data.id}:${service.data.version}`) || [];
|
|
463
|
-
acc[versionedKey] =
|
|
526
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
527
|
+
buildServiceNode(service, owners, context, serviceChannels, flowRefsByService.get(versionedKey) || []),
|
|
528
|
+
service,
|
|
529
|
+
adrs
|
|
530
|
+
);
|
|
464
531
|
if (service.data.latestVersion === service.data.version) {
|
|
465
532
|
// Store reference to versioned key instead of duplicating the full node
|
|
466
533
|
acc[`service:${service.data.id}`] = versionedKey;
|
|
@@ -498,7 +565,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
498
565
|
const type = pluralizeMessageType(message as any);
|
|
499
566
|
const versionedKey = `${type}:${message.data.id}:${message.data.version}`;
|
|
500
567
|
const hasFieldUsage = messagesWithFieldUsage.has(message.data.id);
|
|
501
|
-
acc[versionedKey] =
|
|
568
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
569
|
+
buildMessageNode(message, owners, context, hasFieldUsage, flowRefsByMessage.get(versionedKey) || []),
|
|
570
|
+
message,
|
|
571
|
+
adrs
|
|
572
|
+
);
|
|
502
573
|
if (message.data.latestVersion === message.data.version) {
|
|
503
574
|
// Store reference to versioned key instead of duplicating the full node
|
|
504
575
|
acc[`${type}:${message.data.id}`] = versionedKey;
|
|
@@ -513,7 +584,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
513
584
|
const containerNodes = containerWithOwners.reduce(
|
|
514
585
|
(acc, { container, owners }) => {
|
|
515
586
|
const versionedKey = `container:${container.data.id}:${container.data.version}`;
|
|
516
|
-
acc[versionedKey] =
|
|
587
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
588
|
+
buildContainerNode(container, owners, context, flowRefsByContainer.get(versionedKey) || []),
|
|
589
|
+
container,
|
|
590
|
+
adrs
|
|
591
|
+
);
|
|
517
592
|
if (container.data.latestVersion === container.data.version) {
|
|
518
593
|
// Store reference to versioned key instead of duplicating the full node
|
|
519
594
|
acc[`container:${container.data.id}`] = versionedKey;
|
|
@@ -547,11 +622,10 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
547
622
|
const dataProductNodes = dataProductWithOwners.reduce(
|
|
548
623
|
(acc, { dataProduct, owners }) => {
|
|
549
624
|
const versionedKey = `data-product:${dataProduct.data.id}:${dataProduct.data.version}`;
|
|
550
|
-
acc[versionedKey] =
|
|
625
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
626
|
+
buildDataProductNode(dataProduct, owners, dataProductContext, flowRefsByDataProduct.get(versionedKey) || []),
|
|
551
627
|
dataProduct,
|
|
552
|
-
|
|
553
|
-
dataProductContext,
|
|
554
|
-
flowRefsByDataProduct.get(versionedKey) || []
|
|
628
|
+
adrs
|
|
555
629
|
);
|
|
556
630
|
if (dataProduct.data.latestVersion === dataProduct.data.version) {
|
|
557
631
|
acc[`data-product:${dataProduct.data.id}`] = versionedKey;
|
|
@@ -561,17 +635,33 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
561
635
|
{} as Record<string, NavNode | string>
|
|
562
636
|
);
|
|
563
637
|
|
|
638
|
+
const adrNodes = adrsWithOwners.reduce(
|
|
639
|
+
(acc, { adr, owners, decisionMakers }) => {
|
|
640
|
+
const versionedKey = getAdrNodeKey(adr);
|
|
641
|
+
acc[versionedKey] = buildAdrNode(adr, owners, decisionMakers, context);
|
|
642
|
+
if (adr.data.latestVersion === adr.data.version) {
|
|
643
|
+
acc[getAdrAliasNodeKey(adr)] = versionedKey;
|
|
644
|
+
}
|
|
645
|
+
return acc;
|
|
646
|
+
},
|
|
647
|
+
{} as Record<string, NavNode | string>
|
|
648
|
+
);
|
|
649
|
+
|
|
564
650
|
const entityNodes = entities.reduce(
|
|
565
651
|
(acc, entity) => {
|
|
566
652
|
const versionedKey = `entity:${entity.data.id}:${entity.data.version}`;
|
|
567
|
-
acc[versionedKey] =
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
653
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
654
|
+
{
|
|
655
|
+
type: 'item',
|
|
656
|
+
title: entity.data.name,
|
|
657
|
+
badge: 'Entity',
|
|
658
|
+
summary: entity.data.summary,
|
|
659
|
+
icon: 'Box',
|
|
660
|
+
href: buildUrl(`/docs/entities/${entity.data.id}/${entity.data.version}`),
|
|
661
|
+
},
|
|
662
|
+
entity,
|
|
663
|
+
adrs
|
|
664
|
+
);
|
|
575
665
|
if (entity.data.latestVersion === entity.data.version) {
|
|
576
666
|
acc[`entity:${entity.data.id}`] = versionedKey;
|
|
577
667
|
}
|
|
@@ -593,13 +683,38 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
593
683
|
{} as Record<string, NavNode>
|
|
594
684
|
);
|
|
595
685
|
|
|
686
|
+
const diagramNodes = diagrams.reduce(
|
|
687
|
+
(acc, diagram) => {
|
|
688
|
+
const versionedKey = `diagram:${diagram.data.id}:${diagram.data.version}`;
|
|
689
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
690
|
+
{
|
|
691
|
+
type: 'item',
|
|
692
|
+
title: diagram.data.name,
|
|
693
|
+
badge: 'Diagram',
|
|
694
|
+
href: buildUrl(`/diagrams/${diagram.data.id}/${diagram.data.version}`),
|
|
695
|
+
},
|
|
696
|
+
diagram,
|
|
697
|
+
adrs
|
|
698
|
+
);
|
|
699
|
+
if (diagram.data.latestVersion === diagram.data.version) {
|
|
700
|
+
acc[`diagram:${diagram.data.id}`] = versionedKey;
|
|
701
|
+
}
|
|
702
|
+
return acc;
|
|
703
|
+
},
|
|
704
|
+
{} as Record<string, NavNode | string>
|
|
705
|
+
);
|
|
706
|
+
|
|
596
707
|
const userNodes = users.reduce(
|
|
597
708
|
(acc, user) => {
|
|
598
|
-
acc[`user:${user.data.id}`] =
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
709
|
+
acc[`user:${user.data.id}`] = withArchitectureDecisionsSection(
|
|
710
|
+
{
|
|
711
|
+
type: 'item',
|
|
712
|
+
title: user.data.name,
|
|
713
|
+
href: buildUrl(`/docs/users/${user.data.id}`),
|
|
714
|
+
},
|
|
715
|
+
user,
|
|
716
|
+
adrs
|
|
717
|
+
);
|
|
603
718
|
return acc;
|
|
604
719
|
},
|
|
605
720
|
{} as Record<string, NavNode>
|
|
@@ -615,29 +730,33 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
615
730
|
resourceDocs,
|
|
616
731
|
resourceDocCategories
|
|
617
732
|
);
|
|
618
|
-
acc[versionedKey] =
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
isChangelogEnabled() &&
|
|
632
|
-
shouldRenderSideBarSection(channel, 'changelog') && {
|
|
633
|
-
title: 'Changelog',
|
|
634
|
-
href: buildUrl(`/docs/${channel.collection}/${channel.data.id}/${channel.data.version}/changelog`),
|
|
733
|
+
acc[versionedKey] = withArchitectureDecisionsSection(
|
|
734
|
+
{
|
|
735
|
+
type: 'item',
|
|
736
|
+
title: channel.data.name,
|
|
737
|
+
badge: 'Channel',
|
|
738
|
+
summary: channel.data.summary,
|
|
739
|
+
...iconFieldsForResource(channel.data, 'ArrowRightLeft'),
|
|
740
|
+
pages: [
|
|
741
|
+
buildQuickReferenceSection(
|
|
742
|
+
[
|
|
743
|
+
{
|
|
744
|
+
title: 'Overview',
|
|
745
|
+
href: buildUrl(`/docs/${channel.collection}/${channel.data.id}/${channel.data.version}`),
|
|
635
746
|
},
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
747
|
+
isChangelogEnabled() &&
|
|
748
|
+
shouldRenderSideBarSection(channel, 'changelog') && {
|
|
749
|
+
title: 'Changelog',
|
|
750
|
+
href: buildUrl(`/docs/${channel.collection}/${channel.data.id}/${channel.data.version}/changelog`),
|
|
751
|
+
},
|
|
752
|
+
].filter(Boolean) as { title: string; href: string }[]
|
|
753
|
+
),
|
|
754
|
+
docsSection,
|
|
755
|
+
].filter(Boolean) as ChildRef[],
|
|
756
|
+
},
|
|
757
|
+
channel,
|
|
758
|
+
adrs
|
|
759
|
+
);
|
|
641
760
|
|
|
642
761
|
if (channel.data.latestVersion === channel.data.version) {
|
|
643
762
|
// Store reference to versioned key instead of duplicating the full node
|
|
@@ -650,11 +769,15 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
650
769
|
|
|
651
770
|
const teamNodes = teams.reduce(
|
|
652
771
|
(acc, team) => {
|
|
653
|
-
acc[`team:${team.data.id}`] =
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
772
|
+
acc[`team:${team.data.id}`] = withArchitectureDecisionsSection(
|
|
773
|
+
{
|
|
774
|
+
type: 'item',
|
|
775
|
+
title: team.data.name,
|
|
776
|
+
href: buildUrl(`/docs/teams/${team.data.id}`),
|
|
777
|
+
},
|
|
778
|
+
team,
|
|
779
|
+
adrs
|
|
780
|
+
);
|
|
658
781
|
return acc;
|
|
659
782
|
},
|
|
660
783
|
{} as Record<string, NavNode>
|
|
@@ -667,7 +790,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
667
790
|
type: 'group',
|
|
668
791
|
title: 'Domains',
|
|
669
792
|
icon: 'Boxes',
|
|
670
|
-
pages: rootDomains.map((domain) => `domain:${domain.data.id}:${domain.data.version}`),
|
|
793
|
+
pages: sortByResourceName(rootDomains).map((domain) => `domain:${domain.data.id}:${domain.data.version}`),
|
|
671
794
|
};
|
|
672
795
|
}
|
|
673
796
|
|
|
@@ -677,14 +800,21 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
677
800
|
type: 'item',
|
|
678
801
|
title: 'Domains',
|
|
679
802
|
icon: 'Boxes',
|
|
680
|
-
pages: domains.map((domain) => `domain:${domain.data.id}:${domain.data.version}`),
|
|
803
|
+
pages: sortByResourceName(domains).map((domain) => `domain:${domain.data.id}:${domain.data.version}`),
|
|
681
804
|
});
|
|
682
805
|
|
|
683
806
|
const agentsList = createLeaf(agents, {
|
|
684
807
|
type: 'item',
|
|
685
808
|
title: 'Agents',
|
|
686
809
|
icon: 'Bot',
|
|
687
|
-
pages: agents.map((agent) => `agent:${agent.data.id}:${agent.data.version}`),
|
|
810
|
+
pages: sortByResourceName(agents).map((agent) => `agent:${agent.data.id}:${agent.data.version}`),
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
const adrsList = createLeaf(adrs, {
|
|
814
|
+
type: 'item',
|
|
815
|
+
title: 'Decision Records',
|
|
816
|
+
icon: 'BookText',
|
|
817
|
+
pages: groupAdrsByStatus(adrs),
|
|
688
818
|
});
|
|
689
819
|
|
|
690
820
|
const internalServices = services.filter((service) => !service.data.externalSystem);
|
|
@@ -694,91 +824,93 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
694
824
|
type: 'item',
|
|
695
825
|
title: 'Services',
|
|
696
826
|
icon: 'Server',
|
|
697
|
-
pages: internalServices.map((service) => `service:${service.data.id}:${service.data.version}`),
|
|
827
|
+
pages: sortByResourceName(internalServices).map((service) => `service:${service.data.id}:${service.data.version}`),
|
|
698
828
|
});
|
|
699
829
|
|
|
700
830
|
const externalSystemsList = createLeaf(externalServices, {
|
|
701
831
|
type: 'item',
|
|
702
832
|
title: 'External Systems',
|
|
703
833
|
icon: 'Globe',
|
|
704
|
-
pages: externalServices.map((service) => `service:${service.data.id}:${service.data.version}`),
|
|
834
|
+
pages: sortByResourceName(externalServices).map((service) => `service:${service.data.id}:${service.data.version}`),
|
|
705
835
|
});
|
|
706
836
|
|
|
707
837
|
const eventsList = createLeaf(events, {
|
|
708
838
|
type: 'group',
|
|
709
839
|
title: 'Events',
|
|
710
840
|
icon: 'Zap',
|
|
711
|
-
pages: events.map((event) => `event:${event.data.id}:${event.data.version}`),
|
|
841
|
+
pages: sortByResourceName(events).map((event) => `event:${event.data.id}:${event.data.version}`),
|
|
712
842
|
});
|
|
713
843
|
|
|
714
844
|
const commandsList = createLeaf(commands, {
|
|
715
845
|
type: 'group',
|
|
716
846
|
title: 'Commands',
|
|
717
847
|
icon: 'Terminal',
|
|
718
|
-
pages: commands.map((command) => `command:${command.data.id}:${command.data.version}`),
|
|
848
|
+
pages: sortByResourceName(commands).map((command) => `command:${command.data.id}:${command.data.version}`),
|
|
719
849
|
});
|
|
720
850
|
|
|
721
851
|
const queriesList = createLeaf(queries, {
|
|
722
852
|
type: 'group',
|
|
723
853
|
title: 'Queries',
|
|
724
854
|
icon: 'Search',
|
|
725
|
-
pages: queries.map((query) => `query:${query.data.id}:${query.data.version}`),
|
|
855
|
+
pages: sortByResourceName(queries).map((query) => `query:${query.data.id}:${query.data.version}`),
|
|
726
856
|
});
|
|
727
857
|
|
|
728
858
|
const flowsList = createLeaf(flows, {
|
|
729
859
|
type: 'item',
|
|
730
860
|
title: 'Flows',
|
|
731
861
|
icon: 'Waypoints',
|
|
732
|
-
pages: flows.map((flow) => `flow:${flow.data.id}:${flow.data.version}`),
|
|
862
|
+
pages: sortByResourceName(flows).map((flow) => `flow:${flow.data.id}:${flow.data.version}`),
|
|
733
863
|
});
|
|
734
864
|
|
|
735
865
|
const containersList = createLeaf(containers, {
|
|
736
866
|
type: 'item',
|
|
737
867
|
title: 'Data Stores',
|
|
738
868
|
icon: 'Database',
|
|
739
|
-
pages: containers.map((container) => `container:${container.data.id}:${container.data.version}`),
|
|
869
|
+
pages: sortByResourceName(containers).map((container) => `container:${container.data.id}:${container.data.version}`),
|
|
740
870
|
});
|
|
741
871
|
|
|
742
872
|
const dataProductsList = createLeaf(dataProducts, {
|
|
743
873
|
type: 'item',
|
|
744
874
|
title: 'Data Products',
|
|
745
875
|
icon: 'Package',
|
|
746
|
-
pages: dataProducts.map(
|
|
876
|
+
pages: sortByResourceName(dataProducts).map(
|
|
877
|
+
(dataProduct) => `data-product:${dataProduct.data.id}:${dataProduct.data.version}`
|
|
878
|
+
),
|
|
747
879
|
});
|
|
748
880
|
|
|
749
881
|
const entitiesList = createLeaf(entities, {
|
|
750
882
|
type: 'item',
|
|
751
883
|
title: 'Entities',
|
|
752
884
|
icon: 'Box',
|
|
753
|
-
pages: entities.map((entity) => `entity:${entity.data.id}:${entity.data.version}`),
|
|
885
|
+
pages: sortByResourceName(entities).map((entity) => `entity:${entity.data.id}:${entity.data.version}`),
|
|
754
886
|
});
|
|
755
887
|
|
|
756
888
|
const designsList = createLeaf(designs, {
|
|
757
889
|
type: 'item',
|
|
758
890
|
title: 'Designs',
|
|
759
891
|
icon: 'SquareMousePointer',
|
|
760
|
-
pages: designs.map((design) => `design:${design.data.id}`),
|
|
892
|
+
pages: sortByResourceName(designs).map((design) => `design:${design.data.id}`),
|
|
761
893
|
});
|
|
762
894
|
|
|
763
895
|
const teamsList = createLeaf(teams, {
|
|
764
896
|
type: 'group',
|
|
765
897
|
title: 'Teams',
|
|
766
898
|
icon: 'Users',
|
|
767
|
-
pages: teams.map((team) => `team:${team.data.id}`),
|
|
899
|
+
pages: sortByResourceName(teams).map((team) => `team:${team.data.id}`),
|
|
768
900
|
});
|
|
769
901
|
|
|
770
902
|
const usersList = createLeaf(users, {
|
|
771
903
|
type: 'group',
|
|
772
904
|
title: 'Users',
|
|
773
905
|
icon: 'User',
|
|
774
|
-
pages: users.map((user) => `user:${user.data.id}`),
|
|
906
|
+
pages: sortByResourceName(users).map((user) => `user:${user.data.id}`),
|
|
775
907
|
});
|
|
776
908
|
|
|
777
909
|
const channelList = createLeaf(channels, {
|
|
778
910
|
type: 'item',
|
|
779
911
|
title: 'Channels',
|
|
780
912
|
icon: 'ArrowRightLeft',
|
|
781
|
-
pages: channels.map((channel) => `channel:${channel.data.id}:${channel.data.version}`),
|
|
913
|
+
pages: sortByResourceName(channels).map((channel) => `channel:${channel.data.id}:${channel.data.version}`),
|
|
782
914
|
});
|
|
783
915
|
|
|
784
916
|
const messagesChildren = ['list:events', 'list:commands', 'list:queries'].filter(
|
|
@@ -811,6 +943,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
811
943
|
'list:domains',
|
|
812
944
|
'list:services',
|
|
813
945
|
'list:agents',
|
|
946
|
+
'list:adrs',
|
|
814
947
|
'list:external-systems',
|
|
815
948
|
'list:messages',
|
|
816
949
|
'list:channels',
|
|
@@ -825,6 +958,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
825
958
|
domainsList,
|
|
826
959
|
servicesList,
|
|
827
960
|
agentsList,
|
|
961
|
+
adrsList,
|
|
828
962
|
externalSystemsList,
|
|
829
963
|
messagesList,
|
|
830
964
|
channelList,
|
|
@@ -836,7 +970,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
836
970
|
peopleList,
|
|
837
971
|
];
|
|
838
972
|
|
|
839
|
-
const validAllChildren = allChildrenKeys
|
|
973
|
+
const validAllChildren = allChildrenKeys
|
|
974
|
+
.map((key, idx) => ({ key, node: allChildrenNodes[idx] }))
|
|
975
|
+
.filter((item): item is { key: string; node: NavNode } => item.node !== undefined)
|
|
976
|
+
.sort((a, b) => a.node.title.localeCompare(b.node.title))
|
|
977
|
+
.map((item) => item.key);
|
|
840
978
|
|
|
841
979
|
let allList;
|
|
842
980
|
if (validAllChildren.length > 0) {
|
|
@@ -852,6 +990,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
852
990
|
...(domainsList ? { 'list:domains': domainsList } : {}),
|
|
853
991
|
...(servicesList ? { 'list:services': servicesList } : {}),
|
|
854
992
|
...(agentsList ? { 'list:agents': agentsList } : {}),
|
|
993
|
+
...(adrsList ? { 'list:adrs': adrsList } : {}),
|
|
855
994
|
...(externalSystemsList ? { 'list:external-systems': externalSystemsList } : {}),
|
|
856
995
|
...(eventsList ? { 'list:events': eventsList } : {}),
|
|
857
996
|
...(commandsList ? { 'list:commands': commandsList } : {}),
|
|
@@ -892,6 +1031,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
892
1031
|
...rootDomainsNodes,
|
|
893
1032
|
...domainNodes,
|
|
894
1033
|
...agentNodes,
|
|
1034
|
+
...adrNodes,
|
|
895
1035
|
...serviceNodes,
|
|
896
1036
|
...messageNodes,
|
|
897
1037
|
...channelNodes,
|
|
@@ -901,6 +1041,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
901
1041
|
...flowNodes,
|
|
902
1042
|
...userNodes,
|
|
903
1043
|
...teamNodes,
|
|
1044
|
+
...diagramNodes,
|
|
904
1045
|
...designNodes,
|
|
905
1046
|
...systemNode,
|
|
906
1047
|
...allNodes,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type CollectionTypes =
|
|
2
2
|
| 'agents'
|
|
3
|
+
| 'adrs'
|
|
3
4
|
| 'commands'
|
|
4
5
|
| 'events'
|
|
5
6
|
| 'queries'
|
|
@@ -15,6 +16,7 @@ export type CollectionMessageTypes = 'commands' | 'events' | 'queries';
|
|
|
15
16
|
export type CollectionUserTypes = 'users' | 'teams';
|
|
16
17
|
export type PageTypes =
|
|
17
18
|
| 'agents'
|
|
19
|
+
| 'adrs'
|
|
18
20
|
| 'events'
|
|
19
21
|
| 'commands'
|
|
20
22
|
| 'queries'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const ADR_STATUS = {
|
|
2
|
+
PROPOSED: 'proposed',
|
|
3
|
+
ACCEPTED: 'accepted',
|
|
4
|
+
REJECTED: 'rejected',
|
|
5
|
+
DEPRECATED: 'deprecated',
|
|
6
|
+
SUPERSEDED: 'superseded',
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export const ADR_STATUS_VALUES = [
|
|
10
|
+
ADR_STATUS.PROPOSED,
|
|
11
|
+
ADR_STATUS.ACCEPTED,
|
|
12
|
+
ADR_STATUS.REJECTED,
|
|
13
|
+
ADR_STATUS.DEPRECATED,
|
|
14
|
+
ADR_STATUS.SUPERSEDED,
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export type AdrStatus = (typeof ADR_STATUS)[keyof typeof ADR_STATUS];
|
|
18
|
+
|
|
19
|
+
export const adrStatusBadgeColor: Record<AdrStatus, string> = {
|
|
20
|
+
[ADR_STATUS.PROPOSED]: 'amber',
|
|
21
|
+
[ADR_STATUS.ACCEPTED]: 'green',
|
|
22
|
+
[ADR_STATUS.REJECTED]: 'red',
|
|
23
|
+
[ADR_STATUS.DEPRECATED]: 'gray',
|
|
24
|
+
[ADR_STATUS.SUPERSEDED]: 'purple',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const isAdrCollection = (collection: string | undefined): collection is 'adrs' => collection === 'adrs';
|
|
28
|
+
|
|
29
|
+
export const hasAdrStatus = (adr: { data?: { status?: string } }, status: AdrStatus) => adr.data?.status === status;
|
|
30
|
+
|
|
31
|
+
export const isDeprecatedAdr = (adr: { data?: { status?: string } }) => hasAdrStatus(adr, ADR_STATUS.DEPRECATED);
|
|
32
|
+
|
|
33
|
+
export const isSupersededAdr = (adr: { data?: { status?: string } }) => hasAdrStatus(adr, ADR_STATUS.SUPERSEDED);
|
|
34
|
+
|
|
35
|
+
export const formatAdrStatus = (status: AdrStatus) =>
|
|
36
|
+
status
|
|
37
|
+
.split('-')
|
|
38
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
39
|
+
.join(' ');
|
|
40
|
+
|
|
41
|
+
export const formatAdrDate = (date: Date) =>
|
|
42
|
+
new Intl.DateTimeFormat('en-US', {
|
|
43
|
+
timeZone: 'UTC',
|
|
44
|
+
year: 'numeric',
|
|
45
|
+
month: 'long',
|
|
46
|
+
day: 'numeric',
|
|
47
|
+
}).format(date);
|
|
48
|
+
|
|
49
|
+
export const createAdrStatusBadge = (status: AdrStatus) => ({
|
|
50
|
+
content: formatAdrStatus(status),
|
|
51
|
+
backgroundColor: adrStatusBadgeColor[status],
|
|
52
|
+
textColor: adrStatusBadgeColor[status],
|
|
53
|
+
});
|