@lexibase/rdx-next 4.2.0 → 5.0.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.
package/bin/locale-routes.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { lstat, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
|
1
|
+
import { lstat, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
|
|
4
4
|
const defaultFiles = [
|
|
@@ -14,6 +14,7 @@ const generated = [
|
|
|
14
14
|
'app/(rdx-locales)/[locale]/not-found.tsx',
|
|
15
15
|
'app/(rdx-locales)/[locale]/docs/[[...slug]]/page.tsx',
|
|
16
16
|
'app/(rdx-locales)/[locale]/rdx-search/[source]/route.ts',
|
|
17
|
+
'app/(rdx-locales)/[locale]/docs/llms.txt/route.ts',
|
|
17
18
|
]
|
|
18
19
|
|
|
19
20
|
/** Root layouts keep HTML language correct on the server, without middleware. */
|
|
@@ -34,6 +35,18 @@ export async function prepareLocaleRoutes(project, runtime, template) {
|
|
|
34
35
|
}
|
|
35
36
|
return current
|
|
36
37
|
}
|
|
38
|
+
// An existing public index owns this URL. Keep it when upgrading a project.
|
|
39
|
+
const publicIndex = path.join(project.rootDir, 'public', 'docs', 'llms.txt')
|
|
40
|
+
const hasPublicIndex = await stat(publicIndex).then(
|
|
41
|
+
(entry) => entry.isFile(),
|
|
42
|
+
(error) => {
|
|
43
|
+
if (error.code === 'ENOENT' || error.code === 'ENOTDIR') return false
|
|
44
|
+
throw error
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
if (hasPublicIndex)
|
|
48
|
+
await rm(await safe('app/docs/llms.txt/route.ts'), { force: true })
|
|
49
|
+
|
|
37
50
|
const marker = await safe('.rdx-localization.json')
|
|
38
51
|
let owned = false
|
|
39
52
|
try {
|
|
@@ -130,6 +143,23 @@ export async function generateStaticParams() {
|
|
|
130
143
|
return project.localization!.locales.flatMap(locale => getSearchSources(getLocalizedProject(project, locale.path)).map(source => ({ locale: locale.path, ...source })))
|
|
131
144
|
}
|
|
132
145
|
export async function GET(_request: Request, { params }: { params: Promise<{ locale: string, source: string }> }) { const { locale, source } = await params; return getSearchResponse(getLocalizedProject(await getProject(), locale), source) }
|
|
146
|
+
`
|
|
147
|
+
)
|
|
148
|
+
await emit(
|
|
149
|
+
'app/(rdx-locales)/[locale]/docs/llms.txt/route.ts',
|
|
150
|
+
`import { getLlmIndexResponse, getLocalizedProject } from '${provider}'
|
|
151
|
+
import { getProject } from '../../../../../rdx-project'
|
|
152
|
+
export const dynamic = 'force-static'
|
|
153
|
+
export const dynamicParams = false
|
|
154
|
+
export async function generateStaticParams() {
|
|
155
|
+
return (await getProject()).localization!.locales.map(locale => ({ locale: locale.path }))
|
|
156
|
+
}
|
|
157
|
+
export async function GET(_request: Request, { params }: { params: Promise<{ locale: string }> }) {
|
|
158
|
+
const project = await getProject()
|
|
159
|
+
const { locale } = await params
|
|
160
|
+
if (!project.localization?.locales.some(entry => entry.path === locale)) return new Response(null, { status: 404 })
|
|
161
|
+
return getLlmIndexResponse(getLocalizedProject(project, locale))
|
|
162
|
+
}
|
|
133
163
|
`
|
|
134
164
|
)
|
|
135
165
|
await writeFile(marker, JSON.stringify({ version: 1 }) + '\n')
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -21,6 +21,17 @@ declare function getRdxSitemap(project: RdxProject, { documentPath, }?: {
|
|
|
21
21
|
documentPath?: (source: RdxContentSource, page: RdxDocPage) => string;
|
|
22
22
|
}): MetadataRoute.Sitemap;
|
|
23
23
|
|
|
24
|
+
type DocumentPath = (source: RdxContentSource, page: Pick<RdxDocPage, 'slug' | 'sourcePath'>) => string;
|
|
25
|
+
declare function getMarkdownHref(htmlPath: string): string;
|
|
26
|
+
declare function getLlmIndexResponse(project: RdxProject, documentPath?: DocumentPath): Response;
|
|
27
|
+
declare function getMarkdownPaths(project: RdxProject, documentPath?: DocumentPath): {
|
|
28
|
+
path: string[];
|
|
29
|
+
}[];
|
|
30
|
+
declare function parseMarkdownPath(path: string[]): string[] | undefined;
|
|
31
|
+
declare function getMarkdownResponse(project: RdxProject, path: string[]): Response;
|
|
32
|
+
declare function markdownNotFound(): Response;
|
|
33
|
+
declare function getDocumentMarkdownResponse(project: RdxProject, source: RdxContentSource | undefined, slug: string, documentPath?: DocumentPath): Response;
|
|
34
|
+
|
|
24
35
|
/** Read metadata from the same content source and index used by the page. */
|
|
25
36
|
declare function getDocumentMetadata({ project, slug, }: {
|
|
26
37
|
project: RdxProject;
|
|
@@ -47,4 +58,4 @@ declare function DocsPage({ slug, project, }: {
|
|
|
47
58
|
project: RdxProject;
|
|
48
59
|
}): Promise<react.JSX.Element>;
|
|
49
60
|
|
|
50
|
-
export { DocsPage, HomePage, NotFoundPage, RdxLayout, getDocumentMetadata, getPageMetadata, getRdxMetadata, getRdxRobots, getRdxSitemap, getSearchResponse, getSearchSources, getSourceRobots };
|
|
61
|
+
export { DocsPage, HomePage, NotFoundPage, RdxLayout, getDocumentMarkdownResponse, getDocumentMetadata, getLlmIndexResponse, getMarkdownHref, getMarkdownPaths, getMarkdownResponse, getPageMetadata, getRdxMetadata, getRdxRobots, getRdxSitemap, getSearchResponse, getSearchSources, getSourceRobots, markdownNotFound, parseMarkdownPath };
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// src/runtime/index.tsx
|
|
2
2
|
import {
|
|
3
|
-
getDocument as
|
|
3
|
+
getDocument as getDocument4,
|
|
4
4
|
getDocsPaths,
|
|
5
|
-
getSourceOptions as
|
|
5
|
+
getSourceOptions as getSourceOptions5,
|
|
6
6
|
resolveDocsRoute as resolveDocsRoute2,
|
|
7
|
-
getLocalizedProject as
|
|
8
|
-
getDocsHref as
|
|
7
|
+
getLocalizedProject as getLocalizedProject3,
|
|
8
|
+
getDocsHref as getDocsHref4,
|
|
9
9
|
getLanguageLinks,
|
|
10
|
-
isFallbackPage as
|
|
10
|
+
isFallbackPage as isFallbackPage4
|
|
11
11
|
} from "@lexibase/rdx-core";
|
|
12
|
+
import { getEditPageHref } from "@lexibase/rdx-core/config";
|
|
12
13
|
import { Button } from "@lexibase/rdx-ui/components/button";
|
|
13
14
|
import { Callout } from "@lexibase/rdx-ui/components/callout";
|
|
14
15
|
import { LanguageDropdown } from "@lexibase/rdx-ui/components/language-dropdown";
|
|
@@ -19,6 +20,8 @@ import { DocsSearch } from "@lexibase/rdx-ui/components/docs-search";
|
|
|
19
20
|
import { Home } from "@lexibase/rdx-ui/components/home";
|
|
20
21
|
import { SkipLink } from "@lexibase/rdx-ui/components/skip-link";
|
|
21
22
|
import { FooterCredit } from "@lexibase/rdx-ui/components/footer-credit";
|
|
23
|
+
import { EditPageLink } from "@lexibase/rdx-ui/components/edit-page-link";
|
|
24
|
+
import { CopyPage } from "@lexibase/rdx-ui/components/copy-page";
|
|
22
25
|
import { BrandLogo } from "@lexibase/rdx-ui/components/brand-logo";
|
|
23
26
|
import { getMdxComponents } from "@lexibase/rdx-ui/components/mdx-components";
|
|
24
27
|
import { getMessages, formatMessage } from "@lexibase/rdx-ui/lib/i18n";
|
|
@@ -61,19 +64,164 @@ function compileDocumentation(source, components, links) {
|
|
|
61
64
|
});
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
// src/runtime/markdown.ts
|
|
68
|
+
import {
|
|
69
|
+
getContentSources,
|
|
70
|
+
getDocsHref,
|
|
71
|
+
getDocsIndex,
|
|
72
|
+
getDocument,
|
|
73
|
+
getLocalizedProject,
|
|
74
|
+
getSourceOptions,
|
|
75
|
+
isFallbackPage
|
|
76
|
+
} from "@lexibase/rdx-core";
|
|
77
|
+
import { exportMarkdownBody } from "@lexibase/rdx-core/mdx";
|
|
78
|
+
function publicUrl(project, path) {
|
|
79
|
+
const base = project.config.metadata.metadataBase;
|
|
80
|
+
return base ? new URL(path, base).href : path;
|
|
81
|
+
}
|
|
82
|
+
function indexPath(project) {
|
|
83
|
+
return `${project.locale ? `/${project.locale.path}` : ""}/docs/llms.txt`;
|
|
84
|
+
}
|
|
85
|
+
function defaultLocale(project) {
|
|
86
|
+
const locale = project.localization?.locales.find(
|
|
87
|
+
(entry) => entry.code === project.localization.defaultLocale
|
|
88
|
+
);
|
|
89
|
+
return !project.locale && locale ? getLocalizedProject(project, locale.path) : project;
|
|
90
|
+
}
|
|
91
|
+
function text(value) {
|
|
92
|
+
return value.replace(/\s+/g, " ").trim().replace(/[\\`*_[\]<>]/g, "\\$&");
|
|
93
|
+
}
|
|
94
|
+
function getMarkdownHref(htmlPath) {
|
|
95
|
+
return `/rdx-markdown${htmlPath}.md`;
|
|
96
|
+
}
|
|
97
|
+
function response(body, type, status = 200) {
|
|
98
|
+
return new Response(body, {
|
|
99
|
+
status,
|
|
100
|
+
headers: {
|
|
101
|
+
"Content-Type": `${type}; charset=utf-8`,
|
|
102
|
+
"X-Robots-Tag": "noindex, follow"
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function getLlmIndexResponse(project, documentPath) {
|
|
107
|
+
project = defaultLocale(project);
|
|
108
|
+
const source = project.sources.find(
|
|
109
|
+
(entry) => entry.id !== "current" && entry.redirectTo === void 0 && entry.badge !== "Archived"
|
|
110
|
+
) ?? project.sources[0];
|
|
111
|
+
const { metadata, description } = project.config;
|
|
112
|
+
const lines = [`# ${text(metadata.applicationName)} Documentation`, ""];
|
|
113
|
+
if (description) lines.push(`> ${text(description)}`, "");
|
|
114
|
+
if (source) {
|
|
115
|
+
for (const category of getDocsIndex(getSourceOptions(project, source))) {
|
|
116
|
+
const pages = category.pages.filter(
|
|
117
|
+
(page) => !isFallbackPage(project, source, page.sourcePath)
|
|
118
|
+
);
|
|
119
|
+
if (!pages.length) continue;
|
|
120
|
+
lines.push(`## ${text(category.title)}`, "");
|
|
121
|
+
for (const page of pages) {
|
|
122
|
+
const href = documentPath?.(source, page) ?? getDocsHref(project, source, page.slug);
|
|
123
|
+
lines.push(
|
|
124
|
+
`- [${text(page.title)}](<${publicUrl(project, getMarkdownHref(href))}>)${page.description ? `: ${text(page.description)}` : ""}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
lines.push("");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return response(lines.join("\n"), "text/plain");
|
|
131
|
+
}
|
|
132
|
+
function getMarkdownPaths(project, documentPath) {
|
|
133
|
+
const paths = /* @__PURE__ */ new Set();
|
|
134
|
+
for (const source of getContentSources(project)) {
|
|
135
|
+
if (source.redirectTo !== void 0) continue;
|
|
136
|
+
for (const category of getDocsIndex(getSourceOptions(project, source))) {
|
|
137
|
+
for (const page of category.pages) {
|
|
138
|
+
if (isFallbackPage(project, source, page.sourcePath)) continue;
|
|
139
|
+
const href = documentPath?.(source, page) ?? getDocsHref(project, source, page.slug);
|
|
140
|
+
paths.add(`${href.slice(1)}.md`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return [...paths].map((path) => ({
|
|
145
|
+
path: path.split("/").map(decodeURIComponent)
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
function parseMarkdownPath(path) {
|
|
149
|
+
const last = path.at(-1);
|
|
150
|
+
return last?.endsWith(".md") && last.length > 3 ? [...path.slice(0, -1), last.slice(0, -3)] : void 0;
|
|
151
|
+
}
|
|
152
|
+
function getMarkdownResponse(project, path) {
|
|
153
|
+
const segments = parseMarkdownPath(path);
|
|
154
|
+
if (!segments) return markdownNotFound();
|
|
155
|
+
if (project.localization) {
|
|
156
|
+
const locale = segments.shift();
|
|
157
|
+
if (!project.localization.locales.some((entry) => entry.path === locale))
|
|
158
|
+
return markdownNotFound();
|
|
159
|
+
project = getLocalizedProject(project, locale);
|
|
160
|
+
}
|
|
161
|
+
if (segments.shift() !== "docs" || !segments.length) return markdownNotFound();
|
|
162
|
+
const edition = project.sources.find(
|
|
163
|
+
(source) => source.routePrefix && source.routePrefix === segments[0]
|
|
164
|
+
);
|
|
165
|
+
if (edition) segments.shift();
|
|
166
|
+
return getDocumentMarkdownResponse(
|
|
167
|
+
project,
|
|
168
|
+
edition ?? project.sources[0],
|
|
169
|
+
segments.join("/")
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
function markdownNotFound() {
|
|
173
|
+
return response(null, "text/markdown", 404);
|
|
174
|
+
}
|
|
175
|
+
function getDocumentMarkdownResponse(project, source, slug, documentPath) {
|
|
176
|
+
if (!source || !slug || source.redirectTo !== void 0)
|
|
177
|
+
return markdownNotFound();
|
|
178
|
+
const options = getSourceOptions(project, source);
|
|
179
|
+
const document = getDocument(slug, options);
|
|
180
|
+
if (!document || isFallbackPage(project, source, document.sourcePath))
|
|
181
|
+
return markdownNotFound();
|
|
182
|
+
const pages = getDocsIndex(options).flatMap((category) => category.pages);
|
|
183
|
+
const bySlug = new Map(pages.map((page2) => [page2.slug, page2]));
|
|
184
|
+
const href = (page2) => publicUrl(
|
|
185
|
+
project,
|
|
186
|
+
documentPath?.(source, page2) ?? getDocsHref(project, source, page2.slug)
|
|
187
|
+
);
|
|
188
|
+
const page = bySlug.get(document.slug);
|
|
189
|
+
const frontmatter = {
|
|
190
|
+
title: page.title,
|
|
191
|
+
...page.description ? { description: page.description } : {},
|
|
192
|
+
url: href(document),
|
|
193
|
+
docs_index: publicUrl(project, indexPath(project))
|
|
194
|
+
};
|
|
195
|
+
const fields = Object.entries(frontmatter).map(
|
|
196
|
+
([key, value]) => `${key}: ${JSON.stringify(value)}`
|
|
197
|
+
);
|
|
198
|
+
const body = exportMarkdownBody(document.content, {
|
|
199
|
+
sourceRoot: options.docsDir,
|
|
200
|
+
sourcePath: document.sourcePath,
|
|
201
|
+
virtualPaths: !!options.fallbackDocsDir,
|
|
202
|
+
documents: pages,
|
|
203
|
+
documentHref: (slug2) => href(bySlug.get(slug2))
|
|
204
|
+
});
|
|
205
|
+
return response(`---
|
|
206
|
+
${fields.join("\n")}
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
${body}`, "text/markdown");
|
|
210
|
+
}
|
|
211
|
+
|
|
64
212
|
// src/runtime/index.tsx
|
|
65
213
|
import {
|
|
66
214
|
createRdxProject,
|
|
67
215
|
getProjectDocsPaths,
|
|
68
|
-
getLocalizedProject as
|
|
216
|
+
getLocalizedProject as getLocalizedProject4
|
|
69
217
|
} from "@lexibase/rdx-core";
|
|
70
218
|
|
|
71
219
|
// src/runtime/search.ts
|
|
72
220
|
import {
|
|
73
|
-
getDocsIndex,
|
|
74
|
-
getDocument,
|
|
75
|
-
getSourceOptions,
|
|
76
|
-
getDocsHref
|
|
221
|
+
getDocsIndex as getDocsIndex2,
|
|
222
|
+
getDocument as getDocument2,
|
|
223
|
+
getSourceOptions as getSourceOptions2,
|
|
224
|
+
getDocsHref as getDocsHref2
|
|
77
225
|
} from "@lexibase/rdx-core";
|
|
78
226
|
import { buildSearchIndex } from "@lexibase/rdx-core/search";
|
|
79
227
|
function getSearchSources(project) {
|
|
@@ -89,16 +237,16 @@ function getSearchResponse(project, key) {
|
|
|
89
237
|
if (!source) return new Response(null, { status: 404, headers });
|
|
90
238
|
if (source.fallbackOnly)
|
|
91
239
|
return Response.json(buildSearchIndex([]), { headers });
|
|
92
|
-
const { docsDir } =
|
|
240
|
+
const { docsDir } = getSourceOptions2(project, source);
|
|
93
241
|
const options = { docsDir };
|
|
94
|
-
const documents =
|
|
242
|
+
const documents = getDocsIndex2(options).flatMap(
|
|
95
243
|
(category) => category.pages.map((page) => ({
|
|
96
244
|
title: page.title,
|
|
97
245
|
description: page.description,
|
|
98
246
|
category: category.title,
|
|
99
|
-
href:
|
|
247
|
+
href: getDocsHref2(project, source, page.slug),
|
|
100
248
|
sourcePath: page.sourcePath,
|
|
101
|
-
content:
|
|
249
|
+
content: getDocument2(page.slug, options)?.content ?? ""
|
|
102
250
|
}))
|
|
103
251
|
);
|
|
104
252
|
return Response.json(buildSearchIndex(documents), { headers });
|
|
@@ -106,10 +254,10 @@ function getSearchResponse(project, key) {
|
|
|
106
254
|
|
|
107
255
|
// src/runtime/indexing.ts
|
|
108
256
|
import {
|
|
109
|
-
getDocsIndex as
|
|
110
|
-
getSourceOptions as
|
|
111
|
-
getContentSources,
|
|
112
|
-
isFallbackPage
|
|
257
|
+
getDocsIndex as getDocsIndex3,
|
|
258
|
+
getSourceOptions as getSourceOptions3,
|
|
259
|
+
getContentSources as getContentSources2,
|
|
260
|
+
isFallbackPage as isFallbackPage2
|
|
113
261
|
} from "@lexibase/rdx-core";
|
|
114
262
|
function getSourceRobots(project, source) {
|
|
115
263
|
const published = project.sources.some(
|
|
@@ -138,11 +286,11 @@ function getRdxSitemap(project, {
|
|
|
138
286
|
if (!base) return [];
|
|
139
287
|
const urls = /* @__PURE__ */ new Set();
|
|
140
288
|
if (project.config.homepage?.enabled) urls.add(new URL("/", base).href);
|
|
141
|
-
for (const source of
|
|
289
|
+
for (const source of getContentSources2(project)) {
|
|
142
290
|
if (!getSourceRobots(project, source).index) continue;
|
|
143
|
-
for (const category of
|
|
291
|
+
for (const category of getDocsIndex3(getSourceOptions3(project, source))) {
|
|
144
292
|
for (const page of category.pages) {
|
|
145
|
-
if (
|
|
293
|
+
if (isFallbackPage2(project, source, page.sourcePath)) continue;
|
|
146
294
|
urls.add(new URL(documentPath(source, page), base).href);
|
|
147
295
|
}
|
|
148
296
|
}
|
|
@@ -153,11 +301,11 @@ function getRdxSitemap(project, {
|
|
|
153
301
|
// src/runtime/metadata.ts
|
|
154
302
|
import {
|
|
155
303
|
resolveDocsRoute,
|
|
156
|
-
getLocalizedProject,
|
|
157
|
-
getDocsHref as
|
|
158
|
-
isFallbackPage as
|
|
159
|
-
getDocument as
|
|
160
|
-
getSourceOptions as
|
|
304
|
+
getLocalizedProject as getLocalizedProject2,
|
|
305
|
+
getDocsHref as getDocsHref3,
|
|
306
|
+
isFallbackPage as isFallbackPage3,
|
|
307
|
+
getDocument as getDocument3,
|
|
308
|
+
getSourceOptions as getSourceOptions4
|
|
161
309
|
} from "@lexibase/rdx-core";
|
|
162
310
|
import { notFound } from "next/navigation";
|
|
163
311
|
function getDocumentMetadata({
|
|
@@ -172,24 +320,24 @@ function getDocumentMetadata({
|
|
|
172
320
|
if (!route.slug) return { robots: { index: false, follow: true } };
|
|
173
321
|
if (!route.document) notFound();
|
|
174
322
|
const page = route.categories.flatMap((category) => category.pages).find((page2) => page2.slug === route.slug);
|
|
175
|
-
const fallback =
|
|
323
|
+
const fallback = isFallbackPage3(project, route.source, page.sourcePath);
|
|
176
324
|
const primary = project.localization?.locales.find(
|
|
177
325
|
(locale) => locale.code === project.localization.defaultLocale
|
|
178
326
|
);
|
|
179
|
-
const canonicalProject = fallback ?
|
|
327
|
+
const canonicalProject = fallback ? getLocalizedProject2(project, primary.path) : project;
|
|
180
328
|
const base = project.config.metadata.metadataBase;
|
|
181
329
|
const languages = project.localization && base ? Object.fromEntries(
|
|
182
330
|
project.localization.locales.flatMap((locale) => {
|
|
183
|
-
const view =
|
|
331
|
+
const view = getLocalizedProject2(project, locale.path);
|
|
184
332
|
const source = view.sources.find(
|
|
185
333
|
(entry) => entry.id === route.source.id
|
|
186
334
|
);
|
|
187
|
-
return !source.fallbackOnly &&
|
|
188
|
-
docsDir:
|
|
335
|
+
return !source.fallbackOnly && getDocument3(page.slug, {
|
|
336
|
+
docsDir: getSourceOptions4(view, source).docsDir
|
|
189
337
|
}) ? [
|
|
190
338
|
[
|
|
191
339
|
locale.code,
|
|
192
|
-
new URL(
|
|
340
|
+
new URL(getDocsHref3(view, source, page.slug), base).href
|
|
193
341
|
]
|
|
194
342
|
] : [];
|
|
195
343
|
})
|
|
@@ -200,7 +348,7 @@ function getDocumentMetadata({
|
|
|
200
348
|
...project.localization && base ? {
|
|
201
349
|
alternates: {
|
|
202
350
|
canonical: new URL(
|
|
203
|
-
|
|
351
|
+
getDocsHref3(
|
|
204
352
|
canonicalProject,
|
|
205
353
|
canonicalProject.sources.find(
|
|
206
354
|
(entry) => entry.id === route.source.id
|
|
@@ -280,13 +428,13 @@ function RdxHeader({
|
|
|
280
428
|
const messages = getMessages(config.lang);
|
|
281
429
|
const { source, slug: currentSlug } = resolveDocsRoute2(project, slug);
|
|
282
430
|
const options = project.sources.filter((edition) => edition.redirectTo === void 0).map((edition) => {
|
|
283
|
-
const docs =
|
|
284
|
-
const destination = currentSlug &&
|
|
431
|
+
const docs = getSourceOptions5(project, edition);
|
|
432
|
+
const destination = currentSlug && getDocument4(currentSlug, docs) ? currentSlug : getDocsPaths(docs)[0];
|
|
285
433
|
return {
|
|
286
434
|
id: edition.id,
|
|
287
435
|
label: edition.id === "current" ? messages.current : formatMessage(messages.version, { version: edition.label }),
|
|
288
436
|
kind: edition.id === "current" ? "live" : edition.badge === "Archived" ? "archived" : "version",
|
|
289
|
-
href:
|
|
437
|
+
href: getDocsHref4(project, edition, destination)
|
|
290
438
|
};
|
|
291
439
|
});
|
|
292
440
|
return /* @__PURE__ */ jsx(
|
|
@@ -303,8 +451,8 @@ function RdxHeader({
|
|
|
303
451
|
) : void 0,
|
|
304
452
|
siteTitle: config.metadata.applicationName,
|
|
305
453
|
logo: /* @__PURE__ */ jsx(BrandLogo, { source: config.navbar?.logo, className: "size-5" }),
|
|
306
|
-
homeHref: config.homepage?.enabled ? "/" :
|
|
307
|
-
docsHref:
|
|
454
|
+
homeHref: config.homepage?.enabled ? "/" : getDocsHref4(project),
|
|
455
|
+
docsHref: getDocsHref4(project, source),
|
|
308
456
|
languageMenu: project.localization ? /* @__PURE__ */ jsx(
|
|
309
457
|
LanguageDropdown,
|
|
310
458
|
{
|
|
@@ -322,7 +470,7 @@ function RdxHeader({
|
|
|
322
470
|
}
|
|
323
471
|
function HomePage({ project }) {
|
|
324
472
|
const { config } = project;
|
|
325
|
-
if (!config.homepage?.enabled) redirect(
|
|
473
|
+
if (!config.homepage?.enabled) redirect(getDocsHref4(project));
|
|
326
474
|
const homepage = config.homepage;
|
|
327
475
|
const CustomHome = homepage.component;
|
|
328
476
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -381,7 +529,7 @@ async function DocsPage({
|
|
|
381
529
|
project
|
|
382
530
|
}) {
|
|
383
531
|
if (project.localization && !project.locale)
|
|
384
|
-
permanentRedirect(
|
|
532
|
+
permanentRedirect(getDocsHref4(project, project.sources[0], slug?.join("/")));
|
|
385
533
|
const messages = getMessages(project.config.lang);
|
|
386
534
|
const {
|
|
387
535
|
source,
|
|
@@ -391,7 +539,7 @@ async function DocsPage({
|
|
|
391
539
|
} = resolveDocsRoute2(project, slug);
|
|
392
540
|
if (source.redirectTo !== void 0)
|
|
393
541
|
permanentRedirect(
|
|
394
|
-
|
|
542
|
+
getDocsHref4(
|
|
395
543
|
project,
|
|
396
544
|
project.sources.find(
|
|
397
545
|
(entry) => entry.routePrefix === source.redirectTo
|
|
@@ -408,15 +556,16 @@ async function DocsPage({
|
|
|
408
556
|
] })
|
|
409
557
|
] });
|
|
410
558
|
if (!document) notFound2();
|
|
411
|
-
const fallback =
|
|
559
|
+
const fallback = isFallbackPage4(project, source, document.sourcePath);
|
|
560
|
+
const editHref = fallback ? void 0 : getEditPageHref(project, source, document.sourcePath);
|
|
412
561
|
const primaryLocale = (source.localization ?? project.localization)?.locales.find(
|
|
413
562
|
(locale) => locale.code === project.localization.defaultLocale
|
|
414
563
|
);
|
|
415
|
-
const originalProject = fallback && primaryLocale ?
|
|
564
|
+
const originalProject = fallback && primaryLocale ? getLocalizedProject3(project, primaryLocale.path) : project;
|
|
416
565
|
const contentSource = originalProject.sources.find(
|
|
417
566
|
(entry) => entry.id === source.id
|
|
418
567
|
);
|
|
419
|
-
const contentOptions =
|
|
568
|
+
const contentOptions = getSourceOptions5(originalProject, contentSource);
|
|
420
569
|
const contentCategories = fallback ? resolveDocsRoute2(originalProject, slug).categories : categories;
|
|
421
570
|
const contentLanguage = fallback ? primaryLocale.code : project.config.lang;
|
|
422
571
|
const { content } = await compileDocumentation(
|
|
@@ -431,18 +580,20 @@ async function DocsPage({
|
|
|
431
580
|
documents: contentCategories.flatMap((category2) => category2.pages)
|
|
432
581
|
}
|
|
433
582
|
);
|
|
434
|
-
const title = typeof document.frontmatter.title === "string" ? document.frontmatter.title : currentSlug;
|
|
435
583
|
const description = typeof document.frontmatter.description === "string" ? document.frontmatter.description : null;
|
|
436
|
-
const hrefFor = (pageSlug) =>
|
|
584
|
+
const hrefFor = (pageSlug) => getDocsHref4(project, source, pageSlug);
|
|
585
|
+
const markdownHref = fallback ? void 0 : getMarkdownHref(hrefFor(currentSlug));
|
|
437
586
|
const sidebarCategories = categories.map((category2) => ({
|
|
438
587
|
title: category2.title,
|
|
439
588
|
links: category2.pages.map((page) => ({
|
|
440
|
-
label: page.title,
|
|
589
|
+
label: page.navTitle ?? page.title,
|
|
590
|
+
highlighting: page.highlighting,
|
|
441
591
|
href: hrefFor(page.slug)
|
|
442
592
|
}))
|
|
443
593
|
}));
|
|
444
594
|
const pages = categories.flatMap((category2) => category2.pages);
|
|
445
595
|
const index = pages.findIndex((page) => page.slug === currentSlug);
|
|
596
|
+
const title = pages[index]?.title ?? currentSlug;
|
|
446
597
|
const previous = pages[index - 1];
|
|
447
598
|
const next = pages[index + 1];
|
|
448
599
|
const category = categories.find(
|
|
@@ -500,7 +651,7 @@ async function DocsPage({
|
|
|
500
651
|
Button,
|
|
501
652
|
{
|
|
502
653
|
variant: "link",
|
|
503
|
-
href:
|
|
654
|
+
href: getDocsHref4(
|
|
504
655
|
originalProject,
|
|
505
656
|
contentSource,
|
|
506
657
|
currentSlug
|
|
@@ -534,7 +685,10 @@ async function DocsPage({
|
|
|
534
685
|
/* @__PURE__ */ jsxs("header", { className: "mb-6", children: [
|
|
535
686
|
source.badge && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4", children: source.badge === "Archived" ? messages.archivedVersion : source.badge }),
|
|
536
687
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-zinc-600 font-semibold uppercase block -mb-0.5", children: category?.title }),
|
|
537
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex flex-wrap items-start gap-x-4 gap-y-2", children: [
|
|
689
|
+
/* @__PURE__ */ jsx("h1", { className: "min-w-0 max-w-full break-words text-4xl font-bold uppercase", children: title }),
|
|
690
|
+
markdownHref && /* @__PURE__ */ jsx(CopyPage, { href: markdownHref }, markdownHref)
|
|
691
|
+
] }),
|
|
538
692
|
description && /* @__PURE__ */ jsx("p", { className: "text-sm text-ring max-w-[726px]", children: description })
|
|
539
693
|
] }),
|
|
540
694
|
/* @__PURE__ */ jsx("div", { className: "h-full w-full flex-1 max-w-[960px]", children: content })
|
|
@@ -542,6 +696,7 @@ async function DocsPage({
|
|
|
542
696
|
}
|
|
543
697
|
),
|
|
544
698
|
/* @__PURE__ */ jsxs("footer", { className: "flex flex-col", children: [
|
|
699
|
+
editHref && /* @__PURE__ */ jsx(EditPageLink, { href: editHref, lang: project.config.lang }),
|
|
545
700
|
/* @__PURE__ */ jsxs("section", { className: "flex items-center justify-between", children: [
|
|
546
701
|
previous ? /* @__PURE__ */ jsx(
|
|
547
702
|
Button,
|
|
@@ -590,8 +745,13 @@ export {
|
|
|
590
745
|
NotFoundPage,
|
|
591
746
|
RdxLayout,
|
|
592
747
|
createRdxProject,
|
|
748
|
+
getDocumentMarkdownResponse,
|
|
593
749
|
getDocumentMetadata,
|
|
594
|
-
|
|
750
|
+
getLlmIndexResponse,
|
|
751
|
+
getLocalizedProject4 as getLocalizedProject,
|
|
752
|
+
getMarkdownHref,
|
|
753
|
+
getMarkdownPaths,
|
|
754
|
+
getMarkdownResponse,
|
|
595
755
|
getPageMetadata,
|
|
596
756
|
getProjectDocsPaths,
|
|
597
757
|
getRdxMetadata,
|
|
@@ -599,5 +759,7 @@ export {
|
|
|
599
759
|
getRdxSitemap,
|
|
600
760
|
getSearchResponse,
|
|
601
761
|
getSearchSources,
|
|
602
|
-
getSourceRobots
|
|
762
|
+
getSourceRobots,
|
|
763
|
+
markdownNotFound,
|
|
764
|
+
parseMarkdownPath
|
|
603
765
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexibase/rdx-next",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "The Next.js runtime for RDX documentation projects.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"next-mdx-remote": "^6.0.0",
|
|
53
53
|
"remark-gfm": "^4",
|
|
54
54
|
"typescript": "6.0.3",
|
|
55
|
-
"@lexibase/rdx-types": "2.
|
|
56
|
-
"@lexibase/rdx-core": "
|
|
55
|
+
"@lexibase/rdx-types": "2.3.0",
|
|
56
|
+
"@lexibase/rdx-core": "3.0.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@lexibase/rdx-ui": "^3.
|
|
59
|
+
"@lexibase/rdx-ui": "^3.5.0",
|
|
60
60
|
"next": "^16.4.2",
|
|
61
61
|
"react": "^19.3.1",
|
|
62
62
|
"react-dom": "^19.3.1"
|
|
@@ -81,9 +81,9 @@
|
|
|
81
81
|
"next": "^16.4.2",
|
|
82
82
|
"react": "19.3.1",
|
|
83
83
|
"react-dom": "19.3.1",
|
|
84
|
-
"@rdx
|
|
84
|
+
"@lexibase/rdx-ui": "3.5.0",
|
|
85
85
|
"@rdx/eslint-config": "1.0.0",
|
|
86
|
-
"@
|
|
86
|
+
"@rdx/typescript-config": "1.0.0"
|
|
87
87
|
},
|
|
88
88
|
"scripts": {
|
|
89
89
|
"dev": "tsup src/index.ts src/runtime/index.tsx --format esm --dts --watch --external @lexibase/rdx-core --external @lexibase/rdx-types --external @lexibase/rdx-ui --external next --external react --external react-dom --external next-mdx-remote",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getMarkdownPaths,
|
|
3
|
+
getMarkdownResponse,
|
|
4
|
+
} from '@lexibase/rdx-next/runtime'
|
|
5
|
+
import { getProject } from '../../../rdx-project'
|
|
6
|
+
|
|
7
|
+
export const dynamic = 'force-static'
|
|
8
|
+
export const dynamicParams = false
|
|
9
|
+
|
|
10
|
+
export async function generateStaticParams() {
|
|
11
|
+
return getMarkdownPaths(await getProject())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function GET(
|
|
15
|
+
_request: Request,
|
|
16
|
+
{ params }: { params: Promise<{ path: string[] }> }
|
|
17
|
+
) {
|
|
18
|
+
return getMarkdownResponse(await getProject(), (await params).path)
|
|
19
|
+
}
|