@eventcatalog/core 3.41.4 → 3.42.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.
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(analytics_exports);
36
36
  var import_os = __toESM(require("os"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.41.4";
39
+ var version = "3.42.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-VQLDZRHC.js";
4
- import "../chunk-OH2U6UEJ.js";
3
+ } from "../chunk-6FAGUEM4.js";
4
+ import "../chunk-VPZ77Y6E.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -110,7 +110,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
110
110
  var import_os = __toESM(require("os"), 1);
111
111
 
112
112
  // package.json
113
- var version = "3.41.4";
113
+ var version = "3.42.0";
114
114
 
115
115
  // src/constants.ts
116
116
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-LYRAK5LI.js";
4
- import "../chunk-VQLDZRHC.js";
3
+ } from "../chunk-L66TCSM7.js";
4
+ import "../chunk-6FAGUEM4.js";
5
5
  import "../chunk-3DVHEVHQ.js";
6
- import "../chunk-OH2U6UEJ.js";
6
+ import "../chunk-VPZ77Y6E.js";
7
7
  import "../chunk-5T63CXKU.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-OH2U6UEJ.js";
3
+ } from "./chunk-VPZ77Y6E.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import os from "os";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-COPXPOV2.js";
3
+ } from "./chunk-UQIDXF2V.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-VQLDZRHC.js";
3
+ } from "./chunk-6FAGUEM4.js";
4
4
  import {
5
5
  countResources,
6
6
  serializeCounts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-OH2U6UEJ.js";
3
+ } from "./chunk-VPZ77Y6E.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "3.41.4";
2
+ var version = "3.42.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "3.41.4";
28
+ var version = "3.42.0";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-OH2U6UEJ.js";
3
+ } from "./chunk-VPZ77Y6E.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -0,0 +1,114 @@
1
+ ---
2
+ sidebar_position: 5
3
+ keywords:
4
+ - api-catalog
5
+ - RFC 9727
6
+ - well-known
7
+ - API discovery
8
+ - OpenAPI
9
+ - AsyncAPI
10
+ - GraphQL
11
+ sidebar_label: api-catalog (RFC 9727)
12
+ title: api-catalog
13
+ description: Machine-readable catalog discovery endpoint for tools and agents
14
+ ---
15
+
16
+ import AddedIn from '@site/src/components/MDX/AddedIn';
17
+
18
+ <AddedIn version="3.42.0" />
19
+
20
+ Let API tools, agents, and crawlers discover every service and domain specification in your catalog from a single endpoint, without parsing HTML.
21
+
22
+ ### What is RFC 9727?
23
+
24
+ [RFC 9727](https://datatracker.ietf.org/doc/rfc9727/) defines the `/.well-known/api-catalog` well-known URI. It returns a [Linkset](https://www.rfc-editor.org/rfc/rfc9264) document that lists every API an organization publishes along with links to their specifications and documentation.
25
+
26
+ Tools that understand RFC 9727 can point at your catalog URL and immediately enumerate all services and domains, their OpenAPI, AsyncAPI, and GraphQL specs, and their documentation pages. No scraping required.
27
+
28
+ ### How it works
29
+
30
+ EventCatalog automatically publishes a Linkset at `/.well-known/api-catalog`. Every service and domain that has `specifications` defined in its frontmatter appears as an entry.
31
+
32
+ Each entry contains:
33
+
34
+ - **`anchor`** - the canonical URL of the service. EventCatalog reads the `servers[].url` field from OpenAPI or AsyncAPI specs and uses that. When no server URL is found it falls back to the EventCatalog documentation page.
35
+ - **`service-desc`** - one link per specification file, pointing at `/api-catalog/specifications/{collection}/{id}/{version}/{specification}` with the correct media type (`application/yaml`, `application/json`, or `application/graphql`).
36
+ - **`service-doc`** - two links per resource: the markdown source and the rendered HTML page.
37
+
38
+ Resources marked `hidden: true` are excluded from the linkset.
39
+
40
+ ### Access the endpoint
41
+
42
+ ```
43
+ GET /.well-known/api-catalog
44
+ HEAD /.well-known/api-catalog
45
+ ```
46
+
47
+ The `GET` response body is `application/linkset+json` profiled against RFC 9727:
48
+
49
+ ```json
50
+ {
51
+ "linkset": [
52
+ {
53
+ "anchor": "https://api.example.com/orders",
54
+ "service-desc": [
55
+ {
56
+ "href": "https://catalog.example.com/api-catalog/specifications/services/OrderService/1.0.0/openapi-b3BlbmFwaS55bWw",
57
+ "type": "application/yaml",
58
+ "title": "Order Service OpenAPI"
59
+ }
60
+ ],
61
+ "service-doc": [
62
+ {
63
+ "href": "https://catalog.example.com/docs/services/OrderService/1.0.0.md",
64
+ "type": "text/markdown",
65
+ "title": "Order Service documentation"
66
+ },
67
+ {
68
+ "href": "https://catalog.example.com/docs/services/OrderService/1.0.0",
69
+ "type": "text/html",
70
+ "title": "Order Service documentation"
71
+ }
72
+ ]
73
+ }
74
+ ]
75
+ }
76
+ ```
77
+
78
+ The `HEAD` response includes a `Link` header so clients can confirm the endpoint exists before fetching the full body:
79
+
80
+ ```
81
+ Link: <https://catalog.example.com/.well-known/api-catalog>; rel="api-catalog"
82
+ ```
83
+
84
+ ### Fetch a specification file
85
+
86
+ The raw specification files referenced in `service-desc` are served from:
87
+
88
+ ```
89
+ GET /api-catalog/specifications/{collection}/{id}/{version}/{specification}
90
+ ```
91
+
92
+ | Segment | Values |
93
+ |---------|--------|
94
+ | `collection` | `services`, `domains` |
95
+ | `id` | The resource `id` field |
96
+ | `version` | The resource `version` field |
97
+ | `specification` | Stable specification identifier, formatted as `{type}-{base64url(path)}` |
98
+
99
+ Example:
100
+
101
+ ```
102
+ GET /api-catalog/specifications/services/OrderService/1.0.0/openapi-b3BlbmFwaS55bWw
103
+ Content-Type: application/yaml
104
+ ```
105
+
106
+ ### MCP server entry
107
+
108
+ When the EventCatalog MCP server is enabled, an additional entry pointing at `/docs/mcp` is appended to the linkset. This lets MCP-aware agents discover the catalog's machine interface alongside its API specifications.
109
+
110
+ ### What is included
111
+
112
+ Only services and domains are included in v1 of this endpoint. Events, commands, queries, data products, schemas, diagrams, teams, and users are out of scope for this release.
113
+
114
+ For a broader machine-readable index of your catalog content, see [llms.txt](/docs/development/developer-tools/llms.txt) and [schemas.txt](/docs/development/developer-tools/schemas.txt).
@@ -114,7 +114,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
114
114
  var import_picocolors = __toESM(require("picocolors"), 1);
115
115
 
116
116
  // package.json
117
- var version = "3.41.4";
117
+ var version = "3.42.0";
118
118
 
119
119
  // src/constants.ts
120
120
  var VERSION = version;
@@ -13,8 +13,8 @@ import {
13
13
  } from "./chunk-3H2RT3CM.js";
14
14
  import {
15
15
  log_build_default
16
- } from "./chunk-LYRAK5LI.js";
17
- import "./chunk-VQLDZRHC.js";
16
+ } from "./chunk-L66TCSM7.js";
17
+ import "./chunk-6FAGUEM4.js";
18
18
  import "./chunk-3DVHEVHQ.js";
