@eventcatalog/core 3.14.6 → 3.15.0-beta.1
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/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-LNIPDPVB.js → chunk-6NJZEWVT.js} +1 -1
- package/dist/{chunk-TERDXO46.js → chunk-GPD6XYQI.js} +1 -1
- package/dist/{chunk-NYVQSLA5.js → chunk-SEJTXM5L.js} +1 -1
- package/dist/{chunk-KWCAGR52.js → chunk-UFOXV4FN.js} +1 -1
- package/dist/{chunk-6NRRWRLT.js → chunk-ZP4JNCSQ.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +75 -11
- package/dist/eventcatalog.js +80 -16
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +56 -10
- package/eventcatalog/src/content.config.ts +89 -20
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +85 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +195 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +86 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +195 -0
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +9 -0
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +15 -9
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +9 -0
- package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +13 -4
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +9 -0
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +9 -0
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +82 -0
- package/eventcatalog/src/stores/sidebar-store/state.ts +27 -2
- package/eventcatalog/src/utils/collections/data-products.ts +6 -2
- package/eventcatalog/src/utils/collections/resource-docs.ts +601 -0
- package/eventcatalog/src/utils/feature.ts +1 -0
- package/package.json +1 -1
|
@@ -29,9 +29,14 @@ export const projectDirBase = (() => {
|
|
|
29
29
|
return projectDir;
|
|
30
30
|
})();
|
|
31
31
|
|
|
32
|
+
const withIgnoredBuildArtifacts = (patterns: string | string[]) => {
|
|
33
|
+
const patternList = Array.isArray(patterns) ? patterns : [patterns];
|
|
34
|
+
return [...patternList, '!dist/**'];
|
|
35
|
+
};
|
|
36
|
+
|
|
32
37
|
const pages = defineCollection({
|
|
33
38
|
loader: glob({
|
|
34
|
-
pattern: ['**/pages/*.(md|mdx)'],
|
|
39
|
+
pattern: withIgnoredBuildArtifacts(['**/pages/*.(md|mdx)']),
|
|
35
40
|
base: projectDirBase,
|
|
36
41
|
}),
|
|
37
42
|
schema: z
|
|
@@ -90,7 +95,7 @@ const resourcePointer = z.object({
|
|
|
90
95
|
|
|
91
96
|
const changelogs = defineCollection({
|
|
92
97
|
loader: glob({
|
|
93
|
-
pattern: ['**/changelog.(md|mdx)'],
|
|
98
|
+
pattern: withIgnoredBuildArtifacts(['**/changelog.(md|mdx)']),
|
|
94
99
|
base: projectDirBase,
|
|
95
100
|
}),
|
|
96
101
|
schema: z.object({
|
|
@@ -229,7 +234,7 @@ const flowStep = z
|
|
|
229
234
|
|
|
230
235
|
const flows = defineCollection({
|
|
231
236
|
loader: glob({
|
|
232
|
-
pattern: ['**/flows/*/index.(md|mdx)', '**/flows/*/versioned/*/index.(md|mdx)'],
|
|
237
|
+
pattern: withIgnoredBuildArtifacts(['**/flows/*/index.(md|mdx)', '**/flows/*/versioned/*/index.(md|mdx)']),
|
|
233
238
|
base: projectDirBase,
|
|
234
239
|
generateId: ({ data }) => {
|
|
235
240
|
return `${data.id}-${data.version}`;
|
|
@@ -317,7 +322,7 @@ const messageDetailsPanelPropertySchema = z.object({
|
|
|
317
322
|
|
|
318
323
|
const events = defineCollection({
|
|
319
324
|
loader: glob({
|
|
320
|
-
pattern: ['**/events/*/index.(md|mdx)', '**/events/*/versioned/*/index.(md|mdx)'],
|
|
325
|
+
pattern: withIgnoredBuildArtifacts(['**/events/*/index.(md|mdx)', '**/events/*/versioned/*/index.(md|mdx)']),
|
|
321
326
|
base: projectDirBase,
|
|
322
327
|
generateId: ({ data, ...rest }) => {
|
|
323
328
|
return `${data.id}-${data.version}`;
|
|
@@ -337,7 +342,7 @@ const events = defineCollection({
|
|
|
337
342
|
|
|
338
343
|
const commands = defineCollection({
|
|
339
344
|
loader: glob({
|
|
340
|
-
pattern: ['**/commands/*/index.(md|mdx)', '**/commands/*/versioned/*/index.(md|mdx)'],
|
|
345
|
+
pattern: withIgnoredBuildArtifacts(['**/commands/*/index.(md|mdx)', '**/commands/*/versioned/*/index.(md|mdx)']),
|
|
341
346
|
base: projectDirBase,
|
|
342
347
|
generateId: ({ data }) => {
|
|
343
348
|
return `${data.id}-${data.version}`;
|
|
@@ -357,7 +362,7 @@ const commands = defineCollection({
|
|
|
357
362
|
|
|
358
363
|
const queries = defineCollection({
|
|
359
364
|
loader: glob({
|
|
360
|
-
pattern: ['**/queries/*/index.(md|mdx)', '**/queries/*/versioned/*/index.(md|mdx)'],
|
|
365
|
+
pattern: withIgnoredBuildArtifacts(['**/queries/*/index.(md|mdx)', '**/queries/*/versioned/*/index.(md|mdx)']),
|
|
361
366
|
base: projectDirBase,
|
|
362
367
|
generateId: ({ data }) => {
|
|
363
368
|
return `${data.id}-${data.version}`;
|
|
@@ -389,7 +394,7 @@ const dataProductOutputPointer = z.object({
|
|
|
389
394
|
|
|
390
395
|
const dataProducts = defineCollection({
|
|
391
396
|
loader: glob({
|
|
392
|
-
pattern: ['**/data-products/*/index.(md|mdx)', '**/data-products/*/versioned/*/index.(md|mdx)'],
|
|
397
|
+
pattern: withIgnoredBuildArtifacts(['**/data-products/*/index.(md|mdx)', '**/data-products/*/versioned/*/index.(md|mdx)']),
|
|
393
398
|
base: projectDirBase,
|
|
394
399
|
generateId: ({ data }) => {
|
|
395
400
|
return `${data.id}-${data.version}`;
|
|
@@ -405,7 +410,7 @@ const dataProducts = defineCollection({
|
|
|
405
410
|
|
|
406
411
|
const services = defineCollection({
|
|
407
412
|
loader: glob({
|
|
408
|
-
pattern: [
|
|
413
|
+
pattern: withIgnoredBuildArtifacts([
|
|
409
414
|
'domains/*/services/*/index.(md|mdx)',
|
|
410
415
|
'domains/*/services/*/versioned/*/index.(md|mdx)',
|
|
411
416
|
|
|
@@ -416,7 +421,7 @@ const services = defineCollection({
|
|
|
416
421
|
// Capture services in the root
|
|
417
422
|
'services/*/index.(md|mdx)', // ✅ Capture only services markdown files
|
|
418
423
|
'services/*/versioned/*/index.(md|mdx)', // ✅ Capture versioned files inside services
|
|
419
|
-
],
|
|
424
|
+
]),
|
|
420
425
|
base: projectDirBase,
|
|
421
426
|
generateId: ({ data, ...rest }) => {
|
|
422
427
|
return `${data.id}-${data.version}`;
|
|
@@ -466,7 +471,7 @@ const dataClassificationEnum = z.enum(['public', 'internal', 'confidential', 're
|
|
|
466
471
|
|
|
467
472
|
const containers = defineCollection({
|
|
468
473
|
loader: glob({
|
|
469
|
-
pattern: ['**/containers/**/index.(md|mdx)', '**/containers/**/versioned/*/index.(md|mdx)'],
|
|
474
|
+
pattern: withIgnoredBuildArtifacts(['**/containers/**/index.(md|mdx)', '**/containers/**/versioned/*/index.(md|mdx)']),
|
|
470
475
|
base: projectDirBase,
|
|
471
476
|
generateId: ({ data }) => {
|
|
472
477
|
return `${data.id}-${data.version}`;
|
|
@@ -505,15 +510,66 @@ const containers = defineCollection({
|
|
|
505
510
|
const customPages = defineCollection({
|
|
506
511
|
loader: glob({
|
|
507
512
|
// any number of child folders
|
|
508
|
-
pattern: ['docs/*.(md|mdx)', 'docs/**/*.@(md|mdx)'],
|
|
513
|
+
pattern: withIgnoredBuildArtifacts(['docs/*.(md|mdx)', 'docs/**/*.@(md|mdx)']),
|
|
509
514
|
base: projectDirBase,
|
|
510
515
|
}),
|
|
511
516
|
schema: customPagesSchema,
|
|
512
517
|
});
|
|
513
518
|
|
|
519
|
+
const resourceDocs = defineCollection({
|
|
520
|
+
loader: glob({
|
|
521
|
+
// Resource-level docs are restricted to known resource paths.
|
|
522
|
+
// This avoids scanning external docs such as node_modules/**/docs.
|
|
523
|
+
pattern: withIgnoredBuildArtifacts([
|
|
524
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/docs/**/*.@(md|mdx)',
|
|
525
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/versioned/*/docs/**/*.@(md|mdx)',
|
|
526
|
+
'domains/*/docs/**/*.@(md|mdx)',
|
|
527
|
+
'domains/*/versioned/*/docs/**/*.@(md|mdx)',
|
|
528
|
+
'domains/*/subdomains/*/docs/**/*.@(md|mdx)',
|
|
529
|
+
'domains/*/subdomains/*/versioned/*/docs/**/*.@(md|mdx)',
|
|
530
|
+
]),
|
|
531
|
+
base: projectDirBase,
|
|
532
|
+
}),
|
|
533
|
+
schema: z.object({
|
|
534
|
+
id: z.string().optional(),
|
|
535
|
+
type: z.string().optional(),
|
|
536
|
+
version: z.string().optional(),
|
|
537
|
+
order: z.number().optional(),
|
|
538
|
+
badges: z.array(badge).optional(),
|
|
539
|
+
title: z.string().optional(),
|
|
540
|
+
summary: z.string().optional(),
|
|
541
|
+
slug: z.string().optional(),
|
|
542
|
+
hidden: z.boolean().optional(),
|
|
543
|
+
}),
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
const resourceDocCategories = defineCollection({
|
|
547
|
+
loader: glob({
|
|
548
|
+
pattern: withIgnoredBuildArtifacts([
|
|
549
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/docs/**/category.json',
|
|
550
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/docs/**/_category_.json',
|
|
551
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/versioned/*/docs/**/category.json',
|
|
552
|
+
'{events,commands,queries,services,flows,containers,channels,entities,data-products}/*/versioned/*/docs/**/_category_.json',
|
|
553
|
+
'domains/*/docs/**/category.json',
|
|
554
|
+
'domains/*/docs/**/_category_.json',
|
|
555
|
+
'domains/*/versioned/*/docs/**/category.json',
|
|
556
|
+
'domains/*/versioned/*/docs/**/_category_.json',
|
|
557
|
+
'domains/*/subdomains/*/docs/**/category.json',
|
|
558
|
+
'domains/*/subdomains/*/docs/**/_category_.json',
|
|
559
|
+
'domains/*/subdomains/*/versioned/*/docs/**/category.json',
|
|
560
|
+
'domains/*/subdomains/*/versioned/*/docs/**/_category_.json',
|
|
561
|
+
]),
|
|
562
|
+
base: projectDirBase,
|
|
563
|
+
}),
|
|
564
|
+
schema: z.object({
|
|
565
|
+
label: z.string().optional(),
|
|
566
|
+
position: z.number().optional(),
|
|
567
|
+
}),
|
|
568
|
+
});
|
|
569
|
+
|
|
514
570
|
const domains = defineCollection({
|
|
515
571
|
loader: glob({
|
|
516
|
-
pattern: [
|
|
572
|
+
pattern: withIgnoredBuildArtifacts([
|
|
517
573
|
// ✅ Strictly include only index.md at the expected levels
|
|
518
574
|
'domains/*/index.(md|mdx)',
|
|
519
575
|
'domains/*/versioned/*/index.(md|mdx)',
|
|
@@ -521,7 +577,7 @@ const domains = defineCollection({
|
|
|
521
577
|
// Capture subdomain folders
|
|
522
578
|
'domains/*/subdomains/*/index.(md|mdx)',
|
|
523
579
|
'domains/*/subdomains/*/versioned/*/index.(md|mdx)',
|
|
524
|
-
],
|
|
580
|
+
]),
|
|
525
581
|
base: projectDirBase,
|
|
526
582
|
generateId: ({ data, ...rest }) => {
|
|
527
583
|
return `${data.id}-${data.version}`;
|
|
@@ -557,7 +613,7 @@ const domains = defineCollection({
|
|
|
557
613
|
|
|
558
614
|
const channels = defineCollection({
|
|
559
615
|
loader: glob({
|
|
560
|
-
pattern: ['**/channels/**/index.(md|mdx)', '**/channels/**/versioned/*/index.(md|mdx)'],
|
|
616
|
+
pattern: withIgnoredBuildArtifacts(['**/channels/**/index.(md|mdx)', '**/channels/**/versioned/*/index.(md|mdx)']),
|
|
561
617
|
base: projectDirBase,
|
|
562
618
|
generateId: ({ data }) => {
|
|
563
619
|
return `${data.id}-${data.version}`;
|
|
@@ -600,7 +656,10 @@ const channels = defineCollection({
|
|
|
600
656
|
|
|
601
657
|
const ubiquitousLanguages = defineCollection({
|
|
602
658
|
loader: glob({
|
|
603
|
-
pattern: [
|
|
659
|
+
pattern: withIgnoredBuildArtifacts([
|
|
660
|
+
'domains/*/ubiquitous-language.(md|mdx)',
|
|
661
|
+
'domains/*/subdomains/*/ubiquitous-language.(md|mdx)',
|
|
662
|
+
]),
|
|
604
663
|
base: projectDirBase,
|
|
605
664
|
generateId: ({ data }) => {
|
|
606
665
|
// File has no id, so we need to generate one
|
|
@@ -624,7 +683,7 @@ const ubiquitousLanguages = defineCollection({
|
|
|
624
683
|
|
|
625
684
|
const entities = defineCollection({
|
|
626
685
|
loader: glob({
|
|
627
|
-
pattern: ['**/entities/*/index.(md|mdx)', '**/entities/*/versioned/*/index.(md|mdx)'],
|
|
686
|
+
pattern: withIgnoredBuildArtifacts(['**/entities/*/index.(md|mdx)', '**/entities/*/versioned/*/index.(md|mdx)']),
|
|
628
687
|
base: projectDirBase,
|
|
629
688
|
generateId: ({ data, ...rest }) => {
|
|
630
689
|
return `${data.id}-${data.version}`;
|
|
@@ -672,7 +731,11 @@ const entities = defineCollection({
|
|
|
672
731
|
});
|
|
673
732
|
|
|
674
733
|
const users = defineCollection({
|
|
675
|
-
loader: glob({
|
|
734
|
+
loader: glob({
|
|
735
|
+
pattern: withIgnoredBuildArtifacts('users/*.(md|mdx)'),
|
|
736
|
+
base: projectDirBase,
|
|
737
|
+
generateId: ({ data }) => data.id as string,
|
|
738
|
+
}),
|
|
676
739
|
schema: z.object({
|
|
677
740
|
id: z.string(),
|
|
678
741
|
name: z.string(),
|
|
@@ -692,7 +755,11 @@ const users = defineCollection({
|
|
|
692
755
|
});
|
|
693
756
|
|
|
694
757
|
const teams = defineCollection({
|
|
695
|
-
loader: glob({
|
|
758
|
+
loader: glob({
|
|
759
|
+
pattern: withIgnoredBuildArtifacts('teams/*.(md|mdx)'),
|
|
760
|
+
base: projectDirBase,
|
|
761
|
+
generateId: ({ data }) => data.id as string,
|
|
762
|
+
}),
|
|
696
763
|
schema: z.object({
|
|
697
764
|
id: z.string(),
|
|
698
765
|
name: z.string(),
|
|
@@ -712,7 +779,7 @@ const teams = defineCollection({
|
|
|
712
779
|
|
|
713
780
|
const designs = defineCollection({
|
|
714
781
|
loader: async () => {
|
|
715
|
-
const data = await globPackage('**/**/*.ecstudio', { cwd: projectDirBase });
|
|
782
|
+
const data = await globPackage('**/**/*.ecstudio', { cwd: projectDirBase, ignore: ['dist/**'] });
|
|
716
783
|
// File all the files in the designs folder
|
|
717
784
|
// Limit 3 designs community edition?
|
|
718
785
|
const files = data.reduce<{ id: string; name: string }[]>((acc, filePath) => {
|
|
@@ -741,7 +808,7 @@ const designs = defineCollection({
|
|
|
741
808
|
|
|
742
809
|
const diagrams = defineCollection({
|
|
743
810
|
loader: glob({
|
|
744
|
-
pattern: ['**/diagrams/**/index.(md|mdx)', '**/diagrams/**/versioned/*/index.(md|mdx)'],
|
|
811
|
+
pattern: withIgnoredBuildArtifacts(['**/diagrams/**/index.(md|mdx)', '**/diagrams/**/versioned/*/index.(md|mdx)']),
|
|
745
812
|
base: projectDirBase,
|
|
746
813
|
generateId: ({ data }) => `${data.id}-${data.version}`,
|
|
747
814
|
}),
|
|
@@ -778,6 +845,8 @@ export const collections = {
|
|
|
778
845
|
|
|
779
846
|
// EventCatalog Pro Collections
|
|
780
847
|
customPages,
|
|
848
|
+
resourceDocs,
|
|
849
|
+
resourceDocCategories,
|
|
781
850
|
|
|
782
851
|
// EventCatalog Studio Collections
|
|
783
852
|
designs,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { isSSR, isResourceDocsEnabled } from '@utils/feature';
|
|
2
|
+
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
+
import { getResourceDocs, getResourceDocsForResource, type ResourceCollection } from '@utils/collections/resource-docs';
|
|
4
|
+
|
|
5
|
+
const supportedResourceCollections = new Set<ResourceCollection>([
|
|
6
|
+
'domains',
|
|
7
|
+
'services',
|
|
8
|
+
'events',
|
|
9
|
+
'commands',
|
|
10
|
+
'queries',
|
|
11
|
+
'flows',
|
|
12
|
+
'containers',
|
|
13
|
+
'channels',
|
|
14
|
+
'entities',
|
|
15
|
+
'data-products',
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
export class Page extends HybridPage {
|
|
19
|
+
static async getStaticPaths() {
|
|
20
|
+
if (isSSR() || !isResourceDocsEnabled()) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const docs = await getResourceDocs();
|
|
25
|
+
|
|
26
|
+
return docs.map((doc) => ({
|
|
27
|
+
params: {
|
|
28
|
+
type: doc.data.resourceCollection,
|
|
29
|
+
id: doc.data.resourceId,
|
|
30
|
+
version: doc.data.resourceVersion,
|
|
31
|
+
docType: doc.data.type,
|
|
32
|
+
docId: doc.data.id,
|
|
33
|
+
docVersion: doc.data.version,
|
|
34
|
+
},
|
|
35
|
+
props: {},
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected static async fetchData(params: any) {
|
|
40
|
+
if (!isResourceDocsEnabled()) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const decodeParam = (value: string) => {
|
|
45
|
+
try {
|
|
46
|
+
return decodeURIComponent(value);
|
|
47
|
+
} catch {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const type = decodeParam(params.type);
|
|
53
|
+
const id = decodeParam(params.id);
|
|
54
|
+
const version = decodeParam(params.version);
|
|
55
|
+
const docType = decodeParam(params.docType);
|
|
56
|
+
const docId = decodeParam(params.docId);
|
|
57
|
+
const docVersion = decodeParam(params.docVersion);
|
|
58
|
+
if (!type || !id || !version || !docType || !docId || !docVersion) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!supportedResourceCollections.has(type as ResourceCollection)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const docsForResource = await getResourceDocsForResource(type as ResourceCollection, id, version);
|
|
67
|
+
const doc = docsForResource.find(
|
|
68
|
+
(resourceDoc) =>
|
|
69
|
+
resourceDoc.data.type === docType && resourceDoc.data.id === docId && resourceDoc.data.version === docVersion
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if (!doc) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return doc;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected static createNotFoundResponse(): Response {
|
|
80
|
+
return new Response(null, {
|
|
81
|
+
status: 404,
|
|
82
|
+
statusText: 'Resource documentation not found',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { render } from 'astro:content';
|
|
3
|
+
|
|
4
|
+
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
5
|
+
import components from '@components/MDX/components';
|
|
6
|
+
import { buildUrl } from '@utils/url-builder';
|
|
7
|
+
import { AlignLeftIcon, HistoryIcon } from 'lucide-react';
|
|
8
|
+
import { isResourceDocsEnabled } from '@utils/feature';
|
|
9
|
+
import { getIcon } from '@utils/badges';
|
|
10
|
+
import { collectionToResourceMap } from '@utils/collections/util';
|
|
11
|
+
|
|
12
|
+
import { Page } from './_index.data';
|
|
13
|
+
|
|
14
|
+
export const prerender = Page.prerender;
|
|
15
|
+
export const getStaticPaths = Page.getStaticPaths;
|
|
16
|
+
|
|
17
|
+
if (!isResourceDocsEnabled()) {
|
|
18
|
+
return Astro.redirect(buildUrl('/docs/custom/feature'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const props = await Page.getData(Astro);
|
|
22
|
+
const { Content, headings } = await render(props);
|
|
23
|
+
|
|
24
|
+
const title = props.data.title || props.data.id;
|
|
25
|
+
const pageTitle = `${title} | ${props.data.resourceId}`;
|
|
26
|
+
const versions = props.data.versions || [props.data.version];
|
|
27
|
+
const badges = (props.data.badges || []).map((badge: any) => ({
|
|
28
|
+
...badge,
|
|
29
|
+
iconComponent: badge.icon ? getIcon(badge.icon) : null,
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const docsBasePath = `/docs/${props.data.resourceCollection}/${props.data.resourceId}/${props.data.resourceVersion}/${encodeURIComponent(props.data.type)}/${encodeURIComponent(props.data.id)}`;
|
|
33
|
+
const singularResourceName =
|
|
34
|
+
collectionToResourceMap[props.data.resourceCollection as keyof typeof collectionToResourceMap] ??
|
|
35
|
+
props.data.resourceCollection.slice(0, props.data.resourceCollection.length - 1);
|
|
36
|
+
|
|
37
|
+
const pagefindAttributes =
|
|
38
|
+
props.data.version === props.data.latestVersion
|
|
39
|
+
? {
|
|
40
|
+
'data-pagefind-body': '',
|
|
41
|
+
'data-pagefind-meta': `title:${pageTitle}`,
|
|
42
|
+
}
|
|
43
|
+
: {};
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
<VerticalSideBarLayout title={pageTitle} description={props.data.summary}>
|
|
47
|
+
<main class="flex docs-layout h-full bg-[rgb(var(--ec-page-bg))]" {...pagefindAttributes}>
|
|
48
|
+
<div class="flex docs-layout w-full pl-16">
|
|
49
|
+
<div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8 bg-[rgb(var(--ec-page-bg))]">
|
|
50
|
+
<div class="border-b border-[rgb(var(--ec-page-border))] pb-4">
|
|
51
|
+
<p class="text-xs uppercase tracking-wide text-[rgb(var(--ec-page-text-muted))]">
|
|
52
|
+
<a
|
|
53
|
+
href={buildUrl(`/docs/${props.data.resourceCollection}/${props.data.resourceId}/${props.data.resourceVersion}`)}
|
|
54
|
+
class="hover:underline"
|
|
55
|
+
>
|
|
56
|
+
{singularResourceName}: {props.data.resourceId}
|
|
57
|
+
</a>
|
|
58
|
+
</p>
|
|
59
|
+
<div class="flex items-center gap-2 pt-1">
|
|
60
|
+
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{title}</h2>
|
|
61
|
+
<span
|
|
62
|
+
class="text-xs rounded-md px-2 py-1 bg-[rgb(var(--ec-content-hover))] text-[rgb(var(--ec-page-text-muted))] border border-[rgb(var(--ec-page-border))]"
|
|
63
|
+
>
|
|
64
|
+
v{props.data.version}
|
|
65
|
+
{props.data.version === props.data.latestVersion && ' (latest)'}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
{
|
|
69
|
+
props.data.summary && (
|
|
70
|
+
<p class="text-lg pt-2 text-[rgb(var(--ec-page-text-muted))] font-light">{props.data.summary}</p>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
{
|
|
74
|
+
badges.length > 0 && (
|
|
75
|
+
<div class="flex flex-wrap gap-3 pt-4">
|
|
76
|
+
{badges.map((badge: any) => (
|
|
77
|
+
<span
|
|
78
|
+
class={`
|
|
79
|
+
inline-flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm font-medium
|
|
80
|
+
bg-[rgb(var(--ec-content-hover))] border border-[rgb(var(--ec-page-border))]
|
|
81
|
+
text-[rgb(var(--ec-page-text))]
|
|
82
|
+
`}
|
|
83
|
+
>
|
|
84
|
+
{badge.iconComponent && (
|
|
85
|
+
<badge.iconComponent className="w-4 h-4 flex-shrink-0 text-[rgb(var(--ec-icon-color))]" />
|
|
86
|
+
)}
|
|
87
|
+
<span>{badge.content}</span>
|
|
88
|
+
</span>
|
|
89
|
+
))}
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
</div>
|
|
94
|
+
<div data-pagefind-ignore>
|
|
95
|
+
{
|
|
96
|
+
props.data.version !== props.data.latestVersion && (
|
|
97
|
+
<div class="rounded-md bg-[rgb(var(--ec-accent-subtle))] p-4 not-prose my-4">
|
|
98
|
+
<div class="flex">
|
|
99
|
+
<div class="flex-shrink-0">
|
|
100
|
+
<svg class="h-5 w-5 text-[rgb(var(--ec-accent))]" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
101
|
+
<path
|
|
102
|
+
fill-rule="evenodd"
|
|
103
|
+
d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
|
|
104
|
+
clip-rule="evenodd"
|
|
105
|
+
/>
|
|
106
|
+
</svg>
|
|
107
|
+
</div>
|
|
108
|
+
<div class="ml-3">
|
|
109
|
+
<h3 class="text-sm font-medium text-[rgb(var(--ec-accent-text))]">New version found</h3>
|
|
110
|
+
<div class="mt-2 text-sm text-[rgb(var(--ec-accent-text))]">
|
|
111
|
+
<p>
|
|
112
|
+
You are looking at a previous version of the {singularResourceName} doc <strong>{title}</strong>.{' '}
|
|
113
|
+
<a
|
|
114
|
+
class="underline hover:text-primary block pt-2"
|
|
115
|
+
href={buildUrl(`${docsBasePath}/${props.data.latestVersion}`)}
|
|
116
|
+
>
|
|
117
|
+
The latest version of this doc is <span>v{props.data.latestVersion}</span> →
|
|
118
|
+
</a>
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
</div>
|
|
127
|
+
<div class="prose py-8 max-w-none">
|
|
128
|
+
<Content components={components(props)} />
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
<aside class="hidden lg:block sticky top-0 pb-10 w-80 overflow-y-auto border-l border-[rgb(var(--ec-page-border))] py-2">
|
|
132
|
+
<div class="sticky top-28 left-0 h-full overflow-y-auto px-6 py-4">
|
|
133
|
+
<h3 class="text-sm text-[rgb(var(--ec-page-text))] font-semibold capitalize flex items-center gap-2">
|
|
134
|
+
<AlignLeftIcon className="w-4 h-4" />
|
|
135
|
+
On this page
|
|
136
|
+
</h3>
|
|
137
|
+
<nav class="space-y-1 text-sm py-4">
|
|
138
|
+
{
|
|
139
|
+
headings.map((heading) => {
|
|
140
|
+
if (heading.depth > 3) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
return (
|
|
144
|
+
<a
|
|
145
|
+
href={`#${heading.slug}`}
|
|
146
|
+
class={`block text-[12px] py-0.5 ${heading.depth === 1 ? 'font-light' : ''} text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))]`}
|
|
147
|
+
style={`padding-left: ${(heading.depth - 1) * 8}px`}
|
|
148
|
+
>
|
|
149
|
+
{heading.text}
|
|
150
|
+
</a>
|
|
151
|
+
);
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
</nav>
|
|
155
|
+
<div class="space-y-2 pb-4">
|
|
156
|
+
<span class="text-xs text-[rgb(var(--ec-page-text))] font-semibold capitalize">Versions ({versions.length})</span>
|
|
157
|
+
<ul role="list" class="space-y-2">
|
|
158
|
+
{
|
|
159
|
+
versions.map((version: string) => (
|
|
160
|
+
<li class="version-item rounded-md px-1 group w-full">
|
|
161
|
+
<a class="flex items-center space-x-2" href={buildUrl(`${docsBasePath}/${encodeURIComponent(version)}`)}>
|
|
162
|
+
<HistoryIcon
|
|
163
|
+
className="h-4 w-4 text-[rgb(var(--ec-page-text-muted))] group-hover:text-[rgb(var(--ec-accent-text))]"
|
|
164
|
+
strokeWidth={1}
|
|
165
|
+
/>
|
|
166
|
+
<span
|
|
167
|
+
class={`font-light text-xs text-[rgb(var(--ec-page-text))] group-hover:text-[rgb(var(--ec-accent-text))] ${
|
|
168
|
+
version === props.data.version ? 'underline' : ''
|
|
169
|
+
}`}
|
|
170
|
+
>
|
|
171
|
+
{version === props.data.latestVersion ? `v${version} (latest)` : `v${version}`}
|
|
172
|
+
</span>
|
|
173
|
+
</a>
|
|
174
|
+
</li>
|
|
175
|
+
))
|
|
176
|
+
}
|
|
177
|
+
</ul>
|
|
178
|
+
<div class="border-b border-[rgb(var(--ec-page-border))] pt-2"></div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</aside>
|
|
182
|
+
</div>
|
|
183
|
+
</main>
|
|
184
|
+
</VerticalSideBarLayout>
|
|
185
|
+
|
|
186
|
+
<style is:global>
|
|
187
|
+
.docs-layout .prose {
|
|
188
|
+
max-width: none;
|
|
189
|
+
overflow: auto;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.version-item:hover {
|
|
193
|
+
background: linear-gradient(to left, rgb(var(--ec-accent-gradient-from)), rgb(var(--ec-accent-gradient-to)));
|
|
194
|
+
}
|
|
195
|
+
</style>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { isSSR, isResourceDocsEnabled } from '@utils/feature';
|
|
2
|
+
import { HybridPage } from '@utils/page-loaders/hybrid-page';
|
|
3
|
+
import { getResourceDocs, getResourceDocsForResource, type ResourceCollection } from '@utils/collections/resource-docs';
|
|
4
|
+
|
|
5
|
+
const supportedResourceCollections = new Set<ResourceCollection>([
|
|
6
|
+
'domains',
|
|
7
|
+
'services',
|
|
8
|
+
'events',
|
|
9
|
+
'commands',
|
|
10
|
+
'queries',
|
|
11
|
+
'flows',
|
|
12
|
+
'containers',
|
|
13
|
+
'channels',
|
|
14
|
+
'entities',
|
|
15
|
+
'data-products',
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
export class Page extends HybridPage {
|
|
19
|
+
static async getStaticPaths() {
|
|
20
|
+
if (isSSR() || !isResourceDocsEnabled()) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const docs = await getResourceDocs();
|
|
25
|
+
const latestDocs = docs.filter((doc) => doc.data.version === doc.data.latestVersion);
|
|
26
|
+
|
|
27
|
+
return latestDocs.map((doc) => ({
|
|
28
|
+
params: {
|
|
29
|
+
type: doc.data.resourceCollection,
|
|
30
|
+
id: doc.data.resourceId,
|
|
31
|
+
version: doc.data.resourceVersion,
|
|
32
|
+
docType: doc.data.type,
|
|
33
|
+
docId: doc.data.id,
|
|
34
|
+
},
|
|
35
|
+
props: {},
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected static async fetchData(params: any) {
|
|
40
|
+
if (!isResourceDocsEnabled()) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const decodeParam = (value: string) => {
|
|
45
|
+
try {
|
|
46
|
+
return decodeURIComponent(value);
|
|
47
|
+
} catch {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const type = decodeParam(params.type);
|
|
53
|
+
const id = decodeParam(params.id);
|
|
54
|
+
const version = decodeParam(params.version);
|
|
55
|
+
const docType = decodeParam(params.docType);
|
|
56
|
+
const docId = decodeParam(params.docId);
|
|
57
|
+
if (!type || !id || !version || !docType || !docId) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!supportedResourceCollections.has(type as ResourceCollection)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const docsForResource = await getResourceDocsForResource(type as ResourceCollection, id, version);
|
|
66
|
+
const doc = docsForResource.find(
|
|
67
|
+
(resourceDoc) =>
|
|
68
|
+
resourceDoc.data.type === docType &&
|
|
69
|
+
resourceDoc.data.id === docId &&
|
|
70
|
+
resourceDoc.data.version === resourceDoc.data.latestVersion
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
if (!doc) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return doc;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected static createNotFoundResponse(): Response {
|
|
81
|
+
return new Response(null, {
|
|
82
|
+
status: 404,
|
|
83
|
+
statusText: 'Resource documentation not found',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|