@eventcatalog/core 4.10.12 → 4.10.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-7URQ754Q.js → chunk-HERAHLM2.js} +1 -1
- package/dist/{chunk-Y5XU3YLT.js → chunk-LITOQH56.js} +1 -1
- package/dist/{chunk-S4LLGOO4.js → chunk-LUW6RDA7.js} +1 -1
- package/dist/{chunk-VFSEVDCQ.js → chunk-ONDFEA5R.js} +1 -1
- package/dist/{chunk-A53VCEEA.js → chunk-V2SKOQYF.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +55 -1
- package/dist/docs/development/authentication/providers/03-setting-up-github.md +29 -0
- package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +2 -2
- package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +17 -0
- package/dist/docs/development/components/07-resource-references.md +7 -1
- package/dist/docs/development/components/components/05-architecture-graph.md +65 -0
- package/dist/docs/development/components/components/{05-attachments.md → 06-attachments.md} +1 -1
- package/dist/docs/development/components/components/{06-channel-information.md → 07-channel-information.md} +1 -1
- package/dist/docs/development/components/components/{07-custom-properties.md → 08-custom-properties.md} +1 -1
- package/dist/docs/development/components/components/{08-design.md → 09-design.md} +1 -1
- package/dist/docs/development/components/components/{09-entitymap.md → 10-entitymap.md} +1 -1
- package/dist/docs/development/components/components/{10-flow.md → 11-flow.md} +1 -1
- package/dist/docs/development/components/components/{11-link.md → 12-link.md} +1 -1
- package/dist/docs/development/components/components/{12-mermaid-file-loader.md → 13-mermaid-file-loader.md} +1 -1
- package/dist/docs/development/components/components/{13-message-table.md → 14-message-table.md} +1 -1
- package/dist/docs/development/components/components/{14-nodegraph.md → 15-nodegraph.md} +1 -1
- package/dist/docs/development/components/components/{15-openapi.md → 16-openapi.md} +1 -1
- package/dist/docs/development/components/components/{16-prompt.md → 17-prompt.md} +1 -1
- package/dist/docs/development/components/components/{17-remote-schema.md → 18-remote-schema.md} +1 -1
- package/dist/docs/development/components/components/{18-resource-group-table.md → 19-resource-group-table.md} +1 -1
- package/dist/docs/development/components/components/{19-resource-link.md → 20-resource-link.md} +1 -1
- package/dist/docs/development/components/components/{20-schema.md → 21-schema.md} +1 -1
- package/dist/docs/development/components/components/{21-schema-viewer.md → 22-schema-viewer.md} +1 -1
- package/dist/docs/development/components/components/{22-steps.md → 23-steps.md} +1 -1
- package/dist/docs/development/components/components/{23-tabs.md → 24-tabs.md} +1 -1
- package/dist/docs/development/components/components/{24-tiles.md → 25-tiles.md} +1 -1
- package/dist/docs/development/components/components/{25-visibility.md → 26-visibility.md} +1 -1
- package/dist/docs/development/customization/04-documentation-sidebar.md +3 -3
- package/dist/docs/development/customization/05-resource-sidebar.md +235 -0
- package/dist/docs/development/customization/09-embed-eventcatalog.md +179 -0
- package/dist/docs/development/customization/_category_.json +1 -1
- package/dist/docs/development/deployment/build-and-deploy.md +4 -0
- package/dist/docs/development/deployment/hosting-options.md +1 -1
- package/dist/docs/development/deployment/link-validation.md +105 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/00-overview.md +76 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/01-setup.md +144 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/_category_.json +10 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/01-configure-rules.md +130 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/02-run-in-ci.md +93 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/03-use-custom-frontmatter.md +81 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/04-reference-external-catalogs.md +51 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +120 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/_category_.json +12 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/01-cli.md +109 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/02-configuration.md +120 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +287 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/04-versions.md +77 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +75 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/_category_.json +12 -0
- package/dist/docs/development/guides/97-architecture-graph.md +78 -0
- package/dist/docs/development/guides/domains/02-create-domain.md +1 -1
- package/dist/docs/development/guides/domains/03-ownership-and-language/02-adding-ubiquitous-language.md +29 -0
- package/dist/docs/development/guides/domains/09-reference.md +10 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/02-adding-channels.md +2 -2
- package/dist/docs/development/guides/resources/messages/04-message-channels/04-adding-messages-to-services.md +8 -0
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/01-add-openapi-specifications.md +2 -2
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/02-add-asyncapi-specifications.md +3 -3
- package/dist/docs/development/guides/systems/05-system-context-maps.md +2 -0
- package/dist/docs/development/license-keys/license-validation.md +7 -3
- package/dist/docs/development/license-keys/overview.md +7 -3
- package/dist/docs/development/upgrading/upgrading.md +3 -3
- package/dist/docs/development/upgrading/v2.md +3 -3
- package/dist/docs/federation/00-overview.md +158 -0
- package/dist/docs/federation/01-first-federation.md +199 -0
- package/dist/docs/federation/_category_.json +12 -0
- package/dist/docs/federation/explanation/_category_.json +12 -0
- package/dist/docs/federation/explanation/how-it-works.md +129 -0
- package/dist/docs/federation/explanation/lockfile-and-cache.md +134 -0
- package/dist/docs/federation/explanation/mvp-status-and-feedback.md +86 -0
- package/dist/docs/federation/explanation/ownership-and-references.md +134 -0
- package/dist/docs/federation/how-to/_category_.json +12 -0
- package/dist/docs/federation/how-to/configure-github-sources.md +156 -0
- package/dist/docs/federation/how-to/configure-validation-rules.md +127 -0
- package/dist/docs/federation/how-to/run-in-ci.md +138 -0
- package/dist/docs/federation/how-to/share-assets-and-components.md +125 -0
- package/dist/docs/federation/how-to/use-local-sources.md +138 -0
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/00-introduction.md +11 -2
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/01-installation.md +11 -3
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/02-plugin-configuration.md +11 -2
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/03-examples.md +11 -1
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/04-configuration.md +11 -1
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/05-setup-team-catalog.md +11 -2
- package/dist/docs/federation/legacy-federation/_category_.json +12 -0
- package/dist/docs/federation/reference/_category_.json +12 -0
- package/dist/docs/federation/reference/cli.md +122 -0
- package/dist/docs/federation/reference/configuration.md +192 -0
- package/dist/docs/federation/reference/diagnostic-rules.md +173 -0
- package/dist/docs/federation/reference/generated-output.md +118 -0
- package/dist/docs/federation/reference/supported-content.md +86 -0
- package/dist/docs/federation/reference/troubleshooting.md +208 -0
- package/dist/docs/plugins/01-intro.md +3 -3
- package/dist/docs/plugins/03-all-plugins.md +2 -2
- package/dist/docs/plugins/asyncapi/00-intro.md +4 -4
- package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +4 -4
- package/dist/docs/plugins/backstage/00-overview.md +53 -0
- package/dist/docs/plugins/backstage/01-get-started.md +95 -0
- package/dist/docs/plugins/backstage/02-embed-entity-tabs.md +109 -0
- package/dist/docs/plugins/backstage/03-add-overview-cards.md +79 -0
- package/dist/docs/plugins/backstage/04-control-theme-and-size.md +54 -0
- package/dist/docs/plugins/backstage/05-migrate-to-annotations.md +49 -0
- package/dist/docs/plugins/backstage/06-configuration.md +85 -0
- package/dist/docs/plugins/backstage/07-components.md +129 -0
- package/dist/docs/plugins/backstage/08-how-embeds-work.md +52 -0
- package/dist/docs/plugins/backstage/_category_.json +4 -3
- package/dist/docs/plugins/eventbridge/00-intro.md +5 -5
- package/dist/docs/plugins/eventbridge/03-api.md +3 -3
- package/dist/docs/plugins/graphql/00-intro.md +2 -2
- package/dist/docs/plugins/graphql/02-plugin-configuration.md +2 -2
- package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
- package/dist/docs/plugins/openapi/00-intro.md +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +5 -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/ChatPanel/ChatPanel.tsx +208 -119
- package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +28 -8
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +45 -0
- package/eventcatalog/src/components/Header.astro +11 -6
- package/eventcatalog/src/components/MDX/Design/Design.astro +2 -2
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -2
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -2
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +2 -2
- package/eventcatalog/src/components/SchemaExplorer/AvroSchemaViewer.tsx +21 -19
- package/eventcatalog/src/components/SchemaExplorer/JSONSchemaViewer.tsx +79 -77
- package/eventcatalog/src/components/SchemaExplorer/ProtobufSchemaViewer.test.tsx +91 -0
- package/eventcatalog/src/components/SchemaExplorer/ProtobufSchemaViewer.tsx +115 -33
- package/eventcatalog/src/components/SchemaExplorer/SchemaViewerHover.test.tsx +33 -0
- package/eventcatalog/src/components/SchemaExplorer/protobuf-validation.test.ts +84 -0
- package/eventcatalog/src/components/SchemaExplorer/protobuf-validation.ts +149 -0
- package/eventcatalog/src/components/Search/Search.astro +11 -4
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +29 -24
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +3 -3
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +5 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +10 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +3 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +2 -2
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -2
- package/eventcatalog/src/utils/feature.ts +1 -0
- package/eventcatalog/src/utils/protobuf-schema.ts +211 -16
- package/package.json +3 -3
- package/dist/docs/cli/channels.md +0 -180
- package/dist/docs/cli/commands.md +0 -183
- package/dist/docs/cli/custom-docs.md +0 -78
- package/dist/docs/cli/data-products.md +0 -177
- package/dist/docs/cli/data-stores.md +0 -166
- package/dist/docs/cli/diagrams.md +0 -147
- package/dist/docs/cli/domains.md +0 -280
- package/dist/docs/cli/entities.md +0 -138
- package/dist/docs/cli/events.md +0 -186
- package/dist/docs/cli/export.md +0 -27
- package/dist/docs/cli/governance.md +0 -24
- package/dist/docs/cli/messages.md +0 -69
- package/dist/docs/cli/queries.md +0 -183
- package/dist/docs/cli/services.md +0 -266
- package/dist/docs/cli/snapshots.md +0 -44
- package/dist/docs/cli/teams.md +0 -75
- package/dist/docs/cli/users.md +0 -75
- package/dist/docs/cli/utilities.md +0 -43
- package/dist/docs/development/developer-tools/eventcatalog-linter.md +0 -732
- package/dist/docs/plugins/backstage/00-intro.md +0 -67
- package/dist/docs/plugins/backstage/01-installation.md +0 -242
- package/dist/docs/plugins/backstage/02-api.md +0 -51
- package/dist/docs/plugins/backstage/03-examples.md +0 -12
- package/dist/docs/plugins/eventcatalog-federation/_category_.json +0 -11
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { Sparkles } from 'lucide-react';
|
|
3
3
|
import ChatPanel from './ChatPanel';
|
|
4
4
|
|
|
5
|
-
const ChatPanelButton = () => {
|
|
5
|
+
const ChatPanelButton = ({ configured = false }: { configured?: boolean }) => {
|
|
6
6
|
const [isOpen, setIsOpen] = useState(false);
|
|
7
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
8
|
+
const closePanel = useCallback(() => {
|
|
9
|
+
setIsOpen(false);
|
|
10
|
+
buttonRef.current?.focus();
|
|
11
|
+
}, []);
|
|
12
|
+
const [shortcut, setShortcut] = useState('⌘I');
|
|
7
13
|
|
|
8
14
|
// Listen for custom event to open chat panel from other components
|
|
9
15
|
useEffect(() => {
|
|
@@ -11,22 +17,36 @@ const ChatPanelButton = () => {
|
|
|
11
17
|
setIsOpen(true);
|
|
12
18
|
};
|
|
13
19
|
|
|
20
|
+
setShortcut(/Mac|iPhone|iPad/.test(navigator.platform) ? '⌘I' : 'Ctrl I');
|
|
21
|
+
const handleShortcut = (event: KeyboardEvent) => {
|
|
22
|
+
if ((event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey && event.key.toLowerCase() === 'i') {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
setIsOpen(true);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
window.addEventListener('keydown', handleShortcut);
|
|
14
28
|
window.addEventListener('eventcatalog:open-chat', handleOpenChat);
|
|
15
|
-
return () =>
|
|
29
|
+
return () => {
|
|
30
|
+
window.removeEventListener('keydown', handleShortcut);
|
|
31
|
+
window.removeEventListener('eventcatalog:open-chat', handleOpenChat);
|
|
32
|
+
};
|
|
16
33
|
}, []);
|
|
17
34
|
|
|
18
35
|
return (
|
|
19
36
|
<>
|
|
20
37
|
<button
|
|
38
|
+
ref={buttonRef}
|
|
21
39
|
onClick={() => setIsOpen(true)}
|
|
22
|
-
className="flex items-center gap-1.5 px-4
|
|
40
|
+
className="flex h-9 shrink-0 items-center justify-center gap-1.5 whitespace-nowrap px-4 rounded-md bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-content-hover))] ring-1 ring-inset ring-[rgb(var(--ec-page-border))] shadow-xs transition-colors text-sm"
|
|
23
41
|
aria-label="Open AI Assistant"
|
|
42
|
+
aria-keyshortcuts="Meta+i Control+i"
|
|
43
|
+
title={`Open Event Catalog Assistant (${shortcut})`}
|
|
24
44
|
>
|
|
25
|
-
<
|
|
26
|
-
<span className="font-light text-
|
|
45
|
+
<Sparkles size={16} className="shrink-0 text-gray-500" aria-hidden="true" />
|
|
46
|
+
<span className="font-light text-gray-500">Ask</span>
|
|
27
47
|
</button>
|
|
28
48
|
|
|
29
|
-
<ChatPanel isOpen={isOpen} onClose={
|
|
49
|
+
<ChatPanel configured={configured} isOpen={isOpen} onClose={closePanel} />
|
|
30
50
|
</>
|
|
31
51
|
);
|
|
32
52
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ArrowUpRight } from 'lucide-react';
|
|
2
|
+
import { buildUrl } from '@utils/url-builder';
|
|
3
|
+
|
|
4
|
+
const setupUrl = 'https://www.eventcatalog.dev/docs/development/ask-your-architecture/eventcatalog-assistant/configuration';
|
|
5
|
+
const introduction = 'Your whole catalog, connected to your AI.';
|
|
6
|
+
const description =
|
|
7
|
+
'Bring your own model and I can help you understand your services, trace how events flow, and explore the impact of a change across your whole catalog.';
|
|
8
|
+
const privacy = 'You choose where your data is processed: on your own infrastructure or with a model provider you trust.';
|
|
9
|
+
const setup = 'I’m not connected to a model yet. Your catalog owner can connect one to get started.';
|
|
10
|
+
|
|
11
|
+
export const offlineReplyText = `${introduction}\n\n${description}\n\n${privacy}\n\n${setup}`;
|
|
12
|
+
|
|
13
|
+
export default function OfflineReply() {
|
|
14
|
+
return (
|
|
15
|
+
<div className="ec-chat-offline w-full space-y-4 py-2 text-[13px] leading-relaxed text-[rgb(var(--ec-content-text))]">
|
|
16
|
+
<div className="space-y-2">
|
|
17
|
+
<p className="text-base font-medium leading-snug text-[rgb(var(--ec-page-text))]">{introduction}</p>
|
|
18
|
+
<p>{description}</p>
|
|
19
|
+
</div>
|
|
20
|
+
<div className="space-y-3 rounded-xl border border-[rgb(var(--ec-accent)/0.15)] bg-[rgb(var(--ec-accent)/0.04)] p-4">
|
|
21
|
+
<div className="space-y-1">
|
|
22
|
+
<p className="font-medium text-[rgb(var(--ec-page-text))]">Your model. Your control.</p>
|
|
23
|
+
<p className="text-[rgb(var(--ec-page-text-muted))]">{privacy}</p>
|
|
24
|
+
</div>
|
|
25
|
+
<p>{setup}</p>
|
|
26
|
+
<a
|
|
27
|
+
href={setupUrl}
|
|
28
|
+
target="_blank"
|
|
29
|
+
rel="noreferrer"
|
|
30
|
+
className="inline-flex items-center gap-2 rounded-lg bg-[rgb(var(--ec-accent))] px-3 py-2 text-xs font-medium text-white transition-colors hover:bg-[rgb(var(--ec-accent-hover))] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[rgb(var(--ec-accent))]"
|
|
31
|
+
>
|
|
32
|
+
Connect your model
|
|
33
|
+
<ArrowUpRight size={14} aria-hidden="true" />
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
<p className="text-xs leading-relaxed text-[rgb(var(--ec-page-text-muted))]">
|
|
37
|
+
Don’t need the assistant?{' '}
|
|
38
|
+
<a href={buildUrl('/settings/assistant')} className="underline underline-offset-2 hover:text-[rgb(var(--ec-page-text))]">
|
|
39
|
+
Turn off Event Catalog Assistant
|
|
40
|
+
</a>{' '}
|
|
41
|
+
or set <code className="text-[11px]">chat.enabled: false</code> in your catalog configuration.
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
import catalog from '@utils/eventcatalog-config/catalog';
|
|
3
3
|
import Search from '@components/Search/Search.astro';
|
|
4
4
|
import { buildUrl } from '@utils/url-builder';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
showEventCatalogBranding,
|
|
7
|
+
showCustomBranding,
|
|
8
|
+
isEventCatalogChatVisible,
|
|
9
|
+
isEventCatalogChatEnabled,
|
|
10
|
+
} from '@utils/feature';
|
|
6
11
|
import { getSession } from 'auth-astro/server';
|
|
7
12
|
import { isAuthEnabled, isSSR } from '@utils/feature';
|
|
8
13
|
import { EnvironmentDropdown } from './EnvironmentDropdown';
|
|
@@ -33,15 +38,15 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
|
|
|
33
38
|
: 'left: var(--ec-vertical-nav-width, 14rem);'}
|
|
34
39
|
>
|
|
35
40
|
<div class="px-6">
|
|
36
|
-
<div class="flex justify-between items-center">
|
|
37
|
-
<div class="
|
|
38
|
-
<div class="w-
|
|
41
|
+
<div class="flex justify-between items-center gap-4">
|
|
42
|
+
<div class="flex min-w-0 flex-1 items-center gap-3">
|
|
43
|
+
<div class="hidden lg:block min-w-0 flex-1 max-w-xl">
|
|
39
44
|
<Search />
|
|
40
45
|
</div>
|
|
41
|
-
{
|
|
46
|
+
{isEventCatalogChatVisible() && <ChatPanelButton configured={isEventCatalogChatEnabled()} client:idle />}
|
|
42
47
|
</div>
|
|
43
48
|
|
|
44
|
-
<div class="hidden md:block
|
|
49
|
+
<div class="hidden md:block shrink-0 ml-auto">
|
|
45
50
|
{
|
|
46
51
|
session ? (
|
|
47
52
|
<div class="flex items-center space-x-4 justify-end pr-2">
|
|
@@ -7,10 +7,10 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
7
7
|
// Visualiser styles ship in the page head so ClientRouter navigations keep them (see NodeGraph.astro).
|
|
8
8
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
9
9
|
|
|
10
|
-
import { isVisualiserEnabled,
|
|
10
|
+
import { isVisualiserEnabled, isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
11
11
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
12
12
|
|
|
13
|
-
const isChatEnabled =
|
|
13
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
14
14
|
|
|
15
15
|
let design: any;
|
|
16
16
|
let id = 'design';
|
|
@@ -7,10 +7,10 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
7
7
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
8
8
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
9
9
|
import { getServices } from '@utils/collections/services';
|
|
10
|
-
import {
|
|
10
|
+
import { isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
11
11
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
12
12
|
|
|
13
|
-
const isChatEnabled =
|
|
13
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
14
14
|
|
|
15
15
|
const { id, version = 'latest', maxHeight, includeKey = true, entities, collection = 'domains', ...rest } = Astro.props;
|
|
16
16
|
let resource = null;
|
|
@@ -6,12 +6,12 @@ import AstroNodeGraph from '../NodeGraph/AstroNodeGraph';
|
|
|
6
6
|
// Visualiser styles ship in the page head so ClientRouter navigations keep them (see NodeGraph.astro).
|
|
7
7
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
8
8
|
import { getVersionFromCollection } from '@utils/collections/versions';
|
|
9
|
-
import { isVisualiserEnabled,
|
|
9
|
+
import { isVisualiserEnabled, isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
10
10
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
11
11
|
import { randomUUID } from 'node:crypto';
|
|
12
12
|
import { parseMdxBooleanProp } from '@utils/markdown';
|
|
13
13
|
|
|
14
|
-
const isChatEnabled =
|
|
14
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
15
15
|
|
|
16
16
|
const { id, version = 'latest', maxHeight, mode = 'simple' } = Astro.props;
|
|
17
17
|
const includeKey = parseMdxBooleanProp(Astro.props.legend ?? Astro.props.includeKey, true);
|
|
@@ -29,11 +29,11 @@ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
|
|
|
29
29
|
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
|
|
30
30
|
import { getNodesAndEdges as getNodesAndEdgesForChannel } from '@utils/node-graphs/channel-node-graph';
|
|
31
31
|
import config from '@config';
|
|
32
|
-
import {
|
|
32
|
+
import { isEventCatalogChatVisible, isDevMode } from '@utils/feature';
|
|
33
33
|
import { loadSavedLayout, applyLayoutToNodes, buildResourceKey } from '@utils/node-graphs/layout-persistence';
|
|
34
34
|
import { compactVisualiserGraph } from '@utils/node-graphs/compact-visualiser-graph';
|
|
35
35
|
|
|
36
|
-
const isChatEnabled =
|
|
36
|
+
const isChatEnabled = isEventCatalogChatVisible();
|
|
37
37
|
|
|
38
38
|
interface Props {
|
|
39
39
|
id: string;
|
|
@@ -138,28 +138,30 @@ const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
|
|
|
138
138
|
|
|
139
139
|
{/* Field details */}
|
|
140
140
|
<div className="flex-grow min-w-0">
|
|
141
|
-
<div className="
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
<div className="-mx-1 rounded px-1 transition-colors hover:bg-[rgb(var(--ec-content-hover))]">
|
|
142
|
+
<div className="flex flex-wrap items-baseline gap-x-1.5 gap-y-1">
|
|
143
|
+
<span className="avro-field-name font-semibold text-[rgb(var(--ec-page-text))] text-sm">{field.name}</span>
|
|
144
|
+
<span className="text-[rgb(var(--ec-accent))] font-mono text-xs">{formatAvroType(field.type)}</span>
|
|
145
|
+
{showRequired && isRequired && (
|
|
146
|
+
<span className="text-red-600 dark:text-red-400 text-xs ml-auto flex-shrink-0">required</span>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
{field.doc && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-1">{field.doc}</p>}
|
|
151
|
+
|
|
152
|
+
{/* Show enum values if present */}
|
|
153
|
+
{enumType && enumType.symbols && (
|
|
154
|
+
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-1">
|
|
155
|
+
Values:{' '}
|
|
156
|
+
{enumType.symbols.map((s: string) => (
|
|
157
|
+
<code key={s} className="bg-[rgb(var(--ec-content-hover))] px-1 rounded mx-0.5 text-[rgb(var(--ec-page-text))]">
|
|
158
|
+
{s}
|
|
159
|
+
</code>
|
|
160
|
+
))}
|
|
161
|
+
</div>
|
|
146
162
|
)}
|
|
147
163
|
</div>
|
|
148
164
|
|
|
149
|
-
{field.doc && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-1">{field.doc}</p>}
|
|
150
|
-
|
|
151
|
-
{/* Show enum values if present */}
|
|
152
|
-
{enumType && enumType.symbols && (
|
|
153
|
-
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-1">
|
|
154
|
-
Values:{' '}
|
|
155
|
-
{enumType.symbols.map((s: string) => (
|
|
156
|
-
<code key={s} className="bg-[rgb(var(--ec-content-hover))] px-1 rounded mx-0.5 text-[rgb(var(--ec-page-text))]">
|
|
157
|
-
{s}
|
|
158
|
-
</code>
|
|
159
|
-
))}
|
|
160
|
-
</div>
|
|
161
|
-
)}
|
|
162
|
-
|
|
163
165
|
{/* Nested fields for record types */}
|
|
164
166
|
{hasNested && recordType && (
|
|
165
167
|
<div className={`avro-nested-content mt-2 ${!isExpanded ? 'hidden' : ''}`}>
|
|
@@ -315,86 +315,88 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
|
|
|
315
315
|
)}
|
|
316
316
|
|
|
317
317
|
<div className="flex-grow">
|
|
318
|
-
<div className="
|
|
319
|
-
<div>
|
|
320
|
-
<span className="font-semibold text-[rgb(var(--ec-page-text))] text-sm">{name}</span>
|
|
321
|
-
<span className="ml-1.5 text-[rgb(var(--ec-accent))] font-mono text-xs">
|
|
322
|
-
{hasVariants ? (details.variantType === 'anyOf' ? 'anyOf' : 'oneOf') : formatType(details.type)}
|
|
323
|
-
{hasType(details.type, 'array') && details.items?.type ? `[${formatType(details.items.type)}]` : ''}
|
|
324
|
-
{details.format ? `<${details.format}>` : ''}
|
|
325
|
-
{details._refPath && (
|
|
326
|
-
<span className="text-blue-600 dark:text-blue-400 ml-1">→ {details._refName || details._refPath}</span>
|
|
327
|
-
)}
|
|
328
|
-
{details._refNotFound && <span className="text-red-600 dark:text-red-400 ml-1">❌ ref not found</span>}
|
|
329
|
-
{details.const !== undefined && (
|
|
330
|
-
<span>
|
|
331
|
-
constant: <code>{details.const}</code>
|
|
332
|
-
</span>
|
|
333
|
-
)}
|
|
334
|
-
</span>
|
|
335
|
-
</div>
|
|
336
|
-
{isRequired && <span className="text-red-600 dark:text-red-400 text-xs ml-3 flex-shrink-0">required</span>}
|
|
337
|
-
</div>
|
|
338
|
-
|
|
339
|
-
{details.description && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5">{details.description}</p>}
|
|
340
|
-
{details.title && details.title !== details.description && (
|
|
341
|
-
<p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5 italic">Title: {details.title}</p>
|
|
342
|
-
)}
|
|
343
|
-
|
|
344
|
-
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-0.5 space-y-0">
|
|
345
|
-
{details.pattern && (
|
|
346
|
-
<div>
|
|
347
|
-
Match pattern:{' '}
|
|
348
|
-
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
349
|
-
{details.pattern}
|
|
350
|
-
</code>
|
|
351
|
-
</div>
|
|
352
|
-
)}
|
|
353
|
-
{details.minimum !== undefined && (
|
|
354
|
-
<div>
|
|
355
|
-
Minimum:{' '}
|
|
356
|
-
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
357
|
-
{details.minimum}
|
|
358
|
-
</code>
|
|
359
|
-
</div>
|
|
360
|
-
)}
|
|
361
|
-
{details.maximum !== undefined && (
|
|
362
|
-
<div>
|
|
363
|
-
Maximum:{' '}
|
|
364
|
-
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
365
|
-
{details.maximum}
|
|
366
|
-
</code>
|
|
367
|
-
</div>
|
|
368
|
-
)}
|
|
369
|
-
{details.minLength !== undefined && (
|
|
318
|
+
<div className="-mx-1 rounded px-1 transition-colors hover:bg-[rgb(var(--ec-content-hover))]">
|
|
319
|
+
<div className="flex justify-between items-baseline">
|
|
370
320
|
<div>
|
|
371
|
-
|
|
372
|
-
<
|
|
373
|
-
{details.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
<div>
|
|
387
|
-
<span className="text-xs inline-block">Allowed values:</span>
|
|
388
|
-
{details.enum.map((val: any, idx: number) => (
|
|
389
|
-
<span key={idx} className="text-xs">
|
|
390
|
-
{' '}
|
|
391
|
-
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
392
|
-
{val}
|
|
393
|
-
</code>
|
|
394
|
-
</span>
|
|
395
|
-
))}
|
|
321
|
+
<span className="font-semibold text-[rgb(var(--ec-page-text))] text-sm">{name}</span>
|
|
322
|
+
<span className="ml-1.5 text-[rgb(var(--ec-accent))] font-mono text-xs">
|
|
323
|
+
{hasVariants ? (details.variantType === 'anyOf' ? 'anyOf' : 'oneOf') : formatType(details.type)}
|
|
324
|
+
{hasType(details.type, 'array') && details.items?.type ? `[${formatType(details.items.type)}]` : ''}
|
|
325
|
+
{details.format ? `<${details.format}>` : ''}
|
|
326
|
+
{details._refPath && (
|
|
327
|
+
<span className="text-blue-600 dark:text-blue-400 ml-1">→ {details._refName || details._refPath}</span>
|
|
328
|
+
)}
|
|
329
|
+
{details._refNotFound && <span className="text-red-600 dark:text-red-400 ml-1">❌ ref not found</span>}
|
|
330
|
+
{details.const !== undefined && (
|
|
331
|
+
<span>
|
|
332
|
+
constant: <code>{details.const}</code>
|
|
333
|
+
</span>
|
|
334
|
+
)}
|
|
335
|
+
</span>
|
|
396
336
|
</div>
|
|
337
|
+
{isRequired && <span className="text-red-600 dark:text-red-400 text-xs ml-3 flex-shrink-0">required</span>}
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
{details.description && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5">{details.description}</p>}
|
|
341
|
+
{details.title && details.title !== details.description && (
|
|
342
|
+
<p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5 italic">Title: {details.title}</p>
|
|
397
343
|
)}
|
|
344
|
+
|
|
345
|
+
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-0.5 space-y-0">
|
|
346
|
+
{details.pattern && (
|
|
347
|
+
<div>
|
|
348
|
+
Match pattern:{' '}
|
|
349
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
350
|
+
{details.pattern}
|
|
351
|
+
</code>
|
|
352
|
+
</div>
|
|
353
|
+
)}
|
|
354
|
+
{details.minimum !== undefined && (
|
|
355
|
+
<div>
|
|
356
|
+
Minimum:{' '}
|
|
357
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
358
|
+
{details.minimum}
|
|
359
|
+
</code>
|
|
360
|
+
</div>
|
|
361
|
+
)}
|
|
362
|
+
{details.maximum !== undefined && (
|
|
363
|
+
<div>
|
|
364
|
+
Maximum:{' '}
|
|
365
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
366
|
+
{details.maximum}
|
|
367
|
+
</code>
|
|
368
|
+
</div>
|
|
369
|
+
)}
|
|
370
|
+
{details.minLength !== undefined && (
|
|
371
|
+
<div>
|
|
372
|
+
Min length:{' '}
|
|
373
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
374
|
+
{details.minLength}
|
|
375
|
+
</code>
|
|
376
|
+
</div>
|
|
377
|
+
)}
|
|
378
|
+
{details.maxLength !== undefined && (
|
|
379
|
+
<div>
|
|
380
|
+
Max length:{' '}
|
|
381
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
382
|
+
{details.maxLength}
|
|
383
|
+
</code>
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
{details.enum && (
|
|
387
|
+
<div>
|
|
388
|
+
<span className="text-xs inline-block">Allowed values:</span>
|
|
389
|
+
{details.enum.map((val: any, idx: number) => (
|
|
390
|
+
<span key={idx} className="text-xs">
|
|
391
|
+
{' '}
|
|
392
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
393
|
+
{val}
|
|
394
|
+
</code>
|
|
395
|
+
</span>
|
|
396
|
+
))}
|
|
397
|
+
</div>
|
|
398
|
+
)}
|
|
399
|
+
</div>
|
|
398
400
|
</div>
|
|
399
401
|
|
|
400
402
|
{(hasNestedProperties || hasArrayItems || hasVariants) && (
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { parseProtobufSchema } from '@utils/protobuf-schema';
|
|
4
|
+
import ProtobufSchemaViewer from './ProtobufSchemaViewer';
|
|
5
|
+
|
|
6
|
+
describe('ProtobufSchemaViewer', () => {
|
|
7
|
+
it('renders Protovalidate required and constraint annotations', () => {
|
|
8
|
+
const schema = parseProtobufSchema(`
|
|
9
|
+
syntax = "proto3";
|
|
10
|
+
|
|
11
|
+
enum Status {
|
|
12
|
+
STATUS_UNSPECIFIED = 0;
|
|
13
|
+
STATUS_ACTIVE = 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
message Journey {
|
|
17
|
+
string id = 1 [
|
|
18
|
+
(buf.validate.field).required = true,
|
|
19
|
+
(buf.validate.field).string.uuid = true
|
|
20
|
+
];
|
|
21
|
+
uint32 passenger_count = 2 [(buf.validate.field).uint32 = { gte: 1, lte: 20 }];
|
|
22
|
+
Status status = 3 [(buf.validate.field).enum = { defined_only: true, not_in: [0] }];
|
|
23
|
+
repeated string stops = 4 [(buf.validate.field).repeated = {
|
|
24
|
+
min_items: 2
|
|
25
|
+
unique: true
|
|
26
|
+
items: { string: { min_len: 3 } }
|
|
27
|
+
}];
|
|
28
|
+
planning.model.v1.TrainServiceReference train_service = 5;
|
|
29
|
+
optional string description = 6 [(datahub.v1.gdpr_rule).string = true];
|
|
30
|
+
}
|
|
31
|
+
`);
|
|
32
|
+
|
|
33
|
+
const html = renderToStaticMarkup(<ProtobufSchemaViewer schema={schema} />);
|
|
34
|
+
const statusField = html.slice(html.indexOf('>status</span>'), html.indexOf('>stops</span>'));
|
|
35
|
+
|
|
36
|
+
expect(html).toContain('required');
|
|
37
|
+
expect(html).toContain('Format');
|
|
38
|
+
expect(html).toContain('UUID');
|
|
39
|
+
expect(html).toContain('Minimum');
|
|
40
|
+
expect(html).toContain('Maximum');
|
|
41
|
+
expect(html).toContain('Defined enum values only');
|
|
42
|
+
expect(html).toContain('Excluded values');
|
|
43
|
+
expect(html).toContain('Minimum items');
|
|
44
|
+
expect(html).toContain('Unique items');
|
|
45
|
+
expect(html).toContain('Item minimum length');
|
|
46
|
+
expect(html).toContain('title="planning.model.v1.TrainServiceReference"');
|
|
47
|
+
expect(html).toContain('>TrainServiceReference</span>');
|
|
48
|
+
expect(statusField).not.toContain('STATUS_UNSPECIFIED');
|
|
49
|
+
expect(statusField).toContain('STATUS_ACTIVE');
|
|
50
|
+
expect(html).toContain('Annotation:');
|
|
51
|
+
expect(html).toContain('(datahub.v1.gdpr_rule).string');
|
|
52
|
+
expect(html).toContain('>true</code>');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('filters enum values using repeated-item and map-value constraints', () => {
|
|
56
|
+
const schema = parseProtobufSchema(`
|
|
57
|
+
syntax = "proto3";
|
|
58
|
+
|
|
59
|
+
enum Status {
|
|
60
|
+
STATUS_UNSPECIFIED = 0;
|
|
61
|
+
STATUS_ACTIVE = 1;
|
|
62
|
+
STATUS_ARCHIVED = 2;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
message Journey {
|
|
66
|
+
repeated Status statuses = 1 [(buf.validate.field).repeated = {
|
|
67
|
+
items: { enum: { in: [1] } }
|
|
68
|
+
}];
|
|
69
|
+
map<string, Status> status_by_key = 2 [(buf.validate.field).map = {
|
|
70
|
+
values: { enum: { not_in: [0, 2] } }
|
|
71
|
+
}];
|
|
72
|
+
Status status = 3 [(buf.validate.field).enum.const = 2];
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
|
|
76
|
+
const html = renderToStaticMarkup(<ProtobufSchemaViewer schema={schema} />);
|
|
77
|
+
const repeatedField = html.slice(html.indexOf('>statuses</span>'), html.indexOf('>status_by_key</span>'));
|
|
78
|
+
const mapField = html.slice(html.indexOf('>status_by_key</span>'), html.indexOf('>status</span>'));
|
|
79
|
+
const directField = html.slice(html.indexOf('>status</span>'), html.indexOf('>Enum:</span>'));
|
|
80
|
+
|
|
81
|
+
expect(repeatedField).toContain('STATUS_ACTIVE');
|
|
82
|
+
expect(repeatedField).not.toContain('STATUS_UNSPECIFIED');
|
|
83
|
+
expect(repeatedField).not.toContain('STATUS_ARCHIVED');
|
|
84
|
+
expect(mapField).toContain('STATUS_ACTIVE');
|
|
85
|
+
expect(mapField).not.toContain('STATUS_UNSPECIFIED');
|
|
86
|
+
expect(mapField).not.toContain('STATUS_ARCHIVED');
|
|
87
|
+
expect(directField).toContain('STATUS_ARCHIVED');
|
|
88
|
+
expect(directField).not.toContain('STATUS_UNSPECIFIED');
|
|
89
|
+
expect(directField).not.toContain('STATUS_ACTIVE');
|
|
90
|
+
});
|
|
91
|
+
});
|