@eventcatalog/core 2.65.0-beta.1 → 2.65.0-beta.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/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-WHI74T3R.js → chunk-76KMPQRC.js} +1 -1
- package/dist/{chunk-KGYO3DWA.js → chunk-V2GM5B5L.js} +1 -1
- package/dist/{chunk-B2DX6NNM.js → chunk-Z5H2XGTS.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +3 -3
- package/eventcatalog/src/components/SchemaExplorer/AvroSchemaViewer.tsx +39 -23
- package/eventcatalog/src/pages/api/schemas/[collection]/[id]/[version]/index.ts +45 -8
- package/package.json +8 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-V2GM5B5L.js";
|
|
4
|
+
import "../chunk-Z5H2XGTS.js";
|
|
5
|
+
import "../chunk-76KMPQRC.js";
|
|
6
6
|
import "../chunk-UPONRQSN.js";
|
|
7
7
|
export {
|
|
8
8
|
log_build_default as default
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
package/dist/eventcatalog.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
} from "./chunk-PLNJC7NZ.js";
|
|
7
7
|
import {
|
|
8
8
|
log_build_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-V2GM5B5L.js";
|
|
10
|
+
import "./chunk-Z5H2XGTS.js";
|
|
11
11
|
import {
|
|
12
12
|
runMigrations
|
|
13
13
|
} from "./chunk-BH3JMNAV.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import "./chunk-55D645EH.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-76KMPQRC.js";
|
|
23
23
|
import {
|
|
24
24
|
getProjectOutDir,
|
|
25
25
|
isAuthEnabled,
|
|
@@ -24,8 +24,8 @@ function formatAvroType(type: any): string {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
if (Array.isArray(type)) {
|
|
27
|
-
// Union type - show all options
|
|
28
|
-
return type.join(' | ');
|
|
27
|
+
// Union type - show all options, properly formatting each member
|
|
28
|
+
return type.map((t) => formatAvroType(t)).join(' | ');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
if (typeof type === 'object') {
|
|
@@ -52,9 +52,16 @@ function formatAvroType(type: any): string {
|
|
|
52
52
|
|
|
53
53
|
// Check if a type has nested fields
|
|
54
54
|
function hasNestedFields(type: any): boolean {
|
|
55
|
+
// Check if it's a direct record type
|
|
55
56
|
if (typeof type === 'object' && !Array.isArray(type)) {
|
|
56
57
|
return type.type === 'record' && type.fields && type.fields.length > 0;
|
|
57
58
|
}
|
|
59
|
+
|
|
60
|
+
// Check if it's a union type that contains a record
|
|
61
|
+
if (Array.isArray(type)) {
|
|
62
|
+
return type.some((t) => typeof t === 'object' && !Array.isArray(t) && t.type === 'record' && t.fields && t.fields.length > 0);
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
return false;
|
|
59
66
|
}
|
|
60
67
|
|
|
@@ -84,6 +91,14 @@ function isFieldRequired(field: any): boolean {
|
|
|
84
91
|
return true;
|
|
85
92
|
}
|
|
86
93
|
|
|
94
|
+
// Helper function to get the record type from a union if it exists
|
|
95
|
+
function getRecordFromUnion(type: any): any {
|
|
96
|
+
if (Array.isArray(type)) {
|
|
97
|
+
return type.find((t) => typeof t === 'object' && !Array.isArray(t) && t.type === 'record');
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
87
102
|
// AvroField component - displays a single field with nested support
|
|
88
103
|
const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
|
|
89
104
|
const [isExpanded, setIsExpanded] = useState(expand);
|
|
@@ -91,34 +106,35 @@ const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
|
|
|
91
106
|
const indentClass = `pl-${level * 4}`;
|
|
92
107
|
const isRequired = showRequired ? isFieldRequired(field) : undefined;
|
|
93
108
|
|
|
109
|
+
// Get the record type, either directly or from within a union
|
|
110
|
+
const recordType = typeof field.type === 'object' && field.type.type === 'record' ? field.type : getRecordFromUnion(field.type);
|
|
111
|
+
|
|
94
112
|
useEffect(() => {
|
|
95
113
|
setIsExpanded(expand);
|
|
96
114
|
}, [expand]);
|
|
97
115
|
|
|
98
116
|
return (
|
|
99
117
|
<div className={`avro-field-container mb-2 border-l border-gray-200 ${indentClass}`}>
|
|
100
|
-
<div className="flex
|
|
118
|
+
<div className="flex space-x-2">
|
|
101
119
|
{/* Collapse/Expand button */}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
<div className="flex-shrink-0 w-4 pt-0.5">
|
|
121
|
+
{hasNested ? (
|
|
122
|
+
<button
|
|
123
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
124
|
+
className="avro-field-toggle text-gray-500 hover:text-gray-700 w-4 text-center"
|
|
125
|
+
aria-expanded={isExpanded}
|
|
126
|
+
>
|
|
127
|
+
<span className="font-mono text-xs">{isExpanded ? '▼' : '▶'}</span>
|
|
128
|
+
</button>
|
|
129
|
+
) : null}
|
|
130
|
+
</div>
|
|
113
131
|
|
|
114
132
|
{/* Field details */}
|
|
115
|
-
<div className="flex-grow">
|
|
116
|
-
<div className="flex
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
</div>
|
|
121
|
-
{showRequired && isRequired && <span className="text-red-600 text-xs ml-3 flex-shrink-0">required</span>}
|
|
133
|
+
<div className="flex-grow min-w-0">
|
|
134
|
+
<div className="flex flex-wrap items-baseline gap-x-1.5 gap-y-1">
|
|
135
|
+
<span className="avro-field-name font-semibold text-gray-800 text-sm">{field.name}</span>
|
|
136
|
+
<span className="text-purple-600 font-mono text-xs">{formatAvroType(field.type)}</span>
|
|
137
|
+
{showRequired && isRequired && <span className="text-red-600 text-xs ml-auto flex-shrink-0">required</span>}
|
|
122
138
|
</div>
|
|
123
139
|
|
|
124
140
|
{field.doc && <p className="text-gray-600 text-xs mt-1">{field.doc}</p>}
|
|
@@ -136,9 +152,9 @@ const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
|
|
|
136
152
|
)}
|
|
137
153
|
|
|
138
154
|
{/* Nested fields for record types */}
|
|
139
|
-
{hasNested && (
|
|
155
|
+
{hasNested && recordType && (
|
|
140
156
|
<div className={`avro-nested-content mt-2 ${!isExpanded ? 'hidden' : ''}`}>
|
|
141
|
-
{
|
|
157
|
+
{recordType.fields.map((nestedField: any) => (
|
|
142
158
|
<AvroField
|
|
143
159
|
key={nestedField.name}
|
|
144
160
|
field={nestedField}
|
|
@@ -3,23 +3,60 @@ import { getCollection } from 'astro:content';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import { isEventCatalogScaleEnabled } from '@utils/feature';
|
|
6
|
+
import { sortVersioned } from '@utils/collections/util';
|
|
6
7
|
|
|
7
8
|
export async function getStaticPaths() {
|
|
8
9
|
const events = await getCollection('events');
|
|
9
10
|
const commands = await getCollection('commands');
|
|
10
11
|
const queries = await getCollection('queries');
|
|
11
12
|
const messages = [...events, ...commands, ...queries];
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
const messagesWithSchemas = messages
|
|
13
15
|
.filter((message) => message.data.schemaPath)
|
|
14
|
-
.filter((message) => fs.existsSync(path.join(path.dirname(message.filePath ?? ''), message.data.schemaPath ?? '')))
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
.filter((message) => fs.existsSync(path.join(path.dirname(message.filePath ?? ''), message.data.schemaPath ?? '')));
|
|
17
|
+
|
|
18
|
+
// Generate paths for specific versions
|
|
19
|
+
const versionedPaths = messagesWithSchemas.map((message) => ({
|
|
20
|
+
params: { collection: message.collection, id: message.data.id, version: message.data.version },
|
|
21
|
+
props: {
|
|
22
|
+
pathToSchema: path.join(path.dirname(message.filePath ?? ''), message.data.schemaPath ?? ''),
|
|
23
|
+
schema: fs.readFileSync(path.join(path.dirname(message.filePath ?? ''), message.data.schemaPath ?? ''), 'utf8'),
|
|
24
|
+
extension: message.data.schemaPath?.split('.').pop(),
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
// Group messages by collection and id to find latest versions
|
|
29
|
+
const groupedMessages = messagesWithSchemas.reduce(
|
|
30
|
+
(acc, message) => {
|
|
31
|
+
const key = `${message.collection}:${message.data.id}`;
|
|
32
|
+
if (!acc[key]) {
|
|
33
|
+
acc[key] = [];
|
|
34
|
+
}
|
|
35
|
+
acc[key].push(message);
|
|
36
|
+
return acc;
|
|
37
|
+
},
|
|
38
|
+
{} as Record<string, typeof messagesWithSchemas>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Generate "latest" paths for each unique collection/id combination
|
|
42
|
+
const latestPaths = Object.values(groupedMessages).map((group) => {
|
|
43
|
+
// Sort by version (descending) and get the latest
|
|
44
|
+
const sorted = sortVersioned(group, (m) => m.data.version);
|
|
45
|
+
const latestMessage = sorted[0];
|
|
46
|
+
return {
|
|
47
|
+
params: { collection: latestMessage.collection, id: latestMessage.data.id, version: 'latest' },
|
|
17
48
|
props: {
|
|
18
|
-
pathToSchema: path.join(path.dirname(
|
|
19
|
-
schema: fs.readFileSync(
|
|
20
|
-
|
|
49
|
+
pathToSchema: path.join(path.dirname(latestMessage.filePath ?? ''), latestMessage.data.schemaPath ?? ''),
|
|
50
|
+
schema: fs.readFileSync(
|
|
51
|
+
path.join(path.dirname(latestMessage.filePath ?? ''), latestMessage.data.schemaPath ?? ''),
|
|
52
|
+
'utf8'
|
|
53
|
+
),
|
|
54
|
+
extension: latestMessage.data.schemaPath?.split('.').pop(),
|
|
21
55
|
},
|
|
22
|
-
}
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return [...versionedPaths, ...latestPaths];
|
|
23
60
|
}
|
|
24
61
|
|
|
25
62
|
export const GET: APIRoute = async ({ props }) => {
|
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.65.0-beta.
|
|
9
|
+
"version": "2.65.0-beta.3",
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"@ai-sdk/google": "^2.0.17",
|
|
26
26
|
"@ai-sdk/openai": "^2.0.42",
|
|
27
27
|
"@ai-sdk/react": "^2.0.60",
|
|
28
|
-
"@astrojs/markdown-remark": "^6.3.
|
|
29
|
-
"@astrojs/mdx": "^4.3.
|
|
30
|
-
"@astrojs/node": "^9.5.
|
|
31
|
-
"@astrojs/react": "^4.4.
|
|
32
|
-
"@astrojs/rss": "^4.0.
|
|
28
|
+
"@astrojs/markdown-remark": "^6.3.9",
|
|
29
|
+
"@astrojs/mdx": "^4.3.12",
|
|
30
|
+
"@astrojs/node": "^9.5.1",
|
|
31
|
+
"@astrojs/react": "^4.4.2",
|
|
32
|
+
"@astrojs/rss": "^4.0.14",
|
|
33
33
|
"@astrojs/tailwind": "^6.0.2",
|
|
34
34
|
"@asyncapi/avro-schema-parser": "^3.0.24",
|
|
35
35
|
"@asyncapi/parser": "^3.4.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@tanstack/react-table": "^8.17.3",
|
|
57
57
|
"@xyflow/react": "^12.3.6",
|
|
58
58
|
"ai": "^5.0.60",
|
|
59
|
-
"astro": "^5.
|
|
59
|
+
"astro": "^5.16.0",
|
|
60
60
|
"astro-compress": "^2.3.8",
|
|
61
61
|
"astro-expressive-code": "^0.41.3",
|
|
62
62
|
"astro-seo": "^0.8.4",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"diff2html": "^3.4.48",
|
|
73
73
|
"dotenv": "^16.5.0",
|
|
74
74
|
"elkjs": "^0.10.0",
|
|
75
|
-
"glob": "^10.
|
|
75
|
+
"glob": "^10.5.0",
|
|
76
76
|
"gray-matter": "^4.0.3",
|
|
77
77
|
"html-to-image": "^1.11.11",
|
|
78
78
|
"js-yaml": "^4.1.0",
|