@eventcatalog/core 4.9.0 → 4.10.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.
Files changed (60) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-XQHS36GO.js → chunk-5XURY2JV.js} +1 -1
  6. package/dist/{chunk-3CGSSMTK.js → chunk-BDFTJVGN.js} +1 -1
  7. package/dist/{chunk-HKVOSQTD.js → chunk-BQXEWQ5J.js} +1 -1
  8. package/dist/{chunk-MPHX5C7M.js → chunk-HFAQXAG3.js} +1 -1
  9. package/dist/{chunk-LVGQ23LR.js → chunk-IC6XSXJO.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +5 -5
  14. package/dist/generate.cjs +1 -1
  15. package/dist/generate.js +3 -3
  16. package/dist/utils/cli-logger.cjs +1 -1
  17. package/dist/utils/cli-logger.js +2 -2
  18. package/eventcatalog/src/components/Badge.astro +3 -1
  19. package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +0 -5
  20. package/eventcatalog/src/components/MDX/Design/Design.astro +2 -0
  21. package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -0
  22. package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -0
  23. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +5 -7
  24. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -0
  25. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +121 -88
  26. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +55 -7
  27. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.spec.ts +59 -15
  28. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +53 -7
  29. package/eventcatalog/src/content.config.ts +70 -0
  30. package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +19 -0
  31. package/eventcatalog/src/enterprise/fields/pages/fields.astro +2 -0
  32. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +1 -1
  33. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +16 -15
  34. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +21 -17
  35. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
  36. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +4 -4
  37. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +16 -8
  38. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +48 -65
  39. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +45 -18
  40. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -1
  41. package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -1
  42. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +5 -1
  43. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +2 -0
  44. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -0
  45. package/eventcatalog/src/stores/sidebar-store/builders/adr.ts +96 -34
  46. package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +167 -75
  47. package/eventcatalog/src/stores/sidebar-store/builders/container.ts +135 -59
  48. package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +144 -58
  49. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +306 -188
  50. package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +108 -39
  51. package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +147 -63
  52. package/eventcatalog/src/stores/sidebar-store/builders/message.ts +212 -121
  53. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +223 -127
  54. package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +3 -23
  55. package/eventcatalog/src/stores/sidebar-store/builders/system.ts +187 -97
  56. package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +678 -0
  57. package/eventcatalog/src/stores/sidebar-store/state.ts +66 -36
  58. package/eventcatalog/src/styles/tailwind.css +82 -0
  59. package/eventcatalog/src/utils/collections/resource-docs.ts +1 -0
  60. package/package.json +3 -3
@@ -1,4 +1,5 @@
1
1
  import { getCollection } from 'astro:content';
2
+ import { getSidebarForResource, indexSidebarsByFolder } from './custom-sidebar';
2
3
  import type { CollectionEntry } from 'astro:content';
3
4
  import { getAgents } from '@utils/collections/agents';
4
5
  import { getAdrAliasNodeKey, getAdrNodeKey, getAdrs, type Adr } from '@utils/collections/adrs';
@@ -40,7 +41,7 @@ import {
40
41
  shouldRenderSideBarSection,
41
42
  withArchitectureDecisionsSection,
42
43
  } from './builders/shared';
43
- import { isArchitectureGraphEnabled, isChangelogEnabled } from '@utils/feature';
44
+ import { isArchitectureGraphEnabled, isChangelogEnabled, isResourceDocsEnabled } from '@utils/feature';
44
45
 
45
46
  export type { NavigationData, NavNode, ChildRef };
46
47
 
@@ -296,6 +297,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
296
297
  ubiquitousLanguages,
297
298
  resourceDocs,
298
299
  resourceDocCategories,
300
+ customSidebarEntries,
299
301
  ] = await Promise.all([
300
302
  getDomains({ getAllVersions: false, includeServicesInSubdomains: false }),
301
303
  getSystems({ getAllVersions: false }),
@@ -316,8 +318,12 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
316
318
  getCollection('ubiquitousLanguages'),
317
319
  getResourceDocs(),
318
320
  getResourceDocCategories(),
321
+ getCollection('sidebars'),
319
322
  ]);