19
19
  import {
20
20
  catalogToAstro
@@ -28,13 +28,13 @@ import {
28
28
  } from "./chunk-ULZYHF3V.js";
29
29
  import {
30
30
  generate
31
- } from "./chunk-YWG7CCN7.js";
31
+ } from "./chunk-KE6YTTLB.js";
32
32
  import {
33
33
  logger
34
- } from "./chunk-COPXPOV2.js";
34
+ } from "./chunk-UQIDXF2V.js";
35
35
  import {
36
36
  VERSION
37
- } from "./chunk-OH2U6UEJ.js";
37
+ } from "./chunk-VPZ77Y6E.js";
38
38
  import {
39
39
  getEventCatalogConfigFile,
40
40
  verifyRequiredFieldsAreInCatalogConfigFile
package/dist/generate.cjs CHANGED
@@ -78,7 +78,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
78
78
  var import_picocolors = __toESM(require("picocolors"), 1);
79
79
 
80
80
  // package.json
81
- var version = "3.41.4";
81
+ var version = "3.42.0";
82
82
 
83
83
  // src/constants.ts
84
84
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-YWG7CCN7.js";
4
- import "./chunk-COPXPOV2.js";
5
- import "./chunk-OH2U6UEJ.js";
3
+ } from "./chunk-KE6YTTLB.js";
4
+ import "./chunk-UQIDXF2V.js";
5
+ import "./chunk-VPZ77Y6E.js";
6
6
  import "./chunk-5T63CXKU.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.41.4";
