@eventcatalog/core 2.54.1 → 2.54.3

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/README.md CHANGED
@@ -140,15 +140,6 @@ Thank you to our project sponsors.
140
140
 
141
141
  <hr />
142
142
 
143
- <div align="center">
144
- <img alt="oso" src="./images/sponsors/oso-logo-green.png" width="30%" />
145
- <p style="margin: 0; padding: 0;">Delivering Apache Kafka professional services to your business
146
- </p>
147
- <a href="https://oso.sh/?utm_source=eventcatalog&utm_medium=web&utm_campaign=sponsorship" target="_blank" >Learn more</a>
148
- </div>
149
-
150
- <hr />
151
-
152
143
  _Sponsors help make EventCatalog sustainable, want to help the project? Get in touch! Or [visit our sponsor page](https://www.eventcatalog.dev/support)._
153
144
 
154
145
  # Enterprise support
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "2.54.1";
40
+ var version = "2.54.3";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-7NKHMS4K.js";
4
- import "../chunk-EUDMSTHT.js";
3
+ } from "../chunk-YXXP2UQA.js";
4
+ import "../chunk-VH23O4GO.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "2.54.1";
109
+ var version = "2.54.3";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-ONQOSPKG.js";
4
- import "../chunk-7NKHMS4K.js";
5
- import "../chunk-EUDMSTHT.js";
3
+ } from "../chunk-JQS6ADYS.js";
4
+ import "../chunk-YXXP2UQA.js";
5
+ import "../chunk-VH23O4GO.js";
6
6
  import "../chunk-E7TXTI7G.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-7NKHMS4K.js";
3
+ } from "./chunk-YXXP2UQA.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.54.1";
2
+ var version = "2.54.3";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-EUDMSTHT.js";
3
+ } from "./chunk-VH23O4GO.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.54.1";
28
+ var version = "2.54.3";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-EUDMSTHT.js";
3
+ } from "./chunk-VH23O4GO.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -157,7 +157,7 @@ var import_axios = __toESM(require("axios"), 1);
157
157
  var import_os = __toESM(require("os"), 1);
158
158
 
159
159
  // package.json
