@redocly/realm-plugin-asciidoc 0.1.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.
@@ -0,0 +1,46 @@
1
+ import type { SearchFacet } from '@redocly/theme';
2
+
3
+ const SEARCH_GROUP_FIELD = 'redocly_category';
4
+ const SEARCH_GROUP_NAME_DOCS = 'Documentation';
5
+
6
+ export function setDocumentSearchFacets(
7
+ documentSearchFacets: Record<string, string | Set<string>>,
8
+ getSearchFacets: () => Map<string, SearchFacet>,
9
+ setSearchFacets: (searchFacets: Map<string, SearchFacet>) => void,
10
+ ): void {
11
+ const searchFacets = getSearchFacets();
12
+
13
+ for (const [key, value] of Object.entries(documentSearchFacets)) {
14
+ const facet = searchFacets.get(key);
15
+ if (facet) {
16
+ const facetValues = new Set((facet.values as string[]) ?? []);
17
+ if (value instanceof Set) {
18
+ [...value].forEach((v) => (facet.values = Array.from(facetValues.add(v))));
19
+ } else {
20
+ facet.values = Array.from(facetValues.add(value));
21
+ }
22
+ }
23
+ }
24
+
25
+ setSearchFacets(searchFacets);
26
+ }
27
+
28
+ export function extractDocumentSearchFacets(
29
+ metadata?: Record<string, unknown>,
30
+ getSearchFacets?: () => Map<string, SearchFacet>,
31
+ ): Record<string, string> {
32
+ const searchFacets: Record<string, string> = {
33
+ [SEARCH_GROUP_FIELD]: SEARCH_GROUP_NAME_DOCS,
34
+ };
35
+
36
+ if (!metadata || !getSearchFacets) return searchFacets;
37
+
38
+ const targetSearchFacets = getSearchFacets();
39
+
40
+ for (const [key, value] of Object.entries(metadata)) {
41
+ if (!targetSearchFacets.has(key)) continue;
42
+ searchFacets[key] = String(value);
43
+ }
44
+
45
+ return searchFacets;
46
+ }
@@ -0,0 +1,98 @@
1
+ import { REDOCLY_ROUTE_RBAC, REDOCLY_TEAMS_RBAC } from '@redocly/config';
2
+
3
+ import type { PageRouteDetails, SearchDocument } from '@redocly/realm/dist/server/types';
4
+ import type { SearchFacet } from '@redocly/theme';
5
+ import type { AsciidocSection, AsciidocFrontmatter } from './types.js';
6
+
7
+ import { extractDocumentSearchFacets, setDocumentSearchFacets } from './search-facets.js';
8
+
9
+ export function searchResolver(
10
+ frontmatter: AsciidocFrontmatter,
11
+ relativePath: string,
12
+ sections: AsciidocSection[],
13
+ getSearchFacets: () => Map<string, SearchFacet>,
14
+ setSearchFacets: (searchFacets: Map<string, SearchFacet>) => void,
15
+ ): (route: PageRouteDetails, staticData: Record<string, unknown>) => Promise<SearchDocument[]> {
16
+ return async (route: PageRouteDetails, staticData: Record<string, unknown>) => {
17
+ if (frontmatter.excludeFromSearch) return [];
18
+
19
+ const metadata = route.metadata || {};
20
+ const facets = extractDocumentSearchFacets(metadata, getSearchFacets);
21
+ setDocumentSearchFacets(facets, getSearchFacets, setSearchFacets);
22
+
23
+ const pageTitle = frontmatter.seo?.title || frontmatter.title || relativePath;
24
+ const pageUrl = route.slug;
25
+ const teamsRbac = staticData[REDOCLY_TEAMS_RBAC] as { [key: string]: string } | undefined;
26
+ const routeRbac = staticData[REDOCLY_ROUTE_RBAC] as
27
+ | { slug?: string; fsPath?: string }
28
+ | undefined;
29
+
30
+ const searchDocuments: SearchDocument[] = [];
31
+
32
+ // Add the main page document
33
+ const allText = flattenSectionsText(sections);
34
+ searchDocuments.push({
35
+ id: pageUrl,
36
+ url: pageUrl,
37
+ title: pageTitle,
38
+ text: allText,
39
+ facets,
40
+ [REDOCLY_TEAMS_RBAC]: teamsRbac,
41
+ [REDOCLY_ROUTE_RBAC]: routeRbac,
42
+ });
43
+
44
+ // Add individual sections as search documents
45
+ for (const section of sections) {
46
+ addSectionDocuments(
47
+ section,
48
+ pageUrl,
49
+ pageTitle,
50
+ facets,
51
+ teamsRbac,
52
+ routeRbac,
53
+ searchDocuments,
54
+ );
55
+ }
56
+
57
+ return searchDocuments;
58
+ };
59
+ }
60
+
61
+ function addSectionDocuments(
62
+ section: AsciidocSection,
63
+ pageUrl: string,
64
+ pageTitle: string,
65
+ facets: Record<string, string>,
66
+ teamsRbac: { [key: string]: string } | undefined,
67
+ routeRbac: { slug?: string; fsPath?: string } | undefined,
68
+ documents: SearchDocument[],
69
+ ): void {
70
+ if (section.textContent) {
71
+ const sectionUrl = `${pageUrl}#${section.id}`;
72
+ documents.push({
73
+ id: sectionUrl,
74
+ url: sectionUrl,
75
+ title: section.title,
76
+ text: section.textContent,
77
+ path: [pageTitle, section.title],
78
+ facets,
79
+ [REDOCLY_TEAMS_RBAC]: teamsRbac,
80
+ [REDOCLY_ROUTE_RBAC]: routeRbac,
81
+ });
82
+ }
83
+
84
+ for (const child of section.children) {
85
+ addSectionDocuments(child, pageUrl, pageTitle, facets, teamsRbac, routeRbac, documents);
86
+ }
87
+ }
88
+
89
+ function flattenSectionsText(sections: AsciidocSection[]): string {
90
+ const parts: string[] = [];
91
+ for (const section of sections) {
92
+ if (section.textContent) parts.push(section.textContent);
93
+ if (section.children.length) {
94
+ parts.push(flattenSectionsText(section.children));
95
+ }
96
+ }
97
+ return parts.join('\n');
98
+ }