@eventcatalog/core 2.42.9 → 2.43.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.
Files changed (58) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/catalog-to-astro-content-directory.js +2 -2
  6. package/dist/{chunk-4A2C2PVU.js → chunk-4DXH4NAT.js} +1 -1
  7. package/dist/{chunk-OQA3PAMR.js → chunk-IZ7E57FH.js} +1 -1
  8. package/dist/{chunk-HDG7YSFG.js → chunk-LUUBKWYP.js} +8 -0
  9. package/dist/{chunk-ISA6KNLN.js → chunk-MXNHNGRS.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.auth.cjs +18 -0
  13. package/dist/eventcatalog.auth.d.cts +18 -0
  14. package/dist/eventcatalog.auth.d.ts +18 -0
  15. package/dist/eventcatalog.auth.js +0 -0
  16. package/dist/eventcatalog.cjs +50 -23
  17. package/dist/eventcatalog.js +29 -8
  18. package/dist/features.cjs +9 -0
  19. package/dist/features.d.cts +2 -1
  20. package/dist/features.d.ts +2 -1
  21. package/dist/features.js +3 -1
  22. package/dist/watcher.js +1 -1
  23. package/eventcatalog/astro.config.mjs +7 -3
  24. package/eventcatalog/auth.config.ts +142 -0
  25. package/eventcatalog/src/components/Header.astro +125 -25
  26. package/eventcatalog/src/middleware.ts +62 -0
  27. package/eventcatalog/src/pages/auth/error.astro +55 -0
  28. package/eventcatalog/src/pages/auth/login.astro +231 -0
  29. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +63 -0
  30. package/eventcatalog/src/pages/directory/[type]/index.astro +6 -23
  31. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +62 -0
  32. package/eventcatalog/src/pages/discover/[type]/index.astro +7 -24
  33. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +62 -0
  34. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +5 -37
  35. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +98 -0
  36. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +68 -0
  37. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +5 -25
  38. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +6 -25
  39. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +6 -35
  40. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +99 -0
  41. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +1 -0
  42. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +40 -0
  43. package/eventcatalog/src/pages/docs/[type]/[id]/{language.astro → language/index.astro} +6 -20
  44. package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +49 -0
  45. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +5 -11
  46. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +46 -0
  47. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +6 -10
  48. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +46 -0
  49. package/eventcatalog/src/pages/docs/users/[id]/index.astro +5 -9
  50. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +99 -0
  51. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +5 -29
  52. package/eventcatalog/src/utils/feature.ts +10 -0
  53. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +12 -1
  54. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -1
  55. package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +68 -0
  56. package/eventcatalog/tsconfig.json +2 -1
  57. package/package.json +3 -1
  58. package/dist/{chunk-SLEMYHTU.js → chunk-SFA7F3CQ.js} +3 -3
@@ -0,0 +1,63 @@
1
+ // pages/directory/[type]/index.page.ts
2
+ import { isSSR } from '@utils/feature';
3
+ import { HybridPage } from '@utils/page-loaders/hybrid-page';
4
+
5
+ export class Page extends HybridPage {
6
+ static get prerender(): boolean {
7
+ return !isSSR();
8
+ }
9
+
10
+ static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
11
+ const { getUsers } = await import('@utils/users');
12
+ const { getTeams } = await import('@utils/teams');
13
+
14
+ const loaders = {
15
+ users: getUsers,
16
+ teams: getTeams,
17
+ };
18
+
19
+ const itemTypes = ['users', 'teams'] as const;
20
+ const allItems = await Promise.all(itemTypes.map((type) => loaders[type]()));
21
+
22
+ return allItems.flatMap((items, index) => ({
23
+ params: {
24
+ type: itemTypes[index],
25
+ },
26
+ props: {
27
+ data: items,
28
+ type: itemTypes[index],
29
+ },
30
+ }));
31
+ }
32
+
33
+ protected static async fetchData(params: any) {
34
+ const { type } = params;
35
+
36
+ if (!type) {
37
+ return null;
38
+ }
39
+
40
+ const { getUsers } = await import('@utils/users');
41
+ const { getTeams } = await import('@utils/teams');
42
+
43
+ const loaders = {
44
+ users: getUsers,
45
+ teams: getTeams,
46
+ };
47
+
48
+ // Get all items of the specified type
49
+ const items = await loaders[type as keyof typeof loaders]();
50
+
51
+ return {
52
+ type,
53
+ data: items,
54
+ };
55
+ }
56
+
57
+ protected static createNotFoundResponse(): Response {
58
+ return new Response(null, {
59
+ status: 404,
60
+ statusText: 'Directory type not found',
61
+ });
62
+ }
63
+ }
@@ -1,30 +1,13 @@
1
1
  ---
