@eventcatalog/core 2.33.0 → 2.33.2

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 (30) 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-TNU27WQF.js → chunk-DDOQCYNI.js} +1 -1
  6. package/dist/{chunk-MC6EBL4I.js → chunk-ESJAFFBK.js} +1 -1
  7. package/dist/{chunk-MXEVMOGW.js → chunk-QXRF5XEW.js} +1 -1
  8. package/dist/constants.cjs +1 -1
  9. package/dist/constants.js +1 -1
  10. package/dist/eventcatalog.cjs +1 -1
  11. package/dist/eventcatalog.js +3 -3
  12. package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +1 -13
  13. package/eventcatalog/src/components/MDX/ResourceGroupTable/ResourceGroupTable.astro +1 -13
  14. package/eventcatalog/src/components/MDX/ResourceLink/ResourceLink.astro +1 -12
  15. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaProperty.astro +161 -0
  16. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewer.astro +36 -95
  17. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewerPortal.tsx +1 -1
  18. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewerRoot.astro +98 -0
  19. package/eventcatalog/src/components/MDX/components.tsx +1 -1
  20. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +26 -1
  21. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +3 -2
  22. package/eventcatalog/src/pages/docs/custom/[...path].mdx.ts +32 -0
  23. package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +19 -2
  24. package/eventcatalog/src/pages/docs/llm/llms.txt.ts +10 -0
  25. package/eventcatalog/src/utils/collections/util.ts +12 -0
  26. package/eventcatalog/src/utils/markdown.ts +30 -0
  27. package/package.json +1 -3
  28. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewer.tsx +0 -62
  29. package/eventcatalog/src/components/MDX/SchemaViewer/css/stoplight-mosaic-styles.css +0 -29609
  30. package/eventcatalog/src/components/MDX/SchemaViewer/css/stoplight-mosaic-theme-default.css +0 -333
@@ -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.33.0";
40
+ var version = "2.33.2";
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-MC6EBL4I.js";
4
- import "../chunk-TNU27WQF.js";
3
+ } from "../chunk-ESJAFFBK.js";
4
+ import "../chunk-DDOQCYNI.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.33.0";
109
+ var version = "2.33.2";
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-MXEVMOGW.js";
4
- import "../chunk-MC6EBL4I.js";
5
- import "../chunk-TNU27WQF.js";
3
+ } from "../chunk-QXRF5XEW.js";
4
+ import "../chunk-ESJAFFBK.js";
5
+ import "../chunk-DDOQCYNI.js";
6
6
  import "../chunk-E7TXTI7G.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.33.0";
2
+ var version = "2.33.2";
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-TNU27WQF.js";
3
+ } from "./chunk-DDOQCYNI.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-MC6EBL4I.js";
3
+ } from "./chunk-ESJAFFBK.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.33.0";
28
+ var version = "2.33.2";
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-TNU27WQF.js";
3
+ } from "./chunk-DDOQCYNI.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.33.0";
160
+ var version = "2.33.2";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,15 +6,15 @@ import {
6
6
  } from "./chunk-UKJ7F5WR.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-MXEVMOGW.js";
10
- import "./chunk-MC6EBL4I.js";
9
+ } from "./chunk-QXRF5XEW.js";
10
+ import "./chunk-ESJAFFBK.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
14
14
  } from "./chunk-7SI5EVOX.js";
