@eventcatalog/core 3.0.0-beta.13 → 3.0.0-beta.14
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-GDNZSDL4.js → chunk-4NW4G57L.js} +1 -1
- package/dist/{chunk-HVITNJND.js → chunk-5USO3QRB.js} +1 -1
- package/dist/{chunk-TTSVZOOO.js → chunk-65DCHZUQ.js} +1 -1
- package/dist/{chunk-URNXOM2X.js → chunk-7F26ZV4O.js} +1 -1
- package/dist/{chunk-SXOMOZU7.js → chunk-YPTOTOIV.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +2 -1
- package/dist/eventcatalog.js +6 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/Header.astro +18 -2
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +30 -11
- package/eventcatalog/src/pages/_index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +15 -3
- package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +178 -0
- package/eventcatalog/src/pages/schemas/explorer/index.astro +5 -155
- package/eventcatalog/src/utils/resource-files.ts +86 -0
- package/package.json +2 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-7F26ZV4O.js";
|
|
4
|
+
import "../chunk-65DCHZUQ.js";
|
|
5
|
+
import "../chunk-YPTOTOIV.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
|
@@ -109,7 +109,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
109
109
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
110
110
|
|
|
111
111
|
// package.json
|
|
112
|
-
var version = "3.0.0-beta.
|
|
112
|
+
var version = "3.0.0-beta.14";
|
|
113
113
|
|
|
114
114
|
// src/constants.ts
|
|
115
115
|
var VERSION = version;
|
|
@@ -921,6 +921,7 @@ program.command("start").description("Serves the contents of your eventcatalog b
|
|
|
921
921
|
);
|
|
922
922
|
const isEventCatalogStarter = await (0, import_license.isEventCatalogStarterEnabled)();
|
|
923
923
|
const isEventCatalogScale = await (0, import_license.isEventCatalogScaleEnabled)();
|
|
924
|
+
await copyServerFiles();
|
|
924
925
|
const isServerOutput = await isOutputServer();
|
|
925
926
|
if (isServerOutput) {
|
|
926
927
|
startServerCatalog({
|
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-7F26ZV4O.js";
|
|
10
|
+
import "./chunk-65DCHZUQ.js";
|
|
11
11
|
import {
|
|
12
12
|
runMigrations
|
|
13
13
|
} from "./chunk-BH3JMNAV.js";
|
|
@@ -23,13 +23,13 @@ import {
|
|
|
23
23
|
} from "./chunk-5VBIXL6C.js";
|
|
24
24
|
import {
|
|
25
25
|
generate
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5USO3QRB.js";
|
|
27
27
|
import {
|
|
28
28
|
logger
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-4NW4G57L.js";
|
|
30
30
|
import {
|
|
31
31
|
VERSION
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-YPTOTOIV.js";
|
|
33
33
|
import "./chunk-UPONRQSN.js";
|
|
34
34
|
|
|
35
35
|
// src/eventcatalog.ts
|
|
@@ -295,6 +295,7 @@ program.command("start").description("Serves the contents of your eventcatalog b
|
|
|
295
295
|
);
|
|
296
296
|
const isEventCatalogStarter = await isEventCatalogStarterEnabled();
|
|
297
297
|
const isEventCatalogScale = await isEventCatalogScaleEnabled();
|
|
298
|
+
await copyServerFiles();
|
|
298
299
|
const isServerOutput = await isOutputServer();
|
|
299
300
|
if (isServerOutput) {
|
|
300
301
|
startServerCatalog({
|
package/dist/generate.cjs
CHANGED
|
@@ -73,7 +73,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
|
|
|
73
73
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
74
74
|
|
|
75
75
|
// package.json
|
|
76
|
-
var version = "3.0.0-beta.
|
|
76
|
+
var version = "3.0.0-beta.14";
|
|
77
77
|
|
|
78
78
|
// src/constants.ts
|
|
79
79
|
var VERSION = version;
|
package/dist/generate.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generate
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-5USO3QRB.js";
|
|
4
|
+
import "./chunk-4NW4G57L.js";
|
|
5
|
+
import "./chunk-YPTOTOIV.js";
|
|
6
6
|
import "./chunk-UPONRQSN.js";
|
|
7
7
|
export {
|
|
8
8
|
generate
|
package/dist/utils/cli-logger.js
CHANGED
|
@@ -60,6 +60,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
|
|
|
60
60
|
class="flex items-center focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400 rounded-full"
|
|
61
61
|
aria-expanded="false"
|
|
62
62
|
aria-haspopup="true"
|
|
63
|
+
aria-label="User menu"
|
|
63
64
|
>
|
|
64
65
|
{session.user?.image && !session.user?.image?.includes('googleusercontent.com') ? (
|
|
65
66
|
<img
|
|
@@ -117,16 +118,28 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
|
|
|
117
118
|
<a
|
|
118
119
|
href="https://discord.com/invite/3rjaZMmrAm"
|
|
119
120
|
class="block p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
|
|
121
|
+
aria-label="Join our Discord community"
|
|
120
122
|
>
|
|
121
|
-
<img
|
|
123
|
+
<img
|
|
124
|
+
src={buildUrl('/icons/discord.svg', true)}
|
|
125
|
+
alt=""
|
|
126
|
+
class="h-6 w-6 hover:opacity-100 transition-opacity"
|
|
127
|
+
aria-hidden="true"
|
|
128
|
+
/>
|
|
122
129
|
</a>
|
|
123
130
|
</li>
|
|
124
131
|
<li>
|
|
125
132
|
<a
|
|
126
133
|
href="https://github.com/event-catalog/eventcatalog"
|
|
127
134
|
class="block p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
|
|
135
|
+
aria-label="View EventCatalog on GitHub"
|
|
128
136
|
>
|
|
129
|
-
<img
|
|
137
|
+
<img
|
|
138
|
+
src={buildUrl('/icons/github.svg', true)}
|
|
139
|
+
alt=""
|
|
140
|
+
class="h-6 w-6 hover:opacity-100 transition-opacity"
|
|
141
|
+
aria-hidden="true"
|
|
142
|
+
/>
|
|
130
143
|
</a>
|
|
131
144
|
</li>
|
|
132
145
|
</ul>
|
|
@@ -137,10 +150,13 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
|
|
|
137
150
|
<a
|
|
138
151
|
href={repositoryUrl}
|
|
139
152
|
class="block p-1.5 rounded-lg hover:bg-gray-100 transition-colors focus:outline-none"
|
|
153
|
+
aria-label="View repository on GitHub"
|
|
140
154
|
>
|
|
141
155
|
<img
|
|
142
156
|
src={buildUrl('/icons/github.svg', true)}
|
|
157
|
+
alt=""
|
|
143
158
|
class="h-6 w-6 opacity-70 hover:opacity-100 transition-opacity"
|
|
159
|
+
aria-hidden="true"
|
|
144
160
|
/>
|
|
145
161
|
</a>
|
|
146
162
|
</li>
|
|
@@ -248,15 +248,19 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
248
248
|
id={item.id}
|
|
249
249
|
data-role="nav-item"
|
|
250
250
|
href={item.href}
|
|
251
|
+
aria-label={item.label}
|
|
251
252
|
class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${
|
|
252
253
|
item.current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'
|
|
253
254
|
}`}
|
|
254
255
|
>
|
|
255
256
|
<div class="has-tooltip">
|
|
256
|
-
<span
|
|
257
|
+
<span
|
|
258
|
+
class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap"
|
|
259
|
+
aria-hidden="true"
|
|
260
|
+
>
|
|
257
261
|
{item.label}
|
|
258
262
|
</span>
|
|
259
|
-
<item.icon className="h-6 w-6" />
|
|
263
|
+
<item.icon className="h-6 w-6" aria-hidden="true" />
|
|
260
264
|
</div>
|
|
261
265
|
</a>
|
|
262
266
|
);
|
|
@@ -271,13 +275,17 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
271
275
|
id={studioNavigationItem[0].id}
|
|
272
276
|
data-role="nav-item"
|
|
273
277
|
href={studioNavigationItem[0].href}
|
|
278
|
+
aria-label={studioNavigationItem[0].label}
|
|
274
279
|
class={`p-1.5 inline-block pt-1 pb-1 mt-0 mb-0 transition-colors duration-200 rounded-lg relative ${studioNavigationItem[0].current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'}`}
|
|
275
280
|
>
|
|
276
281
|
<div class="has-tooltip">
|
|
277
|
-
<span
|
|
282
|
+
<span
|
|
283
|
+
class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap"
|
|
284
|
+
aria-hidden="true"
|
|
285
|
+
>
|
|
278
286
|
{studioNavigationItem[0].label}
|
|
279
287
|
</span>
|
|
280
|
-
<SquareDashedMousePointerIcon className="h-6 w-6" />
|
|
288
|
+
<SquareDashedMousePointerIcon className="h-6 w-6" aria-hidden="true" />
|
|
281
289
|
</div>
|
|
282
290
|
</a>
|
|
283
291
|
)
|
|
@@ -291,17 +299,24 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
291
299
|
id={item.id}
|
|
292
300
|
data-role="nav-item"
|
|
293
301
|
href={item.href}
|
|
302
|
+
aria-label={item.label}
|
|
294
303
|
class={`p-1.5 inline-block transition-colors duration-200 rounded-lg mb-8 relative ${
|
|
295
304
|
item.current ? 'text-white bg-gray-900' : 'hover:bg-gray-800 hover:text-white text-gray-700'
|
|
296
305
|
}`}
|
|
297
306
|
>
|
|
298
307
|
<div class="has-tooltip">
|
|
299
|
-
<span
|
|
300
|
-
|
|
308
|
+
<span
|
|
309
|
+
class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 flex items-center gap-1 whitespace-nowrap"
|
|
310
|
+
aria-hidden="true"
|
|
311
|
+
>
|
|
312
|
+
<Sparkles className="h-3 w-3" aria-hidden="true" /> {item.label}
|
|
301
313
|
</span>
|
|
302
|
-
<item.icon className="h-6 w-6" />
|
|
303
|
-
<div
|
|
304
|
-
|
|
314
|
+
<item.icon className="h-6 w-6" aria-hidden="true" />
|
|
315
|
+
<div
|
|
316
|
+
class="absolute -top-1 -right-1 bg-gradient-to-r from-amber-400 to-amber-500 rounded-full p-0.5 shadow-lg"
|
|
317
|
+
aria-hidden="true"
|
|
318
|
+
>
|
|
319
|
+
<Sparkles className="h-2 w-2 text-white" aria-hidden="true" />
|
|
305
320
|
</div>
|
|
306
321
|
</div>
|
|
307
322
|
</a>
|
|
@@ -316,13 +331,17 @@ const canPageBeEmbedded = isEmbedEnabled();
|
|
|
316
331
|
id="/pro"
|
|
317
332
|
data-role="nav-item"
|
|
318
333
|
href={buildUrl('/plans')}
|
|
334
|
+
aria-label="Upgrade EventCatalog"
|
|
319
335
|
class={`p-1.5 inline-block transition-colors duration-200 rounded-lg ${currentPath.includes('/pro') ? 'text-white bg-gray-900' : 'bg-gray-200 hover:bg-gray-800 hover:text-white text-gray-700'}`}
|
|
320
336
|
>
|
|
321
337
|
<div class="has-tooltip">
|
|
322
|
-
<span
|
|
338
|
+
<span
|
|
339
|
+
class="tooltip rounded shadow-lg p-1 text-xs bg-gray-900 text-white ml-10 whitespace-nowrap"
|
|
340
|
+
aria-hidden="true"
|
|
341
|
+
>
|
|
323
342
|
Upgrade EventCatalog
|
|
324
343
|
</span>
|
|
325
|
-
<Rocket className="h-6 w-6" />
|
|
344
|
+
<Rocket className="h-6 w-6" aria-hidden="true" />
|
|
326
345
|
</div>
|
|
327
346
|
</a>
|
|
328
347
|
</div>
|
|
@@ -304,6 +304,7 @@ const quickActions = [
|
|
|
304
304
|
<button
|
|
305
305
|
data-search-trigger
|
|
306
306
|
class="group flex items-center gap-3 w-full px-4 py-3 bg-white border-2 border-gray-200 rounded-lg hover:border-blue-400 hover:shadow-md transition-all cursor-pointer"
|
|
307
|
+
aria-label="Search events, services, and domains"
|
|
307
308
|
>
|
|
308
309
|
<svg
|
|
309
310
|
class="w-5 h-5 text-gray-400 group-hover:text-blue-500 transition-colors"
|
|
@@ -69,9 +69,21 @@ const pagefindAttributes =
|
|
|
69
69
|
</VerticalSideBarLayout>
|
|
70
70
|
|
|
71
71
|
<script is:inline src={js}></script>
|
|
72
|
-
<script define:vars={{ schema: stringified, config }}>
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
<script is:inline define:vars={{ schema: stringified, config }}>
|
|
73
|
+
function initAsyncApi() {
|
|
74
|
+
const root = document.getElementById('asyncapi');
|
|
75
|
+
if (!root || root.dataset.initialized) return;
|
|
76
|
+
|
|
77
|
+
if (typeof AsyncApiStandalone !== 'undefined') {
|
|
78
|
+
AsyncApiStandalone.render({ schema, config }, root);
|
|
79
|
+
root.dataset.initialized = 'true';
|
|
80
|
+
} else {
|
|
81
|
+
setTimeout(initAsyncApi, 50);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
document.addEventListener('astro:page-load', initAsyncApi);
|
|
86
|
+
initAsyncApi();
|
|
75
87
|
</script>
|
|
76
88
|
|
|
77
89
|
<style>
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { isSSR } from '@utils/feature';
|
|
2
|
+
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
+
import { getEvents } from '@utils/collections/events';
|
|
4
|
+
import { getCommands } from '@utils/collections/commands';
|
|
5
|
+
import { getQueries } from '@utils/collections/queries';
|
|
6
|
+
import { getServices, getSpecificationsForService } from '@utils/collections/services';
|
|
7
|
+
import { getOwner } from '@utils/collections/owners';
|
|
8
|
+
import { buildUrl } from '@utils/url-builder';
|
|
9
|
+
import { resourceFileExists, readResourceFile } from '@utils/resource-files';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
|
|
12
|
+
// Helper function to enrich owners with full details
|
|
13
|
+
async function enrichOwners(ownersRaw: any[]) {
|
|
14
|
+
if (!ownersRaw || ownersRaw.length === 0) return [];
|
|
15
|
+
|
|
16
|
+
const owners = await Promise.all(ownersRaw.map(getOwner));
|
|
17
|
+
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
18
|
+
|
|
19
|
+
return filteredOwners.map((o) => ({
|
|
20
|
+
id: o.data.id,
|
|
21
|
+
name: o.data.name,
|
|
22
|
+
type: o.collection,
|
|
23
|
+
href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function fetchAllSchemas() {
|
|
28
|
+
// Fetch all messages
|
|
29
|
+
const events = await getEvents({ getAllVersions: true });
|
|
30
|
+
const commands = await getCommands({ getAllVersions: true });
|
|
31
|
+
const queries = await getQueries({ getAllVersions: true });
|
|
32
|
+
|
|
33
|
+
// Fetch all services
|
|
34
|
+
const services = await getServices({ getAllVersions: true });
|
|
35
|
+
|
|
36
|
+
// Combine all messages
|
|
37
|
+
const allMessages = [...events, ...commands, ...queries];
|
|
38
|
+
|
|
39
|
+
// Filter messages with schemas and read schema content - only keep essential data
|
|
40
|
+
const messagesWithSchemas = await Promise.all(
|
|
41
|
+
allMessages
|
|
42
|
+
.filter((message) => message.data.schemaPath)
|
|
43
|
+
.filter((message) => resourceFileExists(message, message.data.schemaPath ?? ''))
|
|
44
|
+
.map(async (message) => {
|
|
45
|
+
try {
|
|
46
|
+
const schemaPath = message.data.schemaPath ?? '';
|
|
47
|
+
const schemaContent = readResourceFile(message, schemaPath) ?? '';
|
|
48
|
+
const schemaExtension = path.extname(schemaPath).slice(1);
|
|
49
|
+
const enrichedOwners = await enrichOwners(message.data.owners || []);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
collection: message.collection,
|
|
53
|
+
data: {
|
|
54
|
+
id: message.data.id,
|
|
55
|
+
name: message.data.name,
|
|
56
|
+
version: message.data.version,
|
|
57
|
+
summary: message.data.summary,
|
|
58
|
+
schemaPath: message.data.schemaPath,
|
|
59
|
+
producers: message.data.producers || [],
|
|
60
|
+
consumers: message.data.consumers || [],
|
|
61
|
+
owners: enrichedOwners,
|
|
62
|
+
},
|
|
63
|
+
schemaContent,
|
|
64
|
+
schemaExtension,
|
|
65
|
+
};
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error(`Error reading schema for ${message.data.id}:`, error);
|
|
68
|
+
const enrichedOwners = await enrichOwners(message.data.owners || []);
|
|
69
|
+
return {
|
|
70
|
+
collection: message.collection,
|
|
71
|
+
data: {
|
|
72
|
+
id: message.data.id,
|
|
73
|
+
name: message.data.name,
|
|
74
|
+
version: message.data.version,
|
|
75
|
+
summary: message.data.summary,
|
|
76
|
+
schemaPath: message.data.schemaPath,
|
|
77
|
+
producers: message.data.producers || [],
|
|
78
|
+
consumers: message.data.consumers || [],
|
|
79
|
+
owners: enrichedOwners,
|
|
80
|
+
},
|
|
81
|
+
schemaContent: '',
|
|
82
|
+
schemaExtension: 'json',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Filter services with specifications and read spec content - only keep essential data
|
|
89
|
+
const servicesWithSpecs = await Promise.all(
|
|
90
|
+
services.map(async (service) => {
|
|
91
|
+
try {
|
|
92
|
+
const specifications = getSpecificationsForService(service);
|
|
93
|
+
|
|
94
|
+
if (specifications.length === 0) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return await Promise.all(
|
|
99
|
+
specifications.map(async (spec) => {
|
|
100
|
+
if (!resourceFileExists(service, spec.path)) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const schemaContent = readResourceFile(service, spec.path) ?? '';
|
|
105
|
+
const schemaExtension = spec.type;
|
|
106
|
+
const enrichedOwners = await enrichOwners(service.data.owners || []);
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
collection: 'services',
|
|
110
|
+
data: {
|
|
111
|
+
id: `${service.data.id}`,
|
|
112
|
+
name: `${service.data.name} - ${spec.name}`,
|
|
113
|
+
version: service.data.version,
|
|
114
|
+
summary: service.data.summary,
|
|
115
|
+
schemaPath: spec.path,
|
|
116
|
+
owners: enrichedOwners,
|
|
117
|
+
},
|
|
118
|
+
schemaContent,
|
|
119
|
+
schemaExtension,
|
|
120
|
+
specType: spec.type,
|
|
121
|
+
specName: spec.name,
|
|
122
|
+
specFilenameWithoutExtension: spec.filenameWithoutExtension,
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error(`Error reading specifications for service ${service.data.id}:`, error);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Flatten and filter out null values
|
|
134
|
+
const flatServicesWithSpecs = servicesWithSpecs.flat().filter((service) => service !== null);
|
|
135
|
+
|
|
136
|
+
return [...messagesWithSchemas, ...flatServicesWithSpecs];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export class Page extends HybridPage {
|
|
140
|
+
static get prerender(): boolean {
|
|
141
|
+
return !isSSR();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
|
|
145
|
+
if (isSSR()) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const allSchemas = await fetchAllSchemas();
|
|
150
|
+
|
|
151
|
+
return [
|
|
152
|
+
{
|
|
153
|
+
params: {},
|
|
154
|
+
props: {
|
|
155
|
+
schemas: allSchemas,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected static async fetchData(_params: any) {
|
|
162
|
+
const allSchemas = await fetchAllSchemas();
|
|
163
|
+
return {
|
|
164
|
+
schemas: allSchemas,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected static hasValidProps(props: any): boolean {
|
|
169
|
+
return props && props.schemas !== undefined;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
protected static createNotFoundResponse(): Response {
|
|
173
|
+
return new Response(null, {
|
|
174
|
+
status: 404,
|
|
175
|
+
statusText: 'Schema explorer not found',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -1,163 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
3
|
-
import { getEvents } from '@utils/collections/events';
|
|
4
|
-
import { getCommands } from '@utils/collections/commands';
|
|
5
|
-
import { getQueries } from '@utils/collections/queries';
|
|
6
|
-
import { getServices, getSpecificationsForService } from '@utils/collections/services';
|
|
7
3
|
import SchemaExplorer from '@components/SchemaExplorer/SchemaExplorer';
|
|
8
4
|
import { isEventCatalogScaleEnabled } from '@utils/feature';
|
|
9
|
-
import {
|
|
10
|
-
import { buildUrl } from '@utils/url-builder';
|
|
11
|
-
import fs from 'fs';
|
|
12
|
-
import path from 'path';
|
|
5
|
+
import { Page } from './_index.data';
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const commands = await getCommands({ getAllVersions: true });
|
|
17
|
-
const queries = await getQueries({ getAllVersions: true });
|
|
7
|
+
export const prerender = Page.prerender;
|
|
8
|
+
export const getStaticPaths = Page.getStaticPaths;
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
const services = await getServices({ getAllVersions: true });
|
|
21
|
-
|
|
22
|
-
// Combine all messages
|
|
23
|
-
const allMessages = [...events, ...commands, ...queries];
|
|
24
|
-
|
|
25
|
-
// Helper function to enrich owners with full details
|
|
26
|
-
async function enrichOwners(ownersRaw: any[]) {
|
|
27
|
-
if (!ownersRaw || ownersRaw.length === 0) return [];
|
|
28
|
-
|
|
29
|
-
const owners = await Promise.all(ownersRaw.map(getOwner));
|
|
30
|
-
const filteredOwners = owners.filter((o) => o !== undefined);
|
|
31
|
-
|
|
32
|
-
return filteredOwners.map((o) => ({
|
|
33
|
-
id: o.data.id,
|
|
34
|
-
name: o.data.name,
|
|
35
|
-
type: o.collection,
|
|
36
|
-
href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Filter messages with schemas and read schema content - only keep essential data
|
|
41
|
-
const messagesWithSchemas = await Promise.all(
|
|
42
|
-
allMessages
|
|
43
|
-
.filter((message) => message.data.schemaPath)
|
|
44
|
-
// Make sure the file exists
|
|
45
|
-
.filter((message) => fs.existsSync(path.join(path.dirname(message.filePath ?? ''), message.data.schemaPath ?? '')))
|
|
46
|
-
.map(async (message) => {
|
|
47
|
-
try {
|
|
48
|
-
// Get the schema file path
|
|
49
|
-
const schemaPath = message.data.schemaPath;
|
|
50
|
-
const fullSchemaPath = path.join(path.dirname(message.filePath ?? ''), schemaPath ?? '');
|
|
51
|
-
|
|
52
|
-
// Read the schema content
|
|
53
|
-
let schemaContent = '';
|
|
54
|
-
if (fs.existsSync(fullSchemaPath)) {
|
|
55
|
-
schemaContent = fs.readFileSync(fullSchemaPath, 'utf-8');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Get schema file extension
|
|
59
|
-
const schemaExtension = path.extname(schemaPath ?? '').slice(1);
|
|
60
|
-
|
|
61
|
-
// Enrich owners with full details
|
|
62
|
-
const enrichedOwners = await enrichOwners(message.data.owners || []);
|
|
63
|
-
|
|
64
|
-
// Only return essential data - strip out markdown, full data objects, etc.
|
|
65
|
-
return {
|
|
66
|
-
collection: message.collection,
|
|
67
|
-
data: {
|
|
68
|
-
id: message.data.id,
|
|
69
|
-
name: message.data.name,
|
|
70
|
-
version: message.data.version,
|
|
71
|
-
summary: message.data.summary,
|
|
72
|
-
schemaPath: message.data.schemaPath,
|
|
73
|
-
producers: message.data.producers || [],
|
|
74
|
-
consumers: message.data.consumers || [],
|
|
75
|
-
owners: enrichedOwners,
|
|
76
|
-
},
|
|
77
|
-
schemaContent,
|
|
78
|
-
schemaExtension,
|
|
79
|
-
};
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.error(`Error reading schema for ${message.data.id}:`, error);
|
|
82
|
-
const enrichedOwners = await enrichOwners(message.data.owners || []);
|
|
83
|
-
return {
|
|
84
|
-
collection: message.collection,
|
|
85
|
-
data: {
|
|
86
|
-
id: message.data.id,
|
|
87
|
-
name: message.data.name,
|
|
88
|
-
version: message.data.version,
|
|
89
|
-
summary: message.data.summary,
|
|
90
|
-
schemaPath: message.data.schemaPath,
|
|
91
|
-
producers: message.data.producers || [],
|
|
92
|
-
consumers: message.data.consumers || [],
|
|
93
|
-
owners: enrichedOwners,
|
|
94
|
-
},
|
|
95
|
-
schemaContent: '',
|
|
96
|
-
schemaExtension: 'json',
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
})
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
// Filter services with specifications and read spec content - only keep essential data
|
|
103
|
-
const servicesWithSpecs = await Promise.all(
|
|
104
|
-
services.map(async (service) => {
|
|
105
|
-
try {
|
|
106
|
-
const specifications = getSpecificationsForService(service);
|
|
107
|
-
|
|
108
|
-
// Only include services that have specifications
|
|
109
|
-
if (specifications.length === 0) {
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Process each specification file for this service
|
|
114
|
-
return await Promise.all(
|
|
115
|
-
specifications.map(async (spec) => {
|
|
116
|
-
const specPath = path.join(path.dirname(service.filePath ?? ''), spec.path);
|
|
117
|
-
|
|
118
|
-
// Only include if the spec file exists
|
|
119
|
-
if (!fs.existsSync(specPath)) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const schemaContent = fs.readFileSync(specPath, 'utf-8');
|
|
124
|
-
// Use spec type (openapi, asyncapi) as the extension for proper labeling
|
|
125
|
-
const schemaExtension = spec.type;
|
|
126
|
-
|
|
127
|
-
// Enrich owners with full details
|
|
128
|
-
const enrichedOwners = await enrichOwners(service.data.owners || []);
|
|
129
|
-
|
|
130
|
-
// Only return essential data - strip out markdown, sends/receives, entities, etc.
|
|
131
|
-
return {
|
|
132
|
-
collection: 'services',
|
|
133
|
-
data: {
|
|
134
|
-
id: `${service.data.id}`,
|
|
135
|
-
name: `${service.data.name} - ${spec.name}`,
|
|
136
|
-
version: service.data.version,
|
|
137
|
-
summary: service.data.summary,
|
|
138
|
-
schemaPath: spec.path,
|
|
139
|
-
owners: enrichedOwners,
|
|
140
|
-
},
|
|
141
|
-
schemaContent,
|
|
142
|
-
schemaExtension,
|
|
143
|
-
specType: spec.type,
|
|
144
|
-
specName: spec.name,
|
|
145
|
-
specFilenameWithoutExtension: spec.filenameWithoutExtension,
|
|
146
|
-
};
|
|
147
|
-
})
|
|
148
|
-
);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error(`Error reading specifications for service ${service.data.id}:`, error);
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
// Flatten and filter out null values
|
|
157
|
-
const flatServicesWithSpecs = servicesWithSpecs.flat().filter((service) => service !== null);
|
|
158
|
-
|
|
159
|
-
// Combine messages and services
|
|
160
|
-
const allSchemas = [...messagesWithSchemas, ...flatServicesWithSpecs];
|
|
10
|
+
const { schemas } = await Page.getData(Astro);
|
|
161
11
|
|
|
162
12
|
const apiAccessEnabled = isEventCatalogScaleEnabled();
|
|
163
13
|
---
|
|
@@ -167,7 +17,7 @@ const apiAccessEnabled = isEventCatalogScaleEnabled();
|
|
|
167
17
|
<div class="flex docs-layout w-full h-full">
|
|
168
18
|
<div class="w-full lg:mr-2 pr-8 py-6 flex flex-col h-full">
|
|
169
19
|
<div class="w-full !max-w-none h-full flex flex-col overflow-hidden">
|
|
170
|
-
<SchemaExplorer client:load schemas={
|
|
20
|
+
<SchemaExplorer client:load schemas={schemas as any} apiAccessEnabled={apiAccessEnabled} />
|
|
171
21
|
</div>
|
|
172
22
|
</div>
|
|
173
23
|
</div>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { isSSR } from '@utils/feature';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get the absolute base path for a resource item.
|
|
7
|
+
*
|
|
8
|
+
* In SSR mode, filePath is relative to the Astro core directory (e.g., "../examples/default/domains/...").
|
|
9
|
+
* We need to resolve it using PROJECT_DIR to get the correct absolute path.
|
|
10
|
+
*
|
|
11
|
+
* In static mode, filePath is resolved correctly by Astro's build context.
|
|
12
|
+
*
|
|
13
|
+
* @param item - The resource item with a filePath property
|
|
14
|
+
* @returns The absolute path to the directory containing the resource
|
|
15
|
+
*/
|
|
16
|
+
export function getResourceBasePath(item: { filePath?: string }): string {
|
|
17
|
+
if (!item.filePath) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const filePath = item.filePath;
|
|
22
|
+
|
|
23
|
+
// In SSR mode, we need to resolve the relative path using PROJECT_DIR
|
|
24
|
+
if (isSSR()) {
|
|
25
|
+
const PROJECT_DIR = process.env.PROJECT_DIR || '';
|
|
26
|
+
|
|
27
|
+
if (PROJECT_DIR) {
|
|
28
|
+
// Get the project folder name from PROJECT_DIR (e.g., "default" from ".../examples/default")
|
|
29
|
+
const projectFolderName = path.basename(PROJECT_DIR);
|
|
30
|
+
|
|
31
|
+
// Find the project folder in the relative path and extract everything after it
|
|
32
|
+
// Pattern: ../examples/default/domains/... -> domains/...
|
|
33
|
+
const regex = new RegExp(`.*?${projectFolderName}/(.+)$`);
|
|
34
|
+
const match = filePath.match(regex);
|
|
35
|
+
|
|
36
|
+
if (match && match[1]) {
|
|
37
|
+
// Join PROJECT_DIR with the relative path within the project
|
|
38
|
+
return path.join(PROJECT_DIR, path.dirname(match[1]));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Static mode: resolve directly using Astro's build context
|
|
44
|
+
return path.dirname(path.resolve(filePath));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get the absolute path to a file within a resource directory.
|
|
49
|
+
*
|
|
50
|
+
* @param item - The resource item with a filePath property
|
|
51
|
+
* @param relativePath - The relative path to the file (e.g., "schema.json")
|
|
52
|
+
* @returns The absolute path to the file
|
|
53
|
+
*/
|
|
54
|
+
export function getResourceFilePath(item: { filePath?: string }, relativePath: string): string {
|
|
55
|
+
const basePath = getResourceBasePath(item);
|
|
56
|
+
return path.join(basePath, relativePath);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if a file exists within a resource directory.
|
|
61
|
+
*
|
|
62
|
+
* @param item - The resource item with a filePath property
|
|
63
|
+
* @param relativePath - The relative path to the file (e.g., "schema.json")
|
|
64
|
+
* @returns True if the file exists, false otherwise
|
|
65
|
+
*/
|
|
66
|
+
export function resourceFileExists(item: { filePath?: string }, relativePath: string): boolean {
|
|
67
|
+
const filePath = getResourceFilePath(item, relativePath);
|
|
68
|
+
return fs.existsSync(filePath);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Read a file from a resource directory.
|
|
73
|
+
*
|
|
74
|
+
* @param item - The resource item with a filePath property
|
|
75
|
+
* @param relativePath - The relative path to the file (e.g., "schema.json")
|
|
76
|
+
* @returns The file content as a string, or null if the file doesn't exist
|
|
77
|
+
*/
|
|
78
|
+
export function readResourceFile(item: { filePath?: string }, relativePath: string): string | null {
|
|
79
|
+
const filePath = getResourceFilePath(item, relativePath);
|
|
80
|
+
|
|
81
|
+
if (!fs.existsSync(filePath)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
86
|
+
}
|
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": "3.0.0-beta.
|
|
9
|
+
"version": "3.0.0-beta.14",
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
@@ -147,6 +147,7 @@
|
|
|
147
147
|
"preview": "astro preview",
|
|
148
148
|
"astro": "astro",
|
|
149
149
|
"start:catalog": "node scripts/start-catalog-locally.js",
|
|
150
|
+
"start:catalog:server": "node scripts/start-server-locally.js",
|
|
150
151
|
"pagefind": "node scripts/pagefind.js",
|
|
151
152
|
"preview:catalog": "node scripts/preview-catalog-locally.js",
|
|
152
153
|
"generate:catalog": "node scripts/generate-catalog-locally.js",
|