39
+ var version = "3.42.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-COPXPOV2.js";
4
- import "../chunk-OH2U6UEJ.js";
3
+ } from "../chunk-UQIDXF2V.js";
4
+ import "../chunk-VPZ77Y6E.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -0,0 +1,191 @@
1
+ import type { APIRoute } from 'astro';
2
+ import yaml from 'js-yaml';
3
+ import { getServices, getSpecificationsForService } from '@utils/collections/services';
4
+ import { getDomains, getSpecificationsForDomain } from '@utils/collections/domains';
5
+ import type { ProcessedSpecification } from '@utils/collections/util';
6
+ import { buildUrl } from '@utils/url-builder';
7
+ import { readResourceFile } from '@utils/resource-files';
8
+ import { isEventCatalogMCPEnabled } from '@utils/feature';
9
+
10
+ const RFC_9727_PROFILE = 'https://www.rfc-editor.org/info/rfc9727';
11
+ const LINKSET_CONTENT_TYPE = `application/linkset+json; profile="${RFC_9727_PROFILE}"`;
12
+
13
+ type LinkTarget = {
14
+ href: string;
15
+ type?: string;
16
+ title?: string;
17
+ };
18
+
19
+ type ApiCatalogEntry = {
20
+ anchor: string;
21
+ 'service-desc': LinkTarget[];
22
+ 'service-doc'?: LinkTarget[];
23
+ };
24
+
25
+ type ApiCatalogResource = Awaited<ReturnType<typeof getServices>>[number] | Awaited<ReturnType<typeof getDomains>>[number];
26
+
27
+ const absoluteUrl = (request: Request, pathOrUrl: string) => new URL(pathOrUrl, request.url).toString();
28
+
29
+ const getSpecificationMediaType = (specification: ProcessedSpecification) => {
30
+ const extension = specification.filename.split('.').pop()?.toLowerCase();
31
+
32
+ if (specification.type === 'graphql') return 'application/graphql';
33
+ if (extension === 'json') return 'application/json';
34
+ if (extension === 'yaml' || extension === 'yml') return 'application/yaml';
35
+
36
+ return 'text/plain';
37
+ };
38
+
39
+ const getSpecificationIdentifier = (specification: ProcessedSpecification) => {
40
+ return `${specification.type}-${Buffer.from(specification.path).toString('base64url')}`;
41
+ };
42
+
43
+ const parseSpecification = (rawSpecification: string, path: string): unknown => {
44
+ if (path.endsWith('.json')) {
45
+ return JSON.parse(rawSpecification);
46
+ }
47
+
48
+ return yaml.load(rawSpecification);
49
+ };
50
+
51
+ const toHttpUrl = (value: unknown): string | undefined => {
52
+ if (typeof value !== 'string' || value.trim() === '') return undefined;
53
+ if (!/^https?:\/\//i.test(value)) return undefined;
54
+
55
+ try {
56
+ const url = new URL(value);
57
+ if (url.protocol === 'http:' || url.protocol === 'https:') {
58
+ return url.toString();
59
+ }
60
+ } catch {
61
+ return undefined;
62
+ }
63
+
64
+ return undefined;
65
+ };
66
+
67
+ const getSpecificationsForResource = (resource: ApiCatalogResource) => {
68
+ if (resource.collection === 'domains') {
69
+ return getSpecificationsForDomain(resource);
70
+ }
71
+
72
+ return getSpecificationsForService(resource);
73
+ };
74
+
75
+ const getEndpointFromSpecification = (request: Request, resource: ApiCatalogResource) => {
76
+ const specifications = getSpecificationsForResource(resource);
77
+
78
+ for (const specification of specifications) {
79
+ if (specification.type !== 'openapi' && specification.type !== 'asyncapi') continue;
80
+
81
+ const rawSpecification = readResourceFile(resource, specification.path);
82
+ if (!rawSpecification) continue;
83
+
84
+ try {
85
+ const parsedSpecification = parseSpecification(rawSpecification, specification.path) as any;
86
+
87
+ if (specification.type === 'openapi') {
88
+ const serverUrl = parsedSpecification?.servers?.find((server: any) => typeof server?.url === 'string')?.url;
89
+ const endpoint = toHttpUrl(serverUrl);
90
+ if (endpoint) return endpoint;
91
+ }
92
+
93
+ if (specification.type === 'asyncapi') {
94
+ const servers = Object.values(parsedSpecification?.servers ?? {}) as any[];
95
+ const serverUrl = servers.find((server) => typeof server?.url === 'string')?.url;
96
+ const endpoint = toHttpUrl(serverUrl);
97
+ if (endpoint) return endpoint;
98
+ }
99
+ } catch {
100
+ // Invalid or unsupported specifications should not prevent catalog discovery.
101
+ }
102
+ }
103
+ };
104
+
105
+ const getResourceDocumentationUrl = (request: Request, resource: ApiCatalogResource) => {
106
+ return absoluteUrl(request, buildUrl(`/docs/${resource.collection}/${resource.data.id}/${resource.data.version}`, true));
107
+ };
108
+
109
+ const getResourceMarkdownUrl = (request: Request, resource: ApiCatalogResource) => {
110
+ return absoluteUrl(request, buildUrl(`/docs/${resource.collection}/${resource.data.id}/${resource.data.version}.md`, true));
111
+ };
112
+
113
+ const toApiCatalogEntry = (request: Request, resource: ApiCatalogResource): ApiCatalogEntry | null => {
114
+ const specifications = getSpecificationsForResource(resource);
115
+ if (specifications.length === 0) return null;
116
+
117
+ const resourceDocumentationUrl = getResourceDocumentationUrl(request, resource);
118
+ const resourceMarkdownUrl = getResourceMarkdownUrl(request, resource);
119
+
120
+ return {
121
+ anchor: getEndpointFromSpecification(request, resource) ?? resourceDocumentationUrl,
122
+ 'service-desc': specifications.map((specification) => ({
123
+ href: absoluteUrl(
124
+ request,
125
+ buildUrl(
126
+ `/api-catalog/specifications/${resource.collection}/${resource.data.id}/${resource.data.version}/${getSpecificationIdentifier(specification)}`,
127
+ true
128
+ )
129
+ ),
130
+ type: getSpecificationMediaType(specification),
131
+ title: `${resource.data.name || resource.data.id} ${specification.name}`,
132
+ })),
133
+ 'service-doc': [
134
+ {
135
+ href: resourceMarkdownUrl,
136
+ type: 'text/markdown',
137
+ title: `${resource.data.name || resource.data.id} documentation`,
138
+ },
139
+ {
140
+ href: resourceDocumentationUrl,
141
+ type: 'text/html',
142
+ title: `${resource.data.name || resource.data.id} documentation`,
143
+ },
144
+ ],
145
+ };
146
+ };
147
+
148
+ const getMcpCatalogEntry = (request: Request): ApiCatalogEntry | null => {
149
+ if (!isEventCatalogMCPEnabled()) return null;
150
+
151
+ const mcpUrl = absoluteUrl(request, buildUrl('/docs/mcp', true));
152
+
153
+ return {
154
+ anchor: mcpUrl,
155
+ 'service-desc': [
156
+ {
157
+ href: mcpUrl,
158
+ type: 'application/json',
159
+ title: 'EventCatalog MCP Server',
160
+ },
161
+ ],
162
+ };
163
+ };
164
+
165
+ export const GET: APIRoute = async ({ request }) => {
166
+ const [services, domains] = await Promise.all([getServices({ getAllVersions: true }), getDomains({ getAllVersions: true })]);
167
+ const resources = [...services, ...domains];
168
+ const linkset = resources
169
+ .map((resource) => toApiCatalogEntry(request, resource))
170
+ .filter((entry): entry is ApiCatalogEntry => entry !== null);
171
+
172
+ const mcpEntry = getMcpCatalogEntry(request);
173
+ if (mcpEntry) {
174
+ linkset.push(mcpEntry);
175
+ }
176
+
177
+ return new Response(JSON.stringify({ linkset }, null, 2), {
178
+ headers: {
179
+ 'Content-Type': LINKSET_CONTENT_TYPE,
180
+ },
181
+ });
182
+ };
183
+
184
+ export const HEAD: APIRoute = async ({ request }) => {
185
+ return new Response(null, {
186
+ headers: {
187
+ 'Content-Type': LINKSET_CONTENT_TYPE,
188
+ Link: `<${absoluteUrl(request, buildUrl('/.well-known/api-catalog', true))}>; rel="api-catalog"`,
189
+ },
190
+ });
191
+ };
@@ -0,0 +1,109 @@
1
+ import type { APIRoute } from 'astro';
2
+ import { getCollection } from 'astro:content';
3
+ import { getSpecificationsForDomain } from '@utils/collections/domains';
4
+ import { getSpecificationsForService } from '@utils/collections/services';
5
+ import type { ProcessedSpecification } from '@utils/collections/util';
6
+ import { readResourceFile } from '@utils/resource-files';
7
+
8
+ type SupportedCollection = 'domains' | 'services';
9
+
10
+ const isSupportedCollection = (collection: string | undefined): collection is SupportedCollection => {
11
+ return collection === 'domains' || collection === 'services';
12
+ };
13
+
14
+ const getSpecificationMediaType = (specification: ProcessedSpecification) => {
15
+ const extension = specification.filename.split('.').pop()?.toLowerCase();
16
+
17
+ if (specification.type === 'graphql') return 'application/graphql';
18
+ if (extension === 'json') return 'application/json';
19
+ if (extension === 'yaml' || extension === 'yml') return 'application/yaml';
20
+
21
+ return 'text/plain';
22
+ };
23
+
24
+ const getSpecificationIdentifier = (specification: ProcessedSpecification) => {
25
+ return `${specification.type}-${Buffer.from(specification.path).toString('base64url')}`;
26
+ };
27
+
28
+ const getSpecificationsForResource = (
29
+ resource:
30
+ | Awaited<ReturnType<typeof getCollection<'services'>>>[number]
31
+ | Awaited<ReturnType<typeof getCollection<'domains'>>>[number]
32
+ ) => {
33
+ if (resource.collection === 'domains') {
34
+ return getSpecificationsForDomain(resource);
35
+ }
36
+
37
+ return getSpecificationsForService(resource);
38
+ };
39
+
40
+ export async function getStaticPaths() {
41
+ const [services, domains] = await Promise.all([getCollection('services'), getCollection('domains')]);
42
+ const resources = [...services, ...domains].filter((resource) => resource.data.hidden !== true);
43
+
44
+ return resources.flatMap((resource) =>
45
+ getSpecificationsForResource(resource).map((specification) => ({
46
+ params: {
47
+ collection: resource.collection,
48
+ id: resource.data.id,
49
+ version: resource.data.version,
50
+ specification: getSpecificationIdentifier(specification),
51
+ },
52
+ props: {
53
+ rawSpecification: readResourceFile(resource, specification.path),
54
+ contentType: getSpecificationMediaType(specification),
55
+ },
56
+ }))
57
+ );
58
+ }
59
+
60
+ export const GET: APIRoute = async ({ params, props }) => {
61
+ if (props.rawSpecification) {
62
+ return new Response(props.rawSpecification, {
63
+ headers: { 'Content-Type': props.contentType ?? 'text/plain' },
64
+ });
65
+ }
66
+
67
+ const { collection, id, version, specification } = params;
68
+
69
+ if (!isSupportedCollection(collection) || !id || !version || !specification) {
70
+ return new Response(JSON.stringify({ error: 'Missing or invalid collection, id, version, or specification parameter' }), {
71
+ status: 400,
72
+ headers: { 'Content-Type': 'application/json' },
73
+ });
74
+ }
75
+
76
+ const resources = await getCollection(collection);
77
+ const resource = resources.find((item) => item.data.id === id && item.data.version === version && item.data.hidden !== true);
78
+
79
+ if (!resource) {
80
+ return new Response(JSON.stringify({ error: 'Resource not found' }), {
81
+ status: 404,
82
+ headers: { 'Content-Type': 'application/json' },
83
+ });
84
+ }
85
+
86
+ const spec = getSpecificationsForResource(resource).find(
87
+ (item) => getSpecificationIdentifier(item) === specification || item.type === specification
88
+ );
89
+
90
+ if (!spec) {
91
+ return new Response(JSON.stringify({ error: 'Specification not found' }), {
92
+ status: 404,
93
+ headers: { 'Content-Type': 'application/json' },
94
+ });
95
+ }
96
+
97
+ const rawSpecification = readResourceFile(resource, spec.path);
98
+
99
+ if (!rawSpecification) {
100
+ return new Response(JSON.stringify({ error: 'Specification file could not be read' }), {
101
+ status: 404,
102
+ headers: { 'Content-Type': 'application/json' },
103
+ });
104
+ }
105
+
106
+ return new Response(rawSpecification, {
107
+ headers: { 'Content-Type': getSpecificationMediaType(spec) },
108
+ });
109
+ };
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "3.41.4",
10
+ "version": "3.42.0",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -113,8 +113,8 @@
113
113
  "uuid": "^10.0.0",
114
114
  "zod": "^4.3.6",
115
115
  "@eventcatalog/sdk": "2.23.0",
116
- "@eventcatalog/visualiser": "^3.22.1",
117
- "@eventcatalog/linter": "1.0.26"
116
+ "@eventcatalog/linter": "1.0.26",
117
+ "@eventcatalog/visualiser": "^3.22.1"
118
118
  },
119
119
  "devDependencies": {
120
120
  "@astrojs/check": "^0.9.9",