15
15
  import {
16
16
  VERSION
17
- } from "./chunk-TNU27WQF.js";
17
+ } from "./chunk-DDOQCYNI.js";
18
18
  import {
19
19
  isBackstagePluginEnabled,
20
20
  isEventCatalogScaleEnabled,
@@ -3,6 +3,7 @@ import { buildUrl } from '@utils/url-builder';
3
3
  import { getCollection } from 'astro:content';
4
4
  import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
5
5
  import PillListFlat from './PillListFlat';
6
+ import { resourceToCollectionMap } from '@utils/collections/util';
6
7
  interface Props {
7
8
  section?: {
8
9
  title?: string;
@@ -20,19 +21,6 @@ const title = section?.title || 'Custom Section';
20
21
  const limit = section?.limit || 10;
21
22
  const sectionItems = section?.items || [];
22
23
 
23
- // Type-safe mapping of resource types to collection names
24
- const resourceToCollectionMap = {
25
- service: 'services',
26
- event: 'events',
27
- command: 'commands',
28
- query: 'queries',
29
- domain: 'domains',
30
- flow: 'flows',
31
- channel: 'channels',
32
- user: 'users',
33
- team: 'teams',
34
- } as const; // Make this a const assertion
35
-
36
24
  // Array to store resolved related resources
37
25
  const resolvedResources = [];
38
26
 
@@ -4,6 +4,7 @@ import { getCollection } from 'astro:content';
4
4
  import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
5
5
  import ResourceGroupTableClient from './ResourceGroupTable.client';
6
6
  import Admonition from '../Admonition';
7
+ import { resourceToCollectionMap } from '@utils/collections/util';
7
8
 
8
9
  export interface Props extends CollectionEntry<'services'> {
9
10
  limit?: number;
@@ -31,19 +32,6 @@ const section = resource.data.resourceGroups?.find((section: any) => section.id
31
32
 
32
33
  const collection = Astro.props.collection as 'services' | 'domains';
33
34
 
34
- // Type-safe mapping of resource types to collection names
35
- const resourceToCollectionMap = {
36
- service: 'services',
37
- event: 'events',
38
- command: 'commands',
39
- query: 'queries',
40
- domain: 'domains',
41
- flow: 'flows',
42
- channel: 'channels',
43
- user: 'users',
44
- team: 'teams',
45
- } as const;
46
-
47
35
  // This will hold our processed resources for the client component
48
36
  const resolvedResources: any[] = [];
49
37
 
@@ -1,17 +1,6 @@
1
1
  ---
2
2
  import { buildUrl } from '@utils/url-builder';
3
-
4
- const resourceToCollectionMap = {
5
- service: 'services',
6
- event: 'events',
7
- command: 'commands',
8
- query: 'queries',
9
- domain: 'domains',
10
- flow: 'flows',
11
- channel: 'channels',
12
- user: 'users',
13
- team: 'teams',
14
- } as const;
3
+ import { resourceToCollectionMap } from '@utils/collections/util';
15
4
 
16
5
  const { id, version, type } = Astro.props;
17
6
  const collection = resourceToCollectionMap[type as keyof typeof resourceToCollectionMap];
@@ -0,0 +1,161 @@
1
+ ---
2
+ import SchemaProp from './SchemaProperty.astro';
3
+
4
+ interface Props {
5
+ name: string;
6
+ details: any;
7
+ isRequired: boolean;
8
+ level: number;
9
+ isListItem?: boolean;
10
+ }
11
+
12
+ const { name, details, isRequired, level, isListItem = false } = Astro.props;
13
+
14
+ const hasNestedProperties = details.type === 'object' && details.properties && Object.keys(details.properties).length > 0;
15
+ const hasArrayItems = details.type === 'array' && details.items;
16
+ const isCollapsible = hasNestedProperties || (hasArrayItems && details.items.type === 'object' && details.items.properties);
17
+
18
+ // Using template literal for class calculation remains safe
19
+ const indentationClass = `pl-${level * 3}`;
20
+
21
+ const contentId = `prop-${name}-${level}-${Math.random().toString(36).substring(2, 7)}`;
22
+ ---
23
+
24
+ {/* Using simpler border class */}
25
+ <div class:list={['property-container mb-1.5 border-l border-gray-100 relative', indentationClass]}>
26
+ <div class="flex items-start space-x-1.5">
27
+ {
28
+ isCollapsible && (
29
+ <button
30
+ type="button"
31
+ aria-expanded="false"
32
+ aria-controls={contentId}
33
+ class="property-toggle text-gray-500 hover:text-gray-700 pt-0.5 focus:outline-none w-3 text-center flex-shrink-0"
34
+ >
35
+ <span class="icon-collapsed font-mono text-xs">&gt;</span>
36
+ <span class="icon-expanded font-mono text-xs hidden">v</span>
37
+ </button>
38
+ )
39
+ }
40
+ {!isCollapsible && <div class="w-3 h-4 flex-shrink-0" />}
41
+
42
+ <div class="flex-grow">
43
+ <div class="flex justify-between items-baseline">
44
+ <div>
45
+ <span class="font-semibold text-gray-800 text-sm">{name}</span>
46
+ <span class="ml-1.5 text-purple-600 font-mono text-xs">
47
+ {/* Expressions using ternary operators are generally safe */}
48
+ {details.type}
49
+ {details.type === 'array' && details.items?.type ? `[${details.items.type}]` : ''}
50
+ {details.format ? `<${details.format}>` : ''}
51
+ </span>
52
+ </div>
53
+ {isRequired && <span class="text-red-600 text-xs ml-3 flex-shrink-0">required</span>}
54
+ </div>
55
+
56
+ {details.description && <p class="text-gray-500 text-xs mt-0.5">{details.description}</p>}
57
+
58
+ {/* Reverted arbitrary text size to standard 'text-xs' */}
59
+ <div class="text-xs text-gray-500 mt-0.5 space-y-0">
60
+ {
61
+ details.pattern && (
62
+ <div>
63
+ Match pattern: <code class="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.pattern}</code>
64
+ </div>
65
+ )
66
+ }
67
+ {
68
+ details.minimum !== undefined && (
69
+ <div>
70
+ Minimum: <code class="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.minimum}</code>
71
+ </div>
72
+ )
73
+ }
74
+ {
75
+ details.maximum !== undefined && (
76
+ <div>
77
+ Maximum: <code class="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.maximum}</code>
78
+ </div>
79
+ )
80
+ }
81
+ {
82
+ details.enum && (
83
+ <div>
84
+ <span class="text-xs inline-block">Allowed values:</span>
85
+
86
+ {/* Map function rendering standard elements */}
87
+ {details.enum.map((val: string) => (
88
+ <span class="text-xs">
89
+ <code class="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{val}</code>
90
+ </span>
91
+ ))}
92
+ </div>
93
+ )
94
+ }
95
+ </div>
96
+
97
+ {
98
+ (hasNestedProperties || hasArrayItems) && (
99
+ // class:list with conditional object is standard and should be safe
100
+ <div id={contentId} class:list={['nested-content mt-1', { hidden: isCollapsible }]}>
101
+ {/* Recursive component calls */}
102
+ {hasNestedProperties &&
103
+ details.properties &&
104
+ Object.entries(details.properties).map(([nestedName, nestedDetails]) => (
105
+ <SchemaProp
106
+ name={nestedName}
107
+ details={nestedDetails}
108
+ isRequired={details.required?.includes(nestedName) ?? false}
109
+ level={level + 1}
110
+ />
111
+ ))}
112
+
113
+ {hasArrayItems && details.items.type === 'object' && details.items.properties && (
114
+ <div class="mt-1 border-l border-dashed border-gray-400 pl-3 ml-1.5">
115
+ <span class="text-xs italic text-gray-500 block mb-1">Item Details:</span>
116
+ {Object.entries(details.items.properties).map(([itemPropName, itemPropDetails]) => (
117
+ <SchemaProp
118
+ name={itemPropName}
119
+ details={itemPropDetails}
120
+ isRequired={details.items.required?.includes(itemPropName) ?? false}
121
+ level={level + 1}
122
+ isListItem={true}
123
+ />
124
+ ))}
125
+ </div>
126
+ )}
127
+ </div>
128
+ )
129
+ }
130
+ </div>
131
+ </div>
132
+ </div>
133
+
134
+ {/* Script tag content remains the same */}
135
+ <script is:inline>
136
+ function setupPropertyToggle() {
137
+ document.querySelectorAll('.property-toggle').forEach((button) => {
138
+ if (button.dataset.listenerAttached) return;
139
+ button.dataset.listenerAttached = 'true';
140
+
141
+ button.addEventListener('click', () => {
142
+ const contentId = button.getAttribute('aria-controls');
143
+ const content = document.getElementById(contentId);
144
+ const isExpanded = button.getAttribute('aria-expanded') === 'true';
145
+ const iconCollapsed = button.querySelector('.icon-collapsed');
146
+ const iconExpanded = button.querySelector('.icon-expanded');
147
+
148
+ if (content) {
149
+ button.setAttribute('aria-expanded', String(!isExpanded));
150
+ content.classList.toggle('hidden');
151
+ iconCollapsed?.classList.toggle('hidden', !isExpanded);
152
+ iconExpanded?.classList.toggle('hidden', isExpanded);
153
+ }
154
+ });
155
+ });
156
+ }
157
+
158
+ setupPropertyToggle();
159
+
160
+ document.addEventListener('astro:page-load', setupPropertyToggle);
161
+ </script>
@@ -1,103 +1,44 @@
1
1
  ---
2
- const { catalog, id, filePath } = Astro.props;
3
- import fs from 'node:fs/promises';
4
- import { existsSync } from 'fs';
5
- import yaml from 'js-yaml';
6
- import path from 'path';
7
- import SchemaViewerClient from './SchemaViewer';
8
- import Admonition from '../Admonition';
9
- let schemas = [];
10
-
11
- function findSchemaViewers(document: string) {
12
- // Define regex pattern to match <SchemaViewer ... />
13
- const pattern = /<SchemaViewer\s+([^>]*)\/>/g;
14
-
15
- // Find all matches of the pattern
16
- const matches = [...document.matchAll(pattern)];
17
-
18
- // Extract the properties of each SchemaViewer
19
- const schemaViewers = matches.map((match) => {
20
- const propsString = match[1];
21
- const props = {};
22
-
23
- // Use regex to extract key-value pairs from propsString
24
- const propsPattern = /(\w+)=["']([^"']+)["']/g;
25
- let propMatch;
26
- while ((propMatch = propsPattern.exec(propsString)) !== null) {
27
- const key = propMatch[1];
28
- const value = propMatch[2];
29
- // @ts-ignore
30
- props[key] = value;
31
- }
32
-
33
- return props;
34
- });
35
-
36
- return schemaViewers;
2
+ // src/components/SchemaViewer.astro
3
+ import SchemaProperty from './SchemaProperty.astro';
4
+
5
+ interface Props {
6
+ schema: Record<string, any>;
7
+ schemaPath: string;
8
+ title: string;
9
+ maxHeight: string;
10
+ file: string;
11
+ id: string;
37
12
  }
38
13
 
39
- try {
40
- const file = await fs.readFile(filePath, 'utf-8');
41
- const schemaViewers = findSchemaViewers(file);
42
-
43
- // Loop around all the possible SchemaViewers in the file.
44
- const getAllComponents = schemaViewers.map(async (schemaViewerProps: any) => {
45
- const schemaPath = path.join(path.dirname(filePath), schemaViewerProps.file);
46
- const exists = existsSync(schemaPath);
47
- let schema;
48
- let render = true;
14
+ const { id, file, title, maxHeight, schema } = Astro.props;
15
+ const { description, properties, required = [] } = schema;
16
+ ---
49
17
 
50
- if (exists) {
51
- // Load the schema for the component
52
- schema = await fs.readFile(schemaPath, 'utf-8');
53
- if (schemaPath.endsWith('.yml') || schemaPath.endsWith('.yaml')) {
54
- schema = yaml.load(schema);
55
- } else {
56
- schema = JSON.parse(schema);
57
- // Lets JSON schema control if the component should be rendered or not
58
- if (schema['x-eventcatalog-render-schema-viewer'] !== undefined) {
59
- render = schema['x-eventcatalog-render-schema-viewer'];
60
- }
61
- }
18
+ <div id={`${id}-${file}-SchemaViewer-client`} class="not-prose my-4">
19
+ {title && <h2 class="text-3xl font-bold mb-2 !mt-0">{title}</h2>}
20
+ <div
21
+ class="schema-viewer p-4 bg-white overflow-y-auto rounded-lg border border-gray-100 shadow-sm font-sans"
22
+ style={{
23
+ maxHeight: maxHeight ? `${maxHeight}em` : `100em`,
24
+ }}
25
+ >
26
+ {description && <p class="text-gray-600 text-xs mb-5">{description}</p>}
27
+ {/* Reduced size, adjusted margin */}
28
+
29
+ {
30
+ properties &&
31
+ Object.entries(properties).map(([name, details]) => (
32
+ <SchemaProperty name={name} details={details} isRequired={required.includes(name)} level={0} />
33
+ ))
62
34
  }
63
35
 
64
- return {
65
- id: schemaViewerProps.id || id,
66
- exists,
67
- schema,
68
- schemaPath,
69
- ...schemaViewerProps,
70
- render,
71
- };
72
- });
73
-
74
- schemas = await Promise.all(getAllComponents);
75
- } catch (error) {
76
- console.log('Failed to process schemas');
77
- console.log(error);
78
- }
79
- ---
80
-
81
- <section class="space-y-4">
82
- {
83
- schemas.length > 0 &&
84
- schemas.map((schema) => {
85
- if (!schema.render) return null;
86
- return (
87
- <div>
88
- {schema.exists && <SchemaViewerClient {...schema} client:only="react" />}
36
+ {!properties && <p class="text-gray-500 text-sm">Schema does not contain any properties.</p>}
37
+ </div>
38
+ </div>
89
39
 
90
- {/* User has tried to load the schema, but it was not found on file system */}
91
- {!schema.exists && (
92
- <Admonition type="warning">
93
- <div>
94
- <span class="block font-bold">{`<SchemaViewer/>`} failed to load</span>
95
- <span class="block">Tried to load schema from {schema.schemaPath}, but no schema can be found</span>
96
- </div>
97
- </Admonition>
98
- )}
99
- </div>
100
- );
101
- })
40
+ <style>
41
+ .schema-viewer code {
42
+ font-family: 'Courier New', Courier, monospace;
102
43
  }
103
- </section>
44
+ </style>
@@ -1,5 +1,5 @@
1
1
  const SchemaViewerPortal = (props: any) => {
2
- return <div id={`${props.id}-SchemaViewer-portal`} />;
2
+ return <div id={`${props.id}-${props.file}-SchemaViewer-portal`} />;
3
3
  };
4
4
 
5
5
  export default SchemaViewerPortal;
@@ -0,0 +1,98 @@
1
+ ---
2
+ const { id, filePath } = Astro.props;
3
+ import fs from 'node:fs/promises';
4
+ import { existsSync } from 'fs';
5
+ import yaml from 'js-yaml';
6
+ import path from 'path';
7
+ import SchemaViewerClient from './SchemaViewer.astro';
8
+ import Admonition from '../Admonition';
9
+ import { getMDXComponentsByName } from '@utils/markdown';
10
+
11
+ let schemas = [];
12
+
13
+ try {
14
+ const file = await fs.readFile(filePath, 'utf-8');
15
+ const schemaViewers = getMDXComponentsByName(file, 'SchemaViewer');
16
+
17
+ // Loop around all the possible SchemaViewers in the file.
18
+ const getAllComponents = schemaViewers.map(async (schemaViewerProps: any) => {
19
+ const schemaPath = path.join(path.dirname(filePath), schemaViewerProps.file);
20
+ const exists = existsSync(schemaPath);
21
+ let schema;
22
+ let render = true;
23
+
24
+ if (exists) {
25
+ // Load the schema for the component
26
+ schema = await fs.readFile(schemaPath, 'utf-8');
27
+ if (schemaPath.endsWith('.yml') || schemaPath.endsWith('.yaml')) {
28
+ schema = yaml.load(schema);
29
+ } else {
30
+ schema = JSON.parse(schema);
31
+ // Lets JSON schema control if the component should be rendered or not
32
+ if (schema['x-eventcatalog-render-schema-viewer'] !== undefined) {
33
+ render = schema['x-eventcatalog-render-schema-viewer'];
34
+ }
35
+ }
36
+ }
37
+
38
+ return {
39
+ id: schemaViewerProps.id || id,
40
+ exists,
41
+ schema,
42
+ schemaPath,
43
+ ...schemaViewerProps,
44
+ render,
45
+ };
46
+ });
47
+
48
+ schemas = await Promise.all(getAllComponents);
49
+ } catch (error) {
50
+ console.log('Failed to process schemas');
51
+ console.log(error);
52
+ }
53
+ ---
54
+
55
+ <section class="space-y-4">
56
+ {
57
+ schemas.length > 0 &&
58
+ schemas.map((schema) => {
59
+ if (!schema.render) return null;
60
+ return (
61
+ <div>
62
+ {schema.exists && <SchemaViewerClient {...schema} />}
63
+
64
+ {/* User has tried to load the schema, but it was not found on file system */}
65
+ {!schema.exists && (
66
+ <Admonition type="warning">
67
+ <div>
68
+ <span class="block font-bold">{`<SchemaViewer/>`} failed to load</span>
69
+ <span class="block">Tried to load schema from {schema.schemaPath}, but no schema can be found</span>
70
+ </div>
71
+ </Admonition>
72
+ )}
73
+ </div>
74
+ );
75
+ })
76
+ }
77
+ </section>
78
+
79
+ <script is:inline define:vars={{ schemas }}>
80
+ // Can we move the SchemaViewerClient to another container? example container with the id "my-schema-viewer-container"
81
+ // and then we can move the SchemaViewerClient to that container?
82
+
83
+ function moveSchemaViewerToPortal(schema) {
84
+ const portalId = `${schema.id}-${schema.file}-SchemaViewer-portal`;
85
+ const schemaViewerContainer = document.getElementById(portalId);
86
+ console.log('schemaViewerContainer', schemaViewerContainer);
87
+ if (schemaViewerContainer) {
88
+ schemaViewerContainer.appendChild(document.getElementById(`${schema.id}-${schema.file}-SchemaViewer-client`));
89
+ }
90
+ }
91
+
92
+ console.log('schemas', schemas);
93
+
94
+ // on DOM ready, move the SchemaViewerClient to the portal
95
+ document.addEventListener('astro:page-load', () => {
96
+ schemas.forEach(moveSchemaViewerToPortal);
97
+ });
98
+ </script>
@@ -34,7 +34,7 @@ const components = (props: any) => {
34
34
  Flow,
35
35
  Link: (mdxProp: any) => jsx(Link, { ...props, ...mdxProp }),
36
36
  MessageTable: (mdxProp: any) => jsx(MessageTable, { ...props, ...mdxProp }),
37
- NodeGraph: (mdxProp: any) => NodeGraphPortal({ ...props.data, ...mdxProp }),
37
+ NodeGraph: (mdxProp: any) => jsx(NodeGraphPortal, { ...props.data, ...mdxProp, props, mdxProp }),
38
38
  OpenAPI,
39
39
  ResourceGroupTable: (mdxProp: any) => jsx(ResourceGroupTable, { ...props, ...mdxProp }),
40
40
  ResourceLink: (mdxProp: any) => jsx(ResourceLink, { ...props, ...mdxProp }),
@@ -9,15 +9,19 @@ import OwnersList from '@components/Lists/OwnersList';
9
9
 
10
10
  import { getOwner } from '@utils/collections/owners';
11
11
  import { buildUrl } from '@utils/url-builder';
12
+ import { resourceToCollectionMap } from '@utils/collections/util';
13
+ import { getMDXComponentsByName } from '@utils/markdown';
14
+ import { getAdjacentPages } from '@enterprise/custom-documentation/utils/custom-docs';
12
15
 
13
16
  import CustomDocsNav from '@enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro';
14
- import { getAdjacentPages } from '@enterprise/custom-documentation/utils/custom-docs';
17
+ import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
15
18
 
16
19
  const props = Astro.props;
17
20
  const doc = props.data;
18
21
  const { Content, headings } = await render(props as any);
19
22
  const currentSlug = props.id;
20
23
 
24
+ const nodeGraphs = getMDXComponentsByName(props.body, 'NodeGraph') || [];
21
25
  // Get sidebar data
22
26
  const sidebar = config?.customDocs?.sidebar || [];
23
27
 
@@ -116,6 +120,27 @@ const badges = doc?.badges || [];
116
120
  <Content components={{ ...mdxComponents(props) }} />
117
121
  </div>
118
122
 
123
+ {
124
+ nodeGraphs.length > 0 &&
125
+ nodeGraphs.map((nodeGraph: any) => {
126
+ const collection = resourceToCollectionMap[nodeGraph.type as keyof typeof resourceToCollectionMap];
127
+ return (
128
+ <NodeGraph
129
+ id={nodeGraph.id}
130
+ version={nodeGraph.version}
131
+ collection={collection}
132
+ title={nodeGraph.title}
133
+ mode="simple"
134
+ linksToVisualiser={true}
135
+ href={{
136
+ label: 'Open in Visualiser',
137
+ url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
138
+ }}
139
+ />
140
+ );
141
+ })
142
+ }
143
+
119
144
  <!-- Previous / Next Navigation -->
120
145
  <div class="py-8 border-t border-gray-200 mt-8">
121
146
  <div class="flex flex-col sm:flex-row justify-between w-full gap-4">