@eventcatalog/core 5.5.1 → 5.6.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/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 +5 -5
- package/dist/{chunk-6KR5ZLEQ.js → chunk-7TTNTHHN.js} +10 -10
- package/dist/{chunk-K5QKWVI3.js → chunk-DEO4QEGO.js} +1 -1
- package/dist/{chunk-GPIKYBQ5.js → chunk-ETS4G6RR.js} +1 -1
- package/dist/{chunk-GZLVDQPM.js → chunk-T3U27UXC.js} +1 -1
- package/dist/{chunk-EBZQJP7F.js → chunk-XBRKEQ66.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
- package/dist/docs/development/guides/domains/09-reference.md +5 -1
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/04-add-generic-specifications.md +139 -0
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/_category_.json +1 -1
- package/dist/docs/development/guides/resources/services/08-reference.md +6 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +10 -10
- 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/public/icons/specification.svg +1 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +38 -20
- package/eventcatalog/src/components/Grids/specification-utils.ts +7 -1
- package/eventcatalog/src/components/MDX/ResourceRef/ResourceRef.astro +1 -1
- package/eventcatalog/src/components/SchemaExplorer/SchemaCodeBlock.tsx +58 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -1
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +38 -76
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +15 -11
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +171 -142
- package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +5 -8
- package/eventcatalog/src/components/SchemaExplorer/types.ts +2 -0
- package/eventcatalog/src/components/SchemaExplorer/utils.ts +70 -1
- package/eventcatalog/src/content.config.ts +3 -1
- package/eventcatalog/src/features/ai/chat-api.ts +6 -1
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +8 -2
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +2 -2
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +67 -67
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +72 -72
- package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +2 -1
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +24 -5
- package/eventcatalog/src/features/mcp/mcp-apps.ts +6 -1
- package/eventcatalog/src/features/mcp/mcp-server.ts +2 -0
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +2 -0
- package/eventcatalog/src/features/studio/tool-sync.ts +67 -3
- package/eventcatalog/src/features/tools/catalog-tools.ts +8 -3
- package/eventcatalog/src/pages/.well-known/api-catalog.ts +1 -11
- package/eventcatalog/src/pages/api-catalog/specifications/[collection]/[id]/[version]/[specification].ts +1 -11
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/generic/[filename].astro +137 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/generic/_SpecificationSource.tsx +44 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/generic/_[filename].data.ts +75 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +14 -1
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +10 -1
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +8 -1
- package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +3 -1
- package/eventcatalog/src/utils/collections/util.ts +38 -1
- package/eventcatalog/src/utils/icon.ts +8 -0
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +5 -2
- package/eventcatalog/src/utils/schema-explorer.ts +7 -2
- package/package.json +6 -6
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from './shared';
|
|
18
18
|
import { isVisualiserEnabled, isChangelogEnabled } from '@utils/feature';
|
|
19
19
|
import { pluralizeMessageType } from '@utils/collections/messages';
|
|
20
|
-
import { iconFieldsForResource } from '@utils/icon';
|
|
20
|
+
import { getGenericSpecificationIcon, iconFieldsForResource } from '@utils/icon';
|
|
21
21
|
import { resolveSidebarPages, toCustomSidebarContext, type SidebarSpec } from '../custom-sidebar';
|
|
22
22
|
|
|
23
23
|
const uniqueRefs = (refs: string[]) => [...new Set(refs)];
|
|
@@ -86,6 +86,7 @@ export const buildServiceSections = (
|
|
|
86
86
|
const openAPISpecifications = specifications.filter((specification) => specification.type === 'openapi');
|
|
87
87
|
const asyncAPISpecifications = specifications.filter((specification) => specification.type === 'asyncapi');
|
|
88
88
|
const graphQLSpecifications = specifications.filter((specification) => specification.type === 'graphql');
|
|
89
|
+
const genericSpecifications = specifications.filter((specification) => specification.type === 'generic');
|
|
89
90
|
|
|
90
91
|
const dataStoresInService = uniqueBy([...(service.data.writesTo || []), ...(service.data.readsFrom || [])], 'id');
|
|
91
92
|
|
|
@@ -189,6 +190,12 @@ export const buildServiceSections = (
|
|
|
189
190
|
leftIcon: '/icons/graphql-black.svg',
|
|
190
191
|
href: buildUrl(`${docsBasePath}/graphql/${specification.filenameWithoutExtension}`),
|
|
191
192
|
})),
|
|
193
|
+
...genericSpecifications.map((specification) => ({
|
|
194
|
+
type: 'item',
|
|
195
|
+
title: `${specification.name}`,
|
|
196
|
+
leftIcon: getGenericSpecificationIcon(specification.icon),
|
|
197
|
+
href: buildUrl(`${docsBasePath}/generic/${specification.filenameWithoutExtension}`),
|
|
198
|
+
})),
|
|
192
199
|
] as ChildRef[],
|
|
193
200
|
}
|
|
194
201
|
: null,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import type { CollectionEntry } from 'astro:content';
|
|
3
3
|
import { buildUrl } from '@utils/url-builder';
|
|
4
|
+
import { isIconPath } from '@utils/icon';
|
|
4
5
|
import { processSpecifications } from '@utils/collections/util';
|
|
5
6
|
import type { ResourceCollection, ResourceDocEntry } from '@utils/collections/resource-docs';
|
|
6
7
|
import type { NavNode, ChildRef } from './builders/shared';
|
|
@@ -119,6 +120,7 @@ const SPEC_ROUTES: Record<string, { segment: string; icon: string }> = {
|
|
|
119
120
|
openapi: { segment: 'spec', icon: '/icons/openapi-black.svg' },
|
|
120
121
|
asyncapi: { segment: 'asyncapi', icon: '/icons/asyncapi-black.svg' },
|
|
121
122
|
graphql: { segment: 'graphql', icon: '/icons/graphql-black.svg' },
|
|
123
|
+
generic: { segment: 'generic', icon: '/icons/specification.svg' },
|
|
122
124
|
};
|
|
123
125
|
|
|
124
126
|
const MESSAGE_COLLECTIONS: Record<string, keyof CustomSidebarContext> = {
|
|
@@ -335,7 +337,7 @@ const resolveSpecPage = (
|
|
|
335
337
|
return {
|
|
336
338
|
type: 'item',
|
|
337
339
|
title: specification.name,
|
|
338
|
-
leftIcon: route.icon,
|
|
340
|
+
leftIcon: specification.type === 'generic' && isIconPath(specification.icon) ? specification.icon : route.icon,
|
|
339
341
|
href: buildUrl(
|
|
340
342
|
`/docs/${owner.collection}/${owner.id}/${owner.version}/${route.segment}/${specification.filenameWithoutExtension}`
|
|
341
343
|
),
|
|
@@ -18,12 +18,13 @@ export const getFolderNameFromFilePath = (filePath: string): string => {
|
|
|
18
18
|
|
|
19
19
|
// --- SPECIFICATION HELPERS ---
|
|
20
20
|
|
|
21
|
-
export type SpecificationType = 'asyncapi' | 'openapi' | 'graphql';
|
|
21
|
+
export type SpecificationType = 'asyncapi' | 'openapi' | 'graphql' | 'generic';
|
|
22
22
|
|
|
23
23
|
export interface SpecificationInput {
|
|
24
24
|
type: SpecificationType;
|
|
25
25
|
path: string;
|
|
26
26
|
name?: string;
|
|
27
|
+
icon?: string;
|
|
27
28
|
headers?: Record<string, string>;
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -33,6 +34,7 @@ export interface ProcessedSpecification {
|
|
|
33
34
|
name: string;
|
|
34
35
|
filename: string;
|
|
35
36
|
filenameWithoutExtension: string;
|
|
37
|
+
icon?: string;
|
|
36
38
|
headers?: Record<string, string>;
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -49,6 +51,41 @@ export const getDefaultSpecificationName = (type: string): string => {
|
|
|
49
51
|
}
|
|
50
52
|
};
|
|
51
53
|
|
|
54
|
+
export type SpecificationCodeLanguage = 'json' | 'yaml' | 'xml' | 'text';
|
|
55
|
+
|
|
56
|
+
const CODE_LANGUAGE_BY_EXTENSION: Record<string, SpecificationCodeLanguage> = {
|
|
57
|
+
json: 'json',
|
|
58
|
+
yaml: 'yaml',
|
|
59
|
+
yml: 'yaml',
|
|
60
|
+
xml: 'xml',
|
|
61
|
+
xsd: 'xml',
|
|
62
|
+
wsdl: 'xml',
|
|
63
|
+
xsl: 'xml',
|
|
64
|
+
xslt: 'xml',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const MEDIA_TYPE_BY_CODE_LANGUAGE: Record<SpecificationCodeLanguage, string> = {
|
|
68
|
+
json: 'application/json',
|
|
69
|
+
yaml: 'application/yaml',
|
|
70
|
+
xml: 'application/xml',
|
|
71
|
+
text: 'text/plain',
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** The syntax of a specification file, from its extension (query strings on remote URLs are ignored) */
|
|
75
|
+
export const getSpecificationCodeLanguage = (filename: string): SpecificationCodeLanguage => {
|
|
76
|
+
const extension =
|
|
77
|
+
getBasename(filename.split(/[?#]/, 1)[0])
|
|
78
|
+
.match(/\.([^.]+)$/)?.[1]
|
|
79
|
+
.toLowerCase() ?? '';
|
|
80
|
+
return CODE_LANGUAGE_BY_EXTENSION[extension] ?? 'text';
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** The media type a specification file is served with */
|
|
84
|
+
export const getSpecificationMediaType = (specification: Pick<ProcessedSpecification, 'type' | 'filename'>): string =>
|
|
85
|
+
specification.type === 'graphql'
|
|
86
|
+
? 'application/graphql'
|
|
87
|
+
: MEDIA_TYPE_BY_CODE_LANGUAGE[getSpecificationCodeLanguage(specification.filename)];
|
|
88
|
+
|
|
52
89
|
interface LegacySpecificationFormat {
|
|
53
90
|
asyncapiPath?: string;
|
|
54
91
|
openapiPath?: string;
|
|
@@ -28,3 +28,11 @@ export function customIconFieldsForResource(data: { styles?: { icon?: string } }
|
|
|
28
28
|
const styleIcon = data?.styles?.icon;
|
|
29
29
|
return isIconPath(styleIcon) ? { leftIcon: styleIcon } : {};
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The icon for a generic specification: its custom `icon` when one is set, otherwise the default
|
|
34
|
+
* specification icon. Unlike the black logos of the other specification types, it reads in both themes.
|
|
35
|
+
*/
|
|
36
|
+
export function getGenericSpecificationIcon(icon: string | undefined): string {
|
|
37
|
+
return isIconPath(icon) ? icon : '/icons/specification.svg';
|
|
38
|
+
}
|
|
@@ -173,7 +173,7 @@ const getSpecMenuItems = (
|
|
|
173
173
|
): { label: string; href: string; separator?: boolean }[] => {
|
|
174
174
|
const items: { label: string; href: string; separator?: boolean }[] = [];
|
|
175
175
|
|
|
176
|
-
const addSpec = (type: string, filePath: string, isFirst: boolean) => {
|
|
176
|
+
const addSpec = (type: string, filePath: string, isFirst: boolean, name?: string) => {
|
|
177
177
|
const filename = filePath.split('/').pop() || filePath;
|
|
178
178
|
const filenameNoExt = filename.replace(/\.[^/.]+$/, '');
|
|
179
179
|
const typeLower = type.toLowerCase();
|
|
@@ -189,6 +189,9 @@ const getSpecMenuItems = (
|
|
|
189
189
|
} else if (typeLower === 'graphql') {
|
|
190
190
|
label = 'View GraphQL spec';
|
|
191
191
|
urlSegment = 'graphql';
|
|
192
|
+
} else if (typeLower === 'generic') {
|
|
193
|
+
label = name ? `View ${name}` : label;
|
|
194
|
+
urlSegment = 'generic';
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
items.push({
|
|
@@ -200,7 +203,7 @@ const getSpecMenuItems = (
|
|
|
200
203
|
|
|
201
204
|
if (Array.isArray(specs)) {
|
|
202
205
|
specs.forEach((spec: any, i: number) => {
|
|
203
|
-
if (spec?.type && spec?.path) addSpec(spec.type, spec.path, i === 0);
|
|
206
|
+
if (spec?.type && spec?.path) addSpec(spec.type, spec.path, i === 0, spec.name);
|
|
204
207
|
});
|
|
205
208
|
} else if (specs && typeof specs === 'object') {
|
|
206
209
|
const legacy = specs as Record<string, string>;
|
|
@@ -11,6 +11,7 @@ import { getFlowsForMessages } from '@utils/collections/flows';
|
|
|
11
11
|
import { getOwner } from '@utils/collections/owners';
|
|
12
12
|
import { buildUrl } from '@utils/url-builder';
|
|
13
13
|
import { getSchemaExtensionForFormat } from '@utils/collections/schemas';
|
|
14
|
+
import { getSpecificationCodeLanguage } from '@utils/collections/util';
|
|
14
15
|
import { resourceFileExists, readResourceFile } from '@utils/resource-files';
|
|
15
16
|
import { getExamplesForResource } from '@utils/collections/examples';
|
|
16
17
|
import { attachFlowGraphs, getMessageUsageGraph } from '@utils/schema-usage-graph';
|
|
@@ -172,7 +173,8 @@ async function buildRegistry() {
|
|
|
172
173
|
return null;
|
|
173
174
|
}
|
|
174
175
|
|
|
175
|
-
|
|
176
|
+
// Generic specifications are shown as source, so their extension is the syntax to highlight
|
|
177
|
+
const schemaExtension = spec.type === 'generic' ? getSpecificationCodeLanguage(spec.path) : spec.type;
|
|
176
178
|
const enrichedOwners = await enrichOwners(service.data.owners || []);
|
|
177
179
|
|
|
178
180
|
return {
|
|
@@ -189,6 +191,7 @@ async function buildRegistry() {
|
|
|
189
191
|
schemaExtension,
|
|
190
192
|
specType: spec.type,
|
|
191
193
|
specName: spec.name,
|
|
194
|
+
specIcon: spec.icon,
|
|
192
195
|
specFilenameWithoutExtension: spec.filenameWithoutExtension,
|
|
193
196
|
};
|
|
194
197
|
})
|
|
@@ -222,7 +225,8 @@ async function buildRegistry() {
|
|
|
222
225
|
return null;
|
|
223
226
|
}
|
|
224
227
|
|
|
225
|
-
|
|
228
|
+
// Generic specifications are shown as source, so their extension is the syntax to highlight
|
|
229
|
+
const schemaExtension = spec.type === 'generic' ? getSpecificationCodeLanguage(spec.path) : spec.type;
|
|
226
230
|
const enrichedOwners = await enrichOwners(domain.data.owners || []);
|
|
227
231
|
|
|
228
232
|
return {
|
|
@@ -239,6 +243,7 @@ async function buildRegistry() {
|
|
|
239
243
|
schemaExtension,
|
|
240
244
|
specType: spec.type,
|
|
241
245
|
specName: spec.name,
|
|
246
|
+
specIcon: spec.icon,
|
|
242
247
|
specFilenameWithoutExtension: spec.filenameWithoutExtension,
|
|
243
248
|
};
|
|
244
249
|
})
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"license": "BUSL-1.1",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "5.
|
|
10
|
+
"version": "5.6.0",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
@@ -141,11 +141,11 @@
|
|
|
141
141
|
"y-protocols": "^1.0.7",
|
|
142
142
|
"yjs": "^13.6.33",
|
|
143
143
|
"zod": "^4.6.6",
|
|
144
|
-
"@eventcatalog/fitness": "0.1.
|
|
145
|
-
"@eventcatalog/linter": "1.
|
|
146
|
-
"@eventcatalog/
|
|
147
|
-
"@eventcatalog/
|
|
148
|
-
"@eventcatalog/
|
|
144
|
+
"@eventcatalog/fitness": "0.1.1",
|
|
145
|
+
"@eventcatalog/linter": "1.3.0",
|
|
146
|
+
"@eventcatalog/visualiser": "^5.1.2",
|
|
147
|
+
"@eventcatalog/sdk": "2.32.0",
|
|
148
|
+
"@eventcatalog/exporters": "0.1.3"
|
|
149
149
|
},
|
|
150
150
|
"devDependencies": {
|
|
151
151
|
"@astrojs/check": "^0.9.10",
|