@eventcatalog/core 5.0.0-beta.8 → 5.0.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 +234 -134
- package/README.md +5 -5
- package/dist/analytics/analytics.cjs +18 -3
- package/dist/analytics/analytics.d.cts +1 -1
- package/dist/analytics/analytics.d.ts +1 -1
- package/dist/analytics/analytics.js +3 -2
- package/dist/analytics/log-build.cjs +157 -76
- package/dist/analytics/log-build.d.cts +2 -2
- package/dist/analytics/log-build.d.ts +2 -2
- package/dist/analytics/log-build.js +7 -5
- package/dist/analytics/studio-usage.cjs +90 -0
- package/dist/analytics/studio-usage.d.cts +5 -0
- package/dist/analytics/studio-usage.d.ts +5 -0
- package/dist/analytics/studio-usage.js +10 -0
- package/dist/analytics/telemetry.cjs +42 -0
- package/dist/analytics/telemetry.d.cts +20 -0
- package/dist/analytics/telemetry.d.ts +20 -0
- package/dist/analytics/telemetry.js +8 -0
- package/dist/catalog-runtime.cjs +1 -1
- package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
- package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
- package/dist/chunk-CA6WCQ2T.js +54 -0
- package/dist/chunk-CPW6G62V.js +17 -0
- package/dist/{chunk-PU25TOOJ.js → chunk-JZN4RSMF.js} +1 -1
- package/dist/{chunk-4W55ZOOS.js → chunk-NEAVAFSJ.js} +66 -35
- package/dist/{chunk-C6T2AAFR.js → chunk-NIVST4WY.js} +9 -3
- package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
- package/dist/{chunk-AYNZXUB5.js → chunk-OX6TSVHY.js} +5 -5
- package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
- package/dist/{chunk-RDIZJ7UT.js → chunk-RE7UTPWH.js} +1 -1
- package/dist/chunk-S5GWAUG5.js +29 -0
- package/dist/{chunk-T4G3VVZ4.js → chunk-YQGRMDRB.js} +4 -2
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +57 -7
- package/dist/docs/development/00-why-eventcatalog.md +11 -11
- package/dist/docs/development/01-fundamentals.md +20 -13
- package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
- package/dist/docs/development/01-getting-started/installation.md +9 -1
- package/dist/docs/development/_getting-started.mdx +1 -1
- package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
- package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
- package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
- package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
- package/dist/docs/development/authentication/01-introduction.md +2 -23
- package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
- package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
- package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
- package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
- package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
- package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
- package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
- package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
- package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
- package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
- package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
- package/dist/docs/development/components/components/11-flow.md +17 -0
- package/dist/docs/development/components/components/15-nodegraph.md +43 -10
- package/dist/docs/development/components/components/18-remote-schema.md +1 -4
- package/dist/docs/development/components/custom-components/07-reference.md +14 -0
- package/dist/docs/development/customization/02-themes.md +0 -5
- package/dist/docs/development/customization/03-search.md +1 -1
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
- package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
- package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
- package/dist/docs/development/deployment/hosting-options.md +7 -2
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
- package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
- package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
- package/dist/docs/development/guides/97-architecture-graph.md +1 -1
- package/dist/docs/development/guides/99-adding-analytics.md +0 -7
- package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
- package/dist/docs/development/guides/domains/09-reference.md +4 -4
- package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
- package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
- package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
- package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
- package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
- package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
- package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
- package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
- package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
- package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
- package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
- package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
- package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
- package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
- package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
- package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
- package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
- package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
- package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
- package/dist/docs/development/guides/systems/01-introduction.md +1 -1
- package/dist/docs/development/guides/systems/02-create-system.md +2 -2
- package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
- package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
- package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
- package/dist/docs/development/guides/systems/06-reference.md +4 -4
- package/dist/docs/development/license/01-license-file.md +151 -0
- package/dist/docs/development/license/_category_.json +12 -0
- package/dist/docs/development/license-keys/_category_.json +3 -3
- package/dist/docs/development/license-keys/integrations.md +7 -37
- package/dist/docs/development/license-keys/license-validation.md +4 -0
- package/dist/docs/development/license-keys/overview.md +5 -1
- package/dist/docs/development/license-keys/plans.md +4 -2
- package/dist/docs/development/studio/01-introduction.md +60 -0
- package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
- package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
- package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
- package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
- package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
- package/dist/docs/development/studio/07-reference.md +294 -0
- package/dist/docs/development/studio/_category_.json +12 -0
- package/dist/docs/development/upgrading/v5.md +345 -0
- package/dist/docs/federation/00-overview.md +2 -8
- package/dist/docs/federation/01-first-federation.md +6 -18
- package/dist/docs/federation/explanation/how-it-works.md +0 -4
- package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
- package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
- package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
- package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
- package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
- package/dist/docs/federation/how-to/run-in-ci.md +2 -9
- package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
- package/dist/docs/federation/how-to/use-local-sources.md +0 -4
- package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
- package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
- package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
- package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
- package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
- package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
- package/dist/docs/federation/reference/cli.md +2 -8
- package/dist/docs/federation/reference/configuration.md +0 -4
- package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
- package/dist/docs/federation/reference/generated-output.md +0 -4
- package/dist/docs/federation/reference/supported-content.md +0 -4
- package/dist/docs/federation/reference/troubleshooting.md +0 -14
- package/dist/docs/plugins/02-generators.md +1 -1
- package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
- package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
- package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
- package/dist/docs/plugins/apicurio/00-intro.md +2 -31
- package/dist/docs/plugins/apicurio/01-installation.md +2 -26
- package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
- package/dist/docs/plugins/apicurio/03-features.md +1 -3
- package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
- package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
- package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
- package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
- package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
- package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
- package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
- package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
- package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
- package/dist/docs/plugins/backstage/00-overview.md +1 -7
- package/dist/docs/plugins/backstage/01-get-started.md +6 -15
- package/dist/docs/plugins/backstage/06-configuration.md +2 -8
- package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
- package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
- package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
- package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
- package/dist/docs/plugins/eventbridge/03-api.md +2 -20
- package/dist/docs/plugins/github/00-intro.md +0 -31
- package/dist/docs/plugins/github/01-installation.md +2 -34
- package/dist/docs/plugins/graphql/00-intro.md +0 -30
- package/dist/docs/plugins/graphql/01-installation.md +1 -53
- package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
- package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
- package/dist/docs/plugins/openapi/00-intro.md +0 -30
- package/dist/docs/plugins/openapi/01-installation.md +1 -57
- package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
- package/dist/docs/plugins/openapi/03-features.md +0 -4
- package/dist/eventcatalog-config-file-utils.cjs +34 -41
- package/dist/eventcatalog-config-file-utils.d.cts +56 -58
- package/dist/eventcatalog-config-file-utils.d.ts +56 -58
- package/dist/eventcatalog-config-file-utils.js +1 -1
- package/dist/eventcatalog.cjs +408 -281
- package/dist/eventcatalog.config.d.cts +26 -15
- package/dist/eventcatalog.config.d.ts +26 -15
- package/dist/eventcatalog.js +46 -27
- package/dist/features.cjs +36 -49
- package/dist/features.d.cts +1 -3
- package/dist/features.d.ts +1 -3
- package/dist/features.js +4 -6
- package/dist/federation/federate.cjs +37 -44
- package/dist/federation/federate.js +5 -5
- package/dist/federation/source-provider.js +2 -2
- package/dist/generate.cjs +37 -42
- package/dist/generate.js +4 -4
- package/dist/resolve-catalog-dependencies.cjs +34 -41
- package/dist/resolve-catalog-dependencies.js +2 -2
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
- package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +5 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
- package/dist/utils/child-process-signals.cjs +53 -0
- package/dist/utils/child-process-signals.d.cts +19 -0
- package/dist/utils/child-process-signals.d.ts +19 -0
- package/dist/utils/child-process-signals.js +6 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +11 -4
- package/dist/utils/license-status.d.cts +3 -2
- package/dist/utils/license-status.d.ts +3 -2
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/astro.config.mjs +21 -1
- package/eventcatalog/integrations/config-loader.mjs +56 -58
- package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
- package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
- package/eventcatalog/integrations/storage.mjs +20 -0
- package/eventcatalog/integrations/studio-server.mjs +4 -1
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
- package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
- package/eventcatalog/src/components/NavigationProgress.astro +7 -0
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
- package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
- package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
- package/eventcatalog/src/components/Search/search-utils.ts +26 -0
- package/eventcatalog/src/components/Seo.astro +5 -1
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
- package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
- package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
- package/eventcatalog/src/components/Settings/Row.tsx +7 -4
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
- package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
- package/eventcatalog/src/components/TrialBadge.astro +20 -9
- package/eventcatalog/src/content.config.ts +19 -2
- package/eventcatalog/src/features/auth/error.astro +4 -2
- package/eventcatalog/src/features/auth/login.astro +2 -1
- package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
- package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
- package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
- package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
- package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
- package/eventcatalog/src/features/server/start.ts +25 -0
- package/eventcatalog/src/features/storage/database.ts +88 -0
- package/eventcatalog/src/features/storage/migrations.ts +85 -0
- package/eventcatalog/src/features/storage/sql/database.sql +5 -0
- package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
- package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
- package/eventcatalog/src/features/storage/sql.ts +28 -0
- package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
- package/eventcatalog/src/features/studio/agents.ts +28 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
- package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
- package/eventcatalog/src/features/studio/api/client.ts +40 -0
- package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
- package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
- package/eventcatalog/src/features/studio/catalog.ts +16 -14
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
- package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
- package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
- package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
- package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
- package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
- package/eventcatalog/src/features/studio/document-name.ts +7 -0
- package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
- package/eventcatalog/src/features/studio/identity.ts +25 -1
- package/eventcatalog/src/features/studio/limits.ts +2 -0
- package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
- package/eventcatalog/src/features/studio/pages/index.astro +596 -373
- package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
- package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
- package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
- package/eventcatalog/src/features/studio/server/storage.ts +53 -73
- package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
- package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
- package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
- package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
- package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
- package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
- package/eventcatalog/src/pages/_index.astro +5 -342
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
- package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
- package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/index.astro +4 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
- package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
- package/eventcatalog/src/pages/settings/license.astro +9 -1
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
- package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
- package/eventcatalog/src/utils/collections/flows.ts +20 -7
- package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
- package/eventcatalog/src/utils/collections/resources.ts +2 -0
- package/eventcatalog/src/utils/collections/util.ts +8 -4
- package/eventcatalog/src/utils/git.ts +11 -0
- package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
- package/eventcatalog/src/utils/license.ts +1 -1
- package/eventcatalog/src/utils/link-validation.ts +25 -19
- package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
- package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
- package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
- package/eventcatalog/src/utils/page-title.ts +15 -0
- package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
- package/eventcatalog/src/utils/trial.ts +13 -0
- package/package.json +11 -11
- package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
- package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
- package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
- package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
- package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
- package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
- package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
- package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
- package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
- package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
- package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
- package/eventcatalog/src/features/studio/clipboard.ts +0 -97
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
- package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
- package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
- package/eventcatalog/src/features/studio/components/icons.ts +0 -53
- package/eventcatalog/src/features/studio/components/status.ts +0 -51
- package/eventcatalog/src/features/studio/edges.ts +0 -56
- package/eventcatalog/src/features/studio/flow-state.ts +0 -92
- package/eventcatalog/src/features/studio/grouping.ts +0 -226
- package/eventcatalog/src/features/studio/layout.ts +0 -42
- package/eventcatalog/src/features/studio/levels.ts +0 -282
- package/eventcatalog/src/features/studio/node-types.ts +0 -205
- package/eventcatalog/src/features/studio/pages/new.astro +0 -24
- package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
- package/eventcatalog/src/features/studio/placement.ts +0 -197
- package/eventcatalog/src/features/studio/studio.css +0 -273
- package/dist/{chunk-A2RZR3U4.js → chunk-6K7XZAYI.js} +3 -3
|
@@ -21,57 +21,56 @@ import {
|
|
|
21
21
|
type FavoriteItem,
|
|
22
22
|
} from '@stores/favorites-store';
|
|
23
23
|
import {
|
|
24
|
+
buildNodeLookup,
|
|
24
25
|
canCollapseGroup,
|
|
25
26
|
findNodeKeyByUrl,
|
|
26
27
|
getBadgeClasses,
|
|
27
28
|
getDefaultCollapsedState,
|
|
28
29
|
hidesDefaultItemIcon,
|
|
29
30
|
isGroupCollapsed,
|
|
31
|
+
resolveNavRef,
|
|
32
|
+
rootLevel,
|
|
33
|
+
stripBasePath,
|
|
30
34
|
toggleGroupCollapsed,
|
|
35
|
+
type NavigationLevel,
|
|
36
|
+
type SidebarSnapshot,
|
|
31
37
|
} from './utils';
|
|
32
38
|
import { resolveIconUrl } from '@utils/icon';
|
|
33
39
|
|
|
34
40
|
const cn = (...classes: (string | false | undefined)[]) => classes.filter(Boolean).join(' ');
|
|
35
41
|
|
|
36
|
-
/**
|
|
37
|
-
* Strip the configured base path from a pathname so URL pattern matching works
|
|
38
|
-
* regardless of the base path setting (e.g. `/eventcatalog/docs/...` → `/docs/...`).
|
|
39
|
-
*/
|
|
40
|
-
const stripBasePath = (pathname: string): string => {
|
|
41
|
-
const base = __EC_BASE__.replace(/\/$/, ''); // e.g. '/eventcatalog'
|
|
42
|
-
if (base && pathname.startsWith(base)) {
|
|
43
|
-
return pathname.slice(base.length) || '/';
|
|
44
|
-
}
|
|
45
|
-
return pathname;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
42
|
// ============================================
|
|
49
43
|
// Component
|
|
50
44
|
// ============================================
|
|
51
45
|
|
|
52
|
-
type
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
type NestedSideBarProps = {
|
|
47
|
+
/**
|
|
48
|
+
* This page's level, built on the server. It renders the sidebar into the HTML and keeps
|
|
49
|
+
* the island showing it until the full navigation data (sidebar-data.json) is loaded.
|
|
50
|
+
*/
|
|
51
|
+
snapshot?: SidebarSnapshot;
|
|
57
52
|
};
|
|
58
53
|
|
|
59
|
-
export default function NestedSideBar() {
|
|
60
|
-
const
|
|
54
|
+
export default function NestedSideBar({ snapshot }: NestedSideBarProps) {
|
|
55
|
+
const storeData = useStore(sidebarStore);
|
|
61
56
|
const favorites = useStore(favoritesStore);
|
|
57
|
+
// Drill-down, restoring state and favorites need the whole catalog; until it loads the
|
|
58
|
+
// snapshot only shows this page's level
|
|
59
|
+
const hasFullData = storeData !== null;
|
|
60
|
+
const data = storeData ?? snapshot?.data ?? null;
|
|
62
61
|
|
|
63
62
|
// Guard against undefined data (e.g., during hydration)
|
|
64
63
|
// Use useMemo to ensure stable references for roots and nodes
|
|
65
64
|
const roots = useMemo(() => data?.roots ?? [], [data?.roots]);
|
|
66
65
|
const nodes = useMemo(() => data?.nodes ?? {}, [data?.nodes]);
|
|
67
66
|
|
|
68
|
-
const [navigationStack, setNavigationStack] = useState<NavigationLevel[]>(
|
|
69
|
-
{ key: null, entries: [], title: 'Documentation' }
|
|
70
|
-
|
|
67
|
+
const [navigationStack, setNavigationStack] = useState<NavigationLevel[]>(
|
|
68
|
+
() => snapshot?.stack ?? [{ key: null, entries: [], title: 'Documentation' }]
|
|
69
|
+
);
|
|
71
70
|
const [animationKey, setAnimationKey] = useState(0);
|
|
72
71
|
const [slideDirection, setSlideDirection] = useState<'forward' | 'backward' | null>(null);
|
|
73
72
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
74
|
-
const [currentPath, setCurrentPath] = useState<string>('');
|
|
73
|
+
const [currentPath, setCurrentPath] = useState<string>(snapshot?.url ?? '');
|
|
75
74
|
const [sectionCollapsePreferences, setSectionCollapsePreferences] = useState(loadCollapsedSections);
|
|
76
75
|
const [showPathPreview, setShowPathPreview] = useState(false);
|
|
77
76
|
const [showFullPath, setShowFullPath] = useState(false);
|
|
@@ -79,33 +78,7 @@ export default function NestedSideBar() {
|
|
|
79
78
|
|
|
80
79
|
// Build a lookup map for faster URL navigation
|
|
81
80
|
// Map format: "type:id" -> "nodeKey"
|
|
82
|
-
const nodeLookup = useMemo(() =>
|
|
83
|
-
const lookup = new Map<string, string>();
|
|
84
|
-
|
|
85
|
-
Object.entries(nodes).forEach(([key, value]) => {
|
|
86
|
-
// Skip keys that are references (string values pointing to other keys)
|
|
87
|
-
// These are unversioned aliases like "domain:E-Commerce" -> "domain:E-Commerce:1.0.0"
|
|
88
|
-
if (typeof value === 'string') return;
|
|
89
|
-
|
|
90
|
-
// Key formats:
|
|
91
|
-
// - "type:id:version" (e.g., "service:OrdersService:0.0.3")
|
|
92
|
-
// - "type:id" (e.g., "user:john", "team:backend") - non-versioned resources
|
|
93
|
-
// - "list:name" (e.g., "list:domains") - skip these
|
|
94
|
-
const parts = key.split(':');
|
|
95
|
-
|
|
96
|
-
// Skip list items
|
|
97
|
-
if (parts[0] === 'list') return;
|
|
98
|
-
|
|
99
|
-
if (parts.length >= 2) {
|
|
100
|
-
// Store as "type:id"
|
|
101
|
-
const type = parts[0];
|
|
102
|
-
const id = parts[1];
|
|
103
|
-
lookup.set(`${type}:${id}`, key);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return lookup;
|
|
108
|
-
}, [nodes]);
|
|
81
|
+
const nodeLookup = useMemo(() => buildNodeLookup(nodes), [nodes]);
|
|
109
82
|
|
|
110
83
|
/**
|
|
111
84
|
* Toggle section collapse state
|
|
@@ -126,7 +99,7 @@ export default function NestedSideBar() {
|
|
|
126
99
|
setNavigationStack((prevStack) => {
|
|
127
100
|
// Only update if the current stack has no entries (initial state)
|
|
128
101
|
if (prevStack.length === 1 && prevStack[0].entries.length === 0) {
|
|
129
|
-
return [
|
|
102
|
+
return [rootLevel(roots)];
|
|
130
103
|
}
|
|
131
104
|
return prevStack;
|
|
132
105
|
});
|
|
@@ -146,21 +119,7 @@ export default function NestedSideBar() {
|
|
|
146
119
|
* Resolve a child reference to a NavNode
|
|
147
120
|
* Handles both direct keys and string references (unversioned aliases pointing to versioned keys)
|
|
148
121
|
*/
|
|
149
|
-
const resolveRef = useCallback(
|
|
150
|
-
(ref: ChildRef): NavNode | null => {
|
|
151
|
-
if (typeof ref === 'string') {
|
|
152
|
-
const node = nodes[ref];
|
|
153
|
-
if (!node) return null;
|
|
154
|
-
// If node is a string, it's a reference to another key (e.g., unversioned alias)
|
|
155
|
-
if (typeof node === 'string') {
|
|
156
|
-
return (nodes[node] as NavNode) ?? null;
|
|
157
|
-
}
|
|
158
|
-
return node;
|
|
159
|
-
}
|
|
160
|
-
return ref;
|
|
161
|
-
},
|
|
162
|
-
[nodes]
|
|
163
|
-
);
|
|
122
|
+
const resolveRef = useCallback((ref: ChildRef): NavNode | null => resolveNavRef(nodes, ref), [nodes]);
|
|
164
123
|
|
|
165
124
|
/**
|
|
166
125
|
* Check if a node is visible (default: true)
|
|
@@ -175,7 +134,7 @@ export default function NestedSideBar() {
|
|
|
175
134
|
*/
|
|
176
135
|
const buildStackFromPath = useCallback(
|
|
177
136
|
(path: string[]): NavigationLevel[] => {
|
|
178
|
-
const stack: NavigationLevel[] = [
|
|
137
|
+
const stack: NavigationLevel[] = [rootLevel(roots)];
|
|
179
138
|
|
|
180
139
|
for (const key of path) {
|
|
181
140
|
const node = resolveRef(key);
|
|
@@ -281,7 +240,7 @@ export default function NestedSideBar() {
|
|
|
281
240
|
if (foundNode && foundNode.pages && foundNode.pages.length > 0) {
|
|
282
241
|
// Fallback: Flattened navigation
|
|
283
242
|
return [
|
|
284
|
-
|
|
243
|
+
rootLevel(roots),
|
|
285
244
|
{ key: foundNodeKey, entries: foundNode.pages, title: foundNode.title, badge: foundNode.badge },
|
|
286
245
|
];
|
|
287
246
|
}
|
|
@@ -296,7 +255,7 @@ export default function NestedSideBar() {
|
|
|
296
255
|
setSlideDirection('backward');
|
|
297
256
|
setAnimationKey((prev) => prev + 1);
|
|
298
257
|
}
|
|
299
|
-
return [
|
|
258
|
+
return [rootLevel(roots)];
|
|
300
259
|
});
|
|
301
260
|
return true;
|
|
302
261
|
}
|
|
@@ -309,14 +268,14 @@ export default function NestedSideBar() {
|
|
|
309
268
|
* Restore state from localStorage on mount, or navigate to URL
|
|
310
269
|
*/
|
|
311
270
|
useEffect(() => {
|
|
312
|
-
if (!
|
|
271
|
+
if (!hasFullData || roots.length === 0 || isInitialized) return;
|
|
313
272
|
|
|
314
273
|
const currentUrl = window.location.pathname;
|
|
315
274
|
const normalizedCurrentUrl = stripBasePath(currentUrl);
|
|
316
275
|
|
|
317
276
|
// Force root navigation on homepage
|
|
318
277
|
if (normalizedCurrentUrl === '/' || normalizedCurrentUrl === '') {
|
|
319
|
-
setNavigationStack([
|
|
278
|
+
setNavigationStack([rootLevel(roots)]);
|
|
320
279
|
setIsInitialized(true);
|
|
321
280
|
return;
|
|
322
281
|
}
|
|
@@ -347,7 +306,7 @@ export default function NestedSideBar() {
|
|
|
347
306
|
const targetNode = resolveRef(targetKey);
|
|
348
307
|
if (targetNode && targetNode.pages && targetNode.pages.length > 0) {
|
|
349
308
|
finalStack = [
|
|
350
|
-
|
|
309
|
+
rootLevel(roots),
|
|
351
310
|
{ key: targetKey, entries: targetNode.pages, title: targetNode.title, badge: targetNode.badge },
|
|
352
311
|
];
|
|
353
312
|
}
|
|
@@ -355,13 +314,13 @@ export default function NestedSideBar() {
|
|
|
355
314
|
|
|
356
315
|
// 3. Fallback to root
|
|
357
316
|
if (!finalStack) {
|
|
358
|
-
setNavigationStack([
|
|
317
|
+
setNavigationStack([rootLevel(roots)]);
|
|
359
318
|
} else {
|
|
360
319
|
setNavigationStack(finalStack);
|
|
361
320
|
}
|
|
362
321
|
|
|
363
322
|
setIsInitialized(true);
|
|
364
|
-
}, [
|
|
323
|
+
}, [hasFullData, roots, isInitialized, buildStackFromPath, findNodeKeyForUrl, tryConnectStack, resolveRef]);
|
|
365
324
|
|
|
366
325
|
/**
|
|
367
326
|
* Save state whenever navigation changes
|
|
@@ -575,6 +534,7 @@ export default function NestedSideBar() {
|
|
|
575
534
|
* Handle drilling down into an item with children
|
|
576
535
|
*/
|
|
577
536
|
const handleDrillDown = (node: NavNode, nodeKey: string | null) => {
|
|
537
|
+
if (!hasFullData) return;
|
|
578
538
|
if (node.pages && node.pages.length > 0) {
|
|
579
539
|
setSlideDirection('forward');
|
|
580
540
|
setAnimationKey((prev) => prev + 1);
|
|
@@ -590,7 +550,7 @@ export default function NestedSideBar() {
|
|
|
590
550
|
* Navigate back one level
|
|
591
551
|
*/
|
|
592
552
|
const navigateBack = () => {
|
|
593
|
-
if (navigationStack.length > 1) {
|
|
553
|
+
if (hasFullData && navigationStack.length > 1) {
|
|
594
554
|
setSlideDirection('backward');
|
|
595
555
|
setAnimationKey((prev) => prev + 1);
|
|
596
556
|
setNavigationStack(navigationStack.slice(0, -1));
|
|
@@ -604,7 +564,7 @@ export default function NestedSideBar() {
|
|
|
604
564
|
* Navigate to a specific level in the stack
|
|
605
565
|
*/
|
|
606
566
|
const navigateToLevel = (levelIndex: number) => {
|
|
607
|
-
if (levelIndex < navigationStack.length - 1) {
|
|
567
|
+
if (hasFullData && levelIndex < navigationStack.length - 1) {
|
|
608
568
|
setSlideDirection('backward');
|
|
609
569
|
setAnimationKey((prev) => prev + 1);
|
|
610
570
|
setNavigationStack(navigationStack.slice(0, levelIndex + 1));
|
|
@@ -634,6 +594,7 @@ export default function NestedSideBar() {
|
|
|
634
594
|
* Navigate to a favorited item
|
|
635
595
|
*/
|
|
636
596
|
const navigateToFavorite = (favorite: FavoriteItem) => {
|
|
597
|
+
if (!hasFullData) return;
|
|
637
598
|
// If it has an href and no children, just navigate to the URL
|
|
638
599
|
const node = resolveRef(favorite.nodeKey);
|
|
639
600
|
if (favorite.href && (!node?.pages || node.pages.length === 0)) {
|
|
@@ -107,6 +107,8 @@ export const saveCollapsedSections = (preferences: SectionCollapsePreferences):
|
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
export const loadCollapsedSections = (): SectionCollapsePreferences => {
|
|
110
|
+
// Rendered on the server for the first paint, where there is nothing saved yet
|
|
111
|
+
if (typeof localStorage === 'undefined') return createSectionCollapsePreferences();
|
|
110
112
|
try {
|
|
111
113
|
const stored = localStorage.getItem(SECTION_PREFERENCES_KEY);
|
|
112
114
|
if (stored) {
|
|
@@ -1,9 +1,130 @@
|
|
|
1
1
|
// Shared utilities for NestedSideBar components
|
|
2
2
|
|
|
3
|
-
import type { NavNode } from '@stores/sidebar-store/state';
|
|
3
|
+
import type { ChildRef, NavigationData, NavNode } from '@stores/sidebar-store/state';
|
|
4
4
|
|
|
5
5
|
export const SIDEBAR_GROUP_COLLAPSE_THRESHOLD = 5;
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Strip the configured base path from a pathname so URL pattern matching works
|
|
9
|
+
* regardless of the base path setting (e.g. `/eventcatalog/docs/...` → `/docs/...`).
|
|
10
|
+
*/
|
|
11
|
+
export const stripBasePath = (pathname: string): string => {
|
|
12
|
+
const base = __EC_BASE__.replace(/\/$/, ''); // e.g. '/eventcatalog'
|
|
13
|
+
if (base && pathname.startsWith(base)) {
|
|
14
|
+
return pathname.slice(base.length) || '/';
|
|
15
|
+
}
|
|
16
|
+
return pathname;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type NavigationLevel = {
|
|
20
|
+
key: string | null; // The key of the node that was drilled into (null for root)
|
|
21
|
+
entries: ChildRef[];
|
|
22
|
+
title: string;
|
|
23
|
+
badge?: string; // Category badge (e.g., "Domain", "Service")
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const rootLevel = (roots: ChildRef[]): NavigationLevel => ({ key: null, entries: roots, title: 'Documentation' });
|
|
27
|
+
|
|
28
|
+
/** Resolve a child reference to a node, following unversioned aliases (string → key). */
|
|
29
|
+
export const resolveNavRef = (nodes: NavigationData['nodes'], ref: ChildRef): NavNode | null => {
|
|
30
|
+
if (typeof ref !== 'string') return ref;
|
|
31
|
+
const node = nodes[ref];
|
|
32
|
+
if (!node) return null;
|
|
33
|
+
if (typeof node === 'string') return (nodes[node] as NavNode) ?? null;
|
|
34
|
+
return node;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Map of "type:id" → versioned node key, used to match URLs to nodes. */
|
|
38
|
+
export const buildNodeLookup = (nodes: NavigationData['nodes']): Map<string, string> => {
|
|
39
|
+
const lookup = new Map<string, string>();
|
|
40
|
+
|
|
41
|
+
Object.entries(nodes).forEach(([key, value]) => {
|
|
42
|
+
// Skip keys that are references (string values pointing to other keys)
|
|
43
|
+
// These are unversioned aliases like "domain:E-Commerce" -> "domain:E-Commerce:1.0.0"
|
|
44
|
+
if (typeof value === 'string') return;
|
|
45
|
+
|
|
46
|
+
// Key formats:
|
|
47
|
+
// - "type:id:version" (e.g., "service:OrdersService:0.0.3")
|
|
48
|
+
// - "type:id" (e.g., "user:john", "team:backend") - non-versioned resources
|
|
49
|
+
// - "list:name" (e.g., "list:domains") - skip these
|
|
50
|
+
const parts = key.split(':');
|
|
51
|
+
|
|
52
|
+
// Skip list items
|
|
53
|
+
if (parts[0] === 'list') return;
|
|
54
|
+
|
|
55
|
+
if (parts.length >= 2) {
|
|
56
|
+
// Store as "type:id"
|
|
57
|
+
lookup.set(`${parts[0]}:${parts[1]}`, key);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return lookup;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* What the sidebar shows for a URL before it knows the reader's saved drill-down path:
|
|
66
|
+
* the root level on the homepage or for pages without children, otherwise the matching
|
|
67
|
+
* resource's own level (the same "flattened" stack the client falls back to).
|
|
68
|
+
*/
|
|
69
|
+
export const getStackForUrl = (
|
|
70
|
+
url: string,
|
|
71
|
+
data: NavigationData,
|
|
72
|
+
nodeLookup: ReadonlyMap<string, string> = buildNodeLookup(data.nodes)
|
|
73
|
+
): NavigationLevel[] => {
|
|
74
|
+
const root = rootLevel(data.roots);
|
|
75
|
+
if (url === '/' || url === '') return [root];
|
|
76
|
+
|
|
77
|
+
const targetKey = findNodeKeyByUrl(url, data.nodes, nodeLookup);
|
|
78
|
+
const target = targetKey ? resolveNavRef(data.nodes, targetKey) : null;
|
|
79
|
+
if (!targetKey || !target?.pages?.length) return [root];
|
|
80
|
+
|
|
81
|
+
return [root, { key: targetKey, entries: target.pages, title: target.title, badge: target.badge }];
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Everything the sidebar needs to render one page's level, without the whole catalog: the
|
|
86
|
+
* stack for the URL and only the nodes that level shows (its items, and the contents of its
|
|
87
|
+
* groups). Rendered on the server so the sidebar appears with the HTML, and handed to the
|
|
88
|
+
* island so it keeps showing it until the full navigation data loads.
|
|
89
|
+
*/
|
|
90
|
+
export type SidebarSnapshot = {
|
|
91
|
+
url: string;
|
|
92
|
+
stack: NavigationLevel[];
|
|
93
|
+
data: NavigationData;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const nodeLookupCache = new WeakMap<NavigationData, Map<string, string>>();
|
|
97
|
+
|
|
98
|
+
export const buildSidebarSnapshot = (data: NavigationData, url: string): SidebarSnapshot => {
|
|
99
|
+
let nodeLookup = nodeLookupCache.get(data);
|
|
100
|
+
if (!nodeLookup) {
|
|
101
|
+
nodeLookup = buildNodeLookup(data.nodes);
|
|
102
|
+
nodeLookupCache.set(data, nodeLookup);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const stack = getStackForUrl(url, data, nodeLookup);
|
|
106
|
+
const level = stack[stack.length - 1];
|
|
107
|
+
const nodes: NavigationData['nodes'] = {};
|
|
108
|
+
|
|
109
|
+
const include = (ref: ChildRef) => {
|
|
110
|
+
if (typeof ref === 'string') {
|
|
111
|
+
if (ref in nodes) return;
|
|
112
|
+
const value = data.nodes[ref];
|
|
113
|
+
if (value === undefined) return;
|
|
114
|
+
nodes[ref] = value;
|
|
115
|
+
if (typeof value === 'string' && data.nodes[value] !== undefined) nodes[value] = data.nodes[value];
|
|
116
|
+
}
|
|
117
|
+
const node = resolveNavRef(data.nodes, ref);
|
|
118
|
+
// Groups render their children inline; items with children only need their own node
|
|
119
|
+
if (node?.type === 'group') node.pages?.forEach(include);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
if (level.key) include(level.key);
|
|
123
|
+
level.entries.forEach(include);
|
|
124
|
+
|
|
125
|
+
return { url, stack, data: { roots: data.roots, nodes } };
|
|
126
|
+
};
|
|
127
|
+
|
|
7
128
|
/**
|
|
8
129
|
* The user's overrides of each group's default collapse state, keyed by group id.
|
|
9
130
|
* A group is in at most one set; absence means "use the group's default".
|
|
@@ -3,10 +3,18 @@ import type { HTMLAttributes } from 'astro/types';
|
|
|
3
3
|
|
|
4
4
|
interface Props extends Omit<HTMLAttributes<'div'>, 'children'> {}
|
|
5
5
|
import NestedSideBar from './NestedSideBar';
|
|
6
|
+
import { buildSidebarSnapshot, stripBasePath } from './NestedSideBar/utils';
|
|
7
|
+
import { getNestedSideBarData } from '@stores/sidebar-store/state';
|
|
6
8
|
import { ClientRouter } from 'astro:transitions';
|
|
9
|
+
|
|
10
|
+
// Render this page's sidebar level into the HTML so it shows before any JavaScript runs;
|
|
11
|
+
// the full navigation still loads from /api/sidebar-data.json (see SearchDataLoader)
|
|
12
|
+
const snapshot = buildSidebarSnapshot(await getNestedSideBarData(), stripBasePath(Astro.url.pathname));
|
|
7
13
|
---
|
|
8
14
|
|
|
9
15
|
<div {...Astro.props}>
|
|
10
16
|
<ClientRouter />
|
|
11
|
-
<NestedSideBar client:only="react"
|
|
17
|
+
<NestedSideBar client:only="react" snapshot={snapshot}>
|
|
18
|
+
<NestedSideBar slot="fallback" snapshot={snapshot} />
|
|
19
|
+
</NestedSideBar>
|
|
12
20
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import catalog from '@utils/eventcatalog-config/catalog';
|
|
3
3
|
import { isDevMode } from '@utils/feature';
|
|
4
|
-
import { getLicenseDaysLeft, getTrialStatus,
|
|
4
|
+
import { BUY_BUSINESS_URL, getLicenseDaysLeft, getTrialStatus, TRIAL_LENGTH_DAYS } from '@utils/trial';
|
|
5
5
|
import { getLicenseStatus } from '@utils/license';
|
|
6
6
|
import { buildUrl } from '@utils/url-builder';
|
|
7
7
|
|
|
@@ -29,20 +29,17 @@ const title = licenseExpired
|
|
|
29
29
|
: licenseDaysLeft !== undefined
|
|
30
30
|
? `Your EventCatalog commercial license expires on ${licensedUntil?.toLocaleDateString()}. Renew it to keep using EventCatalog commercially.`
|
|
31
31
|
: trial?.ended
|
|
32
|
-
? `Your ${TRIAL_LENGTH_DAYS}-day EventCatalog trial ended on ${trial.endsAt.toLocaleDateString()}.
|
|
33
|
-
: `You're on a ${TRIAL_LENGTH_DAYS}-day EventCatalog trial, ending on ${trial?.endsAt.toLocaleDateString()}.
|
|
32
|
+
? `Your ${TRIAL_LENGTH_DAYS}-day EventCatalog trial ended on ${trial.endsAt.toLocaleDateString()}. See your license settings.`
|
|
33
|
+
: `You're on a ${TRIAL_LENGTH_DAYS}-day EventCatalog trial, ending on ${trial?.endsAt.toLocaleDateString()}. See your license settings.`;
|
|
34
34
|
const warning = licenseExpired || licenseDaysLeft !== undefined || trial?.ended;
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
const href = isLicense ? buildUrl('/settings/license') : LICENSE_FAQ_URL;
|
|
35
|
+
// The badge opens Settings > License, where the license is renewed or bought
|
|
36
|
+
const href = buildUrl('/settings/license');
|
|
38
37
|
---
|
|
39
38
|
|
|
40
39
|
{
|
|
41
40
|
(licenseExpired || licenseDaysLeft !== undefined || trial) && (
|
|
42
41
|
<a
|
|
43
42
|
href={href}
|
|
44
|
-
target={isLicense ? undefined : '_blank'}
|
|
45
|
-
rel={isLicense ? undefined : 'noopener noreferrer'}
|
|
46
43
|
title={title}
|
|
47
44
|
data-trial-ended={trial?.ended ? 'true' : undefined}
|
|
48
45
|
data-license-expired={licenseExpired ? 'true' : undefined}
|
|
@@ -50,7 +47,7 @@ const href = isLicense ? buildUrl('/settings/license') : LICENSE_FAQ_URL;
|
|
|
50
47
|
'inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-xs font-medium transition-colors',
|
|
51
48
|
warning
|
|
52
49
|
? 'border-[rgb(var(--ec-badge-color-amber-text)/0.3)] bg-[rgb(var(--ec-badge-color-amber-background))] text-[rgb(var(--ec-badge-color-amber-text))] hover:opacity-90'
|
|
53
|
-
: 'border-
|
|
50
|
+
: 'border-transparent bg-[rgb(var(--ec-page-text))] text-[rgb(var(--ec-page-bg))] hover:opacity-85',
|
|
54
51
|
]}
|
|
55
52
|
>
|
|
56
53
|
<svg
|
|
@@ -80,3 +77,17 @@ const href = isLicense ? buildUrl('/settings/license') : LICENSE_FAQ_URL;
|
|
|
80
77
|
</a>
|
|
81
78
|
)
|
|
82
79
|
}
|
|
80
|
+
{
|
|
81
|
+
/* Once the trial has ended, a link to buy the Business plan sits next to the badge */
|
|
82
|
+
trial?.ended && (
|
|
83
|
+
<a
|
|
84
|
+
href={BUY_BUSINESS_URL}
|
|
85
|
+
target="_blank"
|
|
86
|
+
rel="noopener noreferrer"
|
|
87
|
+
data-buy-business="true"
|
|
88
|
+
class="inline-flex items-center whitespace-nowrap rounded-full border border-transparent bg-[rgb(var(--ec-page-text))] px-2.5 py-1 text-xs font-medium text-[rgb(var(--ec-page-bg))] transition-opacity hover:opacity-85"
|
|
89
|
+
>
|
|
90
|
+
Buy Business
|
|
91
|
+
</a>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
@@ -502,7 +502,24 @@ const agents = defineCollection({
|
|
|
502
502
|
),
|
|
503
503
|
});
|
|
504
504
|
|
|
505
|
-
|
|
505
|
+
// ADRs need a status and a date, and say so when they're missing or invalid. Astro's own message for
|
|
506
|
+
// a missing or unreadable date was "Expected type date, received object", with the field name garbled.
|
|
507
|
+
const adrStatus = z.enum(ADR_STATUS_VALUES, {
|
|
508
|
+
error: (issue) =>
|
|
509
|
+
issue.input === undefined ? `Required: one of ${ADR_STATUS_VALUES.map((value) => `"${value}"`).join(', ')}` : undefined,
|
|
510
|
+
});
|
|
511
|
+
const adrDate = z.preprocess(
|
|
512
|
+
// Converted to a date only when it's set: a missing date coerced first became an invalid date
|
|
513
|
+
(value) => (value == null ? value : new Date(value as string | number | Date)),
|
|
514
|
+
z.date({
|
|
515
|
+
error: (issue) =>
|
|
516
|
+
issue.input === undefined
|
|
517
|
+
? 'Required: a date, e.g. 2026-06-01'
|
|
518
|
+
: issue.input instanceof Date
|
|
519
|
+
? 'Invalid date: use a date, e.g. 2026-06-01'
|
|
520
|
+
: undefined,
|
|
521
|
+
})
|
|
522
|
+
);
|
|
506
523
|
|
|
507
524
|
const adrPointer = z.object({
|
|
508
525
|
id: z.string(),
|
|
@@ -539,7 +556,7 @@ const adrs = defineCollection({
|
|
|
539
556
|
z
|
|
540
557
|
.object({
|
|
541
558
|
status: adrStatus,
|
|
542
|
-
date:
|
|
559
|
+
date: adrDate,
|
|
543
560
|
decisionMakers: z.array(ownerReference).optional(),
|
|
544
561
|
appliesTo: z.array(adrResourcePointer).optional(),
|
|
545
562
|
supersedes: z.array(adrPointer).optional(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import '../../styles/tailwind.css';
|
|
3
|
+
import { formatPageTitle } from '@utils/page-title';
|
|
3
4
|
// src/pages/auth/error.astro
|
|
4
5
|
|
|
5
6
|
const { searchParams } = new URL(Astro.request.url);
|
|
@@ -14,6 +15,7 @@ const errorMessages = {
|
|
|
14
15
|
|
|
15
16
|
// @ts-ignore
|
|
16
17
|
const errorMessage = errorMessages[error] || errorMessages.Default;
|
|
18
|
+
const pageTitle = formatPageTitle('Authentication Error');
|
|
17
19
|
---
|
|
18
20
|
|
|
19
21
|
<!doctype html>
|
|
@@ -25,10 +27,10 @@ const errorMessage = errorMessages[error] || errorMessages.Default;
|
|
|
25
27
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
26
28
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
27
29
|
<meta name="generator" content={Astro.generator} />
|
|
28
|
-
<title>
|
|
30
|
+
<title>{pageTitle}</title>
|
|
29
31
|
</head>
|
|
30
32
|
<body>
|
|
31
|
-
<main title=
|
|
33
|
+
<main title={pageTitle}>
|
|
32
34
|
<div class="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
33
35
|
<div class="max-w-md w-full space-y-8 text-center">
|
|
34
36
|
<div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import '../../styles/tailwind.css';
|
|
3
3
|
import config from '@config';
|
|
4
|
+
import { formatPageTitle } from '@utils/page-title';
|
|
4
5
|
const { title, logo } = config;
|
|
5
6
|
import { join } from 'node:path';
|
|
6
7
|
import { isAuthEnabled, isSSR } from '@utils/feature';
|
|
@@ -106,7 +107,7 @@ const providerConfig = {
|
|
|
106
107
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
107
108
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
108
109
|
<meta name="generator" content={Astro.generator} />
|
|
109
|
-
<title>Sign In
|
|
110
|
+
<title>{formatPageTitle('Sign In')}</title>
|
|
110
111
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
111
112
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
112
113
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
@@ -96,6 +96,14 @@ export function isMcpRoute(pathname: string) {
|
|
|
96
96
|
return pathname === '/docs/mcp' || pathname.startsWith('/docs/mcp/');
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// The Studio API answers in JSON, rather than sending callers to the sign-in page
|
|
100
|
+
const isStudioApiRoute = (pathname: string) => pathname === '/api/studio' || pathname.startsWith('/api/studio/');
|
|
101
|
+
const signInRequired = () =>
|
|
102
|
+
new Response(JSON.stringify({ error: 'Sign in to use this API' }), {
|
|
103
|
+
status: 401,
|
|
104
|
+
headers: { 'Content-Type': 'application/json' },
|
|
105
|
+
});
|
|
106
|
+
|
|
99
107
|
export const authMiddleware: MiddlewareHandler = async (context, next) => {
|
|
100
108
|
const { request, redirect, locals } = context;
|
|
101
109
|
const url = new URL(request.url);
|
|
@@ -131,6 +139,7 @@ export const authMiddleware: MiddlewareHandler = async (context, next) => {
|
|
|
131
139
|
const session = await getSession(request);
|
|
132
140
|
|
|
133
141
|
if (!session) {
|
|
142
|
+
if (isStudioApiRoute(pathname)) return signInRequired();
|
|
134
143
|
const callbackUrl = encodeURIComponent(pathname + url.search);
|
|
135
144
|
return redirect(`/auth/login?callbackUrl=${callbackUrl}`);
|
|
136
145
|
}
|
|
@@ -157,6 +166,7 @@ export const authMiddleware: MiddlewareHandler = async (context, next) => {
|
|
|
157
166
|
typedLocals.matchesPattern = matchesPattern;
|
|
158
167
|
} catch (error) {
|
|
159
168
|
console.error('Session error:', error);
|
|
169
|
+
if (isStudioApiRoute(pathname)) return signInRequired();
|
|
160
170
|
const callbackUrl = encodeURIComponent(pathname + url.search);
|
|
161
171
|
return redirect(`/auth/login?callbackUrl=${callbackUrl}`);
|
|
162
172
|
}
|
|
@@ -194,12 +204,22 @@ function normalizeUserData(session: any): NormalizedUser {
|
|
|
194
204
|
}
|
|
195
205
|
}
|
|
196
206
|
|
|
207
|
+
// The host of a token's issuer (e.g. `dev-123.okta.com`), or '' when it isn't a URL
|
|
208
|
+
const issuerHost = (issuer: unknown) => {
|
|
209
|
+
try {
|
|
210
|
+
return new URL(String(issuer)).hostname;
|
|
211
|
+
} catch {
|
|
212
|
+
return '';
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
197
216
|
function detectProvider(session: any): string {
|
|
198
217
|
const account = session.account;
|
|
199
218
|
if (account?.provider) return account.provider;
|
|
200
219
|
|
|
201
220
|
if (session.user?.sub?.startsWith('auth0|')) return 'auth0';
|
|
202
|
-
|
|
221
|
+
const host = issuerHost(session.user?.iss);
|
|
222
|
+
if (host === 'okta.com' || host.endsWith('.okta.com') || session.user?.provider?.includes('okta')) return 'okta';
|
|
203
223
|
if (session.user?.iss?.includes('microsoft')) return 'microsoft';
|
|
204
224
|
if (session.user?.iss?.includes('google')) return 'google';
|
|
205
225
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<VerticalSideBarLayout title="Unauthorized
|
|
5
|
+
<VerticalSideBarLayout title="Unauthorized" showNestedSideBar={false}>
|
|
6
6
|
<div class="flex h-[calc(100vh-120px)] bg-white">
|
|
7
7
|
<main class="flex w-full items-center justify-center bg-white text-center sm:p-12">
|
|
8
8
|
<div class="w-full max-w-xl text-center">
|
|
@@ -7,7 +7,7 @@ import FieldsExplorer from '@components/FieldsExplorer/FieldsExplorer';
|
|
|
7
7
|
export const prerender = false;
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
<VerticalSideBarLayout title="Fields Explorer
|
|
10
|
+
<VerticalSideBarLayout title="Fields Explorer" showNestedSideBar={false}>
|
|
11
11
|
<style is:global>
|
|
12
12
|
#eventcatalog-header {
|
|
13
13
|
left: calc(var(--ec-vertical-nav-width, 14rem) + var(--ec-fields-sidebar-width, 320px)) !important;
|
|
@@ -176,24 +176,30 @@ export default function eventCatalogIntegration(): AstroIntegration {
|
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
//
|
|
179
|
+
// What a server starts before anyone asks for it (the storage configured, migrated; Studio), called by
|
|
180
|
+
// `eventcatalog start` once it listens
|
|
181
|
+
if (isSSR()) {
|
|
182
|
+
params.injectRoute({
|
|
183
|
+
pattern: '/_eventcatalog/start',
|
|
184
|
+
entrypoint: path.join(packageDirectory, 'src/features/server/start.ts'),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Collaborative canvases in EventCatalog Studio (/studio lists them, /studio?new=1 starts one). Their WebSocket
|
|
180
189
|
// server is in integrations/studio-server.mjs.
|
|
181
190
|
if (isCanvasEnabled()) {
|
|
182
191
|
params.injectRoute({
|
|
183
192
|
pattern: '/studio',
|
|
184
193
|
entrypoint: path.join(packageDirectory, 'src/features/studio/pages/index.astro'),
|
|
185
194
|
});
|
|
186
|
-
params.injectRoute({
|
|
187
|
-
pattern: '/studio/new',
|
|
188
|
-
entrypoint: path.join(packageDirectory, 'src/features/studio/pages/new.astro'),
|
|
189
|
-
});
|
|
190
195
|
params.injectRoute({
|
|
191
196
|
pattern: '/studio/[id]',
|
|
192
197
|
entrypoint: path.join(packageDirectory, 'src/features/studio/pages/[id].astro'),
|
|
193
198
|
});
|
|
199
|
+
// The Studio API (canvases as a whole: listing, creating, deleting)
|
|
194
200
|
params.injectRoute({
|
|
195
|
-
pattern: '/
|
|
196
|
-
entrypoint: path.join(packageDirectory, 'src/features/studio/
|
|
201
|
+
pattern: '/api/studio/canvases/[...path]',
|
|
202
|
+
entrypoint: path.join(packageDirectory, 'src/features/studio/api/canvases.ts'),
|
|
197
203
|
});
|
|
198
204
|
params.injectRoute({
|
|
199
205
|
pattern: '/webmcp-relay/[file]',
|