160
- var version = "2.54.1";
160
+ var version = "2.54.3";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-XE6PFSH5.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-ONQOSPKG.js";
10
- import "./chunk-7NKHMS4K.js";
9
+ } from "./chunk-JQS6ADYS.js";
10
+ import "./chunk-YXXP2UQA.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-LDBRNJIL.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-EUDMSTHT.js";
18
+ } from "./chunk-VH23O4GO.js";
19
19
  import {
20
20
  getProjectOutDir,
21
21
  isAuthEnabled,
@@ -4,28 +4,47 @@ import { getNodesAndEdges } from '@utils/node-graphs/domain-entity-map.ts';
4
4
  import Admonition from '@components/MDX/Admonition';
5
5
  import NodeGraph from '../NodeGraph/NodeGraph';
6
6
  import { getVersionFromCollection } from '@utils/collections/versions';
7
+ import { getServices } from '@utils/collections/services';
7
8
 
8
- const { id, version = 'latest', maxHeight, includeKey = true, entities } = Astro.props;
9
+ const { id, version = 'latest', maxHeight, includeKey = true, entities, collection = 'domains', ...rest } = Astro.props;
10
+ let resource = null;
9
11
 
10
- // Find the flow for the given id and version
11
- const domains = await getDomains();
12
- const domainCollection = getVersionFromCollection(domains, id, version) || [];
13
- const domain = domainCollection[0];
12
+ let resourceId = id;
13
+
14
+ // If the user did not provide an id, we need to use the id from the rest props (the collection)
15
+ const isAstroGeneratedId = id.match(/-\d+\.\d+\.\d+$/);
16
+ if (isAstroGeneratedId) {
17
+ resourceId = rest.data.id;
18
+ }
19
+
20
+ if (collection === 'domains') {
21
+ const domains = await getDomains();
22
+ const domainCollection = getVersionFromCollection(domains, resourceId, version) || [];
23
+ resource = domainCollection[0];
24
+ } else if (collection === 'services') {
25
+ const services = await getServices();
26
+ const serviceCollection = getVersionFromCollection(services, resourceId, version) || [];
27
+ resource = serviceCollection[0];
28
+ } else {
29
+ throw new Error(`Invalid collection: ${collection}`);
30
+ }
14
31
 
15
32
  const { nodes, edges } = await getNodesAndEdges({
16
- id: id,
17
- version: domain?.data?.version,
33
+ id: resourceId,
34
+ version: resource?.data?.version,
18
35
  ...(entities ? { entities } : {}), // Pass entities if provided
36
+ type: collection,
19
37
  });
20
38
  ---
21
39
 
22
40
  {
23
- !domain && (
41
+ !resource && (
24
42
  <Admonition type="warning">
25
43
  <div>
26
44
  <span class="block font-bold">{`<EntityMap/>`} failed to load</span>
27
45
  <span class="block">
28
- Tried to load domain id: {id} with version {version}. Make sure you have this domain defined in your project.
46
+ Tried to load {collection} id: {id} with version {version}. Make sure you have this {collection} defined in your
47
+ project.
29
48
  </span>
30
49
  </div>
31
50
  </Admonition>
@@ -49,7 +68,7 @@ const { nodes, edges } = await getNodesAndEdges({
49
68
  linkTo={'visualiser'}
50
69
  mode="simple"
51
70
  includeKey={includeKey}
52
- footerLabel=`Entity Map - ${domain?.data?.name} - v(${domain?.data?.version})`
71
+ footerLabel={`Entity Map - ${resource?.data?.name} - v(${resource?.data?.version})`}
53
72
  client:only="react"
54
73
  portalId={`${id}-entity-map-portal`}
55
74
  />
@@ -44,7 +44,7 @@ const components = (props: any) => {
44
44
  MessageTable: (mdxProp: any) => jsx(MessageTable, { ...props, ...mdxProp }),
45
45
  EntityPropertiesTable: (mdxProp: any) => jsx(EntityPropertiesTable, { ...props, ...mdxProp }),
46
46
  NodeGraph: (mdxProp: any) => jsx(NodeGraphPortal, { ...props.data, ...mdxProp, props, mdxProp }),
47
- EntityMap,
47
+ EntityMap: (mdxProp: any) => jsx(EntityMap, { ...props, ...mdxProp }),
48
48
  OpenAPI,
49
49
  ResourceGroupTable: (mdxProp: any) => jsx(ResourceGroupTable, { ...props, ...mdxProp }),
50
50
  ResourceLink: (mdxProp: any) => jsx(ResourceLink, { ...props, ...mdxProp }),
@@ -35,6 +35,7 @@ const SearchResultItem = React.memo<{
35
35
  if (type === 'openapi') return 'OpenAPI';
36
36
  if (type === 'language') return 'Language';
37
37
  if (type === 'entities') return 'Entity';
38
+ if (type === 'queries') return 'Query';
38
39
  // For plurals, remove 's' at the end, otherwise just capitalize
39
40
  if (type.endsWith('s')) {
40
41
  return type.charAt(0).toUpperCase() + type.slice(1, -1);
@@ -113,8 +114,6 @@ const SearchModal: React.FC = () => {
113
114
  useEffect(() => {
114
115
  const handleModalToggle = (event: CustomEvent) => {
115
116
  setIsOpen(event.detail.isOpen);
116
-
117
- // Load all results when modal opens - will be handled by another effect
118
117
  };
119
118
 
120
119
  window.addEventListener('searchModalToggle', handleModalToggle as EventListener);
@@ -286,57 +285,6 @@ const SearchModal: React.FC = () => {
286
285
  return 'other';
287
286
  }, []);
288
287
 
289
- // Load all results using a wildcard search
290
- const loadAllResults = useCallback(async () => {
291
- if (!pagefind) return;
292
-
293
- setIsLoading(true);
294
- try {
295
- // Use a common word or wildcard to get all indexed content
296
- const search = await pagefind.search('a');
297
- if (!search || !search.results) {
298
- return;
299
- }
300
- const processedResults: SearchResult[] = [];
301
-
302
- for (const result of search.results) {
303
- const data = await result.data();
304
- const type = getTypeFromUrl(data.url);
305
-
306
- // Clean the title by removing any "Type | " prefix if it exists
307
- let cleanTitle = data.meta?.title || 'Untitled';
308
-
309
- // Use regex for more efficient prefix removal
310
- cleanTitle = cleanTitle.replace(
311
- /^(Domains?|Services?|Events?|Commands?|Queries?|Entities?|Channels?|Teams?|Users?|Language) \| /,
312
- ''
313
- );
314
-
315
- processedResults.push({
316
- id: result.id,
317
- name: cleanTitle,
318
- type: type,
319
- description: data.excerpt || '',
320
- url: data.url,
321
- tags: data.meta?.tags ? data.meta.tags.split(',').map((tag: string) => tag.trim()) : [],
322
- });
323
- }
324
-
325
- setAllResults(processedResults);
326
- } catch (error) {
327
- console.error('Error loading all results:', error);
328
- } finally {
329
- setIsLoading(false);
330
- }
331
- }, [pagefind, getTypeFromUrl]);
332
-
333
- // Load results when modal opens and pagefind is available
334
- useEffect(() => {
335
- if (isOpen && pagefind && !pagefindLoadError) {
336
- loadAllResults();
337
- }
338
- }, [isOpen, pagefind, pagefindLoadError, loadAllResults]);
339
-
340
288
  // Perform search
341
289
  const performSearch = useCallback(
342
290
  async (searchTerm: string): Promise<SearchResult[]> => {
@@ -407,7 +355,7 @@ const SearchModal: React.FC = () => {
407
355
  [exactMatch, currentSearch]
408
356
  );
409
357
 
410
- // Update results
358
+ // Update results with debouncing
411
359
  const updateResults = useCallback(async () => {
412
360
  if (currentSearch.trim()) {
413
361
  const results = await performSearch(currentSearch);
@@ -417,10 +365,19 @@ const SearchModal: React.FC = () => {
417
365
  }
418
366
  }, [currentSearch, performSearch]);
419
367
 
420
- // Search on input change
368
+ // Search on input change with debouncing
421
369
  useEffect(() => {
422
- updateResults();
423
- }, [updateResults]);
370
+ if (!currentSearch.trim()) {
371
+ setAllResults([]);
372
+ return;
373
+ }
374
+
375
+ const debounceTimer = setTimeout(() => {
376
+ updateResults();
377
+ }, 300); // 300ms debounce
378
+
379
+ return () => clearTimeout(debounceTimer);
380
+ }, [currentSearch, updateResults]);
424
381
 
425
382
  // Handle input change
426
383
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -578,7 +535,7 @@ const SearchModal: React.FC = () => {
578
535
  <div className="flex items-center gap-1.5">
579
536
  <span>All Resources</span>
580
537
  </div>
581
- <span className="text-xs text-gray-400">{counts.all}</span>
538
+ <span className="text-xs text-gray-700 font-thin">{counts.all}</span>
582
539
  </div>
583
540
  </button>
584
541
  </div>
@@ -586,7 +543,7 @@ const SearchModal: React.FC = () => {
586
543
 
587
544
  {/* Resources Section */}
588
545
  <div className="mb-4">
589
- <h3 className="text-xs font-medium text-gray-600 mb-2">Resources</h3>
546
+ <h3 className="text-xs font-bold text-gray-600 mb-2">Resources</h3>
590
547
  <div className="space-y-1">
591
548
  {Object.entries({
592
549
  domains: 'Domains',
@@ -610,9 +567,9 @@ const SearchModal: React.FC = () => {
610
567
  <div className="flex items-center justify-between">
611
568
  <div className="flex items-center gap-1.5">
612
569
  {IconComponent && <IconComponent className="h-3 w-3" />}
613
- <span>{label}</span>
570
+ <span className="font-thin">{label}</span>
614
571
  </div>
615
- <span className="text-xs text-gray-400">{counts[key as keyof typeof counts]}</span>
572
+ <span className="text-xs text-gray-700 font-thin">{counts[key as keyof typeof counts]}</span>
616
573
  </div>
617
574
  </button>
618
575
  );
@@ -622,7 +579,7 @@ const SearchModal: React.FC = () => {
622
579
 
623
580
  {/* Messages Section */}
624
581
  <div className="mb-4">
625
- <h3 className="text-xs font-medium text-gray-600 mb-2">Messages</h3>
582
+ <h3 className="text-xs font-bold text-gray-600 mb-2">Messages</h3>
626
583
  <div className="space-y-1">
627
584
  {Object.entries({
628
585
  events: 'Events',
@@ -646,9 +603,9 @@ const SearchModal: React.FC = () => {
646
603
  <div className="flex items-center justify-between">
647
604
  <div className="flex items-center gap-1.5">
648
605
  {IconComponent && <IconComponent className="h-3 w-3" />}
649
- <span>{label}</span>
606
+ <span className="font-thin">{label}</span>
650
607
  </div>
651
- <span className="text-xs text-gray-400">{counts[key as keyof typeof counts]}</span>
608
+ <span className="text-xs text-gray-700 font-thin">{counts[key as keyof typeof counts]}</span>
652
609
  </div>
653
610
  </button>
654
611
  );
@@ -658,7 +615,7 @@ const SearchModal: React.FC = () => {
658
615
 
659
616
  {/* Organization Section */}
660
617
  <div className="mb-4">
661
- <h3 className="text-xs font-medium text-gray-600 mb-2">Organization</h3>
618
+ <h3 className="text-xs font-bold text-gray-600 mb-2">Organization</h3>
662
619
  <div className="space-y-1">
663
620
  {Object.entries({
664
621
  teams: 'Teams',
@@ -680,9 +637,9 @@ const SearchModal: React.FC = () => {
680
637
  <div className="flex items-center justify-between">
681
638
  <div className="flex items-center gap-1.5">
682
639
  {IconComponent && <IconComponent className="h-3 w-3" />}
683
- <span>{label}</span>
640
+ <span className="font-thin">{label}</span>
684
641
  </div>
685
- <span className="text-xs text-gray-400">{counts[key as keyof typeof counts]}</span>
642
+ <span className="text-xs text-gray-700 font-thin">{counts[key as keyof typeof counts]}</span>
686
643
  </div>
687
644
  </button>
688
645
  );
@@ -692,7 +649,7 @@ const SearchModal: React.FC = () => {
692
649
 
693
650
  {/* Specifications Section */}
694
651
  <div className="mb-4">
695
- <h3 className="text-xs font-medium text-gray-600 mb-2">Specifications</h3>
652
+ <h3 className="text-xs font-bold text-gray-600 mb-2">Specifications</h3>
696
653
  <div className="space-y-1">
697
654
  {Object.entries({
698
655
  openapi: 'OpenAPI Specification',
@@ -714,9 +671,9 @@ const SearchModal: React.FC = () => {
714
671
  <div className="flex items-center justify-between">
715
672
  <div className="flex items-center gap-1.5">
716
673
  <IconComponent className="h-3 w-3" />
717
- <span>{label}</span>
674
+ <span className="font-thin">{label}</span>
718
675
  </div>
719
- <span className="text-xs text-gray-400">{counts[key as keyof typeof counts]}</span>
676
+ <span className="text-xs text-gray-700 font-thin">{counts[key as keyof typeof counts]}</span>
720
677
  </div>
721
678
  </button>
722
679
  );
@@ -726,25 +683,16 @@ const SearchModal: React.FC = () => {
726
683
  </div>
727
684
 
728
685
  {/* Right Results */}
729
- <div className="flex-1 p-4 overflow-y-auto">
730
- {/* Show stats and exact match toggle */}
731
- <div className="mb-4 flex items-center justify-between">
732
- <div className="text-sm text-gray-500">
733
- {currentSearch.trim() ? (
734
- <>
735
- <span>{filteredResults.length} results</span> for "{currentSearch}"
736
- {isLoading && <span className="ml-2">Loading...</span>}
737
- </>
738
- ) : (
739
- <>
740
- <span>{filteredResults.length} resources</span> in EventCatalog
741
- {isLoading && <span className="ml-2">Loading...</span>}
742
- </>
743
- )}
744
- </div>
686
+ <div className="flex-1 flex flex-col overflow-hidden">
687
+ {/* Show stats and exact match toggle - only when there are results or search term */}
688
+ {currentSearch.trim() && (filteredResults.length > 0 || isLoading) && (
689
+ <div className="p-4 pb-2 flex items-center justify-between border-b border-gray-100">
690
+ <div className="text-sm text-gray-500 font-thin">
691
+ <span>{filteredResults.length} results</span> for "{currentSearch}"
692
+ {isLoading && <span className="ml-2">Loading...</span>}
693
+ </div>
745
694
 
746
- {/* Exact Match Checkbox - moved here */}
747
- {currentSearch.trim() && (
695
+ {/* Exact Match Checkbox */}
748
696
  <div className="flex items-center">
749
697
  <input
750
698
  id="exact-match-results"
@@ -757,49 +705,51 @@ const SearchModal: React.FC = () => {
757
705
  Exact match in title
758
706
  </label>
759
707
  </div>
760
- )}
761
- </div>
762
-
763
- <div className="search-results grid grid-cols-1 lg:grid-cols-2 gap-3">
764
- {!currentSearch.trim() && filteredResults.length === 0 ? (
765
- // Show when no search term is entered and no results loaded yet
766
- <div className="col-span-full text-center py-20">
767
- <svg className="mx-auto h-16 w-16 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
768
- <path
769
- strokeLinecap="round"
770
- strokeLinejoin="round"
771
- strokeWidth="1.5"
772
- d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
773
- />
774
- </svg>
775
- <h3 className="mt-4 text-lg font-medium text-gray-900">
776
- {isLoading ? 'Loading resources...' : 'Discover your EventCatalog'}
777
- </h3>
778
- <p className="mt-2 text-sm text-gray-300">
779
- {isLoading
780
- ? 'Fetching all available resources from EventCatalog.'
781
- : 'Start typing to search for domains, services, events, and more.'}
782
- </p>
708
+ </div>
709
+ )}
710
+
711
+ {/* Main content area */}
712
+ <div className="flex-1 overflow-y-auto">
713
+ {!currentSearch.trim() ? (
714
+ // Show when no search term is entered - centered
715
+ <div className="h-full flex items-center justify-center">
716
+ <div className="text-center">
717
+ <MagnifyingGlassIcon className="mx-auto h-8 w-8 text-gray-300" />
718
+ <h3 className="mt-4 text-lg font-medium text-gray-900">Discover your EventCatalog</h3>
719
+ <p className="mt-2 text-sm text-gray-500 font-thin">
720
+ Start typing to search for domains, services, events, and more.
721
+ </p>
722
+ </div>
723
+ </div>
724
+ ) : filteredResults.length === 0 && !isLoading ? (
725
+ // Show when search term exists but no results and not loading - centered
726
+ <div className="h-full flex items-center justify-center">
727
+ <div className="text-center">
728
+ <MagnifyingGlassIcon className="mx-auto h-8 w-8 text-gray-300" />
729
+ <h3 className="mt-2 text-sm font-bold text-gray-900">No results found</h3>
730
+ <p className="mt-1 text-sm text-gray-500 font-thin">
731
+ No results found for "<span className="font-medium">{currentSearch}</span>".
732
+ </p>
733
+ </div>
783
734
  </div>
784
- ) : currentSearch.trim() && filteredResults.length === 0 ? (
785
- // Show when search term exists but no results
786
- <div className="col-span-full text-center py-16">
787
- <svg className="mx-auto h-12 w-12 text-gray-300" stroke="currentColor" fill="none" viewBox="0 0 48 48">
788
- <path
789
- d="M21 21l6-6m-6 6l6 6m-6-6h6m-6 0v6"
790
- strokeWidth="2"
791
- strokeLinecap="round"
792
- strokeLinejoin="round"
793
- />
794
- </svg>
795
- <h3 className="mt-2 text-sm font-medium text-gray-900">No results found</h3>
796
- <p className="mt-1 text-sm text-gray-500">
797
- No results found for "<span className="font-medium">{currentSearch}</span>". Try different keywords or
798
- check your spelling.
799
- </p>
735
+ ) : isLoading ? (
736
+ // Show loading state - centered
737
+ <div className="h-full flex items-center justify-center">
738
+ <div className="text-center">
739
+ <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600 mx-auto"></div>
740
+ <h3 className="mt-4 text-sm font-medium text-gray-900">Searching...</h3>
741
+ <p className="mt-2 text-sm text-gray-500 font-thin">
742
+ Finding results for "<span className="font-medium">{currentSearch}</span>"
743
+ </p>
744
+ </div>
800
745
  </div>
801
746
  ) : (
802
- <SearchResults results={filteredResults} typeConfig={typeConfig} currentSearch={currentSearch} />
747
+ // Show results in a grid with padding
748
+ <div className="p-4">
749
+ <div className="search-results grid grid-cols-1 lg:grid-cols-2 gap-3">
750
+ <SearchResults results={filteredResults} typeConfig={typeConfig} currentSearch={currentSearch} />
751
+ </div>
752
+ </div>
803
753
  )}
804
754
  </div>
805
755
  </div>
@@ -6,6 +6,7 @@ import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/
6
6
  import { getVersionFromCollection } from '@utils/collections/versions';
7
7
  import { getEntities, type Entity } from '@utils/entities';
8
8
  import { getDomains, type Domain } from '@utils/collections/domains';
9
+ import { getServices, type Service } from '@utils/collections/services';
9
10
 
10
11
  const elk = new ELK();
11
12
 
@@ -13,36 +14,45 @@ interface Props {
13
14
  id: string;
14
15
  version: string;
15
16
  entities?: string[]; // Optional: array of entity IDs/names to include
17
+ type?: 'domains' | 'services';
16
18
  }
17
19
 
18
- export const getNodesAndEdges = async ({ id, version, entities }: Props) => {
20
+ export const getNodesAndEdges = async ({ id, version, entities, type = 'domains' }: Props) => {
19
21
  let nodes = [] as any,
20
22
  edges = [] as any;
21
23
 
22
24
  const allDomains = await getDomains();
23
25
  const allEntities = await getEntities();
26
+ const allServices = await getServices();
24
27
 
25
- const domain = getVersionFromCollection(allDomains, id, version)[0] as Domain;
26
- let domainEntities = (domain?.data?.entities ?? []) as any;
28
+ let resource = null;
29
+
30
+ if (type === 'domains') {
31
+ resource = getVersionFromCollection(allDomains, id, version)[0] as Domain;
32
+ } else if (type === 'services') {
33
+ resource = getVersionFromCollection(allServices, id, version)[0] as Service;
34
+ }
35
+
36
+ let resourceEntities = (resource?.data?.entities ?? []) as any;
27
37
 
28
38
  // If entities filter is provided, filter domainEntities to only those specified
29
39
  if (entities && Array.isArray(entities) && entities.length > 0) {
30
- domainEntities = domainEntities.filter(
40
+ resourceEntities = resourceEntities.filter(
31
41
  (entity: Entity) => entities.includes(entity.data.id) || entities.includes(entity.data.name)
32
42
  );
33
43
  }
34
44
 
35
- const entitiesWithReferences = domainEntities.filter((entity: Entity) =>
45
+ const entitiesWithReferences = resourceEntities.filter((entity: Entity) =>
36
46
  entity.data.properties?.some((property: any) => property.references)
37
47
  );
38
48
  // Creates all the entity nodes for the domain
39
- for (const entity of domainEntities) {
49
+ for (const entity of resourceEntities) {
40
50
  const nodeId = generateIdForNode(entity);
41
51
  nodes.push({
42
52
  id: nodeId,
43
53
  type: 'entities',
44
54
  position: { x: 0, y: 0 },
45
- data: { label: entity.data.name, entity, domainName: domain?.data.name, domainId: domain?.data.id },
55
+ data: { label: entity.data.name, entity, domainName: resource?.data.name, domainId: resource?.data.id },
46
56
  });
47
57
  }
48
58
 
@@ -53,7 +63,7 @@ export const getNodesAndEdges = async ({ id, version, entities }: Props) => {
53
63
  .filter((ref: any) => ref !== undefined);
54
64
 
55
65
  const externalToDomain = Array.from(new Set<string>(listOfReferencedEntities as string[])) // Remove duplicates
56
- .filter((entityId: any) => !domainEntities.some((domainEntity: any) => domainEntity.id === entityId));
66
+ .filter((entityId: any) => !resourceEntities.some((domainEntity: any) => domainEntity.id === entityId));
57
67
 
58
68
  // Helper function to find which domain an entity belongs to
59
69
  const findEntityDomain = (entityId: string) => {
@@ -98,7 +108,7 @@ export const getNodesAndEdges = async ({ id, version, entities }: Props) => {
98
108
  entitiesWithReferences.push(...addedExternalEntities);
99
109
 
100
110
  // Create complete list of entities for edge creation and layout
101
- const allEntitiesInGraph = [...domainEntities, ...addedExternalEntities];
111
+ const allEntitiesInGraph = [...resourceEntities, ...addedExternalEntities];
102
112
 
103
113
  // Go through any entities that are related to other entities
104
114
  for (const entity of entitiesWithReferences) {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "2.54.1",
9
+ "version": "2.54.3",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -26,7 +26,7 @@
26
26
  "@ai-sdk/openai": "^1.3.16",
27
27
  "@astrojs/markdown-remark": "^6.3.3",
28
28
  "@astrojs/mdx": "^4.3.1",
29
- "@astrojs/node": "^9.3.0",
29
+ "@astrojs/node": "^9.3.1",
30
30
  "@astrojs/react": "^4.3.0",
31
31
  "@astrojs/rss": "^4.0.12",
32
32
  "@astrojs/tailwind": "^6.0.2",
@@ -56,7 +56,7 @@
56
56
  "@tanstack/react-table": "^8.17.3",
57
57
  "@xyflow/react": "^12.3.6",
58
58
  "ai": "^4.3.9",
59
- "astro": "^5.12.0",
59
+ "astro": "^5.12.5",
60
60
  "astro-compress": "^2.3.8",
61
61
  "astro-expressive-code": "^0.40.1",
62
62
  "astro-seo": "^0.8.4",