@eventcatalog/core 2.56.3 → 2.57.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/README.md CHANGED
@@ -34,7 +34,7 @@
34
34
  <h4>Features: Documentation for Event Driven Architectures, Integration with any broker, Generator from your OpenAPI and AsyncAPI documents, Docs and Code, Markdown driven, Document Domains/Services/Messages/Schemas and more, Content versioning, Assign Owners, Schemas, OpenAPI, MDX Components and more...</h4>
35
35
 
36
36
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
37
- [![All Contributors](https://img.shields.io/badge/all_contributors-60-orange.svg?style=flat-square)](#contributors-)
37
+ [![All Contributors](https://img.shields.io/badge/all_contributors-61-orange.svg?style=flat-square)](#contributors-)
38
38
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
39
39
 
40
40
  [Read the Docs](https://www.eventcatalog.dev/docs/development/getting-started/introduction) | [View Demo](https://demo.eventcatalog.dev)
@@ -264,6 +264,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
264
264
  <td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/lucianlature/"><img src="https://avatars.githubusercontent.com/u/24992?v=4?s=100" width="100px;" alt="Lucian Lature"/><br /><sub><b>Lucian Lature</b></sub></a><br /><a href="https://github.com/event-catalog/eventcatalog/issues?q=author%3Alucianlature" title="Bug reports">🐛</a></td>
265
265
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/villAsh"><img src="https://avatars.githubusercontent.com/u/50195101?v=4?s=100" width="100px;" alt="Vilas Chauvhan"/><br /><sub><b>Vilas Chauvhan</b></sub></a><br /><a href="https://github.com/event-catalog/eventcatalog/commits?author=villAsh" title="Code">💻</a></td>
266
266
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/mrerichoffman"><img src="https://avatars.githubusercontent.com/u/7565432?v=4?s=100" width="100px;" alt="Eric Hoffman"/><br /><sub><b>Eric Hoffman</b></sub></a><br /><a href="https://github.com/event-catalog/eventcatalog/issues?q=author%3Amrerichoffman" title="Bug reports">🐛</a></td>
267
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/wimhaesen-kine"><img src="https://avatars.githubusercontent.com/u/231914377?v=4?s=100" width="100px;" alt="wimhaesen-kine"/><br /><sub><b>wimhaesen-kine</b></sub></a><br /><a href="https://github.com/event-catalog/eventcatalog/commits?author=wimhaesen-kine" title="Code">💻</a></td>
267
268
  </tr>
268
269
  </tbody>
269
270
  </table>
@@ -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.56.3";
40
+ var version = "2.57.0";
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-RB5C7AID.js";
4
- import "../chunk-OHDQ4LG4.js";
3
+ } from "../chunk-24JFJA4V.js";
4
+ import "../chunk-6ILF3VK6.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.56.3";
109
+ var version = "2.57.0";
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-TBYGYYON.js";
4
- import "../chunk-RB5C7AID.js";
5
- import "../chunk-OHDQ4LG4.js";
3
+ } from "../chunk-NVY3KN4D.js";
4
+ import "../chunk-24JFJA4V.js";
5
+ import "../chunk-6ILF3VK6.js";
6
6
  import "../chunk-UPONRQSN.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-OHDQ4LG4.js";
3
+ } from "./chunk-6ILF3VK6.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.56.3";
2
+ var version = "2.57.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-RB5C7AID.js";
3
+ } from "./chunk-24JFJA4V.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.56.3";
28
+ var version = "2.57.0";
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-OHDQ4LG4.js";
3
+ } from "./chunk-6ILF3VK6.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.56.3";
160
+ var version = "2.57.0";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-TBYGYYON.js";
10
- import "./chunk-RB5C7AID.js";
9
+ } from "./chunk-NVY3KN4D.js";
10
+ import "./chunk-24JFJA4V.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-55D645EH.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-OHDQ4LG4.js";
18
+ } from "./chunk-6ILF3VK6.js";
19
19
  import {
20
20
  getProjectOutDir,
21
21
  isAuthEnabled,
@@ -0,0 +1,56 @@
1
+ ---
2
+ import fs from 'fs';
3
+ import { getAbsoluteFilePathForAstroFile } from '@utils/files';
4
+ import Admonition from '@components/MDX/Admonition';
5
+
6
+ const { file: mermaidFile, filePath } = Astro.props;
7
+
8
+ // const escapeHtml = (str: string) => str.replace(/[&<>"']/g, (c) => escapeMap[c]);
9
+ let isValidMermaidFile = mermaidFile.endsWith('.mmd') || mermaidFile.endsWith('.mermaid');
10
+ let mermaidFileContent = '';
11
+
12
+ if (isValidMermaidFile) {
13
+ try {
14
+ const pathToSpec = getAbsoluteFilePathForAstroFile(filePath, mermaidFile);
15
+ mermaidFileContent = fs.readFileSync(pathToSpec, 'utf8');
16
+ } catch (error) {
17
+ console.error(`Error reading design file: ${error}`);
18
+ }
19
+ }
20
+ ---
21
+
22
+ {
23
+ !mermaidFileContent && (
24
+ <Admonition type="warning">
25
+ <div>
26
+ <span class="block font-bold">{`<MermaidFileLoader/>`} failed to load</span>
27
+ <span class="block">
28
+ Tried to load mermaid file: {mermaidFile}. Make sure you have this mermaid file defined in your project.
29
+ </span>
30
+ </div>
31
+ </Admonition>
32
+ )
33
+ }
34
+
35
+ {
36
+ !isValidMermaidFile && (
37
+ <Admonition type="warning">
38
+ <div>
39
+ <span class="block font-bold">{`<MermaidFileLoader/>`} failed to load</span>
40
+ <span class="block">
41
+ Tried to load mermaid file: {mermaidFile}. Make sure the file extension is either .mmd or .mermaid.
42
+ </span>
43
+ </div>
44
+ </Admonition>
45
+ )
46
+ }
47
+
48
+ {
49
+ mermaidFileContent && isValidMermaidFile && (
50
+ <div class="mermaid-block pb-4">
51
+ <div class="mermaid border border-gray-200 rounded-lg p-1" data-content={mermaidFileContent}>
52
+ <p>Loading graph...</p>
53
+ </div>
54
+ </div>
55
+ )
56
+ }
@@ -17,7 +17,7 @@ import {
17
17
  type NodeTypes,
18
18
  } from '@xyflow/react';
19
19
  import '@xyflow/react/dist/style.css';
20
- import { HistoryIcon } from 'lucide-react';
20
+ import { ExternalLink, HistoryIcon } from 'lucide-react';
21
21
  import { toPng } from 'html-to-image';
22
22
  import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
23
23
  // Nodes and edges
@@ -49,6 +49,7 @@ import { CogIcon } from '@heroicons/react/20/solid';
49
49
  import { useEventCatalogVisualiser } from 'src/hooks/eventcatalog-visualizer';
50
50
  import VisualiserSearch, { type VisualiserSearchRef } from './VisualiserSearch';
51
51
  import StepWalkthrough from './StepWalkthrough';
52
+ import StudioModal from './StudioModal';
52
53
  interface Props {
53
54
  nodes: any;
54
55
  edges: any;
@@ -65,6 +66,8 @@ interface Props {
65
66
  showSearch?: boolean;
66
67
  zoomOnScroll?: boolean;
67
68
  designId?: string;
69
+ isStudioModalOpen?: boolean;
70
+ setIsStudioModalOpen?: (isOpen: boolean) => void;
68
71
  }
69
72
 
70
73
  const getVisualiserUrlForCollection = (collectionItem: CollectionEntry<CollectionTypes>) => {
@@ -84,6 +87,8 @@ const NodeGraphBuilder = ({
84
87
  showFlowWalkthrough = true,
85
88
  showSearch = true,
86
89
  zoomOnScroll = false,
90
+ isStudioModalOpen,
91
+ setIsStudioModalOpen = () => {},
87
92
  }: Props) => {
88
93
  const nodeTypes = useMemo(
89
94
  () =>
@@ -128,6 +133,7 @@ const NodeGraphBuilder = ({
128
133
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);
129
134
  const [animateMessages, setAnimateMessages] = useState(false);
130
135
  const [activeStepIndex, setActiveStepIndex] = useState<number | null>(null);
136
+ // const [isStudioModalOpen, setIsStudioModalOpen] = useState(false);
131
137
 
132
138
  // Check if there are channels to determine if we need the visualizer functionality
133
139
  const hasChannels = useMemo(() => initialNodes.some((node: any) => node.type === 'channels'), [initialNodes]);
@@ -138,7 +144,7 @@ const NodeGraphBuilder = ({
138
144
  setEdges,
139
145
  skipProcessing: !hasChannels, // Pass flag to skip processing when no channels
140
146
  });
141
- const { fitView, getNodes } = useReactFlow();
147
+ const { fitView, getNodes, toObject } = useReactFlow();
142
148
  const searchRef = useRef<VisualiserSearchRef>(null);
143
149
  const reactFlowWrapperRef = useRef<HTMLDivElement>(null);
144
150
  const scrollableContainerRef = useRef<HTMLElement | null>(null);
@@ -337,6 +343,10 @@ const NodeGraphBuilder = ({
337
343
  a.click();
338
344
  }, []);
339
345
 
346
+ const openStudioModal = () => {
347
+ setIsStudioModalOpen(true);
348
+ };
349
+
340
350
  const handleExportVisual = useCallback(() => {
341
351
  const imageWidth = 1024;
342
352
  const imageHeight = 768;
@@ -569,7 +579,7 @@ const NodeGraphBuilder = ({
569
579
  >
570
580
  <Panel position="top-center" className="w-full pr-6 ">
571
581
  <div className="flex space-x-2 justify-between items-center">
572
- <div className="flex space-x-2">
582
+ <div className="flex space-x-2 ml-4">
573
583
  <div>
574
584
  <button
575
585
  onClick={() => setIsSettingsOpen(!isSettingsOpen)}
@@ -668,13 +678,27 @@ const NodeGraphBuilder = ({
668
678
  <p className="text-[10px] text-gray-500">Show or hide channels in the visualizer.</p>
669
679
  </div>
670
680
  )}
671
- <div className="pt-4 border-t border-gray-200">
681
+ <div className="pt-4 border-t border-gray-200 space-y-2">
682
+ <button
683
+ onClick={openStudioModal}
684
+ className="w-full flex items-center justify-center space-x-2 px-4 py-2 bg-black hover:bg-gray-800 text-white text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transition-colors"
685
+ >
686
+ <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
687
+ <path
688
+ strokeLinecap="round"
689
+ strokeLinejoin="round"
690
+ strokeWidth="2"
691
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
692
+ />
693
+ </svg>
694
+ <span>Open in EventCatalog Studio</span>
695
+ </button>
672
696
  <button
673
697
  onClick={handleExportVisual}
674
- className="w-full flex items-center justify-center space-x-2 px-4 py-2 bg-purple-600 text-white text-sm font-medium rounded-md hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
698
+ className="w-full flex items-center justify-center border border-gray-200 space-x-2 px-4 py-2 bg-white text-gray-800 text-sm font-medium rounded-md hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
675
699
  >
676
700
  <DocumentArrowDownIcon className="w-4 h-4" />
677
- <span>Export Visual</span>
701
+ <span>Export as png</span>
678
702
  </button>
679
703
  </div>
680
704
  </div>
@@ -714,6 +738,7 @@ const NodeGraphBuilder = ({
714
738
  </Panel>
715
739
  )}
716
740
  </ReactFlow>
741
+ <StudioModal isOpen={isStudioModalOpen || false} onClose={() => setIsStudioModalOpen(false)} />
717
742
  </div>
718
743
  );
719
744
  };
@@ -759,6 +784,11 @@ const NodeGraph = ({
759
784
  }: NodeGraphProps) => {
760
785
  const [elem, setElem] = useState(null);
761
786
  const [showFooter, setShowFooter] = useState(true);
787
+ const [isStudioModalOpen, setIsStudioModalOpen] = useState(false);
788
+
789
+ const openStudioModal = useCallback(() => {
790
+ setIsStudioModalOpen(true);
791
+ }, []);
762
792
 
763
793
  const containerToRenderInto = portalId || `${id}-portal`;
764
794
 
@@ -794,6 +824,8 @@ const NodeGraph = ({
794
824
  showSearch={showSearch}
795
825
  zoomOnScroll={zoomOnScroll}
796
826
  designId={designId || id}
827
+ isStudioModalOpen={isStudioModalOpen}
828
+ setIsStudioModalOpen={setIsStudioModalOpen}
797
829
  />
798
830
 
799
831
  {showFooter && (
@@ -806,7 +838,14 @@ const NodeGraph = ({
806
838
 
807
839
  {href && (
808
840
  <div className="py-2 w-full text-right flex justify-between">
809
- <span className="text-sm text-gray-500 italic">Right click a node to access documentation</span>
841
+ {/* <span className="text-sm text-gray-500 italic">Right click a node to access documentation</span> */}
842
+ <button
843
+ onClick={openStudioModal}
844
+ className=" text-sm underline text-gray-800 hover:text-primary flex items-center space-x-1"
845
+ >
846
+ <span>Open in EventCatalog Studio</span>
847
+ <ExternalLink className="w-3 h-3" />
848
+ </button>
810
849
  <a className=" text-sm underline text-gray-800 hover:text-primary" href={href}>
811
850
  {hrefLabel} &rarr;
812
851
  </a>
@@ -0,0 +1,129 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import * as Dialog from '@radix-ui/react-dialog';
3
+ import { CheckIcon, ClipboardIcon, ExternalLinkIcon } from 'lucide-react';
4
+ import { useReactFlow } from '@xyflow/react';
5
+ import { exportNodeGraphForStudio } from '@utils/node-graphs/export-node-graph';
6
+
7
+ interface StudioModalProps {
8
+ isOpen: boolean;
9
+ onClose: () => void;
10
+ }
11
+
12
+ const StudioModal: React.FC<StudioModalProps> = ({ isOpen, onClose }) => {
13
+ const [copySuccess, setCopySuccess] = useState(false);
14
+
15
+ const { toObject } = useReactFlow();
16
+
17
+ const handleCopyToClipboard = useCallback(async () => {
18
+ const visualizerData = toObject();
19
+ const studioData = exportNodeGraphForStudio(visualizerData);
20
+
21
+ try {
22
+ await navigator.clipboard.writeText(JSON.stringify(studioData, null, 2));
23
+ setCopySuccess(true);
24
+ setTimeout(() => setCopySuccess(false), 2000);
25
+ } catch (error) {
26
+ console.error('Failed to copy to clipboard:', error);
27
+ // Fallback for older browsers
28
+ const textarea = document.createElement('textarea');
29
+ textarea.value = JSON.stringify(studioData, null, 2);
30
+ document.body.appendChild(textarea);
31
+ textarea.select();
32
+ document.execCommand('copy');
33
+ document.body.removeChild(textarea);
34
+ setCopySuccess(true);
35
+ setTimeout(() => setCopySuccess(false), 2000);
36
+ }
37
+ }, []);
38
+
39
+ const handleOpenStudio = () => {
40
+ window.open(
41
+ 'https://app.eventcatalog.studio/playground?import=true&utm_source=eventcatalog&utm_medium=referral&utm_campaign=playground-import',
42
+ '_blank'
43
+ );
44
+ onClose();
45
+ };
46
+
47
+ return (
48
+ <Dialog.Root open={isOpen} onOpenChange={onClose}>
49
+ <Dialog.Portal>
50
+ <Dialog.Overlay className="fixed inset-0 bg-black/50 data-[state=open]:animate-overlayShow z-50" />
51
+ <Dialog.Content className="fixed top-1/2 left-1/2 w-[90vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-xl focus:outline-none data-[state=open]:animate-contentShow z-[100]">
52
+ <Dialog.Title className="text-lg font-semibold text-gray-900 mb-3">Open in EventCatalog Studio</Dialog.Title>
53
+
54
+ <Dialog.Description className="text-sm text-gray-600 mb-6">
55
+ Import your diagram into{' '}
56
+ <a
57
+ href="https://eventcatalog.studio"
58
+ className="text-purple-600 hover:text-purple-700 underline"
59
+ target="_blank"
60
+ rel="noopener noreferrer"
61
+ >
62
+ EventCatalog Studio
63
+ </a>{' '}
64
+ to create designs from your visualization of your architecture.
65
+ </Dialog.Description>
66
+
67
+ <div className="space-y-4">
68
+ <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
69
+ <h4 className="text-sm font-bold text-gray-900 mb-2">Step 1: Copy diagram</h4>
70
+ <p className="text-xs text-gray-600 mb-3">Copy your diagram data to your clipboard.</p>
71
+ <button
72
+ onClick={handleCopyToClipboard}
73
+ className={`w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md border transition-colors ${
74
+ copySuccess
75
+ ? 'bg-green-50 border-green-200 text-green-700'
76
+ : 'bg-white border-gray-300 text-gray-700 hover:bg-gray-50'
77
+ }`}
78
+ >
79
+ {copySuccess ? (
80
+ <>
81
+ <CheckIcon className="w-4 h-4" />
82
+ <span>Copied!</span>
83
+ </>
84
+ ) : (
85
+ <>
86
+ <ClipboardIcon className="w-4 h-4" />
87
+ <span>Copy diagram to clipboard</span>
88
+ </>
89
+ )}
90
+ </button>
91
+ </div>
92
+
93
+ <div className="bg-purple-50 rounded-lg p-4 border border-purple-200">
94
+ <h4 className="text-sm font-bold text-gray-900 mb-2">Step 2: Open EventCatalog Studio</h4>
95
+ <p className="text-xs text-gray-600 mb-3">
96
+ Go to EventCatalog Studio and import your design using the "Import from EventCatalog" button.
97
+ </p>
98
+
99
+ <button
100
+ onClick={handleOpenStudio}
101
+ className="w-full flex items-center justify-center space-x-2 px-4 py-2 bg-purple-600 text-white text-sm font-medium rounded-md hover:bg-purple-700 transition-colors"
102
+ >
103
+ <ExternalLinkIcon className="w-4 h-4" />
104
+ <span>Open EventCatalog Studio</span>
105
+ </button>
106
+ <p className="text-[12px] text-gray-500 italic mt-4 mb-0">
107
+ Don't worry, none of your data is stored by EventCatalog Studio, everything is local to your browser.
108
+ </p>
109
+ </div>
110
+ </div>
111
+
112
+ <div className="mt-6 flex justify-end">
113
+ <Dialog.Close asChild>
114
+ <button
115
+ type="button"
116
+ className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transition-colors"
117
+ onClick={onClose}
118
+ >
119
+ Close
120
+ </button>
121
+ </Dialog.Close>
122
+ </div>
123
+ </Dialog.Content>
124
+ </Dialog.Portal>
125
+ </Dialog.Root>
126
+ );
127
+ };
128
+
129
+ export default StudioModal;
@@ -25,6 +25,7 @@ import Lucid from '@components/MDX/Lucid/Lucid.astro';
25
25
  import DrawIO from '@components/MDX/DrawIO/DrawIO.astro';
26
26
  import FigJam from '@components/MDX/FigJam/FigJam.astro';
27
27
  import Design from '@components/MDX/Design/Design.astro';
28
+ import MermaidFileLoader from '@components/MDX/MermaidFileLoader/MermaidFileLoader.astro';
28
29
  // Portals: required for server/client components
29
30
  import NodeGraphPortal from '@components/MDX/NodeGraph/NodeGraphPortal';
30
31
  import SchemaViewerPortal from '@components/MDX/SchemaViewer/SchemaViewerPortal';
@@ -62,6 +63,7 @@ const components = (props: any) => {
62
63
  Lucid: (mdxProp: any) => jsx(Lucid, { ...props, ...mdxProp }),
63
64
  DrawIO: (mdxProp: any) => jsx(DrawIO, { ...props, ...mdxProp }),
64
65
  FigJam: (mdxProp: any) => jsx(FigJam, { ...props, ...mdxProp }),
66
+ MermaidFileLoader: (mdxProp: any) => jsx(MermaidFileLoader, { ...props, ...mdxProp }),
65
67
  };
66
68
  };
67
69
 
@@ -0,0 +1,87 @@
1
+ import type { ReactFlowInstance, Node, ReactFlowJsonObject, Edge } from '@xyflow/react';
2
+
3
+ // Define the structure of resource data that can be found in nodes
4
+ interface ResourceData {
5
+ id?: string;
6
+ name?: string;
7
+ summary?: string;
8
+ version?: string;
9
+ }
10
+
11
+ // Define the possible node data structure
12
+ interface NodeDataWithResources {
13
+ [key: string]: any;
14
+ channel?: ResourceData;
15
+ custom?: ResourceData;
16
+ data?: ResourceData;
17
+ domain?: ResourceData;
18
+ entity?: ResourceData;
19
+ message?: ResourceData;
20
+ flow?: ResourceData;
21
+ service?: ResourceData;
22
+ step?: ResourceData;
23
+ user?: ResourceData;
24
+ }
25
+
26
+ export const exportNodeGraphForStudio = (data: ReactFlowJsonObject) => {
27
+ const dataTypes: (keyof NodeDataWithResources)[] = [
28
+ 'channel',
29
+ 'custom',
30
+ 'data',
31
+ 'domain',
32
+ 'entity',
33
+ 'message',
34
+ 'flow',
35
+ 'service',
36
+ 'step',
37
+ 'user',
38
+ ];
39
+
40
+ // try and remove unwanted data for studio
41
+ const nodes = data.nodes.map((node: Node) => {
42
+ let nodeData = node.data as NodeDataWithResources;
43
+ const dataProperties = Object.keys(nodeData) as (keyof NodeDataWithResources)[];
44
+
45
+ // If we find a match.....
46
+ const hasCustomDataType = dataProperties.find((property) => dataTypes.includes(property));
47
+
48
+ if (hasCustomDataType && nodeData[hasCustomDataType]) {
49
+ const resourceData = nodeData[hasCustomDataType] as ResourceData;
50
+ nodeData = {
51
+ ...nodeData,
52
+ [hasCustomDataType]: {
53
+ id: resourceData?.id,
54
+ name: resourceData?.name,
55
+ summary: resourceData?.summary,
56
+ version: resourceData?.version,
57
+ },
58
+ };
59
+ }
60
+
61
+ return {
62
+ ...node,
63
+ data: {
64
+ ...nodeData,
65
+ // We dont need these for studio
66
+ source: undefined,
67
+ target: undefined,
68
+ // Studio wants all nodes in full mode
69
+ mode: 'full',
70
+ },
71
+ };
72
+ });
73
+
74
+ const edges = data.edges.map((edge: Edge) => {
75
+ return {
76
+ ...edge,
77
+ data: undefined,
78
+ type: 'animatedMessage',
79
+ };
80
+ });
81
+
82
+ return {
83
+ ...data,
84
+ nodes,
85
+ edges,
86
+ };
87
+ };
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.56.3",
9
+ "version": "2.57.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },