@eventcatalog/core 5.5.2 → 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-CNN747RO.js → chunk-7TTNTHHN.js} +10 -10
- package/dist/{chunk-7ZEKF2LA.js → chunk-DEO4QEGO.js} +1 -1
- package/dist/{chunk-WG6ZK6L3.js → chunk-ETS4G6RR.js} +1 -1
- package/dist/{chunk-5HSYALWK.js → chunk-T3U27UXC.js} +1 -1
- package/dist/{chunk-MC4F3VVM.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 +16 -16
- package/dist/federation/federate.js +3 -3
- 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/generated/canvas.html +1 -1
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +1 -1
- 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
- package/dist/{chunk-QJ7KKN2D.js → chunk-NCEZDQSW.js} +7 -7
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { ClipboardDocumentIcon, ArrowsPointingOutIcon } from '@heroicons/react/24/outline';
|
|
3
|
+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
4
|
+
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
|
5
|
+
import { oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
|
6
|
+
import { getLanguageForHighlight, SCHEMA_CODE_STYLE } from './utils';
|
|
7
|
+
import { useDarkMode } from './useDarkMode';
|
|
8
|
+
import { renderHighlightedRows } from '@utils/syntax-highlighter-renderer';
|
|
9
|
+
|
|
10
|
+
export const SCHEMA_CODE_ACTION_CLASS =
|
|
11
|
+
'pointer-events-auto inline-flex items-center gap-1 rounded-md bg-[rgb(var(--ec-content-hover)/0.9)] text-[11px] font-medium text-[rgb(var(--ec-page-text-muted))] backdrop-blur-xs transition-colors hover:bg-[rgb(var(--ec-page-bg)/0.75)] hover:text-[rgb(var(--ec-page-text))]';
|
|
12
|
+
|
|
13
|
+
interface SchemaCodeBlockProps {
|
|
14
|
+
code: string;
|
|
15
|
+
/** The schema's extension or format, see getLanguageForHighlight */
|
|
16
|
+
extension?: string;
|
|
17
|
+
onCopy: () => void;
|
|
18
|
+
isCopied: boolean;
|
|
19
|
+
onOpenFullscreen?: () => void;
|
|
20
|
+
/** Extra actions shown before the fullscreen and copy buttons */
|
|
21
|
+
actions?: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Highlighted schema source with line numbers, as shown on the Schema tab of the Schema Explorer and on specification pages */
|
|
25
|
+
export default function SchemaCodeBlock({ code, extension, onCopy, isCopied, onOpenFullscreen, actions }: SchemaCodeBlockProps) {
|
|
26
|
+
const isDarkMode = useDarkMode();
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="relative flex h-full min-h-0 flex-col overflow-hidden rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-code-bg))]">
|
|
30
|
+
<div className="pointer-events-none absolute right-4 top-4 z-10 flex items-center gap-1.5">
|
|
31
|
+
{actions}
|
|
32
|
+
{onOpenFullscreen && (
|
|
33
|
+
<button onClick={onOpenFullscreen} className={`${SCHEMA_CODE_ACTION_CLASS} p-1.5`} title="Open in fullscreen">
|
|
34
|
+
<ArrowsPointingOutIcon className="h-3.5 w-3.5" />
|
|
35
|
+
</button>
|
|
36
|
+
)}
|
|
37
|
+
<button onClick={onCopy} className={`${SCHEMA_CODE_ACTION_CLASS} px-2 py-1.5`} title="Copy code">
|
|
38
|
+
<ClipboardDocumentIcon className="h-3 w-3" />
|
|
39
|
+
{isCopied ? 'Copied!' : 'Copy'}
|
|
40
|
+
</button>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div className="min-h-0 flex-1 overflow-auto">
|
|
44
|
+
<SyntaxHighlighter
|
|
45
|
+
renderer={renderHighlightedRows}
|
|
46
|
+
language={getLanguageForHighlight(extension)}
|
|
47
|
+
style={isDarkMode ? oneDark : oneLight}
|
|
48
|
+
customStyle={{ ...SCHEMA_CODE_STYLE, height: '100%' }}
|
|
49
|
+
showLineNumbers={true}
|
|
50
|
+
wrapLines={true}
|
|
51
|
+
wrapLongLines={true}
|
|
52
|
+
>
|
|
53
|
+
{code}
|
|
54
|
+
</SyntaxHighlighter>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -11,7 +11,8 @@ import { renderHighlightedRows } from '@utils/syntax-highlighter-renderer';
|
|
|
11
11
|
interface SchemaCodeModalProps {
|
|
12
12
|
isOpen: boolean;
|
|
13
13
|
onOpenChange: (open: boolean) => void;
|
|
14
|
-
|
|
14
|
+
// Only what the modal shows, so specification pages can open it too
|
|
15
|
+
message: Pick<SchemaItem, 'schemaExtension' | 'schemaContent'> & { data: Pick<SchemaItem['data'], 'name' | 'version'> };
|
|
15
16
|
onCopy: () => void;
|
|
16
17
|
isCopied: boolean;
|
|
17
18
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { ClipboardDocumentIcon, ArrowsPointingOutIcon } from '@heroicons/react/24/outline';
|
|
2
|
-
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
3
|
-
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
|
4
|
-
import { oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
|
5
1
|
import { buildUrl } from '@utils/url-builder';
|
|
6
2
|
import JSONSchemaViewer from './JSONSchemaViewer';
|
|
7
3
|
import AvroSchemaViewer from './AvroSchemaViewer';
|
|
8
4
|
import ProtobufSchemaViewer from './ProtobufSchemaViewer';
|
|
9
|
-
import {
|
|
5
|
+
import SchemaCodeBlock, { SCHEMA_CODE_ACTION_CLASS } from './SchemaCodeBlock';
|
|
10
6
|
import type { SchemaItem } from './types';
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
|
|
8
|
+
const SPEC_URL_SEGMENTS: Record<string, string> = {
|
|
9
|
+
openapi: 'spec',
|
|
10
|
+
asyncapi: 'asyncapi',
|
|
11
|
+
graphql: 'graphql',
|
|
12
|
+
generic: 'generic',
|
|
13
|
+
};
|
|
13
14
|
|
|
14
15
|
interface SchemaContentViewerProps {
|
|
15
16
|
message: SchemaItem;
|
|
@@ -34,8 +35,6 @@ export default function SchemaContentViewer({
|
|
|
34
35
|
showRequired = false,
|
|
35
36
|
onOpenFullscreen,
|
|
36
37
|
}: SchemaContentViewerProps) {
|
|
37
|
-
const isDarkMode = useDarkMode();
|
|
38
|
-
|
|
39
38
|
if (!message.schemaContent) {
|
|
40
39
|
return (
|
|
41
40
|
<div className="flex items-center justify-center h-full text-[rgb(var(--ec-page-text-muted))]">
|
|
@@ -57,73 +56,36 @@ export default function SchemaContentViewer({
|
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
let urlSegment = 'spec';
|
|
69
|
-
if (specType === 'asyncapi') {
|
|
70
|
-
urlSegment = 'asyncapi';
|
|
71
|
-
} else if (specType === 'graphql') {
|
|
72
|
-
urlSegment = 'graphql';
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const specUrl = buildUrl(`/docs/services/${message.data.id}/${message.data.version}/${urlSegment}/${specFilename}`);
|
|
59
|
+
// Services link to their specification's own page
|
|
60
|
+
const specUrl =
|
|
61
|
+
message.collection === 'services'
|
|
62
|
+
? buildUrl(
|
|
63
|
+
`/docs/services/${message.data.id}/${message.data.version}/${SPEC_URL_SEGMENTS[message.specType || 'openapi'] ?? 'spec'}/${message.specFilenameWithoutExtension || 'schema'}`
|
|
64
|
+
)
|
|
65
|
+
: undefined;
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
>
|
|
101
|
-
<ArrowsPointingOutIcon className="h-3.5 w-3.5" />
|
|
102
|
-
</button>
|
|
103
|
-
)}
|
|
104
|
-
<button
|
|
105
|
-
onClick={onCopy}
|
|
106
|
-
className="pointer-events-auto inline-flex items-center gap-1 rounded-md bg-[rgb(var(--ec-content-hover)/0.9)] px-2 py-1.5 text-[11px] font-medium text-[rgb(var(--ec-page-text-muted))] backdrop-blur-xs transition-colors hover:bg-[rgb(var(--ec-page-bg)/0.75)] hover:text-[rgb(var(--ec-page-text))]"
|
|
107
|
-
title="Copy code"
|
|
108
|
-
>
|
|
109
|
-
<ClipboardDocumentIcon className="h-3 w-3" />
|
|
110
|
-
{isCopied ? 'Copied!' : 'Copy'}
|
|
111
|
-
</button>
|
|
112
|
-
</div>
|
|
113
|
-
|
|
114
|
-
<div className="min-h-0 flex-1 overflow-auto">
|
|
115
|
-
<SyntaxHighlighter
|
|
116
|
-
renderer={renderHighlightedRows}
|
|
117
|
-
language={getLanguageForHighlight(message.schemaExtension)}
|
|
118
|
-
style={isDarkMode ? oneDark : oneLight}
|
|
119
|
-
customStyle={{ ...SCHEMA_CODE_STYLE, height: '100%' }}
|
|
120
|
-
showLineNumbers={true}
|
|
121
|
-
wrapLines={true}
|
|
122
|
-
wrapLongLines={true}
|
|
123
|
-
>
|
|
124
|
-
{message.schemaContent}
|
|
125
|
-
</SyntaxHighlighter>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
67
|
+
return (
|
|
68
|
+
<SchemaCodeBlock
|
|
69
|
+
code={message.schemaContent}
|
|
70
|
+
extension={message.schemaExtension}
|
|
71
|
+
onCopy={onCopy}
|
|
72
|
+
isCopied={isCopied}
|
|
73
|
+
onOpenFullscreen={onOpenFullscreen}
|
|
74
|
+
actions={
|
|
75
|
+
specUrl && (
|
|
76
|
+
<a href={specUrl} className={`${SCHEMA_CODE_ACTION_CLASS} px-2 py-1`} title="View full specification">
|
|
77
|
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
78
|
+
<path
|
|
79
|
+
strokeLinecap="round"
|
|
80
|
+
strokeLinejoin="round"
|
|
81
|
+
strokeWidth={2}
|
|
82
|
+
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
83
|
+
/>
|
|
84
|
+
</svg>
|
|
85
|
+
View Spec
|
|
86
|
+
</a>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
/>
|
|
128
90
|
);
|
|
129
91
|
}
|
|
@@ -30,9 +30,10 @@ import SchemaCodeModal from './SchemaCodeModal';
|
|
|
30
30
|
import SchemaViewerModal from './SchemaViewerModal';
|
|
31
31
|
import {
|
|
32
32
|
copyToClipboard,
|
|
33
|
+
getSchemaDownloadExtension,
|
|
33
34
|
downloadSchema,
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
getSchemaDisplayLabel,
|
|
36
|
+
getSchemaIconUrl,
|
|
36
37
|
getSchemaRelationshipReference,
|
|
37
38
|
getSchemaRelationshipHref,
|
|
38
39
|
SCHEMA_RELATIONSHIP_LABELS,
|
|
@@ -95,7 +96,7 @@ const SchemaMetadata = ({ message, owners }: { message: SchemaItem; owners: Owne
|
|
|
95
96
|
const schemaRows: MetadataRow[] = [
|
|
96
97
|
{ label: 'Name', value: message.data.name },
|
|
97
98
|
...(message.schemaName && message.schemaName !== message.data.name ? [{ label: 'Schema', value: message.schemaName }] : []),
|
|
98
|
-
{ label: 'Format', value:
|
|
99
|
+
{ label: 'Format', value: getSchemaDisplayLabel(message) },
|
|
99
100
|
{
|
|
100
101
|
label: MESSAGE_TYPE_LABELS[message.collection] ? 'Message Type' : 'Resource',
|
|
101
102
|
value: (
|
|
@@ -249,7 +250,7 @@ const SchemaVersionsTable = ({
|
|
|
249
250
|
{version.data.summary ? <p className="line-clamp-2 max-w-2xl">{version.data.summary}</p> : <span>-</span>}
|
|
250
251
|
</td>
|
|
251
252
|
<td className="whitespace-nowrap px-4 py-3 text-sm text-[rgb(var(--ec-page-text-muted))]">
|
|
252
|
-
{
|
|
253
|
+
{getSchemaDisplayLabel(version)}
|
|
253
254
|
</td>
|
|
254
255
|
<td className="whitespace-nowrap px-4 py-3 text-sm text-[rgb(var(--ec-page-text-muted))]">
|
|
255
256
|
{version.source?.updatedAt ? formatSchemaUpdatedAt(version.source.updatedAt) : '-'}
|
|
@@ -343,7 +344,7 @@ export default function SchemaDetailsPanel({
|
|
|
343
344
|
|
|
344
345
|
const { color } = getCollectionStyles(message.collection);
|
|
345
346
|
const ext = message.schemaExtension?.toLowerCase() || '';
|
|
346
|
-
const
|
|
347
|
+
const iconUrl = getSchemaIconUrl(message);
|
|
347
348
|
const owners = message.data.owners || [];
|
|
348
349
|
const producers = message.data.producers || [];
|
|
349
350
|
const consumers = message.data.consumers || [];
|
|
@@ -429,10 +430,13 @@ export default function SchemaDetailsPanel({
|
|
|
429
430
|
}, [comparing, diffFromItem, diffToItem]);
|
|
430
431
|
const selectedDiffs = selectedDiff ? [selectedDiff] : [];
|
|
431
432
|
|
|
432
|
-
// Parse JSON Schema, Avro and Protobuf schemas for the Properties tab
|
|
433
|
+
// Parse JSON Schema, Avro and Protobuf schemas for the Properties tab. Generic specifications are only shown as code.
|
|
433
434
|
const viewableSchema = useMemo(
|
|
434
|
-
() =>
|
|
435
|
-
|
|
435
|
+
() =>
|
|
436
|
+
message.specType === 'generic'
|
|
437
|
+
? ({ kind: 'code' } as const)
|
|
438
|
+
: parseSchemaForViewer(message.schemaExtension, message.schemaContent),
|
|
439
|
+
[message.schemaContent, message.schemaExtension, message.specType]
|
|
436
440
|
);
|
|
437
441
|
const parsedSchema = viewableSchema.kind === 'json' ? viewableSchema.schema : null;
|
|
438
442
|
const parsedAvroSchema = viewableSchema.kind === 'avro' ? viewableSchema.schema : null;
|
|
@@ -457,7 +461,7 @@ export default function SchemaDetailsPanel({
|
|
|
457
461
|
|
|
458
462
|
const handleDownload = () => {
|
|
459
463
|
if (!message.schemaContent) return;
|
|
460
|
-
downloadSchema(message.schemaContent, message.data.id, message
|
|
464
|
+
downloadSchema(message.schemaContent, message.data.id, getSchemaDownloadExtension(message));
|
|
461
465
|
};
|
|
462
466
|
|
|
463
467
|
const isCopied = copiedId === message.data.id;
|
|
@@ -558,8 +562,8 @@ export default function SchemaDetailsPanel({
|
|
|
558
562
|
<div className="min-w-0 flex-1">
|
|
559
563
|
<div className="flex min-w-0 items-center gap-3">
|
|
560
564
|
<div className="flex-shrink-0 flex items-center justify-center w-9 h-9 rounded-lg bg-[rgb(var(--ec-content-hover))] border border-[rgb(var(--ec-page-border)/0.5)]">
|
|
561
|
-
{
|
|
562
|
-
<img src={
|
|
565
|
+
{iconUrl ? (
|
|
566
|
+
<img src={iconUrl} alt={`${ext} icon`} className="h-5 w-5 schema-icon" />
|
|
563
567
|
) : (
|
|
564
568
|
<span className="text-xs font-bold font-mono text-[rgb(var(--ec-page-text-muted))]">{'{ }'}</span>
|
|
565
569
|
)}
|