@eventcatalog/core 4.12.2 → 5.0.0-beta.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/LICENSE +226 -95
- package/NOTICE +30 -0
- package/README.md +3 -2
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +43 -16
- package/dist/analytics/log-build.d.cts +6 -5
- package/dist/analytics/log-build.d.ts +6 -5
- package/dist/analytics/log-build.js +4 -3
- package/dist/{chunk-U4YJSTGV.js → chunk-AYNZXUB5.js} +2 -10
- package/dist/{chunk-IVVM67LN.js → chunk-CR6AK5LR.js} +1 -1
- package/dist/{chunk-GTIC4R74.js → chunk-LR7AGRHN.js} +13 -16
- package/dist/chunk-TQLRG35T.js +203 -0
- package/dist/{chunk-WK4J6FP3.js → chunk-TWN43V4T.js} +1 -1
- package/dist/{chunk-ZW3MYAWF.js → chunk-WAIADKQE.js} +1 -1
- package/dist/{chunk-RPVA2SZY.js → chunk-ZHKEARLJ.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +407 -291
- package/dist/eventcatalog.config.d.cts +2 -3
- package/dist/eventcatalog.config.d.ts +2 -3
- package/dist/eventcatalog.js +30 -93
- package/dist/federation/content-cache.d.cts +0 -5
- package/dist/federation/content-cache.d.ts +0 -5
- package/dist/federation/diagnostics.d.cts +0 -5
- package/dist/federation/diagnostics.d.ts +0 -5
- package/dist/federation/federate.cjs +0 -9
- package/dist/federation/federate.d.cts +0 -5
- package/dist/federation/federate.d.ts +0 -5
- package/dist/federation/federate.js +2 -3
- package/dist/federation/filesystem-source-provider.d.cts +0 -5
- package/dist/federation/filesystem-source-provider.d.ts +0 -5
- package/dist/federation/github-source-provider.d.cts +0 -5
- package/dist/federation/github-source-provider.d.ts +0 -5
- package/dist/federation/output-transaction.d.cts +0 -4
- package/dist/federation/output-transaction.d.ts +0 -4
- package/dist/federation/public-assets.d.cts +0 -5
- package/dist/federation/public-assets.d.ts +0 -5
- package/dist/federation/source-provider.d.cts +0 -5
- package/dist/federation/source-provider.d.ts +0 -5
- package/dist/federation/types.d.cts +0 -5
- package/dist/federation/types.d.ts +0 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/license-C1y-56bb.d.cts +23 -0
- package/dist/license-C1y-56bb.d.ts +23 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__layout.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__react.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__server.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +12 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__graphql.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__json.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__markup.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__protobuf.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__yaml.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-dark.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-light.mjs +3 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +240 -0
- package/dist/utils/license-status.d.cts +28 -0
- package/dist/utils/license-status.d.ts +28 -0
- package/dist/utils/license-status.js +12 -0
- package/eventcatalog/astro.config.mjs +1 -1
- package/eventcatalog/integrations/eventcatalog-runtime.mjs +1 -1
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +29 -19
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +74 -0
- package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +24 -28
- package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +16 -11
- package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +4 -218
- package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +27 -36
- package/eventcatalog/src/components/Header.astro +43 -58
- package/eventcatalog/src/components/Lists/PillListFlat.styles.css +17 -17
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +1 -1
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +49 -18
- package/eventcatalog/src/components/MDX/RemoteFile.astro +2 -24
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +59 -93
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +1 -32
- package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +20 -67
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -11
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +11 -60
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -3
- package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +0 -3
- package/eventcatalog/src/components/SchemaExplorer/VersionHistoryModal.tsx +2 -9
- package/eventcatalog/src/components/SchemaExplorer/parse-schema.ts +46 -0
- package/eventcatalog/src/components/SchemaExplorer/utils.ts +11 -0
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +2 -9
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +288 -0
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +3 -19
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +85 -30
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +7 -75
- package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +2 -2
- package/eventcatalog/src/components/TrialBadge.astro +82 -0
- package/eventcatalog/src/content.config.ts +9 -90
- package/eventcatalog/src/{enterprise → features}/ai/chat-api.ts +22 -34
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/ga4.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/gtm.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/posthog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsHead.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsTracker.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/tracker.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/api/catalog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/[...auth].ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/custom-pages.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/index.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/resource-docs.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/collection.ts +0 -5
- package/eventcatalog/src/features/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/index.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/types.ts +0 -5
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/index.astro → features/custom-documentation/components/CustomDocumentationPage.astro} +5 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/badge-styles.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/custom-docs.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/docs-search.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-pages/routes.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/directory/user-team-directory.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-extractor.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-indexer.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/fields-db.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/pages/api/fields.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/fields/pages/fields.astro +1 -2
- package/eventcatalog/src/{enterprise → features}/integrations/eventcatalog-features.ts +17 -75
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/links.ts +59 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +299 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/shared.ts +14 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +454 -0
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +432 -0
- package/eventcatalog/src/features/mcp/apps/mermaid-stub.ts +10 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/schema-code.tsx +65 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/shared.ts +23 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +170 -0
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +98 -0
- package/eventcatalog/src/features/mcp/apps/shared/resource-types.ts +15 -0
- package/eventcatalog/src/features/mcp/apps/viewer/shared.ts +24 -0
- package/eventcatalog/src/features/mcp/apps/viewer/styles.css +25 -0
- package/eventcatalog/src/features/mcp/apps/viewer/view.tsx +59 -0
- package/eventcatalog/src/features/mcp/mcp-app-icons.ts +63 -0
- package/eventcatalog/src/features/mcp/mcp-apps.ts +160 -0
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scope.ts +7 -7
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scoped-tools.ts +47 -40
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-server.ts +347 -34
- package/eventcatalog/src/{enterprise → features}/mcp/oauth-protected-resource.ts +0 -5
- package/eventcatalog/src/features/mcp/schema-viewer.ts +24 -0
- package/eventcatalog/src/{enterprise → features}/tools/catalog-tools.ts +133 -102
- package/eventcatalog/src/features/tools/index.ts +5 -0
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/reset.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/save.ts +0 -5
- package/eventcatalog/src/layouts/BaseLayout.astro +2 -2
- package/eventcatalog/src/layouts/Footer.astro +31 -39
- package/eventcatalog/src/layouts/SettingsLayout.astro +6 -6
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +7 -37
- package/eventcatalog/src/{enterprise → pages}/api/schemas/[collection]/[id]/[version]/index.ts +0 -22
- package/eventcatalog/src/{enterprise → pages}/api/schemas/services/[id]/[version]/[specification]/index.ts +0 -19
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].md.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].mdx.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +9 -5
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +12 -0
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/root-index.astro → pages/docs/custom/index.astro} +1 -23
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -9
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +4 -4
- package/eventcatalog/src/pages/docs/llm/schemas.txt.ts +0 -11
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +2 -2
- package/eventcatalog/src/pages/index.astro +2 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +0 -3
- package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -4
- package/eventcatalog/src/pages/settings/assistant.astro +2 -4
- package/eventcatalog/src/pages/settings/license.astro +18 -0
- package/eventcatalog/src/pages/settings/llm-access.astro +1 -4
- package/eventcatalog/src/pages/settings/mcp.astro +33 -4
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -2
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +2 -45
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +7 -109
- package/eventcatalog/src/pages/visualiser/_mermaid-route.ts +78 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/_index.data.ts +44 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +3 -40
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/_index.data.ts +29 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +3 -38
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -32
- package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -8
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +2 -12
- package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +0 -10
- package/eventcatalog/src/stores/sidebar-store/state.ts +4 -6
- package/eventcatalog/src/styles/theme.css +22 -18
- package/eventcatalog/src/styles/themes/forest.css +8 -8
- package/eventcatalog/src/styles/themes/ocean.css +8 -8
- package/eventcatalog/src/styles/themes/sapphire.css +8 -8
- package/eventcatalog/src/styles/themes/sunset.css +8 -8
- package/eventcatalog/src/utils/clipboard.ts +4 -4
- package/eventcatalog/src/utils/collections/flow-step-schema.ts +117 -0
- package/eventcatalog/src/utils/collections/pointer-schema.ts +7 -0
- package/eventcatalog/src/utils/collections/resource-docs.ts +677 -14
- package/eventcatalog/src/utils/collections/schema-loader.ts +0 -5
- package/eventcatalog/src/utils/feature.ts +14 -23
- package/eventcatalog/src/utils/license.ts +114 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram-types.ts +32 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram.ts +84 -0
- package/eventcatalog/src/utils/node-graphs/catalog-force-graph.ts +1 -0
- package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +4 -25
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -39
- package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +11 -27
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +679 -0
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +3 -20
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +62 -4
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +8 -23
- package/eventcatalog/src/utils/node-graphs/flow-lanes.ts +119 -0
- package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +153 -45
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +28 -0
- package/eventcatalog/src/utils/node-graphs/layout-persistence.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +16 -34
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -25
- package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +18 -54
- package/eventcatalog/src/utils/node-graphs/system-levels-node-graph.ts +59 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +20 -80
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -78
- package/eventcatalog/src/utils/trial.ts +36 -0
- package/eventcatalog/tsconfig.json +1 -1
- package/package.json +11 -11
- package/dist/chunk-FV56YFM4.js +0 -7
- package/dist/federation/entitlement.cjs +0 -31
- package/dist/federation/entitlement.d.cts +0 -12
- package/dist/federation/entitlement.d.ts +0 -12
- package/dist/federation/entitlement.js +0 -6
- package/dist/runtime-dependencies/dagre.mjs +0 -3
- package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +0 -265
- package/eventcatalog/src/enterprise/LICENSE +0 -57
- package/eventcatalog/src/enterprise/README.md +0 -5
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +0 -691
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +0 -9
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/[...path]/index.astro +0 -18
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/feature.astro +0 -171
- package/eventcatalog/src/enterprise/feature.ts +0 -75
- package/eventcatalog/src/enterprise/tools/index.ts +0 -10
- package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +0 -126
- package/eventcatalog/src/pages/settings/billing.astro +0 -17
- package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +0 -26
- package/eventcatalog/src/types/mcp-modules.d.ts +0 -67
- package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +0 -261
- package/eventcatalog/src/utils/node-graphs/export-node-graph.ts +0 -91
- /package/eventcatalog/src/{enterprise → features}/auth/error.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/login.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/unauthorized.astro +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path]/_index.data.ts +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path].mdx.ts +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
1
3
|
// Feature checks also run during Astro config evaluation, before @config exists.
|
|
2
4
|
import config from './eventcatalog-config/source';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
const projectDirectory = () => process.env.PROJECT_DIR || process.cwd();
|
|
7
|
+
|
|
5
8
|
export const isEventCatalogChatVisible = () => config?.chat?.enabled ?? true;
|
|
6
9
|
export const isSSR = () => config?.output === 'server';
|
|
7
10
|
export const isVisualiserEnabled = () => config?.visualiser?.enabled ?? true;
|
|
@@ -15,25 +18,13 @@ export const isMarkdownDownloadEnabled = () => config?.llmsTxt?.enabled ?? true;
|
|
|
15
18
|
export const isFullCatalogAPIEnabled = () => config?.api?.fullCatalogAPIEnabled ?? false;
|
|
16
19
|
export const isDevMode = () => process.env.EVENTCATALOG_DEV_MODE === 'true';
|
|
17
20
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
isCustomDocsEnabled,
|
|
29
|
-
isResourceDocsEnabled,
|
|
30
|
-
isEventCatalogChatEnabled,
|
|
31
|
-
isEventCatalogUpgradeEnabled,
|
|
32
|
-
isCustomLandingPageEnabled,
|
|
33
|
-
isCustomPagesEnabled,
|
|
34
|
-
isAuthEnabled,
|
|
35
|
-
isCustomStylesEnabled,
|
|
36
|
-
isEventCatalogMCPEnabled,
|
|
37
|
-
isEventCatalogMCPAuthEnabled,
|
|
38
|
-
isIntegrationsEnabled,
|
|
39
|
-
} from '../enterprise/feature';
|
|
21
|
+
// The assistant needs a model configured (eventcatalog.chat.js) and a server to run on
|
|
22
|
+
export const isEventCatalogChatEnabled = () =>
|
|
23
|
+
fs.existsSync(join(projectDirectory(), 'eventcatalog.chat.js')) && isSSR() && isEventCatalogChatVisible();
|
|
24
|
+
|
|
25
|
+
// Authentication needs providers configured (eventcatalog.auth.js) and a server to run on
|
|
26
|
+
export const isAuthEnabled = () =>
|
|
27
|
+
(config?.auth?.enabled ?? false) && fs.existsSync(join(projectDirectory(), 'eventcatalog.auth.js')) && isSSR();
|
|
28
|
+
|
|
29
|
+
export const isEventCatalogMCPEnabled = () => isSSR() && (config?.mcp?.enabled ?? true);
|
|
30
|
+
export const isEventCatalogMCPAuthEnabled = () => isEventCatalogMCPEnabled() && (config?.mcp?.auth?.enabled ?? false);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { clearCache, hasCommercialLicense, verifyOfflineLicense } from '@eventcatalog/license';
|
|
4
|
+
|
|
5
|
+
export { LICENSE_FAQ_URL, LICENSE_RENEW_URL } from './trial';
|
|
6
|
+
|
|
7
|
+
// Details from the license token
|
|
8
|
+
export type LicenseDetails = { org?: string; licenseId?: string; issuedAt?: Date };
|
|
9
|
+
|
|
10
|
+
// Scale and Starter plans, licensed with a license key instead of a license.jwt
|
|
11
|
+
export type LicensePlan = 'scale' | 'starter';
|
|
12
|
+
|
|
13
|
+
export type LicenseStatus =
|
|
14
|
+
| { state: 'none' }
|
|
15
|
+
| ({ state: 'licensed'; expiresAt: Date } & LicenseDetails)
|
|
16
|
+
| { state: 'plan'; plan: LicensePlan }
|
|
17
|
+
| ({ state: 'expired'; expiresAt?: Date } & LicenseDetails)
|
|
18
|
+
| { state: 'invalid'; reason: string };
|
|
19
|
+
|
|
20
|
+
const toDate = (seconds: unknown) => (typeof seconds === 'number' ? new Date(seconds * 1000) : undefined);
|
|
21
|
+
|
|
22
|
+
const getDetails = (claims: Record<string, unknown>): LicenseDetails => ({
|
|
23
|
+
org: typeof claims.org === 'string' ? claims.org : undefined,
|
|
24
|
+
licenseId: typeof claims.licenseId === 'string' ? claims.licenseId : undefined,
|
|
25
|
+
issuedAt: toDate(claims.iat),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const INVALID_REASONS: Record<string, string> = {
|
|
29
|
+
LICENSE_FILE_EMPTY: 'the file is empty',
|
|
30
|
+
LICENSE_NOT_YET_VALID: 'it is not valid yet',
|
|
31
|
+
LICENSE_SIGNATURE_INVALID: 'its signature is invalid',
|
|
32
|
+
LICENSE_VALIDATION_FAILED: 'it was not issued by EventCatalog',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// The license file: EC_LICENSE, or license.jwt in the root of the catalog
|
|
36
|
+
export const getLicenseFilePath = (projectDirectory: string) =>
|
|
37
|
+
process.env.EC_LICENSE || path.join(projectDirectory, 'license.jwt');
|
|
38
|
+
|
|
39
|
+
// The token's claims, without verifying it (for an expired license, which the verifier rejects)
|
|
40
|
+
const readClaims = (licenseFilePath: string): Record<string, unknown> => {
|
|
41
|
+
try {
|
|
42
|
+
const payload = fs.readFileSync(licenseFilePath, 'utf8').trim().split('.')[1];
|
|
43
|
+
return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
|
|
44
|
+
} catch {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Verified statuses by license file and its last change, so a license is checked once per change
|
|
50
|
+
const statusCache = new Map<string, Promise<LicenseStatus>>();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The Scale or Starter plan, checked by the CLI with its license key and passed to Astro
|
|
54
|
+
* (see checkPlanLicense in the CLI's license-status).
|
|
55
|
+
*/
|
|
56
|
+
export const getLicensePlan = (): LicensePlan | undefined => {
|
|
57
|
+
if (process.env.EVENTCATALOG_SCALE === 'true') return 'scale';
|
|
58
|
+
if (process.env.EVENTCATALOG_STARTER === 'true') return 'starter';
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Verifies the catalog's license.jwt offline (signature, issuer, audience and dates).
|
|
63
|
+
* Cached until the license file changes.
|
|
64
|
+
*/
|
|
65
|
+
export const getCommercialLicenseStatus = (
|
|
66
|
+
projectDirectory = process.env.PROJECT_DIR || process.cwd()
|
|
67
|
+
): Promise<LicenseStatus> => {
|
|
68
|
+
const licensePath = getLicenseFilePath(projectDirectory);
|
|
69
|
+
const modifiedAt = fs.statSync(licensePath, { throwIfNoEntry: false })?.mtimeMs;
|
|
70
|
+
if (modifiedAt === undefined) return Promise.resolve({ state: 'none' });
|
|
71
|
+
|
|
72
|
+
const key = `${licensePath}:${modifiedAt}`;
|
|
73
|
+
if (!statusCache.has(key)) statusCache.set(key, verifyLicense(licensePath));
|
|
74
|
+
return statusCache.get(key)!;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The catalog's license: a commercial license (license.jwt) first, then a Scale or Starter plan.
|
|
79
|
+
*/
|
|
80
|
+
export const getLicenseStatus = async (projectDirectory?: string): Promise<LicenseStatus> => {
|
|
81
|
+
const license = await getCommercialLicenseStatus(projectDirectory);
|
|
82
|
+
if (license.state === 'licensed') return license;
|
|
83
|
+
const plan = getLicensePlan();
|
|
84
|
+
return plan ? { state: 'plan', plan } : license;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const verifyLicense = async (licensePath: string): Promise<LicenseStatus> => {
|
|
88
|
+
// The license package logs its own errors; callers report the status instead
|
|
89
|
+
const consoleError = console.error;
|
|
90
|
+
console.error = () => {};
|
|
91
|
+
try {
|
|
92
|
+
// The package keeps the first license it verifies; this file may have changed since
|
|
93
|
+
clearCache();
|
|
94
|
+
if (await hasCommercialLicense()) {
|
|
95
|
+
const entitlements = await verifyOfflineLicense({ licensePath });
|
|
96
|
+
return { state: 'licensed', ...getDetails(entitlements), expiresAt: new Date(entitlements.exp! * 1000) };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Not a commercial license: verify it again to report why
|
|
100
|
+
clearCache();
|
|
101
|
+
const entitlements = await verifyOfflineLicense({ licensePath });
|
|
102
|
+
if (typeof entitlements.exp !== 'number') return { state: 'invalid', reason: 'it has no expiry date' };
|
|
103
|
+
// Verified within the verifier's clock tolerance, but past its expiry date
|
|
104
|
+
return { state: 'expired', ...getDetails(entitlements), expiresAt: new Date(entitlements.exp * 1000) };
|
|
105
|
+
} catch (error: any) {
|
|
106
|
+
if (error?.code === 'LICENSE_EXPIRED') {
|
|
107
|
+
const claims = readClaims(licensePath);
|
|
108
|
+
return { state: 'expired', ...getDetails(claims), expiresAt: toDate(claims.exp) };
|
|
109
|
+
}
|
|
110
|
+
return { state: 'invalid', reason: INVALID_REASONS[error?.code] || error?.message || String(error) };
|
|
111
|
+
} finally {
|
|
112
|
+
console.error = consoleError;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The resources that have an architecture diagram, and the shape of a diagram. Has no imports so
|
|
3
|
+
* it can be shared by the diagram builders, the MCP tools and the MCP App view bundled for the browser.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const ARCHITECTURE_DIAGRAM_COLLECTIONS = [
|
|
7
|
+
'events',
|
|
8
|
+
'commands',
|
|
9
|
+
'queries',
|
|
10
|
+
'agents',
|
|
11
|
+
'services',
|
|
12
|
+
'domains',
|
|
13
|
+
'systems',
|
|
14
|
+
'flows',
|
|
15
|
+
'containers',
|
|
16
|
+
'data-products',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export type ArchitectureDiagramCollection = (typeof ARCHITECTURE_DIAGRAM_COLLECTIONS)[number];
|
|
20
|
+
|
|
21
|
+
export const isArchitectureDiagramCollection = (collection: string): collection is ArchitectureDiagramCollection =>
|
|
22
|
+
(ARCHITECTURE_DIAGRAM_COLLECTIONS as readonly string[]).includes(collection);
|
|
23
|
+
|
|
24
|
+
export type ArchitectureDiagramDetail = 'overview' | 'full';
|
|
25
|
+
|
|
26
|
+
export type Graph = { nodes: any[]; edges: any[] };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The diagram with its levels, as the Diagram page shows it: the detailed graph, and for
|
|
30
|
+
* domains and systems the level 1 overview and the graph without messages and channels.
|
|
31
|
+
*/
|
|
32
|
+
export type ArchitectureDiagramView = Graph & { overview?: Graph; hiddenMessages?: Graph };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The architecture diagram for a resource, built the same way as its Diagram page
|
|
3
|
+
* in the visualiser. Shared by the `.mermaid` visualiser route and the architecture
|
|
4
|
+
* diagram tool used by AI Chat and the MCP server, so they show the same thing.
|
|
5
|
+
*/
|
|
6
|
+
import config from '@config';
|
|
7
|
+
import { getNodesAndEdges as getNodesAndEdgesForService } from '@utils/node-graphs/services-node-graph';
|
|
8
|
+
import { getNodesAndEdges as getNodesAndEdgesForAgent } from '@utils/node-graphs/agents-node-graph';
|
|
9
|
+
import {
|
|
10
|
+
getNodesAndEdgesForCommands,
|
|
11
|
+
getNodesAndEdgesForEvents,
|
|
12
|
+
getNodesAndEdgesForQueries,
|
|
13
|
+
} from '@utils/node-graphs/message-node-graph';
|
|
14
|
+
import { getNodesAndEdges as getNodesAndEdgesForFlows } from '@utils/node-graphs/flows-node-graph';
|
|
15
|
+
import { getNodesAndEdges as getNodesAndEdgesForDataProduct } from '@utils/node-graphs/data-products-node-graph';
|
|
16
|
+
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
|
|
17
|
+
import { getNodesAndEdges as getNodesAndEdgesForDomainLevels } from '@utils/node-graphs/domain-levels-node-graph';
|
|
18
|
+
import { getNodesAndEdges as getNodesAndEdgesForSystemLevels } from '@utils/node-graphs/system-levels-node-graph';
|
|
19
|
+
import type {
|
|
20
|
+
ArchitectureDiagramCollection,
|
|
21
|
+
ArchitectureDiagramDetail,
|
|
22
|
+
ArchitectureDiagramView,
|
|
23
|
+
Graph,
|
|
24
|
+
} from '@utils/node-graphs/architecture-diagram-types';
|
|
25
|
+
|
|
26
|
+
// Domains and systems are shown in levels: level 1 (`overview`) is the domains and
|
|
27
|
+
// systems and how they relate, and the detailed graph expands systems into their
|
|
28
|
+
// services, messages and channels
|
|
29
|
+
const getLevelsFunctions = {
|
|
30
|
+
domains: getNodesAndEdgesForDomainLevels,
|
|
31
|
+
systems: getNodesAndEdgesForSystemLevels,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// A graph builder for every other collection with a diagram
|
|
35
|
+
const getNodesAndEdgesFunctions = {
|
|
36
|
+
agents: getNodesAndEdgesForAgent,
|
|
37
|
+
services: getNodesAndEdgesForService,
|
|
38
|
+
events: getNodesAndEdgesForEvents,
|
|
39
|
+
commands: getNodesAndEdgesForCommands,
|
|
40
|
+
queries: getNodesAndEdgesForQueries,
|
|
41
|
+
flows: getNodesAndEdgesForFlows,
|
|
42
|
+
containers: getNodesAndEdgesForContainer,
|
|
43
|
+
'data-products': getNodesAndEdgesForDataProduct,
|
|
44
|
+
} satisfies Record<Exclude<ArchitectureDiagramCollection, keyof typeof getLevelsFunctions>, unknown>;
|
|
45
|
+
|
|
46
|
+
export async function getArchitectureDiagramView({
|
|
47
|
+
collection,
|
|
48
|
+
id,
|
|
49
|
+
version,
|
|
50
|
+
}: {
|
|
51
|
+
collection: ArchitectureDiagramCollection;
|
|
52
|
+
id: string;
|
|
53
|
+
version: string;
|
|
54
|
+
}): Promise<ArchitectureDiagramView> {
|
|
55
|
+
const options = {
|
|
56
|
+
id,
|
|
57
|
+
version,
|
|
58
|
+
mode: 'full' as const,
|
|
59
|
+
channelRenderMode: config.visualiser?.channels?.renderMode === 'single' ? ('single' as const) : ('flat' as const),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (collection === 'domains' || collection === 'systems') {
|
|
63
|
+
const { nodes, edges, overview, hiddenMessages } = await getLevelsFunctions[collection](options);
|
|
64
|
+
return { nodes, edges, overview, hiddenMessages };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { nodes, edges } = await getNodesAndEdgesFunctions[collection](options);
|
|
68
|
+
return { nodes, edges };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function getArchitectureDiagramGraph({
|
|
72
|
+
detail = 'full',
|
|
73
|
+
...resource
|
|
74
|
+
}: {
|
|
75
|
+
collection: ArchitectureDiagramCollection;
|
|
76
|
+
id: string;
|
|
77
|
+
version: string;
|
|
78
|
+
detail?: ArchitectureDiagramDetail;
|
|
79
|
+
}): Promise<Graph> {
|
|
80
|
+
const view = await getArchitectureDiagramView(resource);
|
|
81
|
+
// A domain without systems or subdomains has no level 1, so it shows the full diagram
|
|
82
|
+
const graph = detail === 'overview' && view.overview ? view.overview : view;
|
|
83
|
+
return { nodes: graph.nodes, edges: graph.edges };
|
|
84
|
+
}
|
|
@@ -245,6 +245,7 @@ export const getCatalogForceGraph = async (): Promise<{ nodes: CatalogGraphNode[
|
|
|
245
245
|
const key = nodeKey('flows', flow.data.id);
|
|
246
246
|
for (const step of (flow.data as any).steps ?? []) {
|
|
247
247
|
addLink(key, nodeKey('services', refId(step.service)!), 'references');
|
|
248
|
+
addLink(key, nodeKey('systems', refId(step.systems || step.system)!), 'references');
|
|
248
249
|
addLink(key, nodeKey('agents', refId(step.agent)!), 'references');
|
|
249
250
|
addLink(key, nodeKey('flows', refId(step.flow)!), 'has sub-flow');
|
|
250
251
|
addLink(key, nodeKey('containers', refId(step.container)!), 'references');
|
|
@@ -4,8 +4,6 @@ import {
|
|
|
4
4
|
buildContextMenuForMessage,
|
|
5
5
|
buildContextMenuForResource,
|
|
6
6
|
buildContextMenuForService,
|
|
7
|
-
calculatedNodes,
|
|
8
|
-
createDagreGraph,
|
|
9
7
|
createEdge,
|
|
10
8
|
createNode,
|
|
11
9
|
generatedIdForEdge,
|
|
@@ -14,10 +12,8 @@ import {
|
|
|
14
12
|
getEdgeLabelForMessageAsSource,
|
|
15
13
|
getEdgeLabelForServiceAsTarget,
|
|
16
14
|
getOperationFields,
|
|
17
|
-
DEFAULT_NODE_WIDTH,
|
|
18
|
-
DEFAULT_NODE_HEIGHT,
|
|
19
|
-
layoutDagreGraph,
|
|
20
15
|
} from './utils/utils';
|
|
16
|
+
import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
|
|
21
17
|
import { createVersionedMap, findInMap } from '@utils/collections/util';
|
|
22
18
|
import { getChannelChain, getChannels } from '@utils/collections/channels';
|
|
23
19
|
import { type Node, type Edge } from '@xyflow/react';
|
|
@@ -111,12 +107,9 @@ type RoutedResource = {
|
|
|
111
107
|
channelRoutes: ChannelRoute[];
|
|
112
108
|
};
|
|
113
109
|
|
|
114
|
-
type DagreGraph = any;
|
|
115
|
-
|
|
116
110
|
interface Props {
|
|
117
111
|
id: string;
|
|
118
112
|
version: string;
|
|
119
|
-
defaultFlow?: DagreGraph;
|
|
120
113
|
mode?: 'simple' | 'full';
|
|
121
114
|
layout?: boolean;
|
|
122
115
|
}
|
|
@@ -126,8 +119,7 @@ interface Props {
|
|
|
126
119
|
* everything that consumes out of it on the right, and any channels it routes to (or is
|
|
127
120
|
* routed from) either side of it.
|
|
128
121
|
*/
|
|
129
|
-
export const getNodesAndEdges = async ({ id, version,
|
|
130
|
-
const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
|
|
122
|
+
export const getNodesAndEdges = async ({ id, version, mode = 'simple', layout = true }: Props) => {
|
|
131
123
|
const nodes: any[] = [];
|
|
132
124
|
const edges: any[] = [];
|
|
133
125
|
|
|
@@ -448,20 +440,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
448
440
|
);
|
|
449
441
|
}
|
|
450
442
|
|
|
451
|
-
|
|
452
|
-
flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
edges.forEach((edge) => {
|
|
456
|
-
flow.setEdge(edge.source, edge.target);
|
|
457
|
-
});
|
|
443
|
+
if (!layout) return { nodes, edges };
|
|
458
444
|
|
|
459
|
-
|
|
460
|
-
layoutDagreGraph(flow);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
nodes: calculatedNodes(flow, nodes),
|
|
465
|
-
edges,
|
|
466
|
-
};
|
|
445
|
+
return layoutNodeGraph({ nodes, edges });
|
|
467
446
|
};
|
|
@@ -1,46 +1,31 @@
|
|
|
1
1
|
import type { CollectionEntry } from 'astro:content';
|
|
2
2
|
import {
|
|
3
|
-
calculatedNodes,
|
|
4
|
-
createDagreGraph,
|
|
5
3
|
createEdge,
|
|
6
4
|
generatedIdForEdge,
|
|
7
5
|
generateIdForNode,
|
|
8
6
|
buildContextMenuForService,
|
|
9
7
|
buildContextMenuForResource,
|
|
10
|
-
DEFAULT_NODE_WIDTH,
|
|
11
|
-
DEFAULT_NODE_HEIGHT,
|
|
12
|
-
layoutDagreGraph,
|
|
13
8
|
} from './utils/utils';
|
|
9
|
+
import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
|
|
14
10
|
import { MarkerType } from '@xyflow/react';
|
|
15
11
|
import { findMatchingNodes } from '@utils/collections/util';
|
|
16
12
|
import { getContainers } from '@utils/collections/containers';
|
|
17
13
|
|
|
18
|
-
type DagreGraph = any;
|
|
19
|
-
|
|
20
14
|
interface Props {
|
|
21
15
|
id: string;
|
|
22
16
|
version: string;
|
|
23
|
-
defaultFlow?: DagreGraph;
|
|
24
17
|
mode?: 'simple' | 'full';
|
|
25
18
|
channelRenderMode?: 'flat' | 'single';
|
|
26
19
|
collection?: CollectionEntry<'containers'>[];
|
|
27
20
|
layout?: boolean;
|
|
28
21
|
}
|
|
29
22
|
|
|
30
|
-
export const getNodesAndEdges = async ({
|
|
31
|
-
id,
|
|
32
|
-
version,
|
|
33
|
-
defaultFlow,
|
|
34
|
-
mode = 'simple',
|
|
35
|
-
channelRenderMode = 'flat',
|
|
36
|
-
layout = true,
|
|
37
|
-
}: Props) => {
|
|
23
|
+
export const getNodesAndEdges = async ({ id, version, mode = 'simple', channelRenderMode = 'flat', layout = true }: Props) => {
|
|
38
24
|
// 1. Fetch data
|
|
39
25
|
const containers = await getContainers();
|
|
40
26
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
edges = [] as any;
|
|
27
|
+
const nodes: any[] = [],
|
|
28
|
+
edges: any[] = [];
|
|
44
29
|
|
|
45
30
|
// Optimized: Use find since we're looking for a specific item
|
|
46
31
|
const container = containers.find((container) => container.data.id === id && container.data.version === version);
|
|
@@ -80,7 +65,7 @@ export const getNodesAndEdges = async ({
|
|
|
80
65
|
repository: service.data.repository as { url: string },
|
|
81
66
|
}),
|
|
82
67
|
},
|
|
83
|
-
position: { x:
|
|
68
|
+
position: { x: 0, y: 0 },
|
|
84
69
|
});
|
|
85
70
|
|
|
86
71
|
if (!bothSentAndReceived.includes(service)) {
|
|
@@ -116,7 +101,7 @@ export const getNodesAndEdges = async ({
|
|
|
116
101
|
version: dataProduct.data.version,
|
|
117
102
|
}),
|
|
118
103
|
},
|
|
119
|
-
position: { x:
|
|
104
|
+
position: { x: 0, y: 0 },
|
|
120
105
|
});
|
|
121
106
|
|
|
122
107
|
if (!dataProductsBothSentAndReceived.includes(dataProduct)) {
|
|
@@ -244,7 +229,7 @@ export const getNodesAndEdges = async ({
|
|
|
244
229
|
if (container) {
|
|
245
230
|
edges.push(
|
|
246
231
|
createEdge({
|
|
247
|
-
id: generatedIdForEdge(
|
|
232
|
+
id: generatedIdForEdge(_service, container) + '-both',
|
|
248
233
|
source: generateIdForNode(_service),
|
|
249
234
|
target: generateIdForNode(container),
|
|
250
235
|
label: `read and writes to \n (${container.data.technology})`,
|
|
@@ -269,7 +254,7 @@ export const getNodesAndEdges = async ({
|
|
|
269
254
|
if (container) {
|
|
270
255
|
edges.push(
|
|
271
256
|
createEdge({
|
|
272
|
-
id: generatedIdForEdge(
|
|
257
|
+
id: generatedIdForEdge(_dataProduct, container) + '-both',
|
|
273
258
|
source: generateIdForNode(_dataProduct),
|
|
274
259
|
target: generateIdForNode(container),
|
|
275
260
|
label: `read and writes to \n (${container.data.technology})`,
|
|
@@ -289,21 +274,9 @@ export const getNodesAndEdges = async ({
|
|
|
289
274
|
}
|
|
290
275
|
});
|
|
291
276
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
edges.forEach((edge: any) => {
|
|
297
|
-
flow.setEdge(edge.source, edge.target);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
// Render the diagram in memory getting hte X and Y
|
|
301
|
-
if (layout) {
|
|
302
|
-
layoutDagreGraph(flow);
|
|
303
|
-
}
|
|
277
|
+
// Resources that both read and write are added twice (as a writer and as a reader), keep the first
|
|
278
|
+
const uniqueNodes = nodes.filter((node: any, index: number) => nodes.findIndex((n: any) => n.id === node.id) === index);
|
|
279
|
+
const graph = { nodes: uniqueNodes, edges };
|
|
304
280
|
|
|
305
|
-
return
|
|
306
|
-
nodes: calculatedNodes(flow, nodes),
|
|
307
|
-
edges,
|
|
308
|
-
};
|
|
281
|
+
return layout ? await layoutNodeGraph(graph) : graph;
|
|
309
282
|
};
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
2
2
|
import {
|
|
3
|
-
createDagreGraph,
|
|
4
3
|
generateIdForNode,
|
|
5
4
|
generatedIdForEdge,
|
|
6
|
-
calculatedNodes,
|
|
7
5
|
createEdge,
|
|
8
6
|
getColorFromString,
|
|
9
7
|
buildContextMenuForResource,
|
|
10
|
-
DEFAULT_NODE_WIDTH,
|
|
11
|
-
DEFAULT_NODE_HEIGHT,
|
|
12
|
-
layoutDagreGraph,
|
|
13
8
|
} from '@utils/node-graphs/utils/utils';
|
|
9
|
+
import { layoutNodeGraph } from '@utils/node-graphs/layout-node-graph';
|
|
14
10
|
|
|
15
11
|
import { findInMap, createVersionedMap, mergeMaps, collectionToResourceMap } from '@utils/collections/util';
|
|
16
12
|
import { MarkerType } from '@xyflow/react';
|
|
@@ -19,12 +15,9 @@ import { getProducersOfMessage } from '@utils/collections/services';
|
|
|
19
15
|
import type { CollectionMessageTypes } from '@types';
|
|
20
16
|
import { getNodesAndEdgesForProducedMessage } from './message-node-graph';
|
|
21
17
|
|
|
22
|
-
type DagreGraph = any;
|
|
23
|
-
|
|
24
18
|
interface Props {
|
|
25
19
|
id: string;
|
|
26
20
|
version: string;
|
|
27
|
-
defaultFlow?: DagreGraph;
|
|
28
21
|
mode?: 'simple' | 'full';
|
|
29
22
|
layout?: boolean;
|
|
30
23
|
}
|
|
@@ -35,10 +28,9 @@ const getNodePropertyFromCollectionType = (type: string) => {
|
|
|
35
28
|
return collectionToResourceMap[type as keyof typeof collectionToResourceMap];
|
|
36
29
|
};
|
|
37
30
|
|
|
38
|
-
export const getNodesAndEdges = async ({ id,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
edges = [] as any;
|
|
31
|
+
export const getNodesAndEdges = async ({ id, version, mode = 'simple', layout = true }: Props) => {
|
|
32
|
+
let nodes: any[] = [],
|
|
33
|
+
edges: any[] = [];
|
|
42
34
|
|
|
43
35
|
const [dataProducts, containers, services, events, queries, commands, channels] = await Promise.all([
|
|
44
36
|
getCollection('data-products'),
|
|
@@ -93,6 +85,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
93
85
|
|
|
94
86
|
nodes.push({
|
|
95
87
|
id: generateIdForNode(inputResource),
|
|
88
|
+
position: { x: 0, y: 0 },
|
|
96
89
|
sourcePosition: 'right',
|
|
97
90
|
targetPosition: 'left',
|
|
98
91
|
data: { mode, [nodeDataKey]: { ...inputResource?.data } },
|
|
@@ -149,6 +142,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
149
142
|
// The data product itself
|
|
150
143
|
nodes.push({
|
|
151
144
|
id: generateIdForNode(dataProduct),
|
|
145
|
+
position: { x: 0, y: 0 },
|
|
152
146
|
sourcePosition: 'right',
|
|
153
147
|
targetPosition: 'left',
|
|
154
148
|
data: {
|
|
@@ -181,6 +175,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
181
175
|
|
|
182
176
|
nodes.push({
|
|
183
177
|
id: generateIdForNode(outputResource),
|
|
178
|
+
position: { x: 0, y: 0 },
|
|
184
179
|
sourcePosition: 'right',
|
|
185
180
|
targetPosition: 'left',
|
|
186
181
|
data: { mode, [nodeDataKey]: { ...outputResource?.data } },
|
|
@@ -210,19 +205,6 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
210
205
|
);
|
|
211
206
|
});
|
|
212
207
|
|
|
213
|
-
nodes.forEach((node: any) => {
|
|
214
|
-
flow.setNode(node.id, { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT });
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
edges.forEach((edge: any) => {
|
|
218
|
-
flow.setEdge(edge.source, edge.target);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
if (layout) {
|
|
222
|
-
// Render the diagram in memory getting the X and Y
|
|
223
|
-
layoutDagreGraph(flow);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
208
|
// Find any duplicated edges, and merge them into one edge
|
|
227
209
|
const uniqueEdgesById = new Map<string, any>();
|
|
228
210
|
edges.forEach((edge: any) => {
|
|
@@ -232,8 +214,10 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
232
214
|
});
|
|
233
215
|
const uniqueEdges = Array.from(uniqueEdgesById.values());
|
|
234
216
|
|
|
235
|
-
|
|
236
|
-
nodes:
|
|
217
|
+
const graph = {
|
|
218
|
+
nodes: nodes.map((node: any) => ({ ...node, position: node.position ?? { x: 0, y: 0 } })),
|
|
237
219
|
edges: uniqueEdges,
|
|
238
220
|
};
|
|
221
|
+
|
|
222
|
+
return layout ? await layoutNodeGraph(graph) : graph;
|
|
239
223
|
};
|