@eventcatalog/core 3.28.4 → 3.29.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.
@@ -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 = "3.28.4";
40
+ var version = "3.29.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-34MH7O22.js";
4
- import "../chunk-45JFXFTE.js";
3
+ } from "../chunk-XN2XNAOY.js";
4
+ import "../chunk-ZY6MUMIK.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -111,7 +111,7 @@ var import_axios = __toESM(require("axios"), 1);
111
111
  var import_os = __toESM(require("os"), 1);
112
112
 
113
113
  // package.json
114
- var version = "3.28.4";
114
+ var version = "3.29.0";
115
115
 
116
116
  // src/constants.ts
117
117
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-BGEC3Y5J.js";
4
- import "../chunk-34MH7O22.js";
3
+ } from "../chunk-NKN2LYFC.js";
4
+ import "../chunk-XN2XNAOY.js";
5
5
  import "../chunk-4UVFXLPI.js";
6
- import "../chunk-45JFXFTE.js";
6
+ import "../chunk-ZY6MUMIK.js";
7
7
  import "../chunk-5T63CXKU.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-4FMLF7P3.js";
3
+ } from "./chunk-B3DM4RWS.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-45JFXFTE.js";
3
+ } from "./chunk-ZY6MUMIK.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-34MH7O22.js";
3
+ } from "./chunk-XN2XNAOY.js";
4
4
  import {
5
5
  countResources,
6
6
  serializeCounts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-45JFXFTE.js";
3
+ } from "./chunk-ZY6MUMIK.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 = "3.28.4";
2
+ var version = "3.29.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "3.28.4";
28
+ var version = "3.29.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-45JFXFTE.js";
3
+ } from "./chunk-ZY6MUMIK.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -114,7 +114,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
114
114
  var import_picocolors = __toESM(require("picocolors"), 1);
115
115
 
116
116
  // package.json
117
- var version = "3.28.4";
117
+ var version = "3.29.0";
118
118
 
119
119
  // src/constants.ts
120
120
  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-BGEC3Y5J.js";
10
- import "./chunk-34MH7O22.js";
9
+ } from "./chunk-NKN2LYFC.js";
10
+ import "./chunk-XN2XNAOY.js";
11
11
  import "./chunk-4UVFXLPI.js";
12
12
  import {
13
13
  runMigrations
@@ -22,13 +22,13 @@ import {
22
22
  } from "./chunk-3KXCGYET.js";
23
23
  import {
24
24
  generate
25
- } from "./chunk-TSBHPGIL.js";
25
+ } from "./chunk-3YZL6CMP.js";
26
26
  import {
27
27
  logger
28
- } from "./chunk-4FMLF7P3.js";
28
+ } from "./chunk-B3DM4RWS.js";
29
29
  import {
30
30
  VERSION
31
- } from "./chunk-45JFXFTE.js";
31
+ } from "./chunk-ZY6MUMIK.js";
32
32
  import {
33
33
  getEventCatalogConfigFile,
34
34
  verifyRequiredFieldsAreInCatalogConfigFile
package/dist/generate.cjs CHANGED
@@ -78,7 +78,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
78
78
  var import_picocolors = __toESM(require("picocolors"), 1);
79
79
 
80
80
  // package.json
81
- var version = "3.28.4";
81
+ var version = "3.29.0";
82
82
 
83
83
  // src/constants.ts
84
84
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-TSBHPGIL.js";
4
- import "./chunk-4FMLF7P3.js";
5
- import "./chunk-45JFXFTE.js";
3
+ } from "./chunk-3YZL6CMP.js";
4
+ import "./chunk-B3DM4RWS.js";
5
+ import "./chunk-ZY6MUMIK.js";
6
6
  import "./chunk-5T63CXKU.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.28.4";
39
+ var version = "3.29.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-4FMLF7P3.js";
4
- import "../chunk-45JFXFTE.js";
3
+ } from "../chunk-B3DM4RWS.js";
4
+ import "../chunk-ZY6MUMIK.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -22,6 +22,12 @@ interface Props {
22
22
  renderAllEdges?: boolean;
23
23
  }
24
24
 
