@farming-labs/next 0.1.107 → 0.1.109
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/config.mjs
CHANGED
|
@@ -258,6 +258,15 @@ function readDocsContentDir(root) {
|
|
|
258
258
|
} catch {}
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
|
+
function readDocsPath(root) {
|
|
262
|
+
for (const ext of FILE_EXTS) {
|
|
263
|
+
const configPath = join(root, `docs.config.${ext}`);
|
|
264
|
+
if (!existsSync(configPath)) continue;
|
|
265
|
+
try {
|
|
266
|
+
return readTopLevelStringProperty(readFileSync(configPath, "utf-8"), "docsPath");
|
|
267
|
+
} catch {}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
261
270
|
function readDocsConfigPath(root) {
|
|
262
271
|
for (const ext of FILE_EXTS) {
|
|
263
272
|
const relativePath = `docs.config.${ext}`;
|
|
@@ -910,8 +919,74 @@ function readAgentFeedbackConfig(root) {
|
|
|
910
919
|
}
|
|
911
920
|
return enabled;
|
|
912
921
|
}
|
|
913
|
-
function
|
|
914
|
-
|
|
922
|
+
function normalizeRouteSegment(value, fallback = "docs") {
|
|
923
|
+
return (value ?? fallback).replace(/^\/+|\/+$/g, "") || fallback;
|
|
924
|
+
}
|
|
925
|
+
function normalizeDocsPath(value, entry) {
|
|
926
|
+
if (typeof value !== "string") return `/${normalizeRouteSegment(entry)}`;
|
|
927
|
+
const cleaned = value.trim();
|
|
928
|
+
if (cleaned === "" || cleaned === "/") return "";
|
|
929
|
+
return `/${cleaned.replace(/^\/+|\/+$/g, "")}`;
|
|
930
|
+
}
|
|
931
|
+
function docsRootSource(entry) {
|
|
932
|
+
return [
|
|
933
|
+
"/:slug((?!",
|
|
934
|
+
"_next/",
|
|
935
|
+
"|api/",
|
|
936
|
+
`|${normalizeRouteSegment(entry)}(?:/|$)`,
|
|
937
|
+
"|favicon\\.ico",
|
|
938
|
+
"|robots\\.txt",
|
|
939
|
+
"|sitemap\\.xml",
|
|
940
|
+
"|sitemap\\.md",
|
|
941
|
+
"|docs\\.md",
|
|
942
|
+
"|llms\\.txt",
|
|
943
|
+
"|llms-full\\.txt",
|
|
944
|
+
"|mcp(?:/|$)",
|
|
945
|
+
"|AGENTS\\.md",
|
|
946
|
+
"|AGENT\\.md",
|
|
947
|
+
"|skill\\.md",
|
|
948
|
+
"|\\.well-known/",
|
|
949
|
+
"|.*\\..*",
|
|
950
|
+
").*)"
|
|
951
|
+
].join("");
|
|
952
|
+
}
|
|
953
|
+
function docsRootMarkdownSource(entry) {
|
|
954
|
+
return [
|
|
955
|
+
"/:slug((?!",
|
|
956
|
+
"_next/",
|
|
957
|
+
"|api/",
|
|
958
|
+
`|${normalizeRouteSegment(entry)}/`,
|
|
959
|
+
"|docs\\.md",
|
|
960
|
+
"|sitemap\\.md",
|
|
961
|
+
"|AGENTS\\.md",
|
|
962
|
+
"|AGENT\\.md",
|
|
963
|
+
"|skill\\.md",
|
|
964
|
+
"|\\.well-known/",
|
|
965
|
+
").*)\\.md"
|
|
966
|
+
].join("");
|
|
967
|
+
}
|
|
968
|
+
function buildDocsPathRewrites(entry, docsPath) {
|
|
969
|
+
const normalizedEntry = normalizeRouteSegment(entry);
|
|
970
|
+
const internalBase = `/${normalizedEntry}`;
|
|
971
|
+
if (docsPath === internalBase) return [];
|
|
972
|
+
if (docsPath === "") return [{
|
|
973
|
+
source: "/",
|
|
974
|
+
destination: `${internalBase}/`
|
|
975
|
+
}, {
|
|
976
|
+
source: docsRootSource(normalizedEntry),
|
|
977
|
+
destination: `${internalBase}/:slug`
|
|
978
|
+
}];
|
|
979
|
+
return [{
|
|
980
|
+
source: docsPath,
|
|
981
|
+
destination: internalBase
|
|
982
|
+
}, {
|
|
983
|
+
source: `${docsPath}/:slug*`,
|
|
984
|
+
destination: `${internalBase}/:slug*`
|
|
985
|
+
}];
|
|
986
|
+
}
|
|
987
|
+
function buildDocsMarkdownRewrites(entry, docsPath) {
|
|
988
|
+
const normalizedEntry = normalizeRouteSegment(entry);
|
|
989
|
+
const publicBase = docsPath || "";
|
|
915
990
|
const markdownAcceptHeader = {
|
|
916
991
|
type: "header",
|
|
917
992
|
key: "accept",
|
|
@@ -922,32 +997,65 @@ function buildDocsMarkdownRewrites(entry) {
|
|
|
922
997
|
key: "signature-agent",
|
|
923
998
|
value: ".+"
|
|
924
999
|
};
|
|
1000
|
+
if (publicBase === "") {
|
|
1001
|
+
const rootPageSource = docsRootSource(normalizedEntry);
|
|
1002
|
+
return [
|
|
1003
|
+
{
|
|
1004
|
+
source: `/${normalizedEntry}.md`,
|
|
1005
|
+
destination: "/api/docs?format=markdown"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
source: docsRootMarkdownSource(normalizedEntry),
|
|
1009
|
+
destination: "/api/docs?format=markdown&path=:slug"
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
source: "/",
|
|
1013
|
+
has: [markdownAcceptHeader],
|
|
1014
|
+
destination: "/api/docs?format=markdown"
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
source: rootPageSource,
|
|
1018
|
+
has: [markdownAcceptHeader],
|
|
1019
|
+
destination: "/api/docs?format=markdown&path=:slug"
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
source: "/",
|
|
1023
|
+
has: [markdownSignatureAgentHeader],
|
|
1024
|
+
destination: "/api/docs?format=markdown"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
source: rootPageSource,
|
|
1028
|
+
has: [markdownSignatureAgentHeader],
|
|
1029
|
+
destination: "/api/docs?format=markdown&path=:slug"
|
|
1030
|
+
}
|
|
1031
|
+
];
|
|
1032
|
+
}
|
|
925
1033
|
return [
|
|
926
1034
|
{
|
|
927
|
-
source:
|
|
1035
|
+
source: `${publicBase}.md`,
|
|
928
1036
|
destination: "/api/docs?format=markdown"
|
|
929
1037
|
},
|
|
930
1038
|
{
|
|
931
|
-
source:
|
|
1039
|
+
source: `${publicBase}/:slug*.md`,
|
|
932
1040
|
destination: "/api/docs?format=markdown&path=:slug*"
|
|
933
1041
|
},
|
|
934
1042
|
{
|
|
935
|
-
source:
|
|
1043
|
+
source: publicBase,
|
|
936
1044
|
has: [markdownAcceptHeader],
|
|
937
1045
|
destination: "/api/docs?format=markdown"
|
|
938
1046
|
},
|
|
939
1047
|
{
|
|
940
|
-
source:
|
|
1048
|
+
source: `${publicBase}/:slug*`,
|
|
941
1049
|
has: [markdownAcceptHeader],
|
|
942
1050
|
destination: "/api/docs?format=markdown&path=:slug*"
|
|
943
1051
|
},
|
|
944
1052
|
{
|
|
945
|
-
source:
|
|
1053
|
+
source: publicBase,
|
|
946
1054
|
has: [markdownSignatureAgentHeader],
|
|
947
1055
|
destination: "/api/docs?format=markdown"
|
|
948
1056
|
},
|
|
949
1057
|
{
|
|
950
|
-
source:
|
|
1058
|
+
source: `${publicBase}/:slug*`,
|
|
951
1059
|
has: [markdownSignatureAgentHeader],
|
|
952
1060
|
destination: "/api/docs?format=markdown&path=:slug*"
|
|
953
1061
|
}
|
|
@@ -970,7 +1078,7 @@ function buildAgentSpecRewrites() {
|
|
|
970
1078
|
];
|
|
971
1079
|
}
|
|
972
1080
|
function buildLlmsTxtRewrites(entry) {
|
|
973
|
-
const normalizedEntry = entry
|
|
1081
|
+
const normalizedEntry = normalizeRouteSegment(entry);
|
|
974
1082
|
return [
|
|
975
1083
|
{
|
|
976
1084
|
source: DEFAULT_LLMS_TXT_ROUTE,
|
|
@@ -1161,7 +1269,12 @@ function findFirstVisibleDocsChildSlug(dir, slugParts) {
|
|
|
1161
1269
|
return childSlugParts;
|
|
1162
1270
|
}
|
|
1163
1271
|
}
|
|
1164
|
-
function
|
|
1272
|
+
function publicDocsRoute(docsPath, slugParts = []) {
|
|
1273
|
+
const slug = slugParts.join("/");
|
|
1274
|
+
if (!slug) return docsPath || "/";
|
|
1275
|
+
return docsPath ? `${docsPath}/${slug}` : `/${slug}`;
|
|
1276
|
+
}
|
|
1277
|
+
function buildHiddenFolderRedirects(docsDir, docsPath) {
|
|
1165
1278
|
const redirects = [];
|
|
1166
1279
|
function scan(dir, slugParts) {
|
|
1167
1280
|
if (!existsSync(dir)) return;
|
|
@@ -1170,8 +1283,8 @@ function buildHiddenFolderRedirects(docsDir, entry) {
|
|
|
1170
1283
|
if (resolveDocsPageFolderIndexBehavior(readDocsPageFrontmatter(pageSource)) === "hidden") {
|
|
1171
1284
|
const destinationSlug = findFirstVisibleDocsChildSlug(dir, slugParts);
|
|
1172
1285
|
if (destinationSlug && destinationSlug.join("/") !== slugParts.join("/")) {
|
|
1173
|
-
const source =
|
|
1174
|
-
const destination =
|
|
1286
|
+
const source = publicDocsRoute(docsPath, slugParts);
|
|
1287
|
+
const destination = publicDocsRoute(docsPath, destinationSlug);
|
|
1175
1288
|
redirects.push({
|
|
1176
1289
|
source,
|
|
1177
1290
|
destination,
|
|
@@ -1185,7 +1298,7 @@ function buildHiddenFolderRedirects(docsDir, entry) {
|
|
|
1185
1298
|
scan(docsDir, []);
|
|
1186
1299
|
return dedupeRedirects(redirects);
|
|
1187
1300
|
}
|
|
1188
|
-
function mergeDocsMarkdownRewrites(entry, mcp, sitemap, agentFeedback, robots, result) {
|
|
1301
|
+
function mergeDocsMarkdownRewrites(entry, docsPath, mcp, sitemap, agentFeedback, robots, result) {
|
|
1189
1302
|
const autoBeforeFilesRewrites = [
|
|
1190
1303
|
...buildAgentSpecRewrites(),
|
|
1191
1304
|
...buildMcpRewrites(mcp),
|
|
@@ -1193,7 +1306,8 @@ function mergeDocsMarkdownRewrites(entry, mcp, sitemap, agentFeedback, robots, r
|
|
|
1193
1306
|
...buildSkillMdRewrites(),
|
|
1194
1307
|
...buildSitemapRewrites(sitemap),
|
|
1195
1308
|
...buildRobotsRewrites(robots),
|
|
1196
|
-
...buildDocsMarkdownRewrites(entry),
|
|
1309
|
+
...buildDocsMarkdownRewrites(entry, docsPath),
|
|
1310
|
+
...buildDocsPathRewrites(entry, docsPath),
|
|
1197
1311
|
...buildAgentFeedbackRewrites(agentFeedback)
|
|
1198
1312
|
];
|
|
1199
1313
|
const autoAfterFilesRewrites = buildLlmsTxtRewrites(entry);
|
|
@@ -1223,6 +1337,7 @@ function withDocs(nextConfig = {}) {
|
|
|
1223
1337
|
const docsConfigRelativeAlias = docsConfigPath.startsWith("./") || docsConfigPath.startsWith("../") ? docsConfigPath : `./${docsConfigPath}`;
|
|
1224
1338
|
if (!hasFile(root, "mdx-components")) writeFileSync(join(root, "mdx-components.tsx"), MDX_COMPONENTS_TEMPLATE);
|
|
1225
1339
|
const entry = readDocsEntry(root);
|
|
1340
|
+
const docsPath = normalizeDocsPath(readDocsPath(root), entry);
|
|
1226
1341
|
const configuredContentDir = readDocsContentDir(root);
|
|
1227
1342
|
const appDir = getNextAppDir(root);
|
|
1228
1343
|
const docsContentDir = configuredContentDir ?? join(appDir, entry);
|
|
@@ -1317,6 +1432,7 @@ function withDocs(nextConfig = {}) {
|
|
|
1317
1432
|
entry,
|
|
1318
1433
|
appDir,
|
|
1319
1434
|
contentDir: docsContentDir,
|
|
1435
|
+
docsPath,
|
|
1320
1436
|
enabled: !isStaticExport
|
|
1321
1437
|
}]);
|
|
1322
1438
|
remarkPlugins.push(["remark-mdx-frontmatter", { name: "metadata" }], "@farming-labs/next/mdx-plugins/remark-heading");
|
|
@@ -1403,9 +1519,9 @@ function withDocs(nextConfig = {}) {
|
|
|
1403
1519
|
if (!isStaticExport) {
|
|
1404
1520
|
const existingRewrites = nextConfig.rewrites;
|
|
1405
1521
|
nextConfig.rewrites = async () => {
|
|
1406
|
-
return mergeDocsMarkdownRewrites(entry, mcp, sitemap, agentFeedback, robots, typeof existingRewrites === "function" ? await existingRewrites() : existingRewrites);
|
|
1522
|
+
return mergeDocsMarkdownRewrites(entry, docsPath, mcp, sitemap, agentFeedback, robots, typeof existingRewrites === "function" ? await existingRewrites() : existingRewrites);
|
|
1407
1523
|
};
|
|
1408
|
-
const autoRedirects = buildHiddenFolderRedirects(docsContentRoot,
|
|
1524
|
+
const autoRedirects = buildHiddenFolderRedirects(docsContentRoot, docsPath);
|
|
1409
1525
|
if (autoRedirects.length > 0) {
|
|
1410
1526
|
const existingRedirects = nextConfig.redirects;
|
|
1411
1527
|
nextConfig.redirects = async () => {
|
|
@@ -7,6 +7,16 @@ function normalizePath(value) {
|
|
|
7
7
|
function normalizeSegment(value, fallback) {
|
|
8
8
|
return (value ?? fallback).replace(/^\/+|\/+$/g, "") || fallback;
|
|
9
9
|
}
|
|
10
|
+
function normalizeDocsPath(value, entry) {
|
|
11
|
+
if (typeof value !== "string") return `/${entry}`;
|
|
12
|
+
const cleaned = value.trim();
|
|
13
|
+
if (cleaned === "" || cleaned === "/") return "";
|
|
14
|
+
return `/${cleaned.replace(/^\/+|\/+$/g, "")}`;
|
|
15
|
+
}
|
|
16
|
+
function joinDocsPath(docsPath, slug) {
|
|
17
|
+
if (!slug) return docsPath || "/";
|
|
18
|
+
return docsPath ? `${docsPath}/${slug}` : `/${slug}`;
|
|
19
|
+
}
|
|
10
20
|
function escapeYamlString(value) {
|
|
11
21
|
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
12
22
|
}
|
|
@@ -27,7 +37,7 @@ function routeFromSourcePath(filePath, options) {
|
|
|
27
37
|
const relativePath = normalized.slice(markerIndex + marker.length);
|
|
28
38
|
if (!relativePath.endsWith("page.mdx") && !relativePath.endsWith("page.md")) continue;
|
|
29
39
|
const slug = relativePath.replace(/\/?page\.mdx?$/, "").replace(/^\/+|\/+$/g, "");
|
|
30
|
-
return
|
|
40
|
+
return joinDocsPath(normalizeDocsPath(options.docsPath, entry), slug);
|
|
31
41
|
}
|
|
32
42
|
return null;
|
|
33
43
|
}
|
|
@@ -41,7 +51,7 @@ function alternateYaml(url) {
|
|
|
41
51
|
return [
|
|
42
52
|
"alternates:",
|
|
43
53
|
" types:",
|
|
44
|
-
` text/markdown: "${escapeYamlString(toDocsMarkdownUrl(url))}"`
|
|
54
|
+
` text/markdown: "${escapeYamlString(url === "/" ? "/docs.md" : toDocsMarkdownUrl(url))}"`
|
|
45
55
|
].join("\n");
|
|
46
56
|
}
|
|
47
57
|
function remarkMarkdownAlternate(options = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/next",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.109",
|
|
4
4
|
"description": "Next.js adapter for @farming-labs/docs — MDX config wrapper",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"tsdown": "^0.20.3",
|
|
101
101
|
"typescript": "^5.9.3",
|
|
102
102
|
"vitest": "^3.2.4",
|
|
103
|
-
"@farming-labs/docs": "0.1.
|
|
104
|
-
"@farming-labs/theme": "0.1.
|
|
103
|
+
"@farming-labs/docs": "0.1.109",
|
|
104
|
+
"@farming-labs/theme": "0.1.109"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
107
|
"@farming-labs/docs": ">=0.0.1",
|