320
323
 
324
+ // Optional per-resource `sidebar.json` overrides, keyed by the folder they sit in.
325
+ const customSidebars = indexSidebarsByFolder(customSidebarEntries);
326
+
321
327
  // Calculate derived lists to avoid extra fetches
322
328
  const allSubDomainIds = new Set(domains.flatMap((d) => (d.data.domains || []).map((sd: any) => sd.data.id)));
323
329
  const rootDomains = domains.filter((d) => !allSubDomainIds.has(d.data.id));
@@ -328,6 +334,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
328
334
  const messages = [...allEvents, ...allCommands, ...allQueries];
329
335
 
330
336
  const context = {
337
+ resourceDocsEnabled: isResourceDocsEnabled(),
331
338
  agents,
332
339
  services,
333
340
  domains,
@@ -433,11 +440,14 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
433
440
 
434
441
  const flowNodes = flows.reduce(
435
442
  (acc, flow) => {
436
- acc[`flow:${flow.data.id}:${flow.data.version}`] = withArchitectureDecisionsSection(
437
- buildFlowNode(flow, context),
438
- flow,
439
- adrs
440
- );
443
+ const sidebar = getSidebarForResource(customSidebars, flow);
444
+ const node = buildFlowNode(flow, context, { sidebar });
445
+ const versionedKey = `flow:${flow.data.id}:${flow.data.version}`;
446
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, flow, adrs);
447
+ if (flow.data.latestVersion === flow.data.version) {
448
+ // Store reference to versioned key instead of duplicating the full node
449
+ acc[`flow:${flow.data.id}`] = versionedKey;
450
+ }
441
451
  return acc;
442
452
  },
443
453
  {} as Record<string, NavNode>
@@ -446,7 +456,10 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
446
456
  const domainNodes = domainsWithOwners.reduce(
447
457
  (acc, { domain, owners }) => {
448
458
  const versionedKey = `domain:${domain.data.id}:${domain.data.version}`;
449
- acc[versionedKey] = withArchitectureDecisionsSection(buildDomainNode(domain, owners, context), domain, adrs);
459
+ const sidebar = getSidebarForResource(customSidebars, domain);
460
+ const domainNode = buildDomainNode(domain, owners, context, { sidebar });
461
+ // A custom sidebar decides for itself whether (and where) `$decision-records` renders.
462
+ acc[versionedKey] = sidebar ? domainNode : withArchitectureDecisionsSection(domainNode, domain, adrs);
450
463
  if (domain.data.latestVersion === domain.data.version) {
451
464
  // Store reference to versioned key instead of duplicating the full node
452
465
  acc[`domain:${domain.data.id}`] = versionedKey;
@@ -538,11 +551,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
538
551
  (acc, { agent, owners }) => {
539
552
  const versionedKey = `agent:${agent.data.id}:${agent.data.version}`;
540
553
  const agentChannels = agentChannelsMap.get(`${agent.data.id}:${agent.data.version}`) || [];
541
- acc[versionedKey] = withArchitectureDecisionsSection(
542
- buildAgentNode(agent, owners, context, agentChannels, flowRefsByAgent.get(versionedKey) || []),
543
- agent,
544
- adrs
545
- );
554
+ const sidebar = getSidebarForResource(customSidebars, agent);
555
+ const node = buildAgentNode(agent, owners, context, agentChannels, flowRefsByAgent.get(versionedKey) || [], { sidebar });
556
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, agent, adrs);
546
557
  if (agent.data.latestVersion === agent.data.version) {
547
558
  acc[`agent:${agent.data.id}`] = versionedKey;
548
559
  }
@@ -555,11 +566,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
555
566
  (acc, { service, owners }) => {
556
567
  const versionedKey = `service:${service.data.id}:${service.data.version}`;
557
568
  const serviceChannels = serviceChannelsMap.get(`${service.data.id}:${service.data.version}`) || [];
558
- acc[versionedKey] = withArchitectureDecisionsSection(
559
- buildServiceNode(service, owners, context, serviceChannels, flowRefsByService.get(versionedKey) || []),
560
- service,
561
- adrs
562
- );
569
+ const sidebar = getSidebarForResource(customSidebars, service);
570
+ const node = buildServiceNode(service, owners, context, serviceChannels, flowRefsByService.get(versionedKey) || [], {
571
+ sidebar,
572
+ });
573
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, service, adrs);
563
574
  if (service.data.latestVersion === service.data.version) {
564
575
  // Store reference to versioned key instead of duplicating the full node
565
576
  acc[`service:${service.data.id}`] = versionedKey;
@@ -612,14 +623,17 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
612
623
  const hasFieldUsage = messagesWithFieldUsage.has(message.data.id);
613
624
  const triggers = getTriggersOfMessage(messageReceivers, message, messages);
614
625
  const triggeredBy = getTriggeredByOfMessage(messageReceivers, message, messages);
615
- acc[versionedKey] = withArchitectureDecisionsSection(
616
- buildMessageNode(message, owners, context, hasFieldUsage, flowRefsByMessage.get(versionedKey) || [], {
617
- triggers,
618
- triggeredBy,
619
- }),
626
+ const sidebar = getSidebarForResource(customSidebars, message);
627
+ const node = buildMessageNode(
620
628
  message,
621
- adrs
629
+ owners,
630
+ context,
631
+ hasFieldUsage,
632
+ flowRefsByMessage.get(versionedKey) || [],
633
+ { triggers, triggeredBy },
634
+ { sidebar }
622
635
  );
636
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, message, adrs);
623
637
  if (message.data.latestVersion === message.data.version) {
624
638
  // Store reference to versioned key instead of duplicating the full node
625
639
  acc[`${type}:${message.data.id}`] = versionedKey;
@@ -634,11 +648,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
634
648
  const containerNodes = containerWithOwners.reduce(
635
649
  (acc, { container, owners }) => {
636
650
  const versionedKey = `container:${container.data.id}:${container.data.version}`;
637
- acc[versionedKey] = withArchitectureDecisionsSection(
638
- buildContainerNode(container, owners, context, flowRefsByContainer.get(versionedKey) || []),
639
- container,
640
- adrs
641
- );
651
+ const sidebar = getSidebarForResource(customSidebars, container);
652
+ const node = buildContainerNode(container, owners, context, flowRefsByContainer.get(versionedKey) || [], { sidebar });
653
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, container, adrs);
642
654
  if (container.data.latestVersion === container.data.version) {
643
655
  // Store reference to versioned key instead of duplicating the full node
644
656
  acc[`container:${container.data.id}`] = versionedKey;
@@ -651,7 +663,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
651
663
  const systemNodes = systemWithOwners.reduce(
652
664
  (acc, { system, owners }) => {
653
665
  const versionedKey = `system:${system.data.id}:${system.data.version}`;
654
- acc[versionedKey] = withArchitectureDecisionsSection(buildSystemNode(system, owners, context), system, adrs);
666
+ const sidebar = getSidebarForResource(customSidebars, system);
667
+ const node = buildSystemNode(system, owners, context, { sidebar });
668
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, system, adrs);
655
669
  if (system.data.latestVersion === system.data.version) {
656
670
  // Store reference to versioned key instead of duplicating the full node
657
671
  acc[`system:${system.data.id}`] = versionedKey;
@@ -670,12 +684,24 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
670
684
  );
671
685
 
672
686
  const dataProductContext = {
687
+ resourceDocsEnabled: isResourceDocsEnabled(),
673
688
  events,
674
689
  commands,
675
690
  queries,
676
691
  services,
677
692
  containers,
678
693
  channels,
694
+ adrs,
695
+ // Included so data-product sidebar.json files resolve the same refs as every other
696
+ // resource (cross-resource specs, schema-existence checks, latest-only pins).
697
+ domains,
698
+ systems,
699
+ agents,
700
+ flows,
701
+ entities,
702
+ dataProducts,
703
+ diagrams,
704
+ schemas,
679
705
  resourceDocs,
680
706
  resourceDocCategories,
681
707
  };
@@ -685,11 +711,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
685
711
  const dataProductNodes = dataProductWithOwners.reduce(
686
712
  (acc, { dataProduct, owners }) => {
687
713
  const versionedKey = `data-product:${dataProduct.data.id}:${dataProduct.data.version}`;
688
- acc[versionedKey] = withArchitectureDecisionsSection(
689
- buildDataProductNode(dataProduct, owners, dataProductContext, flowRefsByDataProduct.get(versionedKey) || []),
690
- dataProduct,
691
- adrs
692
- );
714
+ const sidebar = getSidebarForResource(customSidebars, dataProduct);
715
+ const node = buildDataProductNode(dataProduct, owners, dataProductContext, flowRefsByDataProduct.get(versionedKey) || [], {
716
+ sidebar,
717
+ });
718
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, dataProduct, adrs);
693
719
  if (dataProduct.data.latestVersion === dataProduct.data.version) {
694
720
  acc[`data-product:${dataProduct.data.id}`] = versionedKey;
695
721
  }
@@ -701,7 +727,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
701
727
  const adrNodes = adrsWithOwners.reduce(
702
728
  (acc, { adr, owners, decisionMakers }) => {
703
729
  const versionedKey = getAdrNodeKey(adr);
704
- acc[versionedKey] = buildAdrNode(adr, owners, decisionMakers, context);
730
+ acc[versionedKey] = buildAdrNode(adr, owners, decisionMakers, context, {
731
+ sidebar: getSidebarForResource(customSidebars, adr),
732
+ });
705
733
  if (adr.data.latestVersion === adr.data.version) {
706
734
  acc[getAdrAliasNodeKey(adr)] = versionedKey;
707
735
  }
@@ -713,7 +741,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
713
741
  const entityNodes = entitiesWithOwners.reduce(
714
742
  (acc, { entity, owners }) => {
715
743
  const versionedKey = `entity:${entity.data.id}:${entity.data.version}`;
716
- acc[versionedKey] = withArchitectureDecisionsSection(buildEntityNode(entity, owners, context), entity, adrs);
744
+ const sidebar = getSidebarForResource(customSidebars, entity);
745
+ const node = buildEntityNode(entity, owners, context, { sidebar });
746
+ acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, entity, adrs);
717
747
  if (entity.data.latestVersion === entity.data.version) {
718
748
  acc[`entity:${entity.data.id}`] = versionedKey;
719
749
  }
@@ -20,6 +20,88 @@
20
20
  font-weight: 400;
21
21
  }
22
22
 
23
+ /*
24
+ * Docs typography scale.
25
+ *
26
+ * Tailwind Typography's defaults are tuned for long-form articles: 1.75 line-height,
27
+ * paragraph gaps of 1.25em and heading gaps of 2em. Reference documentation (Stripe,
28
+ * GitHub, Vercel, Mintlify) measures at ~1.6 line-height, 1em paragraph gaps and heading
29
+ * gaps of ~1.5em with 500–600 weight headings. Tighten to match so pages read as reference
30
+ * material rather than essays.
31
+ *
32
+ * Scoped to `.docs-layout` (resource, resource-doc, resources, language pages) and
33
+ * `.custom-docs-shell` (custom documentation) so other
34
+ * prose surfaces — chat panel, admonitions on custom pages, the homepage — keep the plugin
35
+ * defaults. These rules are unlayered, so they win over the plugin's `@layer utilities`
36
+ * output regardless of source order; `h2 + *` etc. are restated because the plugin's
37
+ * zero-specificity `:where()` versions would otherwise lose to the rules above them.
38
+ */
39
+ .docs-layout .prose,
40
+ .custom-docs-shell .prose {
41
+ line-height: 1.6;
42
+ }
43
+
44
+ .docs-layout .prose p,
45
+ .custom-docs-shell .prose p,
46
+ .docs-layout .prose ul,
47
+ .custom-docs-shell .prose ul,
48
+ .docs-layout .prose ol,
49
+ .custom-docs-shell .prose ol,
50
+ .docs-layout .prose blockquote,
51
+ .custom-docs-shell .prose blockquote,
52
+ .docs-layout .prose table,
53
+ .custom-docs-shell .prose table {
54
+ margin-top: 1em;
55
+ margin-bottom: 1em;
56
+ }
57
+
58
+ .docs-layout .prose li,
59
+ .custom-docs-shell .prose li {
60
+ margin-top: 0.25em;
61
+ margin-bottom: 0.25em;
62
+ }
63
+
64
+ .docs-layout .prose h2,
65
+ .custom-docs-shell .prose h2 {
66
+ font-weight: 600;
67
+ letter-spacing: -0.01em;
68
+ margin-top: 1.6em;
69
+ margin-bottom: 0.6em;
70
+ }
71
+
72
+ .docs-layout .prose h3,
73
+ .custom-docs-shell .prose h3 {
74
+ font-weight: 600;
75
+ margin-top: 1.5em;
76
+ margin-bottom: 0.5em;
77
+ }
78
+
79
+ .docs-layout .prose h4,
80
+ .custom-docs-shell .prose h4 {
81
+ font-weight: 600;
82
+ margin-top: 1.4em;
83
+ margin-bottom: 0.4em;
84
+ }
85
+
86
+ .docs-layout .prose h2 + *,
87
+ .custom-docs-shell .prose h2 + *,
88
+ .docs-layout .prose h3 + *,
89
+ .custom-docs-shell .prose h3 + *,
90
+ .docs-layout .prose h4 + *,
91
+ .custom-docs-shell .prose h4 + * {
92
+ margin-top: 0;
93
+ }
94
+
95
+ .docs-layout .prose > :first-child,
96
+ .custom-docs-shell .prose > :first-child {
97
+ margin-top: 0;
98
+ }
99
+
100
+ .docs-layout .prose > :last-child,
101
+ .custom-docs-shell .prose > :last-child {
102
+ margin-bottom: 0;
103
+ }
104
+
23
105
  /* Dark mode uses data-theme attribute, not prefers-color-scheme */
24
106
  @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
25
107
 
@@ -6,6 +6,7 @@ export {
6
6
  getResourceDocCategoriesForResource,
7
7
  getResourceDocsForResource,
8
8
  getGroupedResourceDocsByType,
9
+ getResourceDocTypeLabel,
9
10
  type ResourceCollection,
10
11
  type ResourceDocEntry,
11
12
  type ResourceDocCategoryEntry,
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "4.9.0",
10
+ "version": "4.10.0",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -119,9 +119,9 @@
119
119
  "update-notifier": "^7.3.1",
120
120
  "uuid": "^11.1.1",
121
121
  "zod": "^4.3.6",
122
- "@eventcatalog/visualiser": "^4.1.3",
123
122
  "@eventcatalog/linter": "1.1.17",
124
- "@eventcatalog/sdk": "2.28.1"
123
+ "@eventcatalog/sdk": "2.28.1",
124
+ "@eventcatalog/visualiser": "^4.1.3"
125
125
  },
126
126
  "devDependencies": {
127
127
  "@astrojs/check": "^0.9.10",