2
- import { getUsers } from '@utils/users';
3
- import { getTeams } from '@utils/teams';
2
+ import type { CollectionEntry } from 'astro:content';
4
3
 
5
4
  import DirectoryLayout, { type Props as DirectoryLayoutProps } from '@layouts/DirectoryLayout.astro';
5
+ import { Page } from './_index.data';
6
6
 
7
- export async function getStaticPaths() {
8
- const loaders = {
9
- users: getUsers,
10
- teams: getTeams,
11
- };
12
-
13
- const itemTypes = ['users', 'teams'] as const;
14
- const allItems = await Promise.all(itemTypes.map((type) => loaders[type]()));
15
-
16
- return allItems.flatMap((items, index) => ({
17
- params: {
18
- type: itemTypes[index],
19
- },
20
- props: {
21
- data: items,
22
- type: itemTypes[index],
23
- },
24
- }));
25
- }
7
+ export const prerender = Page.prerender;
8
+ export const getStaticPaths = Page.getStaticPaths;
26
9
 
27
- const { type, data } = Astro.props;
10
+ const { type, data } = await Page.getData(Astro);
28
11
 
29
12
  function mapToItem(i: any) {
30
13
  return {
@@ -42,7 +25,7 @@ function mapToItem(i: any) {
42
25
  title={`${type} (${data.length})`}
43
26
  subtitle={`Find, filter and search for any ${type} in your system.`}
44
27
  data={data.map(
45
- (d) =>
28
+ (d: CollectionEntry<'users' | 'teams'>) =>
46
29
  ({
47
30
  collection: d.collection,
48
31
  data: {
@@ -0,0 +1,62 @@
1
+ // pages/discover/[type]/index.page.ts
2
+ import { isSSR } from '@utils/feature';
3
+ import { HybridPage } from '@utils/page-loaders/hybrid-page';
4
+ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
5
+
6
+ export class Page extends HybridPage {
7
+ static get prerender(): boolean {
8
+ return !isSSR();
9
+ }
10
+
11
+ static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
12
+ const { getFlows } = await import('@utils/collections/flows');
13
+
14
+ const loaders = {
15
+ ...pageDataLoader,
16
+ flows: getFlows,
17
+ };
18
+
19
+ const itemTypes = ['events', 'commands', 'queries', 'services', 'domains', 'flows'] as const;
20
+ const allItems = await Promise.all(itemTypes.map((type) => loaders[type]()));
21
+
22
+ return allItems.flatMap((items, index) => ({
23
+ params: {
24
+ type: itemTypes[index],
25
+ },
26
+ props: {
27
+ data: items,
28
+ type: itemTypes[index],
29
+ },
30
+ }));
31
+ }
32
+
33
+ protected static async fetchData(params: any) {
34
+ const { type } = params;
35
+
36
+ if (!type) {
37
+ return null;
38
+ }
39
+
40
+ const { getFlows } = await import('@utils/collections/flows');
41
+
42
+ const loaders = {
43
+ ...pageDataLoader,
44
+ flows: getFlows,
45
+ };
46
+
47
+ // @ts-ignore
48
+ const items = await loaders[type]();
49
+
50
+ return {
51
+ type,
52
+ data: items,
53
+ };
54
+ }
55
+
56
+ protected static createNotFoundResponse(): Response {
57
+ return new Response(null, {
58
+ status: 404,
59
+ statusText: 'Collection type not found',
60
+ });
61
+ }
62
+ }
@@ -1,30 +1,13 @@
1
1
  ---
2
+ import type { CollectionEntry } from 'astro:content';
3
+ import type { CollectionTypes } from '@types';
2
4
  import DiscoverLayout, { type Props as DiscoverLayoutProps } from '@layouts/DiscoverLayout.astro';
3
- import { getFlows } from '@utils/collections/flows';
5
+ import { Page } from './_index.data';
4
6
 
5
- import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
7
+ export const prerender = Page.prerender;
8
+ export const getStaticPaths = Page.getStaticPaths;
6
9
 
7
- export async function getStaticPaths() {
8
- const loaders = {
9
- ...pageDataLoader,
10
- flows: getFlows,
11
- };
12
-
13
- const itemTypes = ['events', 'commands', 'queries', 'services', 'domains', 'flows'] as const;
14
- const allItems = await Promise.all(itemTypes.map((type) => loaders[type]()));
15
-
16
- return allItems.flatMap((items, index) => ({
17
- params: {
18
- type: itemTypes[index],
19
- },
20
- props: {
21
- data: items,
22
- type: itemTypes[index],
23
- },
24
- }));
25
- }
26
-
27
- const { type, data } = Astro.props;
10
+ const { type, data } = await Page.getData(Astro);
28
11
 
29
12
  function mapToItem(i: any) {
30
13
  return {
@@ -42,7 +25,7 @@ function mapToItem(i: any) {
42
25
  title={`${type} (${data.length})`}
43
26
  subtitle={`Find, filter and search for any ${type} in your system.`}
44
27
  data={data.map(
45
- (d) =>
28
+ (d: CollectionEntry<CollectionTypes>) =>
46
29
  ({
47
30
  collection: d.collection,
48
31
  data: {
@@ -0,0 +1,62 @@
1
+ import { isSSR } from '@utils/feature';
2
+ import { HybridPage } from '@utils/page-loaders/hybrid-page';
3
+ import type { PageTypes } from '@types';
4
+ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
5
+
6
+ /**
7
+ * Documentation page class for all collection types with versioning
8
+ */
9
+ export class Page extends HybridPage {
10
+ static async getStaticPaths() {
11
+ if (isSSR()) {
12
+ return [];
13
+ }
14
+
15
+ const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains', 'flows', 'channels', 'entities'];
16
+ const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
17
+
18
+ return allItems.flatMap((items, index) =>
19
+ items.map((item) => ({
20
+ params: {
21
+ type: itemTypes[index],
22
+ id: item.data.id,
23
+ version: item.data.version,
24
+ },
25
+ props: {
26
+ type: itemTypes[index],
27
+ ...item,
28
+ },
29
+ }))
30
+ );
31
+ }
32
+
33
+ protected static async fetchData(params: any) {
34
+ const { type, id, version } = params;
35
+
36
+ if (!type || !id || !version) {
37
+ return null;
38
+ }
39
+
40
+ // Get all items of the specified type
41
+ const items = await pageDataLoader[type as PageTypes]();
42
+
43
+ // Find the specific item by id and version
44
+ const item = items.find((i) => i.data.id === id && i.data.version === version);
45
+
46
+ if (!item) {
47
+ return null;
48
+ }
49
+
50
+ return {
51
+ type,
52
+ ...item,
53
+ };
54
+ }
55
+
56
+ protected static createNotFoundResponse(): Response {
57
+ return new Response(null, {
58
+ status: 404,
59
+ statusText: 'Documentation not found',
60
+ });
61
+ }
62
+ }
@@ -5,53 +5,21 @@ import { renderToString } from 'react-dom/server';
5
5
  import { Parser } from '@asyncapi/parser';
6
6
  import { AvroSchemaParser } from '@asyncapi/avro-schema-parser';
7
7
  import fs from 'fs';
8
- import { getSpecificationsForService } from '@utils/collections/services';
9
- import type { CollectionTypes, PageTypes } from '@types';
10
8
 
11
9
  import '@asyncapi/react-component/styles/default.min.css';
12
10
  import js from '@asyncapi/react-component/browser/standalone/without-parser.js?url';
13
11
  import { AsyncApiComponentWP, type ConfigInterface } from '@asyncapi/react-component';
14
- import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
15
- import type { CollectionEntry } from 'astro:content';
16
12
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
17
13
  import Config from '@utils/eventcatalog-config/catalog';
14
+ import { Page } from './_[filename].data';
18
15
 
19
- export async function getStaticPaths() {
20
- const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains'];
21
- const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
16
+ export const prerender = Page.prerender;
17
+ export const getStaticPaths = Page.getStaticPaths;
22
18
 
23
- const hasSpecifications = (item: CollectionEntry<CollectionTypes>) => {
24
- const specifications = getSpecificationsForService(item);
25
- // Ensure there is at least one 'asyncapi' specification
26
- return specifications && specifications.some((spec) => spec.type === 'asyncapi');
27
- };
28
-
29
- const filteredItems = allItems.map((items) => items.filter(hasSpecifications));
30
-
31
- return filteredItems.flatMap((items, index) =>
32
- items.flatMap((item) => {
33
- const asyncApiSpecifications = getSpecificationsForService(item).filter((spec) => spec.type === 'asyncapi');
34
-
35
- return asyncApiSpecifications.map((spec) => ({
36
- params: {
37
- type: itemTypes[index],
38
- id: item.data.id,
39
- version: item.data.version,
40
- filename: spec.filenameWithoutExtension || spec.type,
41
- },
42
- props: {
43
- type: itemTypes[index],
44
- filenameWithoutExtension: spec.filenameWithoutExtension || spec.type,
45
- filename: spec.filename || spec.type,
46
- ...item,
47
- },
48
- }));
49
- })
50
- );
51
- }
19
+ // Get data
20
+ const { collection, data, filePath, filename } = await Page.getData(Astro);
52
21
 
53
22
  // @ts-ignore
54
- const { collection, catalog, data, filePath, filename } = Astro.props;
55
23
  const fileName = filename || 'asyncapi.yaml';
56
24
  const directory = path.dirname(filePath || '');
57
25
  const pathToSpec = path.join(directory, fileName);
@@ -0,0 +1,98 @@
1
+ // pages/docs/[type]/[id]/[version]/asyncapi/[filename]/index.page.ts
2
+ import { isSSR, isAuthEnabled } from '@utils/feature';
3
+ import { HybridPage } from '@utils/page-loaders/hybrid-page';
4
+ import type { CollectionEntry } from 'astro:content';
5
+ import type { CollectionTypes, PageTypes } from '@types';
6
+
7
+ export class Page extends HybridPage {
8
+ static get prerender(): boolean {
9
+ return !isSSR();
10
+ }
11
+
12
+ static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
13
+ if (isSSR()) {
14
+ return [];
15
+ }
16
+
17
+ const { pageDataLoader } = await import('@utils/page-loaders/page-data-loader');
18
+ const { getSpecificationsForService } = await import('@utils/collections/services');
19
+
20
+ const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains'];
21
+ const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
22
+
23
+ const hasSpecifications = (item: CollectionEntry<CollectionTypes>) => {
24
+ const specifications = getSpecificationsForService(item);
25
+ // Ensure there is at least one 'asyncapi' specification
26
+ return specifications && specifications.some((spec) => spec.type === 'asyncapi');
27
+ };
28
+
29
+ const filteredItems = allItems.map((items) => items.filter(hasSpecifications));
30
+
31
+ return filteredItems.flatMap((items, index) =>
32
+ items.flatMap((item) => {
33
+ const asyncApiSpecifications = getSpecificationsForService(item).filter((spec) => spec.type === 'asyncapi');
34
+
35
+ return asyncApiSpecifications.map((spec) => ({
36
+ params: {
37
+ type: itemTypes[index],
38
+ id: item.data.id,
39
+ version: item.data.version,
40
+ filename: spec.filenameWithoutExtension || spec.type,
41
+ },
42
+ props: {
43
+ type: itemTypes[index],
44
+ filenameWithoutExtension: spec.filenameWithoutExtension || spec.type,
45
+ filename: spec.filename || spec.type,
46
+ ...item,
47
+ },
48
+ }));
49
+ })
50
+ );
51
+ }
52
+
53
+ protected static async fetchData(params: any) {
54
+ const { type, id, version, filename } = params;
55
+
56
+ if (!type || !id || !version || !filename) {
57
+ return null;
58
+ }
59
+
60
+ const { pageDataLoader } = await import('@utils/page-loaders/page-data-loader');
61
+ const { getSpecificationsForService } = await import('@utils/collections/services');
62
+
63
+ // Get all items of the specified type
64
+ const items = await pageDataLoader[type as PageTypes]();
65
+
66
+ // Find the specific item by id and version
67
+ const item = items.find((i) => i.data.id === id && i.data.version === version);
68
+
69
+ if (!item) {
70
+ return null;
71
+ }
72
+
73
+ // Check if this item has AsyncAPI specifications
74
+ const specifications = getSpecificationsForService(item);
75
+ const asyncApiSpecifications = specifications.filter((spec) => spec.type === 'asyncapi');
76
+
77
+ // Find the specific specification
78
+ const spec = asyncApiSpecifications.find((s) => (s.filenameWithoutExtension || s.type) === filename);
79
+
80
+ if (!spec) {
81
+ return null;
82
+ }
83
+
84
+ return {
85
+ type,
86
+ filenameWithoutExtension: spec.filenameWithoutExtension || spec.type,
87
+ filename: spec.filename || spec.type,
88
+ ...item,
89
+ };
90
+ }
91
+
92
+ protected static createNotFoundResponse(): Response {
93
+ return new Response(null, {
94
+ status: 404,
95
+ statusText: 'AsyncAPI specification not found',
96
+ });
97
+ }
98
+ }
@@ -0,0 +1,68 @@
1
+ import { isSSR } from '@utils/feature';
2
+ import { HybridPage } from '@utils/page-loaders/hybrid-page';
3
+ import type { PageTypes } from '@types';
4
+
5
+ export class Page extends HybridPage {
6
+ static get prerender(): boolean {
7
+ return !isSSR();
8
+ }
9
+
10
+ static async getStaticPaths(): Promise<Array<{ params: any; props: any }>> {
11
+ if (isSSR()) {
12
+ return [];
13
+ }
14
+
15
+ const { pageDataLoader } = await import('@utils/page-loaders/page-data-loader');
16
+
17
+ const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains', 'flows'];
18
+ const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
19
+
20
+ return allItems.flatMap((items, index) =>
21
+ items.map((item) => ({
22
+ params: {
23
+ type: itemTypes[index],
24
+ id: item.data.id,
25
+ version: item.data.version,
26
+ },
27
+ props: {
28
+ type: itemTypes[index],
29
+ allCollectionItems: items,
30
+ ...item,
31
+ },
32
+ }))
33
+ );
34
+ }
35
+
36
+ protected static async fetchData(params: any) {
37
+ const { type, id, version } = params;
38
+
39
+ if (!type || !id || !version) {
40
+ return null;
41
+ }
42
+
43
+ const { pageDataLoader } = await import('@utils/page-loaders/page-data-loader');
44
+
45
+ // Get all items of the specified type
46
+ const items = await pageDataLoader[type as PageTypes]();
47
+
48
+ // Find the specific item by id and version
49
+ const item = items.find((i) => i.data.id === id && i.data.version === version);
50
+
51
+ if (!item) {
52
+ return null;
53
+ }
54
+
55
+ return {
56
+ type,
57
+ allCollectionItems: items,
58
+ ...item,
59
+ };
60
+ }
61
+
62
+ protected static createNotFoundResponse(): Response {
63
+ return new Response(null, {
64
+ status: 404,
65
+ statusText: 'Changelog not found',
66
+ });
67
+ }
68
+ }
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  import Footer from '@layouts/Footer.astro';
3
- import type { PageTypes } from '@types';
4
3
  import { getChangeLogs } from '@utils/collections/changelogs';
5
4
  import {
6
5
  RectangleGroupIcon,
@@ -10,7 +9,6 @@ import {
10
9
  MagnifyingGlassIcon,
11
10
  QueueListIcon,
12
11
  } from '@heroicons/react/24/outline';
13
- import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
14
12
  import { render, getEntry } from 'astro:content';
15
13
  import mdxComponents from '@components/MDX/components';
16
14
  import 'diff2html/bundles/css/diff2html.min.css';
@@ -20,38 +18,20 @@ import { getPreviousVersion } from '@utils/collections/util';
20
18
  import { getDiffsForCurrentAndPreviousVersion } from '@utils/collections/file-diffs';
21
19
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
22
20
  import { ClientRouter } from 'astro:transitions';
23
-
24
21
  import { isChangelogEnabled } from '@utils/feature';
25
22
 
26
- export async function getStaticPaths() {
27
- if (!isChangelogEnabled()) {
28
- return [];
29
- }
23
+ import { Page } from './_index.data';
30
24
 
31
- const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains', 'flows'];
32
- const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
25
+ export const prerender = Page.prerender;
26
+ export const getStaticPaths = Page.getStaticPaths;
33
27
 
34
- return allItems.flatMap((items, index) =>
35
- items.map((item) => ({
36
- params: {
37
- type: itemTypes[index],
38
- id: item.data.id,
39
- version: item.data.version,
40
- },
41
- props: {
42
- type: itemTypes[index],
43
- allCollectionItems: items,
44
- ...item,
45
- },
46
- }))
47
- );
48
- }
28
+ // Get data
29
+ const props = await Page.getData(Astro);
49
30
 
50
31
  if (!isChangelogEnabled()) {
51
32
  return Astro.redirect('/docs');
52
33
  }
53
34
 
54
- const props = Astro.props;
55
35
  let collectionItem = props;
56
36
  const logs = await getChangeLogs(props);
57
37
 
@@ -31,7 +31,6 @@ import {
31
31
  } from '@heroicons/react/24/outline';
32
32
  import { ArrowsRightLeftIcon } from '@heroicons/react/20/solid';
33
33
  import { Box, Boxes } from 'lucide-react';
34
- import type { PageTypes } from '@types';
35
34
  import type { CollectionTypes } from '@types';
36
35
 
37
36
  import { ClientRouter } from 'astro:transitions';
@@ -40,7 +39,6 @@ import type { CollectionEntry } from 'astro:content';
40
39
 
41
40
  import { getIcon } from '@utils/badges';
42
41
  import { getDeprecatedDetails } from '@utils/collections/util';
43
- import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
44
42
  import { buildUrl } from '@utils/url-builder';
45
43
  import { getSchemasFromResource } from '@utils/collections/schemas';
46
44
  import { isEventCatalogChatEnabled, isMarkdownDownloadEnabled } from '@utils/feature';
@@ -48,38 +46,21 @@ import { isEventCatalogChatEnabled, isMarkdownDownloadEnabled } from '@utils/fea
48
46
  import { getMDXComponentsByName } from '@utils/markdown';
49
47
 
50
48
  import config from '@config';
49
+ import { Page } from './_index.data';
51
50
 
52
- export async function getStaticPaths() {
53
- const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains', 'flows', 'channels', 'entities'];
54
- const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
51
+ export const prerender = Page.prerender;
52
+ export const getStaticPaths = Page.getStaticPaths;
55
53
 
56
- return allItems.flatMap((items, index) =>
57
- items.map((item) => ({
58
- params: {
59
- type: itemTypes[index],
60
- id: item.data.id,
61
- version: item.data.version,
62
- },
63
- props: {
64
- type: itemTypes[index],
65
- ...item,
66
- },
67
- }))
68
- );
69
- }
70
-
71
- const props = Astro.props;
54
+ // Get data
55
+ const props = await Page.getData(Astro);
72
56
 
73
57
  const { Content } = await render(props);
74
58
 
75
- // const { Content } = await props.render();
76
-
77
- // Capitalize the first letter of a string
78
59
  const pageTitle = `${props.collection} | ${props.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
79
60
  const contentBadges = props.data.badges || [];
80
61
 
81
62
  const getContentBadges = () =>
82
- contentBadges.map((badge) => ({
63
+ contentBadges.map((badge: any) => ({
83
64
  ...badge,
84
65
  icon: badge.icon ? getIcon(badge.icon) : null,
85
66
  }));
@@ -11,45 +11,16 @@ import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
11
11
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
12
12
  import { getSpecificationsForService } from '@utils/collections/services';
13
13
  import './_styles.css';
14
+ import { Page } from './_[filename].data.ts';
14
15
 
15
- export async function getStaticPaths() {
16
- const itemTypes: PageTypes[] = ['events', 'commands', 'queries', 'services', 'domains'];
16
+ export const prerender = Page.prerender;
17
+ export const getStaticPaths = Page.getStaticPaths;
17
18
 
18
- const allItems = await Promise.all(itemTypes.map((type) => pageDataLoader[type]()));
19
-
20
- const hasSpecifications = (item: CollectionEntry<CollectionTypes>) => {
21
- const specifications = getSpecificationsForService(item);
22
- // Ensure there is at least one 'openapi' specification
23
- return specifications && specifications.some((spec) => spec.type === 'openapi');
24
- };
25
-
26
- const filteredItems = allItems.map((items) => items.filter(hasSpecifications));
27
-
28
- return filteredItems.flatMap((items, index) =>
29
- items.flatMap((item) => {
30
- // Filter for openapi specifications only
31
- const openApiSpecifications = getSpecificationsForService(item).filter((spec) => spec.type === 'openapi');
32
-
33
- return openApiSpecifications.map((spec) => ({
34
- params: {
35
- type: itemTypes[index],
36
- id: item.data.id,
37
- version: item.data.version,
38
- filename: spec.filenameWithoutExtension || spec.type,
39
- },
40
- props: {
41
- type: itemTypes[index],
42
- filenameWithoutExtension: spec.filenameWithoutExtension || spec.type,
43
- filename: spec.filename || spec.type,
44
- ...item,
45
- },
46
- }));
47
- })
48
- );
49
- }
19
+ // Get data
20
+ const props = await Page.getData(Astro);
50
21
 
51
22
  // @ts-ignore
52
- const { collection, data, catalog, filePath, filename } = Astro.props;
23
+ const { collection, data, catalog, filePath, filename } = props;
53
24
  const fileName = filename || 'openapi.yml';
54
25
 
55
26
  const directory = path.dirname(filePath || '');