25
+ interface Maps {
26
+ messageMap: Map<string, any[]>;
27
+ serviceMap: Map<string, any[]>;
28
+ flowMap: Map<string, any[]>;
29
+ }
30
+
25
31
  const getServiceNode = (step: any, serviceMap: Map<string, any[]>) => {
26
32
  const service = findInMap(serviceMap, step.service.id, step.service.version);
27
33
  return {
@@ -49,53 +55,58 @@ const getMessageNode = (step: any, messageMap: Map<string, any[]>) => {
49
55
  };
50
56
  };
51
57
 
52
- export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simple', renderAllEdges = false }: Props) => {
53
- const graph = defaultFlow || createDagreGraph({ ranksep: 360, nodesep: 200 });
54
- const nodes = [] as any,
55
- edges = [] as any;
56
-
57
- // Fetch all collections in parallel
58
- const [flows, events, commands, queries, services] = await Promise.all([
59
- getCollection('flows'),
60
- getCollection('events'),
61
- getCollection('commands'),
62
- getCollection('queries'),
63
- getCollection('services'),
64
- ]);
65
-
66
- const flow = flows.find((flow) => flow.data.id === id && flow.data.version === version);
67
-
68
- // Nothing found...
69
- if (!flow) {
70
- return {
71
- nodes: [],
72
- edges: [],
73
- };
74
- }
58
+ // Rewrite every id/source/target in a precomputed sub-flow graph with a
59
+ // namespace prefix so inlined copies don't collide with the parent. Nested
60
+ // `data.expandedNodes` / `data.expandedEdges` payloads are rewritten too so
61
+ // the namespace chain stays unique when the same sub-flow is inlined under
62
+ // multiple parents.
63
+ const prefixGraph = (graph: { nodes: any[]; edges: any[] }, prefix: string) => {
64
+ if (!prefix) return graph;
65
+ const nodes = graph.nodes.map((n) => {
66
+ const next: any = { ...n, id: `${prefix}${n.id}` };
67
+ if (n.data?.expandedNodes || n.data?.expandedEdges) {
68
+ const nested = prefixGraph({ nodes: n.data.expandedNodes ?? [], edges: n.data.expandedEdges ?? [] }, prefix);
69
+ next.data = { ...n.data, expandedNodes: nested.nodes, expandedEdges: nested.edges };
70
+ }
71
+ return next;
72
+ });
73
+ const edges = graph.edges.map((e) => ({
74
+ ...e,
75
+ id: `${prefix}${e.id}`,
76
+ source: `${prefix}${e.source}`,
77
+ target: `${prefix}${e.target}`,
78
+ }));
79
+ return { nodes, edges };
80
+ };
75
81
 
76
- // Build maps for O(1) lookups
77
- const messages = [...events, ...commands, ...queries];
78
- const messageMap = createVersionedMap(messages);
79
- const serviceMap = createVersionedMap(services);
80
- const flowMap = createVersionedMap(flows);
82
+ // `subFlowCache` keys each flow's graph by `id@version` so an N-times
83
+ // referenced sub-flow is built once. `visited` short-circuits cycles.
84
+ const buildFlowGraphInternal = (
85
+ flow: any,
86
+ maps: Maps,
87
+ mode: 'simple' | 'full',
88
+ subFlowCache: Map<string, { nodes: any[]; edges: any[] }>,
89
+ visited: Set<string>
90
+ ) => {
91
+ const nodes: any[] = [];
92
+ const edges: any[] = [];
81
93
 
82
- const steps = flow?.data.steps || [];
94
+ const steps = flow?.data?.steps || [];
95
+ const stepNodeId = (stepId: any) => `step-${stepId}`;
83
96
 
84
- // Hydrate the steps with information they may need.
85
97
  const hydratedSteps = steps.map((step: any) => {
86
- if (step.service) return getServiceNode(step, serviceMap);
87
- if (step.flow) return getFlowNode(step, flowMap);
88
- if (step.message) return getMessageNode(step, messageMap);
98
+ if (step.service) return getServiceNode(step, maps.serviceMap);
99
+ if (step.flow) return getFlowNode(step, maps.flowMap);
100
+ if (step.message) return getMessageNode(step, maps.messageMap);
89
101
  if (step.actor) return { ...step, type: 'actor', actor: step.actor };
90
102
  if (step.custom) return { ...step, type: 'custom', custom: step.custom };
91
103
  if (step.externalSystem) return { ...step, type: 'externalSystem', externalSystem: step.externalSystem };
92
104
  return { ...step, type: 'step' };
93
105
  });
94
106
 
95
- // Create nodes
96
107
  hydratedSteps.forEach((step: any, index: number) => {
97
- const node = {
98
- id: `step-${step.id}`,
108
+ const node: NodeType = {
109
+ id: stepNodeId(step.id),
99
110
  sourcePosition: 'right',
100
111
  targetPosition: 'left',
101
112
  data: {
@@ -124,6 +135,21 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
124
135
  id: step.flow.data.id,
125
136
  version: step.flow.data.version,
126
137
  });
138
+
139
+ // Guard cycles; inline the sub-flow's graph so the client can expand on click.
140
+ const subFlowKey = `${step.flow.data.id}@${step.flow.data.version}`;
141
+ if (!visited.has(subFlowKey)) {
142
+ let cached = subFlowCache.get(subFlowKey);
143
+ if (!cached) {
144
+ cached = buildFlowGraphInternal(step.flow, maps, mode, subFlowCache, new Set([...visited, subFlowKey]));
145
+ subFlowCache.set(subFlowKey, cached);
146
+ }
147
+ if (cached.nodes.length > 0) {
148
+ const { nodes: childNodes, edges: childEdges } = prefixGraph(cached, `${node.id}__`);
149
+ node.data.expandedNodes = childNodes;
150
+ node.data.expandedEdges = childEdges;
151
+ }
152
+ }
127
153
  }
128
154
  if (step.message) {
129
155
  node.data.message = { ...step.message, ...step.message.data };
@@ -142,12 +168,10 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
142
168
  nodes.push(node);
143
169
  });
144
170
 
145
- // Create Edges
146
- hydratedSteps.forEach((step: any, index: number) => {
171
+ hydratedSteps.forEach((step: any) => {
147
172
  let paths = step.next_steps || [];
148
173
 
149
174
  if (step.next_step) {
150
- // If its a string or number
151
175
  if (!step.next_step?.id) {
152
176
  paths = [{ id: step.next_step }];
153
177
  } else {
@@ -165,8 +189,8 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
165
189
  paths.forEach((path: any) => {
166
190
  edges.push({
167
191
  id: `step-${step.id}-step-${path.id}`,
168
- source: `step-${step.id}`,
169
- target: `step-${path.id}`,
192
+ source: stepNodeId(step.id),
193
+ target: stepNodeId(path.id),
170
194
  type: 'flow-edge',
171
195
  label: path.label,
172
196
  animated: true,
@@ -184,6 +208,45 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
184
208
  });
185
209
  });
186
210
 
211
+ return { nodes, edges };
212
+ };
213
+
214
+ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simple', renderAllEdges = false }: Props) => {
215
+ const graph = defaultFlow || createDagreGraph({ ranksep: 360, nodesep: 200 });
216
+
217
+ const [flows, events, commands, queries, services] = await Promise.all([
218
+ getCollection('flows'),
219
+ getCollection('events'),
220
+ getCollection('commands'),
221
+ getCollection('queries'),
222
+ getCollection('services'),
223
+ ]);
224
+
225
+ const flow = flows.find((flow) => flow.data.id === id && flow.data.version === version);
226
+
227
+ if (!flow) {
228
+ return {
229
+ nodes: [],
230
+ edges: [],
231
+ };
232
+ }
233
+
234
+ const messages = [...events, ...commands, ...queries];
235
+ const maps: Maps = {
236
+ messageMap: createVersionedMap(messages),
237
+ serviceMap: createVersionedMap(services),
238
+ flowMap: createVersionedMap(flows),
239
+ };
240
+
241
+ const subFlowCache = new Map<string, { nodes: any[]; edges: any[] }>();
242
+ const { nodes, edges } = buildFlowGraphInternal(
243
+ flow,
244
+ maps,
245
+ mode,
246
+ subFlowCache,
247
+ new Set([`${flow.data.id}@${flow.data.version}`])
248
+ );
249
+
187
250
  nodes.forEach((node: any) => {
188
251
  graph.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
189
252
  });
@@ -192,7 +255,6 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
192
255
  graph.setEdge(edge.source, edge.target);
193
256
  });
194
257
 
195
- // Render the diagram in memory getting hte X and Y
196
258
  dagre.layout(graph);
197
259
 
198
260
  return {
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "3.28.4",
10
+ "version": "3.29.0",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -103,9 +103,9 @@
103
103
  "update-notifier": "^7.3.1",
104
104
  "uuid": "^10.0.0",
105
105
  "zod": "^4.3.6",
106
+ "@eventcatalog/linter": "1.0.21",
106
107
  "@eventcatalog/sdk": "2.20.0",
107
- "@eventcatalog/visualiser": "^3.18.4",
108
- "@eventcatalog/linter": "1.0.21"
108
+ "@eventcatalog/visualiser": "^3.19.0"
109
109
  },
110
110
  "devDependencies": {
111
111
  "@astrojs/check": "^0.9.8",