@eventcatalog/core 5.0.0-beta.3 → 5.0.0-beta.30
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 +160 -77
- 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-6OC46WQJ.js → chunk-55QETQZ3.js} +66 -35
- package/dist/{chunk-TQLRG35T.js → chunk-AD7CL772.js} +78 -45
- package/dist/chunk-CA6WCQ2T.js +54 -0
- package/dist/chunk-CPW6G62V.js +17 -0
- package/dist/{chunk-423S2KHN.js → chunk-FLAZ2JVN.js} +4 -2
- package/dist/{chunk-BH2F5WPN.js → chunk-GQI5UYXZ.js} +1 -1
- package/dist/{chunk-GYIVJXOJ.js → chunk-NA7OTBWW.js} +1 -1
- package/dist/{chunk-MDWB5HLO.js → chunk-NKNOXQ62.js} +1 -1
- package/dist/{chunk-3PKS2IIP.js → chunk-OX6TSVHY.js} +1 -1
- package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
- package/dist/chunk-S5GWAUG5.js +29 -0
- package/dist/{chunk-NDJOAITI.js → chunk-T3OROMAU.js} +9 -3
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- 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 +531 -356
- package/dist/eventcatalog.config.d.cts +59 -1
- package/dist/eventcatalog.config.d.ts +59 -1
- package/dist/eventcatalog.js +63 -25
- package/dist/features.cjs +34 -41
- package/dist/features.js +2 -2
- package/dist/federation/federate.cjs +37 -44
- package/dist/federation/federate.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/@hocuspocus__provider.mjs +3 -0
- package/dist/runtime-dependencies/@hocuspocus__server.mjs +3 -0
- package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +3 -0
- package/dist/runtime-dependencies/@mcp-b__webmcp-polyfill.mjs +3 -0
- package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +13 -1
- package/dist/runtime-dependencies/react-hotkeys-hook.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
- package/dist/runtime-dependencies/y-protocols.mjs +3 -0
- package/dist/runtime-dependencies/y-protocols__awareness.mjs +3 -0
- package/dist/runtime-dependencies/yjs.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 +78 -45
- package/dist/utils/license-status.d.cts +15 -5
- package/dist/utils/license-status.d.ts +15 -5
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/astro.config.mjs +23 -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 +32 -0
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
- package/eventcatalog/src/components/Header.astro +3 -3
- 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 +53 -83
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +131 -0
- 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 +10 -0
- 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 +34 -1
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +47 -0
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +24 -0
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +278 -0
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +272 -0
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +65 -65
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +2 -1
- package/eventcatalog/src/features/mcp/mcp-apps.ts +6 -3
- package/eventcatalog/src/features/mcp/mcp-server.ts +36 -5
- 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 +384 -0
- 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 +540 -0
- package/eventcatalog/src/features/studio/canvas-preview.ts +52 -0
- package/eventcatalog/src/features/studio/catalog-resources.ts +155 -0
- package/eventcatalog/src/features/studio/catalog.ts +173 -0
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +518 -0
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +118 -0
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +434 -0
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +143 -0
- 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 +109 -0
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +206 -0
- 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 +293 -0
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +396 -0
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +2091 -0
- 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 +63 -0
- package/eventcatalog/src/features/studio/hooks/presence-store.ts +119 -0
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +353 -0
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +54 -0
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +109 -0
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +782 -0
- package/eventcatalog/src/features/studio/identity.ts +59 -0
- package/eventcatalog/src/features/studio/limits.ts +2 -0
- package/eventcatalog/src/features/studio/pages/[id].astro +69 -0
- package/eventcatalog/src/features/studio/pages/index.astro +784 -0
- package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +27 -0
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +495 -0
- package/eventcatalog/src/features/studio/server/runtime.ts +498 -0
- package/eventcatalog/src/features/studio/server/sign-in.ts +18 -0
- package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
- package/eventcatalog/src/features/studio/server/storage.ts +90 -0
- package/eventcatalog/src/features/studio/server/tool-icons.ts +30 -0
- package/eventcatalog/src/features/studio/tool-sync.ts +75 -0
- package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
- package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +13 -5
- 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 +1 -0
- 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/util.ts +8 -4
- package/eventcatalog/src/utils/feature.ts +8 -0
- package/eventcatalog/src/utils/git.ts +22 -5
- 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/export-mermaid.ts +0 -2
- 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 +14 -1
- package/package.json +19 -13
- package/dist/runtime-dependencies/shelljs.mjs +0 -3
- package/eventcatalog/public/studio-bg.png +0 -0
- package/eventcatalog/src/components/Studio/StudioPageModal.tsx +0 -150
- package/eventcatalog/src/pages/studio.astro +0 -316
|
@@ -84,7 +84,8 @@ export function useMcpAppView<Payload>(options: McpAppViewOptions<Payload>) {
|
|
|
84
84
|
setHostContext(context);
|
|
85
85
|
}, [app]);
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
// setPayload: views that switch what they show themselves (e.g. picking a canvas) without a new tool result
|
|
88
|
+
return { app, payload, setPayload, error: connectionError?.message ?? error, hostContext };
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
/** Adds the view's styles and renders it */
|
|
@@ -12,7 +12,7 @@ const mcpAppViews = import.meta.glob<string>('./apps/generated/*.html', { query:
|
|
|
12
12
|
export const getMcpAppViewLoader = (name: string) => mcpAppViews[`./apps/generated/${name}.html`];
|
|
13
13
|
|
|
14
14
|
/** Tool `_meta` telling MCP hosts that support MCP Apps to show the tool's result in a view */
|
|
15
|
-
const appViewMeta = (resourceUri: string, visibility?: Array<'model' | 'app'>) => ({
|
|
15
|
+
export const appViewMeta = (resourceUri: string, visibility?: Array<'model' | 'app'>) => ({
|
|
16
16
|
ui: { resourceUri, ...(visibility && { visibility }) },
|
|
17
17
|
[RESOURCE_URI_META_KEY]: resourceUri,
|
|
18
18
|
});
|
|
@@ -38,6 +38,8 @@ type ToolDefinition<Shape extends z.ZodRawShape> = {
|
|
|
38
38
|
description: string;
|
|
39
39
|
/** The tool's arguments, as a Zod shape */
|
|
40
40
|
input: Shape;
|
|
41
|
+
/** More `_meta` for the tool, e.g. host extensions such as ChatGPT's `openai/ui` entrypoints */
|
|
42
|
+
meta?: Record<string, unknown>;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export type McpAppDefinition<Shape extends z.ZodRawShape, ViewShape extends z.ZodRawShape, Payload> = {
|
|
@@ -47,7 +49,8 @@ export type McpAppDefinition<Shape extends z.ZodRawShape, ViewShape extends z.Zo
|
|
|
47
49
|
name: string;
|
|
48
50
|
uri: string;
|
|
49
51
|
description: string;
|
|
50
|
-
|
|
52
|
+
/** Origins the view may load from (resourceDomains) and connect to with fetch or WebSockets (connectDomains) */
|
|
53
|
+
csp?: { resourceDomains?: string[]; connectDomains?: string[] };
|
|
51
54
|
/** How hosts open the view: ChatGPT reads these before loading it, so it can open straight in that mode */
|
|
52
55
|
displayModes?: { preferred: McpUiDisplayMode; available: McpUiDisplayMode[] };
|
|
53
56
|
};
|
|
@@ -110,7 +113,7 @@ export function registerMcpApp<Shape extends z.ZodRawShape, ViewShape extends z.
|
|
|
110
113
|
description: app.tool.description,
|
|
111
114
|
inputSchema: toolInput,
|
|
112
115
|
annotations: app.annotations,
|
|
113
|
-
_meta: loadView ? appViewMeta(app.resource.uri) : undefined,
|
|
116
|
+
_meta: loadView ? { ...appViewMeta(app.resource.uri), ...app.tool.meta } : undefined,
|
|
114
117
|
},
|
|
115
118
|
showInView
|
|
116
119
|
);
|
|
@@ -22,6 +22,9 @@ import { RESOURCE_VIEWS, VIEWER_META_KEY, VIEWER_RESOURCE_URI, VIEWER_VIEW_TOOL,
|
|
|
22
22
|
import { toSchemaViewerSchemas } from './schema-viewer';
|
|
23
23
|
import { getMcpAppViewLoader, mcpAppNote, registerMcpApp } from './mcp-apps';
|
|
24
24
|
import { buildUrl } from '@utils/url-builder';
|
|
25
|
+
import { isCanvasEnabled } from '@utils/feature';
|
|
26
|
+
import { CANVAS_TOOL_NAMES, registerCanvasTools } from '@features/studio/server/canvas-mcp';
|
|
27
|
+
import { startStudio } from '@features/studio/server/runtime';
|
|
25
28
|
|
|
26
29
|
const loadViewerView = getMcpAppViewLoader('viewer');
|
|
27
30
|
|
|
@@ -36,6 +39,10 @@ const SHOW_RESOURCE_DESCRIPTION = [
|
|
|
36
39
|
type McpServerOptions = {
|
|
37
40
|
/** Where this EventCatalog is served, for links from MCP App views back to it */
|
|
38
41
|
catalogUrl: string;
|
|
42
|
+
/** The MCP client's user agent, to name agents that join a canvas */
|
|
43
|
+
userAgent?: string;
|
|
44
|
+
/** Offer the canvas tools (by default when Studio is on, for the whole catalog) */
|
|
45
|
+
canvases?: boolean;
|
|
39
46
|
};
|
|
40
47
|
|
|
41
48
|
const catalogDirectory = process.env.PROJECT_DIR || process.cwd();
|
|
@@ -115,7 +122,10 @@ function getServerInstructions(scope?: McpScope) {
|
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
// Create MCP Server with tools that access Astro collections
|
|
118
|
-
function createMcpServer(
|
|
125
|
+
function createMcpServer(
|
|
126
|
+
scope: McpScope | undefined,
|
|
127
|
+
{ catalogUrl, userAgent, canvases = !scope && isCanvasEnabled() }: McpServerOptions
|
|
128
|
+
) {
|
|
119
129
|
const server = new McpServer(
|
|
120
130
|
{
|
|
121
131
|
name: scope ? `EventCatalog MCP Server — ${scope.name} ${scope.ref.kind}` : 'EventCatalog MCP Server',
|
|
@@ -396,7 +406,7 @@ function createMcpServer(scope: McpScope | undefined, { catalogUrl }: McpServerO
|
|
|
396
406
|
if (resource.error !== undefined) return { error: resource.error };
|
|
397
407
|
|
|
398
408
|
const schemas = await tools.getSchemaForResource({ ...params, resourceVersion: resource.version });
|
|
399
|
-
if ('error' in schemas) return schemas;
|
|
409
|
+
if ('error' in schemas && schemas.error !== undefined) return { error: schemas.error };
|
|
400
410
|
|
|
401
411
|
return {
|
|
402
412
|
resource: {
|
|
@@ -831,6 +841,9 @@ function createMcpServer(scope: McpScope | undefined, { catalogUrl }: McpServerO
|
|
|
831
841
|
);
|
|
832
842
|
}
|
|
833
843
|
|
|
844
|
+
// Collaborative canvases (when the collaboration server runs in this process)
|
|
845
|
+
if (canvases) registerCanvasTools(server, { catalogUrl, userAgent });
|
|
846
|
+
|
|
834
847
|
return server;
|
|
835
848
|
}
|
|
836
849
|
|
|
@@ -964,7 +977,9 @@ const handleGetRequest = async (c: Context, kind?: McpScopeKind) => {
|
|
|
964
977
|
version: MCP_SERVER_VERSION,
|
|
965
978
|
status: 'running',
|
|
966
979
|
...(scope && { scope: scope.ref }),
|
|
967
|
-
tools: scope
|
|
980
|
+
tools: scope
|
|
981
|
+
? getScopedBuiltInTools(scope)
|
|
982
|
+
: [...globalBuiltInTools, ...(isCanvasEnabled() ? CANVAS_TOOL_NAMES : []), ...extendedToolNames],
|
|
968
983
|
extendedTools: !scope && extendedToolNames.length > 0 ? extendedToolNames : undefined,
|
|
969
984
|
resources: getMcpResourceUris(scope),
|
|
970
985
|
});
|
|
@@ -983,7 +998,23 @@ const handleMcpRequest = async (c: Context, kind?: McpScopeKind) => {
|
|
|
983
998
|
}
|
|
984
999
|
|
|
985
1000
|
const scope = await resolveRequestScope(c, kind);
|
|
986
|
-
|
|
1001
|
+
// Canvas tools work on Studio's canvases: started (storage loaded) before they're listed, and left out when
|
|
1002
|
+
// Studio isn't available (the rest of the catalog's tools still work)
|
|
1003
|
+
const canvases =
|
|
1004
|
+
!scope &&
|
|
1005
|
+
isCanvasEnabled() &&
|
|
1006
|
+
(await startStudio().then(
|
|
1007
|
+
() => true,
|
|
1008
|
+
(error) => {
|
|
1009
|
+
console.error(`[studio] Canvas tools are off: ${(error as Error).message}`);
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
));
|
|
1013
|
+
const server = createMcpServer(scope, {
|
|
1014
|
+
catalogUrl: new URL(c.req.url).origin,
|
|
1015
|
+
userAgent: c.req.header('user-agent'),
|
|
1016
|
+
canvases,
|
|
1017
|
+
});
|
|
987
1018
|
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
988
1019
|
sessionIdGenerator: undefined,
|
|
989
1020
|
});
|
|
@@ -1023,7 +1054,7 @@ app.post('/', (c: Context) => handleMcpRequest(c));
|
|
|
1023
1054
|
|
|
1024
1055
|
// Astro API route handler - delegates all requests to Hono
|
|
1025
1056
|
// Note: SSR checks are handled at build time by the integration
|
|
1026
|
-
// This route is only injected when isEventCatalogMCPEnabled() returns true
|
|
1057
|
+
// This route is only injected when isEventCatalogMCPEnabled() or isCanvasEnabled() returns true
|
|
1027
1058
|
export const ALL: APIRoute = async ({ request }) => {
|
|
1028
1059
|
return app.fetch(request);
|
|
1029
1060
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { APIRoute } from 'astro';
|
|
2
|
+
import { isCanvasEnabled } from '@utils/feature';
|
|
3
|
+
import { startStorage } from '../storage/database';
|
|
4
|
+
import { startStudio } from '../studio/server/runtime';
|
|
5
|
+
import { isSignedIn } from '../studio/server/sign-in';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What the server starts before anyone asks for it: `eventcatalog start` calls this once the server listens. Each
|
|
9
|
+
* feature that needs starting has its own start function, called here in order: the storage configured is opened and
|
|
10
|
+
* migrated first (features keep their state in it), then Studio (so tabs reconnecting after a restart find it
|
|
11
|
+
* ready). Under /_eventcatalog, which sign-in lets through (the server calls it without a session); it says nothing
|
|
12
|
+
* about what's stored.
|
|
13
|
+
*/
|
|
14
|
+
export const GET: APIRoute = async () => {
|
|
15
|
+
try {
|
|
16
|
+
await startStorage();
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error(`[eventcatalog] Could not open the database: ${(error as Error).message}`);
|
|
19
|
+
}
|
|
20
|
+
// Studio says why if it can't start
|
|
21
|
+
if (isCanvasEnabled()) await startStudio({ isSignedIn }).catch(() => {});
|
|
22
|
+
return new Response(null, { status: 204 });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const prerender = false;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import config from '../../utils/eventcatalog-config/source';
|
|
4
|
+
import type { Config } from '../../../../src/eventcatalog.config';
|
|
5
|
+
import { migrate, type Database } from './migrations';
|
|
6
|
+
import { namedStatements } from './sql';
|
|
7
|
+
import databaseSql from './sql/database.sql?raw';
|
|
8
|
+
|
|
9
|
+
/** `storage` in eventcatalog.config.js: memory (the default), or one SQLite database for the whole catalog */
|
|
10
|
+
export type StorageConfig = NonNullable<Config['storage']>;
|
|
11
|
+
export type StorageType = StorageConfig['type'];
|
|
12
|
+
export type { Database };
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_STORAGE: StorageConfig = { type: 'memory' };
|
|
15
|
+
const DEFAULT_DATABASE_PATH = '.eventcatalog/eventcatalog.db';
|
|
16
|
+
|
|
17
|
+
const SQL = namedStatements(databaseSql, ['useWriteAheadLog']);
|
|
18
|
+
|
|
19
|
+
/** The database file a config asks for (relative to the catalog), or undefined when state is kept in memory */
|
|
20
|
+
export const getDatabasePath = (storage: StorageConfig | undefined, projectDirectory: string) => {
|
|
21
|
+
const chosen = storage ?? DEFAULT_STORAGE;
|
|
22
|
+
switch (chosen.type) {
|
|
23
|
+
case 'memory':
|
|
24
|
+
return undefined;
|
|
25
|
+
case 'sqlite':
|
|
26
|
+
return path.resolve(projectDirectory, chosen.path ?? DEFAULT_DATABASE_PATH);
|
|
27
|
+
default:
|
|
28
|
+
throw new Error(`Unknown storage type "${(chosen as { type?: string }).type}": use "memory" or "sqlite"`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const open = async (file: string): Promise<Database> => {
|
|
33
|
+
// Node's built-in SQLite (no native package to install), asked of Node itself: the dev server loads this through
|
|
34
|
+
// Vite, which doesn't know node:sqlite and fails to import it
|
|
35
|
+
type Sqlite = { DatabaseSync: new (file: string) => Database };
|
|
36
|
+
const getBuiltinModule = (process as { getBuiltinModule?: (id: string) => unknown }).getBuiltinModule;
|
|
37
|
+
let sqlite: Sqlite | undefined;
|
|
38
|
+
try {
|
|
39
|
+
sqlite = getBuiltinModule
|
|
40
|
+
? (getBuiltinModule('node:sqlite') as Sqlite | undefined)
|
|
41
|
+
: await import(/* @vite-ignore */ ['node', 'sqlite'].join(':'));
|
|
42
|
+
} catch (error) {
|
|
43
|
+
throw new Error(`Could not load node:sqlite (${(error as Error).message})`);
|
|
44
|
+
}
|
|
45
|
+
if (!sqlite?.DatabaseSync) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`SQLite storage needs Node.js 22.13 or later (it uses node:sqlite); this is Node.js ${process.versions.node}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
51
|
+
const database = new sqlite.DatabaseSync(file);
|
|
52
|
+
database.exec(SQL.useWriteAheadLog);
|
|
53
|
+
migrate(database);
|
|
54
|
+
return database;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Opened once per process, by file (kept on globalThis: the dev server's integrations and the app load this module
|
|
58
|
+
// separately, and code reloads in dev keep globalThis)
|
|
59
|
+
const DATABASES = Symbol.for('eventcatalog.databases');
|
|
60
|
+
const store = globalThis as typeof globalThis & { [DATABASES]?: Map<string, Promise<Database>> };
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The database in `file`, brought up to date by the migrations: opened the first time it's asked for, then shared by
|
|
64
|
+
* every feature. Rejects (every time) if it can't be opened or migrated, e.g. when a newer EventCatalog updated it.
|
|
65
|
+
*/
|
|
66
|
+
export const openDatabase = (file: string): Promise<Database> => {
|
|
67
|
+
const databases = (store[DATABASES] ??= new Map());
|
|
68
|
+
let database = databases.get(file);
|
|
69
|
+
if (!database) {
|
|
70
|
+
database = open(file);
|
|
71
|
+
databases.set(file, database);
|
|
72
|
+
}
|
|
73
|
+
return database;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Opens the storage configured, running the migrations it needs. Called as the dev server and `eventcatalog start`
|
|
78
|
+
* start (not on build: builds often run somewhere other than where the database lives), so it's ready before any
|
|
79
|
+
* feature uses it. Returns the database file, or undefined when state is kept in memory.
|
|
80
|
+
*/
|
|
81
|
+
export const startStorage = async (projectDirectory = process.env.PROJECT_DIR || process.cwd()) => {
|
|
82
|
+
if ((config as { studio?: { storage?: unknown } }).studio?.storage) {
|
|
83
|
+
console.warn('[eventcatalog] studio.storage is no longer used: set storage in eventcatalog.config.js instead');
|
|
84
|
+
}
|
|
85
|
+
const file = getDatabasePath(config.storage, projectDirectory);
|
|
86
|
+
if (file) await openDatabase(file);
|
|
87
|
+
return file;
|
|
88
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { namedStatements } from './sql';
|
|
2
|
+
import runnerSql from './sql/migrations.sql?raw';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Changes to the database's schema, for every feature that keeps state, as .sql files in ./sql/migrations named
|
|
6
|
+
* `NNNN-what-it-does.sql` (one numbered order for the whole catalog; tables are named for their feature, e.g.
|
|
7
|
+
* `studio_canvases`). They run in order when the database opens, each once, recorded in its `migrations` table. To
|
|
8
|
+
* change the schema, add a file with the next number: never change one that has shipped, since databases out there have
|
|
9
|
+
* already run it.
|
|
10
|
+
*/
|
|
11
|
+
export type Migration = { version: number; name: string; sql: string };
|
|
12
|
+
|
|
13
|
+
/** The parts of node:sqlite's DatabaseSync EventCatalog uses */
|
|
14
|
+
export type Database = {
|
|
15
|
+
exec: (sql: string) => void;
|
|
16
|
+
prepare: (sql: string) => { run: (...values: unknown[]) => unknown; all: () => unknown[] };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Built into the server code (no files to find at runtime, wherever it's deployed)
|
|
20
|
+
const files = import.meta.glob<string>('./sql/migrations/*.sql', { query: '?raw', import: 'default', eager: true });
|
|
21
|
+
const SQL = namedStatements(runnerSql, ['createMigrationsTable', 'appliedVersions', 'recordMigration']);
|
|
22
|
+
|
|
23
|
+
/** Migrations from their files, in order (an error if a file is misnamed or two have the same number) */
|
|
24
|
+
export const toMigrations = (sources: Record<string, string>): Migration[] => {
|
|
25
|
+
const migrations = Object.entries(sources).map(([file, sql]) => {
|
|
26
|
+
const name = file
|
|
27
|
+
.split('/')
|
|
28
|
+
.pop()!
|
|
29
|
+
.replace(/\.sql$/, '');
|
|
30
|
+
const version = Number(/^(\d{4})-[a-z0-9-]+$/.exec(name)?.[1]);
|
|
31
|
+
if (!version) throw new Error(`Migration "${file}" should be named like 0003-what-it-does.sql`);
|
|
32
|
+
return { version, name, sql };
|
|
33
|
+
});
|
|
34
|
+
migrations.sort((a, b) => a.version - b.version);
|
|
35
|
+
migrations.forEach((migration, index) => {
|
|
36
|
+
if (migration.version !== index + 1) {
|
|
37
|
+
throw new Error(`Migrations should be numbered 1, 2, 3...: expected ${index + 1} before ${migration.name}`);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return migrations;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const MIGRATIONS = toMigrations(files);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The database was updated by a newer EventCatalog. Features don't fall back to memory for this (changes would quietly
|
|
47
|
+
* stop being saved): they aren't available until EventCatalog is updated. Told by its code, as the dev server's
|
|
48
|
+
* integrations and the app load this module separately.
|
|
49
|
+
*/
|
|
50
|
+
const DATABASE_TOO_NEW = 'EVENTCATALOG_DATABASE_TOO_NEW';
|
|
51
|
+
export const isDatabaseTooNew = (error: unknown) => (error as { code?: unknown } | null)?.code === DATABASE_TOO_NEW;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Brings a database up to date: runs the migrations it hasn't run yet, each in a transaction (all of it or none).
|
|
55
|
+
* Refuses a database that has run migrations this version doesn't know (made by a newer EventCatalog).
|
|
56
|
+
*/
|
|
57
|
+
export const migrate = (database: Database, migrations: Migration[] = MIGRATIONS) => {
|
|
58
|
+
database.exec(SQL.createMigrationsTable);
|
|
59
|
+
const applied = new Set(
|
|
60
|
+
(database.prepare(SQL.appliedVersions).all() as { version: number }[]).map((row) => Number(row.version))
|
|
61
|
+
);
|
|
62
|
+
const latest = migrations.at(-1)?.version ?? 0;
|
|
63
|
+
const newer = [...applied].filter((version) => version > latest);
|
|
64
|
+
if (newer.length) {
|
|
65
|
+
throw Object.assign(
|
|
66
|
+
new Error(
|
|
67
|
+
`The EventCatalog database has been updated by a newer EventCatalog (migration ${Math.max(...newer)}; this version knows up to ${latest}). Update EventCatalog to use it.`
|
|
68
|
+
),
|
|
69
|
+
{ code: DATABASE_TOO_NEW }
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const record = database.prepare(SQL.recordMigration);
|
|
73
|
+
for (const migration of migrations) {
|
|
74
|
+
if (applied.has(migration.version)) continue;
|
|
75
|
+
database.exec('BEGIN');
|
|
76
|
+
try {
|
|
77
|
+
database.exec(migration.sql);
|
|
78
|
+
record.run(migration.version, migration.name, Date.now());
|
|
79
|
+
database.exec('COMMIT');
|
|
80
|
+
} catch (error) {
|
|
81
|
+
database.exec('ROLLBACK');
|
|
82
|
+
throw new Error(`Could not run migration ${migration.name}: ${(error as Error).message}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- Statements run as the database opens (see database.ts), each named by the `-- name:` line above it.
|
|
2
|
+
|
|
3
|
+
-- name: useWriteAheadLog
|
|
4
|
+
-- Readers don't wait for writers (set as the database opens: it can't be changed inside a migration's transaction)
|
|
5
|
+
PRAGMA journal_mode = WAL;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Studio's canvases: each one's whole Yjs document (Y.encodeStateAsUpdate), and when it last changed.
|
|
2
|
+
CREATE TABLE studio_canvases (
|
|
3
|
+
name TEXT PRIMARY KEY,
|
|
4
|
+
state BLOB NOT NULL,
|
|
5
|
+
updated_at INTEGER NOT NULL
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
-- Studio canvases that were deleted, so a browser that still has one open can't bring it back.
|
|
9
|
+
CREATE TABLE studio_deleted_canvases (
|
|
10
|
+
name TEXT PRIMARY KEY,
|
|
11
|
+
deleted_at INTEGER NOT NULL
|
|
12
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- The statements the migration runner runs (see migrations.ts), each named by the `-- name:` line above it. Its own
|
|
2
|
+
-- table is made here rather than in a migration: it records which migrations have run, so it's needed before any do.
|
|
3
|
+
|
|
4
|
+
-- name: createMigrationsTable
|
|
5
|
+
CREATE TABLE IF NOT EXISTS migrations (
|
|
6
|
+
version INTEGER PRIMARY KEY,
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
applied_at INTEGER NOT NULL
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
-- name: appliedVersions
|
|
12
|
+
SELECT version FROM migrations;
|
|
13
|
+
|
|
14
|
+
-- name: recordMigration
|
|
15
|
+
INSERT INTO migrations (version, name, applied_at) VALUES (?, ?, ?);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statements kept in .sql files (./sql), each named by a `-- name: <name>` line above it. A file's statements are
|
|
3
|
+
* looked up by the names the code expects: a missing one is an error when the module loads, not when it's first run.
|
|
4
|
+
*/
|
|
5
|
+
export const namedStatements = <Name extends string>(source: string, names: readonly Name[]): Record<Name, string> => {
|
|
6
|
+
const statements = new Map<string, string>();
|
|
7
|
+
let current: { name: string; lines: string[] } | undefined;
|
|
8
|
+
const finish = () => {
|
|
9
|
+
if (current) statements.set(current.name, current.lines.join('\n').trim());
|
|
10
|
+
};
|
|
11
|
+
for (const line of source.split('\n')) {
|
|
12
|
+
const name = /^--\s*name:\s*(\S+)\s*$/.exec(line)?.[1];
|
|
13
|
+
if (name) {
|
|
14
|
+
finish();
|
|
15
|
+
current = { name, lines: [] };
|
|
16
|
+
} else {
|
|
17
|
+
current?.lines.push(line);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
finish();
|
|
21
|
+
return Object.fromEntries(
|
|
22
|
+
names.map((name) => {
|
|
23
|
+
const statement = statements.get(name);
|
|
24
|
+
if (!statement) throw new Error(`No SQL statement named "${name}"`);
|
|
25
|
+
return [name, statement];
|
|
26
|
+
})
|
|
27
|
+
) as Record<Name, string>;
|
|
28
|
+
};
|