@eventcatalog/core 5.0.0-beta.1 → 5.0.0-beta.11
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 +227 -128
- package/README.md +4 -4
- 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 +71 -35
- package/dist/analytics/log-build.js +5 -4
- 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/{chunk-KYJZJLBD.js → chunk-4YFM63DS.js} +9 -3
- package/dist/{chunk-UDS3SYLZ.js → chunk-76DAAJLV.js} +56 -33
- package/dist/{chunk-TQLRG35T.js → chunk-AWOO63ME.js} +71 -45
- package/dist/chunk-CPW6G62V.js +17 -0
- package/dist/{chunk-K2ACDO7Y.js → chunk-LQZ7IG7B.js} +1 -1
- package/dist/{chunk-S2QGT7ZF.js → chunk-MFEMKQZ6.js} +1 -1
- package/dist/{chunk-Q6SD5SNQ.js → chunk-WM4QYMIA.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +204 -124
- package/dist/eventcatalog.config.d.cts +59 -1
- package/dist/eventcatalog.config.d.ts +59 -1
- package/dist/eventcatalog.js +30 -11
- package/dist/federation/federate.js +2 -2
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- 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/manifest.json +8 -1
- package/dist/runtime-dependencies/react-hotkeys-hook.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/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +71 -45
- package/dist/utils/license-status.d.cts +14 -5
- package/dist/utils/license-status.d.ts +14 -5
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/astro.config.mjs +5 -0
- package/eventcatalog/integrations/storage.mjs +20 -0
- package/eventcatalog/integrations/studio-server.mjs +32 -0
- package/eventcatalog/src/components/Grids/utils.tsx +0 -23
- package/eventcatalog/src/components/Header.astro +3 -3
- package/eventcatalog/src/components/MDX/CodeGroup/CodeGroup.tsx +6 -1
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +12 -4
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +16 -7
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +10 -0
- package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +4 -62
- package/eventcatalog/src/components/Tables/Discover/columns.tsx +17 -150
- package/eventcatalog/src/components/Tables/Resources/ResourcesTable.tsx +425 -0
- package/eventcatalog/src/components/Tables/RowActionsMenu.tsx +157 -0
- package/eventcatalog/src/components/Tables/TablePagination.tsx +82 -0
- package/eventcatalog/src/features/ai/chat-api.ts +3 -3
- package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +10 -0
- package/eventcatalog/src/features/integrations/eventcatalog-features.ts +34 -1
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +47 -0
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +22 -0
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +276 -0
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +210 -0
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +75 -74
- 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 +381 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +170 -0
- package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
- package/eventcatalog/src/features/studio/api/client.ts +35 -0
- package/eventcatalog/src/features/studio/canvas-actions.ts +414 -0
- package/eventcatalog/src/features/studio/canvas-doc.ts +414 -0
- package/eventcatalog/src/features/studio/canvas-preview.ts +53 -0
- package/eventcatalog/src/features/studio/catalog-resources.ts +155 -0
- package/eventcatalog/src/features/studio/catalog.ts +171 -0
- package/eventcatalog/src/features/studio/clipboard.ts +97 -0
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +154 -0
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +370 -0
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +117 -0
- package/eventcatalog/src/features/studio/components/Comments.tsx +770 -0
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +281 -0
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +144 -0
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +145 -0
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +81 -0
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +115 -0
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +34 -0
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +314 -0
- package/eventcatalog/src/features/studio/components/Picture.tsx +21 -0
- package/eventcatalog/src/features/studio/components/Presence.tsx +286 -0
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +212 -0
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +260 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1216 -0
- package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +255 -0
- package/eventcatalog/src/features/studio/components/icons.ts +53 -0
- package/eventcatalog/src/features/studio/components/status.ts +53 -0
- package/eventcatalog/src/features/studio/edges.ts +56 -0
- package/eventcatalog/src/features/studio/flow-state.ts +92 -0
- package/eventcatalog/src/features/studio/grouping.ts +226 -0
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +46 -0
- package/eventcatalog/src/features/studio/hooks/presence-store.ts +119 -0
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +347 -0
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +54 -0
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +104 -0
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +589 -0
- package/eventcatalog/src/features/studio/identity.ts +37 -0
- package/eventcatalog/src/features/studio/layout.ts +42 -0
- package/eventcatalog/src/features/studio/levels.ts +282 -0
- package/eventcatalog/src/features/studio/node-types.ts +205 -0
- package/eventcatalog/src/features/studio/pages/[id].astro +68 -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/placement.ts +197 -0
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +510 -0
- package/eventcatalog/src/features/studio/server/runtime.ts +491 -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/studio.css +273 -0
- package/eventcatalog/src/features/studio/tool-sync.ts +75 -0
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +10 -5
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +52 -63
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +34 -46
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +11 -29
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_ResourcesPage.astro +79 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +32 -14
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +63 -58
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +2 -62
- package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +13 -0
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +24 -42
- package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +2 -0
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +2 -0
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +23 -23
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +13 -0
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +18 -27
- package/eventcatalog/src/stores/sidebar-store/state.ts +5 -0
- package/eventcatalog/src/styles/tailwind.css +2 -2
- package/eventcatalog/src/utils/collections/channels.ts +56 -1
- package/eventcatalog/src/utils/collections/flows.ts +50 -1
- package/eventcatalog/src/utils/collections/message-connections.ts +60 -0
- package/eventcatalog/src/utils/collections/message-triggers.ts +2 -1
- package/eventcatalog/src/utils/collections/resource-owners.ts +193 -0
- package/eventcatalog/src/utils/collections/resources.ts +310 -0
- package/eventcatalog/src/utils/collections/util.ts +31 -0
- package/eventcatalog/src/utils/feature.ts +8 -0
- package/eventcatalog/src/utils/git.ts +11 -5
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +0 -2
- package/eventcatalog/src/utils/trial.ts +1 -1
- package/package.json +17 -12
- package/dist/runtime-dependencies/shelljs.mjs +0 -3
- package/eventcatalog/public/studio-bg.png +0 -0
- package/eventcatalog/src/components/Grids/DomainGrid.tsx +0 -838
- package/eventcatalog/src/components/Grids/MessageGrid.tsx +0 -344
- package/eventcatalog/src/components/Grids/SystemGrid.tsx +0 -185
- package/eventcatalog/src/components/Grids/components.tsx +0 -170
- package/eventcatalog/src/components/Grids/message-link.ts +0 -38
- package/eventcatalog/src/components/Studio/StudioPageModal.tsx +0 -150
- package/eventcatalog/src/components/Tables/SystemResources/SystemResourcesTable.tsx +0 -294
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.spec.ts +0 -65
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_resources.ts +0 -46
- package/eventcatalog/src/pages/studio.astro +0 -316
- package/dist/{chunk-AYNZXUB5.js → chunk-KHACCTW2.js} +3 -3
|
@@ -1,38 +1,20 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
2
|
+
// The architecture overview pages were replaced by the Resources pages; this route only
|
|
3
|
+
// redirects so old links keep working.
|
|
4
|
+
import LatestVersionRedirect from '@components/LatestVersionRedirect.astro';
|
|
5
|
+
import { isSSR } from '@utils/feature';
|
|
6
|
+
import { buildUrl } from '@utils/url-builder';
|
|
8
7
|
import { Page } from './_index.data';
|
|
9
8
|
|
|
10
9
|
export const prerender = Page.prerender;
|
|
11
10
|
export const getStaticPaths = Page.getStaticPaths;
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
let domain = props;
|
|
16
|
-
|
|
17
|
-
const pageTitle = `${props.type} | ${props.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
|
|
18
|
-
|
|
19
|
-
const type = props.type;
|
|
12
|
+
const { data, redirectPath } = await Page.getData(Astro);
|
|
13
|
+
const redirectUrl = buildUrl(redirectPath);
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
if (isSSR()) {
|
|
16
|
+
return Astro.redirect(`${redirectUrl}${Astro.url.search}${Astro.url.hash}`, 301);
|
|
17
|
+
}
|
|
22
18
|
---
|
|
23
19
|
|
|
24
|
-
<
|
|
25
|
-
<main class="flex docs-layout min-h-full bg-[rgb(var(--ec-page-bg))]">
|
|
26
|
-
<div class="flex docs-layout w-full">
|
|
27
|
-
<div class="w-full min-w-0 lg:mr-2 xl:pr-12 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
28
|
-
{type === 'domains' && <DomainGrid domain={domain} client:load />}
|
|
29
|
-
{type === 'systems' && <SystemGrid system={props} client:load />}
|
|
30
|
-
{
|
|
31
|
-
(type === 'agents' || type === 'services') && (
|
|
32
|
-
<MessageGrid service={props} specifications={specifications} client:load />
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</main>
|
|
38
|
-
</VerticalSideBarLayout>
|
|
20
|
+
<LatestVersionRedirect title={`${data.name} | Resources`} redirectUrl={redirectUrl} />
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
3
|
+
import { buildUrl } from '@utils/url-builder';
|
|
4
|
+
import { isVisualiserEnabled } from '@utils/feature';
|
|
5
|
+
import {
|
|
6
|
+
ResourcesTable,
|
|
7
|
+
type ResourceItem,
|
|
8
|
+
} from '@components/Tables/Resources/ResourcesTable';
|
|
9
|
+
import { getCollection } from 'astro:content';
|
|
10
|
+
import {
|
|
11
|
+
getDocsPath,
|
|
12
|
+
getFavorite,
|
|
13
|
+
getResourceGroups,
|
|
14
|
+
getResourceRelationship,
|
|
15
|
+
getSchemaPath,
|
|
16
|
+
getVisualiserPath,
|
|
17
|
+
type ResourceOwner,
|
|
18
|
+
type ResourceOwnerCollection,
|
|
19
|
+
} from '@utils/collections/resources';
|
|
20
|
+
|
|
21
|
+
// Shared by the generic Resources route and the services route.
|
|
22
|
+
interface Props {
|
|
23
|
+
resourceOwner: ResourceOwner;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { resourceOwner } = Astro.props;
|
|
27
|
+
const { data } = resourceOwner;
|
|
28
|
+
const ownerCollection = resourceOwner.collection as ResourceOwnerCollection;
|
|
29
|
+
|
|
30
|
+
// Only show resources directly attached to the owner. Domain child resources are not
|
|
31
|
+
// flattened, so services inside a child system remain on that system's page.
|
|
32
|
+
const resourceGroups = getResourceGroups(data, ownerCollection, resourceOwner);
|
|
33
|
+
|
|
34
|
+
const withBaseUrl = (path: string | undefined) => (path ? buildUrl(path) : undefined);
|
|
35
|
+
|
|
36
|
+
// Messages with an entry in the schemas collection have a schema page.
|
|
37
|
+
const schemaKeys = new Set(
|
|
38
|
+
(await getCollection('schemas')).map(
|
|
39
|
+
({ data: schema }) => `${schema.message.collectionName}:${schema.message.id}:${schema.message.version}`
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const resources: ResourceItem[] = resourceGroups.flatMap(({ collection, items }) =>
|
|
44
|
+
items.map((item) => ({
|
|
45
|
+
collection,
|
|
46
|
+
id: item.data.id,
|
|
47
|
+
name: item.data.name || item.data.id,
|
|
48
|
+
version: item.data.version,
|
|
49
|
+
summary: item.data.summary,
|
|
50
|
+
icon: item.data?.styles?.icon,
|
|
51
|
+
href: buildUrl(getDocsPath(collection, item)),
|
|
52
|
+
visualiserHref: withBaseUrl(getVisualiserPath(collection, item, isVisualiserEnabled())),
|
|
53
|
+
schemaHref: withBaseUrl(getSchemaPath(collection, item, schemaKeys)),
|
|
54
|
+
favorite: getFavorite(collection, item),
|
|
55
|
+
relationship: getResourceRelationship(data, ownerCollection, collection, item, resourceOwner),
|
|
56
|
+
}))
|
|
57
|
+
);
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
<VerticalSideBarLayout title={`${data.name} | Resources`}>
|
|
61
|
+
<style is:global>
|
|
62
|
+
:root[data-embedded='true'] #resources-page {
|
|
63
|
+
height: 100dvh !important;
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
66
|
+
{/* Like the discover pages: pull the table out of the content gutter and fill the viewport so it can paginate. */}
|
|
67
|
+
<main
|
|
68
|
+
id="resources-page"
|
|
69
|
+
class="flex h-full min-h-0 flex-col overflow-hidden bg-[rgb(var(--ec-page-bg))]"
|
|
70
|
+
style="margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1); margin-right: calc(var(--ec-app-content-padding-right, 5rem) * -1); height: calc(100dvh - 60px);"
|
|
71
|
+
>
|
|
72
|
+
<ResourcesTable
|
|
73
|
+
resources={resources}
|
|
74
|
+
title={`${data.name} Resources`}
|
|
75
|
+
description={`${resources.length} ${resources.length === 1 ? 'resource' : 'resources'} mapped to ${data.name}.`}
|
|
76
|
+
client:only="react"
|
|
77
|
+
/>
|
|
78
|
+
</main>
|
|
79
|
+
</VerticalSideBarLayout>
|
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { Page, ServicePage } from './_index.data';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const mocks = vi.hoisted(() => ({
|
|
5
|
+
getOwnersWithResources: vi.fn(),
|
|
6
|
+
findOwnerWithResources: vi.fn(),
|
|
7
7
|
}));
|
|
8
8
|
|
|
9
|
-
vi.mock('@utils/
|
|
10
|
-
vi.mock('@utils/collections/
|
|
9
|
+
vi.mock('@utils/feature', () => ({ isSSR: () => false }));
|
|
10
|
+
vi.mock('@utils/collections/resource-owners', () => ({
|
|
11
|
+
RESOURCE_OWNER_COLLECTIONS: ['domains', 'systems', 'services', 'flows', 'channels', 'events', 'commands', 'queries'],
|
|
12
|
+
createResourcesCatalog: () => ({}),
|
|
13
|
+
getOwnersWithResources: mocks.getOwnersWithResources,
|
|
14
|
+
findOwnerWithResources: mocks.findOwnerWithResources,
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const owner = (collection: string, id: string) => ({ collection, data: { id, version: '1.0.0' } });
|
|
11
18
|
|
|
12
|
-
describe('Resources
|
|
19
|
+
describe('Resources routes', () => {
|
|
13
20
|
beforeEach(() => {
|
|
14
|
-
|
|
21
|
+
mocks.getOwnersWithResources.mockReset().mockImplementation(async (type: string) => [owner(type, `${type}-owner`)]);
|
|
22
|
+
mocks.findOwnerWithResources.mockReset();
|
|
15
23
|
});
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
// /docs/services/[id]/[docType]/[docId] would otherwise catch /docs/services/{id}/{version}/resources,
|
|
26
|
+
// so services get their own route and the generic route leaves them out.
|
|
27
|
+
it('gives every owner type but services a path on the generic route', async () => {
|
|
28
|
+
const paths = await Page.getStaticPaths();
|
|
19
29
|
|
|
20
|
-
expect(
|
|
30
|
+
expect(paths.map(({ params }) => params.type)).toEqual(['domains', 'systems', 'flows', 'channels', 'events', 'commands', 'queries']);
|
|
31
|
+
expect(paths[0]).toEqual({ params: { type: 'domains', id: 'domains-owner', version: '1.0.0' }, props: owner('domains', 'domains-owner') });
|
|
21
32
|
});
|
|
22
33
|
|
|
23
|
-
it('
|
|
24
|
-
await
|
|
34
|
+
it('gives services their own route without a type param', async () => {
|
|
35
|
+
const paths = await ServicePage.getStaticPaths();
|
|
36
|
+
|
|
37
|
+
expect(paths).toEqual([{ params: { id: 'services-owner', version: '1.0.0' }, props: owner('services', 'services-owner') }]);
|
|
38
|
+
});
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
it('returns not found for types without a Resources page on a server request', async () => {
|
|
41
|
+
await expect(Page.getData({ params: { type: 'entities', id: 'Order', version: '1.0.0' }, props: {} } as any)).rejects.toMatchObject({
|
|
42
|
+
status: 404,
|
|
43
|
+
});
|
|
44
|
+
expect(mocks.findOwnerWithResources).not.toHaveBeenCalled();
|
|
27
45
|
});
|
|
28
46
|
});
|
|
@@ -1,74 +1,79 @@
|
|
|
1
1
|
import { isSSR } from '@utils/feature';
|
|
2
2
|
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
-
import {
|
|
3
|
+
import type { ResourceOwner, ResourceOwnerCollection } from '@utils/collections/resources';
|
|
4
|
+
import {
|
|
5
|
+
createResourcesCatalog,
|
|
6
|
+
findOwnerWithResources,
|
|
7
|
+
getOwnersWithResources,
|
|
8
|
+
RESOURCE_OWNER_COLLECTIONS,
|
|
9
|
+
} from '@utils/collections/resource-owners';
|
|
4
10
|
|
|
5
|
-
// The Resources page lists the resources
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
// The Resources page lists the resources attached to a single system, domain, service, flow,
|
|
12
|
+
// channel or message. Every other resource type 404s.
|
|
13
|
+
//
|
|
14
|
+
// Services have their own route (pages/docs/services/[id]/[version]/resources), because the
|
|
15
|
+
// version-less alias /docs/services/[id]/[docType]/[docId] outranks this generic route and
|
|
16
|
+
// would otherwise catch /docs/services/{id}/{version}/resources.
|
|
17
|
+
const GENERIC_ROUTE_TYPES = RESOURCE_OWNER_COLLECTIONS.filter((type) => type !== 'services');
|
|
9
18
|
|
|
10
|
-
|
|
19
|
+
type RouteParams = { type?: string; id?: string; version?: string };
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
const createResourcesPage = ({
|
|
22
|
+
types,
|
|
23
|
+
toParams,
|
|
24
|
+
typeOf,
|
|
25
|
+
}: {
|
|
26
|
+
types: ResourceOwnerCollection[];
|
|
27
|
+
toParams: (type: ResourceOwnerCollection, owner: ResourceOwner) => RouteParams;
|
|
28
|
+
typeOf: (params: RouteParams) => string | undefined;
|
|
29
|
+
}) =>
|
|
30
|
+
class extends HybridPage {
|
|
31
|
+
static get prerender(): boolean {
|
|
32
|
+
return !isSSR();
|
|
33
|
+
}
|
|
20
34
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
static async getStaticPaths(): Promise<Array<{ params: RouteParams; props: ResourceOwner }>> {
|
|
36
|
+
if (isSSR()) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
25
39
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
const catalog = createResourcesCatalog();
|
|
41
|
+
const paths: Array<{ params: RouteParams; props: ResourceOwner }> = [];
|
|
42
|
+
for (const type of types) {
|
|
43
|
+
for (const owner of await getOwnersWithResources(type, catalog)) {
|
|
44
|
+
paths.push({ params: toParams(type, owner), props: owner });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return paths;
|
|
29
48
|
}
|
|
30
49
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
owners[index]
|
|
35
|
-
.filter((owner) => hasResources(owner, type))
|
|
36
|
-
.map((owner) => ({
|
|
37
|
-
params: {
|
|
38
|
-
type,
|
|
39
|
-
id: owner.data.id,
|
|
40
|
-
version: owner.data.version,
|
|
41
|
-
},
|
|
42
|
-
props: {
|
|
43
|
-
...owner,
|
|
44
|
-
},
|
|
45
|
-
}))
|
|
46
|
-
);
|
|
47
|
-
}
|
|
50
|
+
protected static async fetchData(params: RouteParams) {
|
|
51
|
+
const type = typeOf(params);
|
|
52
|
+
const { id, version } = params;
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
if (!type || !id || !version || !types.includes(type as ResourceOwnerCollection)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
return null;
|
|
58
|
+
return findOwnerWithResources(type as ResourceOwnerCollection, id, version);
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
protected static createNotFoundResponse(): Response {
|
|
62
|
+
return new Response(null, {
|
|
63
|
+
status: 404,
|
|
64
|
+
statusText: 'Resources not found',
|
|
65
|
+
});
|
|
61
66
|
}
|
|
67
|
+
};
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
export const Page = createResourcesPage({
|
|
70
|
+
types: GENERIC_ROUTE_TYPES,
|
|
71
|
+
toParams: (type, owner) => ({ type, id: owner.data.id, version: owner.data.version }),
|
|
72
|
+
typeOf: (params) => params.type,
|
|
73
|
+
});
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
+
export const ServicePage = createResourcesPage({
|
|
76
|
+
types: ['services'],
|
|
77
|
+
toParams: (_type, owner) => ({ id: owner.data.id, version: owner.data.version }),
|
|
78
|
+
typeOf: () => 'services',
|
|
79
|
+
});
|
|
@@ -1,71 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
3
|
-
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
4
|
-
import { buildUrl } from '@utils/url-builder';
|
|
5
|
-
import {
|
|
6
|
-
SystemResourcesTable,
|
|
7
|
-
type SystemResourceItem,
|
|
8
|
-
type SystemResourceCollection,
|
|
9
|
-
} from '@components/Tables/SystemResources/SystemResourcesTable';
|
|
10
|
-
import { getResourceGroups, type ResourceOwnerCollection } from './_resources';
|
|
11
|
-
|
|
2
|
+
import ResourcesPage from './_ResourcesPage.astro';
|
|
12
3
|
import { Page } from './_index.data';
|
|
13
4
|
|
|
14
5
|
export const prerender = Page.prerender;
|
|
15
6
|
export const getStaticPaths = Page.getStaticPaths;
|
|
16
7
|
|
|
17
8
|
const resourceOwner = await Page.getData(Astro);
|
|
18
|
-
const { data } = resourceOwner;
|
|
19
|
-
const ownerCollection = resourceOwner.collection as ResourceOwnerCollection;
|
|
20
|
-
|
|
21
|
-
// Only show resources directly attached to this system/domain. Domain child resources
|
|
22
|
-
// are not flattened, so services inside a child system remain on that system's page.
|
|
23
|
-
const resourceGroups = getResourceGroups(data, ownerCollection);
|
|
24
|
-
|
|
25
|
-
const hrefForResource = (collection: SystemResourceCollection, id: string, version: string) => {
|
|
26
|
-
if (collection === 'entities') {
|
|
27
|
-
return buildUrl(`/docs/entities/${id}/${version}`);
|
|
28
|
-
}
|
|
29
|
-
return buildUrl(`/docs/${collection}/${id}/${version}`);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const ownerTypeLabel = ownerCollection === 'domains' ? 'Domain' : 'System';
|
|
33
|
-
|
|
34
|
-
const resources: SystemResourceItem[] = resourceGroups.flatMap(({ collection, items }) =>
|
|
35
|
-
items.map((item: any) => ({
|
|
36
|
-
collection,
|
|
37
|
-
id: item.data.id,
|
|
38
|
-
name: item.data.name || item.data.id,
|
|
39
|
-
version: item.data.version,
|
|
40
|
-
summary: item.data.summary,
|
|
41
|
-
icon: item.data?.styles?.icon,
|
|
42
|
-
href: hrefForResource(collection, item.data.id, item.data.version),
|
|
43
|
-
}))
|
|
44
|
-
);
|
|
45
9
|
---
|
|
46
10
|
|
|
47
|
-
<
|
|
48
|
-
<main class="flex docs-layout min-h-full bg-[rgb(var(--ec-page-bg))]">
|
|
49
|
-
<div class="flex docs-layout w-full">
|
|
50
|
-
<div class="w-full min-w-0 lg:mr-2 xl:pr-12 py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
51
|
-
{/* Header mirrors the resource page (docs/[type]/[id]/[version]/index.astro). */}
|
|
52
|
-
<div class="border-b border-[rgb(var(--ec-page-border))] md:pb-3 pt-4">
|
|
53
|
-
<div class="flex flex-col gap-4">
|
|
54
|
-
<span class="text-xs md:text-sm font-semibold text-[rgb(var(--ec-accent))] capitalize">{ownerTypeLabel}</span>
|
|
55
|
-
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">
|
|
56
|
-
{data.name} Resources
|
|
57
|
-
</h2>
|
|
58
|
-
</div>
|
|
59
|
-
<p class="text-base pt-4 pb-1 text-[rgb(var(--ec-page-text-muted))] font-light">
|
|
60
|
-
{resources.length} {resources.length === 1 ? 'resource' : 'resources'} mapped to the {data.name}{' '}
|
|
61
|
-
{ownerTypeLabel.toLowerCase()}.
|
|
62
|
-
</p>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<div class="pt-8 pb-4 w-full">
|
|
66
|
-
<SystemResourcesTable resources={resources} client:only="react" />
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
</main>
|
|
71
|
-
</VerticalSideBarLayout>
|
|
11
|
+
<ResourcesPage resourceOwner={resourceOwner} />
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Services need their own Resources route: /docs/services/[id]/[docType]/[docId] outranks
|
|
3
|
+
// the generic /docs/[type]/[id]/[version]/resources route and would catch these URLs.
|
|
4
|
+
import ResourcesPage from '../../../../[type]/[id]/[version]/resources/_ResourcesPage.astro';
|
|
5
|
+
import { ServicePage } from '../../../../[type]/[id]/[version]/resources/_index.data';
|
|
6
|
+
|
|
7
|
+
export const prerender = ServicePage.prerender;
|
|
8
|
+
export const getStaticPaths = ServicePage.getStaticPaths;
|
|
9
|
+
|
|
10
|
+
const resourceOwner = await ServicePage.getData(Astro);
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<ResourcesPage resourceOwner={resourceOwner} />
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
buildDiagramNavItems,
|
|
12
12
|
buildResourceDocsSection,
|
|
13
13
|
buildArchitectureDecisionsSection,
|
|
14
|
+
buildResourcesLink,
|
|
14
15
|
} from './shared';
|
|
15
16
|
import { isVisualiserEnabled, isChangelogEnabled } from '@utils/feature';
|
|
16
17
|
import { pluralizeMessageType } from '@utils/collections/messages';
|
|
@@ -131,19 +132,6 @@ export const buildDomainSections = (
|
|
|
131
132
|
const sortedReceivesMessages = [...receivesMessages].sort(byResourceName);
|
|
132
133
|
const renderMessages = shouldRenderSideBarSection(domain, 'messages');
|
|
133
134
|
|
|
134
|
-
// The Resources page/link only makes sense when the domain has direct resources.
|
|
135
|
-
// Keep this aligned with the resource groups rendered by the page.
|
|
136
|
-
const hasResources =
|
|
137
|
-
subDomains.length > 0 ||
|
|
138
|
-
systemsInDomain.length > 0 ||
|
|
139
|
-
agentsInDomain.length > 0 ||
|
|
140
|
-
dataProductsInDomain.length > 0 ||
|
|
141
|
-
allServicesInDomain.length > 0 ||
|
|
142
|
-
domainFlows.length > 0 ||
|
|
143
|
-
entitiesInDomain.length > 0 ||
|
|
144
|
-
sendsMessages.length > 0 ||
|
|
145
|
-
receivesMessages.length > 0;
|
|
146
|
-
|
|
147
135
|
// Diagrams
|
|
148
136
|
const domainDiagrams = domain.data.diagrams || [];
|
|
149
137
|
const diagramNavItems = buildDiagramNavItems(domainDiagrams, context.diagrams);
|
|
@@ -223,10 +211,7 @@ export const buildDomainSections = (
|
|
|
223
211
|
'quick-reference': buildQuickReferenceSection(
|
|
224
212
|
[
|
|
225
213
|
{ title: 'Overview', href: buildUrl(`/docs/domains/${domain.data.id}/${domain.data.version}`) },
|
|
226
|
-
|
|
227
|
-
title: 'Domain Resources',
|
|
228
|
-
href: buildUrl(`/docs/domains/${domain.data.id}/${domain.data.version}/resources`),
|
|
229
|
-
},
|
|
214
|
+
buildResourcesLink(context, 'domains', domain.data.id, domain.data.version),
|
|
230
215
|
renderUbiquitousLanguage && {
|
|
231
216
|
title: 'Ubiquitous Language',
|
|
232
217
|
href: buildUrl(`/docs/domains/${domain.data.id}/language`),
|
|
@@ -239,31 +224,28 @@ export const buildDomainSections = (
|
|
|
239
224
|
].filter(Boolean) as { title: string; href: string }[]
|
|
240
225
|
),
|
|
241
226
|
documentation: docsSection,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
},
|
|
265
|
-
].filter(Boolean) as ChildRef[],
|
|
266
|
-
},
|
|
227
|
+
// Every Architecture link is a visualiser view, so the group is left out when the visualiser is off.
|
|
228
|
+
architecture: renderVisualiser
|
|
229
|
+
? {
|
|
230
|
+
type: 'group',
|
|
231
|
+
title: 'Architecture',
|
|
232
|
+
icon: 'Workflow',
|
|
233
|
+
pages: [
|
|
234
|
+
// The domain's diagram, with levels from the domains it talks to down to
|
|
235
|
+
// its messages
|
|
236
|
+
{
|
|
237
|
+
type: 'item',
|
|
238
|
+
title: 'Diagram',
|
|
239
|
+
href: buildUrl(`/visualiser/domains/${domain.data.id}/${domain.data.version}`),
|
|
240
|
+
},
|
|
241
|
+
renderEntities && {
|
|
242
|
+
type: 'item',
|
|
243
|
+
title: 'Entity Diagram',
|
|
244
|
+
href: buildUrl(`/visualiser/domains/${domain.data.id}/${domain.data.version}/entity-map`),
|
|
245
|
+
},
|
|
246
|
+
].filter(Boolean) as ChildRef[],
|
|
247
|
+
}
|
|
248
|
+
: null,
|
|
267
249
|
diagrams: hasDiagrams
|
|
268
250
|
? {
|
|
269
251
|
type: 'group',
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
buildResourceDocsSection,
|
|
7
7
|
shouldRenderSideBarSection,
|
|
8
8
|
buildArchitectureDecisionsSection,
|
|
9
|
+
buildResourcesLink,
|
|
9
10
|
} from './shared';
|
|
10
11
|
import { isChangelogEnabled } from '@utils/feature';
|
|
11
12
|
import { createVersionedMap, findInMap } from '@utils/collections/util';
|
|
@@ -157,6 +158,7 @@ export const buildFlowSections = (flow: CollectionEntry<'flows'>, context: Resou
|
|
|
157
158
|
'quick-reference': buildQuickReferenceSection(
|
|
158
159
|
[
|
|
159
160
|
{ title: 'Overview', href: buildUrl(`/docs/flows/${flow.data.id}/${flow.data.version}`) },
|
|
161
|
+
buildResourcesLink(context, 'flows', flow.data.id, flow.data.version),
|
|
160
162
|
isChangelogEnabled() &&
|
|
161
163
|
shouldRenderSideBarSection(flow, 'changelog') && {
|
|
162
164
|
title: 'Changelog',
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
buildDiagramNavItems,
|
|
12
12
|
buildResourceDocsSection,
|
|
13
13
|
buildArchitectureDecisionsSection,
|
|
14
|
+
buildResourcesLink,
|
|
14
15
|
} from './shared';
|
|
15
16
|
import { isVisualiserEnabled, isChangelogEnabled } from '@utils/feature';
|
|
16
17
|
import { iconFieldsForResource } from '@utils/icon';
|
|
@@ -137,6 +138,7 @@ export const buildMessageSections = (
|
|
|
137
138
|
title: 'Overview',
|
|
138
139
|
href: buildUrl(`/docs/${collection}/${message.data.id}/${message.data.version}`),
|
|
139
140
|
},
|
|
141
|
+
buildResourcesLink(context, collection, message.data.id, message.data.version),
|
|
140
142
|
isChangelogEnabled() &&
|
|
141
143
|
shouldRenderSideBarSection(message, 'changelog') && {
|
|
142
144
|
title: 'Changelog',
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
buildDiagramNavItems,
|
|
14
14
|
buildResourceDocsSection,
|
|
15
15
|
buildArchitectureDecisionsSection,
|
|
16
|
+
buildResourcesLink,
|
|
16
17
|
} from './shared';
|
|
17
18
|
import { isVisualiserEnabled, isChangelogEnabled } from '@utils/feature';
|
|
18
19
|
import { pluralizeMessageType } from '@utils/collections/messages';
|
|
@@ -98,6 +99,7 @@ export const buildServiceSections = (
|
|
|
98
99
|
const hasAttachments = service.data.attachments && service.data.attachments.length > 0;
|
|
99
100
|
|
|
100
101
|
const hasDataStores = dataStoresInService.length > 0;
|
|
102
|
+
|
|
101
103
|
const resourceGroups = service.data.resourceGroups || [];
|
|
102
104
|
const hasResourceGroups = resourceGroups.length > 0;
|
|
103
105
|
|
|
@@ -126,6 +128,7 @@ export const buildServiceSections = (
|
|
|
126
128
|
'quick-reference': buildQuickReferenceSection(
|
|
127
129
|
[
|
|
128
130
|
{ title: 'Overview', href: buildUrl(docsBasePath) },
|
|
131
|
+
buildResourcesLink(context, 'services', service.data.id, service.data.version),
|
|
129
132
|
isChangelogEnabled() &&
|
|
130
133
|
shouldRenderSideBarSection(service, 'changelog') && {
|
|
131
134
|
title: 'Changelog',
|
|
@@ -134,29 +137,26 @@ export const buildServiceSections = (
|
|
|
134
137
|
].filter(Boolean) as { title: string; href: string }[]
|
|
135
138
|
),
|
|
136
139
|
documentation: docsSection,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
].filter(Boolean) as ChildRef[],
|
|
159
|
-
},
|
|
140
|
+
// Every Architecture link is a visualiser view, so the group is left out when the visualiser is off.
|
|
141
|
+
architecture: renderVisualiser
|
|
142
|
+
? {
|
|
143
|
+
type: 'group',
|
|
144
|
+
title: 'Architecture',
|
|
145
|
+
icon: 'Workflow',
|
|
146
|
+
pages: [
|
|
147
|
+
{
|
|
148
|
+
type: 'item',
|
|
149
|
+
title: 'Diagram',
|
|
150
|
+
href: buildUrl(`/visualiser/services/${service.data.id}/${service.data.version}`),
|
|
151
|
+
},
|
|
152
|
+
renderEntities && {
|
|
153
|
+
type: 'item',
|
|
154
|
+
title: 'Entity Diagram',
|
|
155
|
+
href: buildUrl(`/visualiser/services/${service.data.id}/${service.data.version}/entity-map`),
|
|
156
|
+
},
|
|
157
|
+
].filter(Boolean) as ChildRef[],
|
|
158
|
+
}
|
|
159
|
+
: null,
|
|
160
160
|
diagrams: hasDiagrams
|
|
161
161
|
? {
|
|
162
162
|
type: 'group',
|
|
@@ -79,8 +79,21 @@ export type ResourceGroupContext = {
|
|
|
79
79
|
teams?: CollectionEntry<'teams'>[];
|
|
80
80
|
resourceDocs: ResourceDocEntry[];
|
|
81
81
|
resourceDocCategories: ResourceDocCategoryEntry[];
|
|
82
|
+
/** `collection:id:version` of every resource with a Resources page (see getResourcesPageKeys). */
|
|
83
|
+
resourcesPages?: Set<string>;
|
|
82
84
|
};
|
|
83
85
|
|
|
86
|
+
/** The Quick Reference link to a resource's Resources page, when it has one. */
|
|
87
|
+
export const buildResourcesLink = (
|
|
88
|
+
context: Pick<ResourceGroupContext, 'resourcesPages'>,
|
|
89
|
+
collection: string,
|
|
90
|
+
id: string,
|
|
91
|
+
version: string
|
|
92
|
+
) =>
|
|
93
|
+
context.resourcesPages?.has(`${collection}:${id}:${version}`)
|
|
94
|
+
? { title: 'Resources', href: buildUrl(`/docs/${collection}/${id}/${version}/resources`) }
|
|
95
|
+
: false;
|
|
96
|
+
|
|
84
97
|
export const buildQuickReferenceSection = (items: { title: string; href: string }[]): NavNode => ({
|
|
85
98
|
type: 'group',
|
|
86
99
|
title: 'Quick Reference',
|