Skip to content

Commit fb8939f

Browse files
committed
fix: index redirect
1 parent 629f51d commit fb8939f

File tree

3 files changed

+162
-24
lines changed

3 files changed

+162
-24
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { Locale, Repo, type PathConfig } from "../../src/shared/interface";
2+
3+
jest.mock("../toc", () => ({
4+
mdxAstToToc: jest.fn(() => []),
5+
}));
6+
7+
jest.mock("../url-resolver", () => ({
8+
calculateFileUrl: jest.fn(() => null),
9+
}));
10+
11+
describe("toc-filter _index whitelist rules", () => {
12+
afterEach(() => {
13+
jest.resetModules();
14+
});
15+
16+
it("allows all stable _index pages, but only root _index for non-stable tidb branches", () => {
17+
const { filterNodesByToc } = require("../toc-filter");
18+
19+
const stableConfig: PathConfig = {
20+
locale: Locale.en,
21+
repo: Repo.tidb,
22+
branch: "release-8.5",
23+
version: "stable",
24+
};
25+
const devConfig: PathConfig = {
26+
locale: Locale.en,
27+
repo: Repo.tidb,
28+
branch: "master",
29+
version: "dev",
30+
};
31+
32+
const tocFilesMap = new Map<string, Set<string>>([
33+
["en/tidb/stable", new Set(["some-file"])],
34+
["en/tidb/dev", new Set(["some-file"])],
35+
]);
36+
const tocNamesByFileMap = new Map<string, Map<string, Set<string>>>();
37+
38+
const nodes = [
39+
{
40+
slug: "en/tidb/release-8.5/_index",
41+
name: "",
42+
filePath: "_index.md",
43+
pathConfig: stableConfig,
44+
},
45+
{
46+
slug: "en/tidb/release-8.5/ai/_index",
47+
name: "",
48+
filePath: "ai/_index.md",
49+
pathConfig: stableConfig,
50+
},
51+
{
52+
slug: "en/tidb/master/_index",
53+
name: "",
54+
filePath: "_index.md",
55+
pathConfig: devConfig,
56+
},
57+
{
58+
slug: "en/tidb/master/ai/_index",
59+
name: "",
60+
filePath: "ai/_index.md",
61+
pathConfig: devConfig,
62+
},
63+
];
64+
65+
const result = filterNodesByToc(nodes, tocFilesMap, tocNamesByFileMap);
66+
expect(result.map((n: any) => n.slug)).toEqual([
67+
"en/tidb/release-8.5/_index",
68+
"en/tidb/release-8.5/ai/_index",
69+
"en/tidb/master/_index",
70+
]);
71+
});
72+
73+
it("keeps legacy behavior for tidbcloud _index pages", () => {
74+
const { filterNodesByToc } = require("../toc-filter");
75+
76+
const tocFilesMap = new Map<string, Set<string>>([
77+
["en/tidbcloud/master", new Set(["some-file"])],
78+
]);
79+
const tocNamesByFileMap = new Map<string, Map<string, Set<string>>>();
80+
81+
const nodes = [
82+
{
83+
slug: "en/tidbcloud/master/tidb-cloud/starter/_index",
84+
name: "",
85+
filePath: "tidb-cloud/starter/_index.md",
86+
pathConfig: {
87+
locale: Locale.en,
88+
repo: Repo.tidbcloud,
89+
branch: "master",
90+
version: null,
91+
} as PathConfig,
92+
},
93+
];
94+
95+
const result = filterNodesByToc(nodes, tocFilesMap, tocNamesByFileMap);
96+
expect(result.map((n: any) => n.slug)).toEqual([
97+
"en/tidbcloud/master/tidb-cloud/starter/_index",
98+
]);
99+
});
100+
});

gatsby/toc-filter.ts

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { mdxAstToToc, TocQueryData } from "./toc";
22
import { generateConfig } from "./path";
33
import { calculateFileUrl } from "./url-resolver";
4-
import { isIgnoredTocRelativePath } from "./toc-ignore";
5-
import { Repo, type PathConfig } from "../src/shared/interface";
6-
7-
// Whitelist of files that should always be built regardless of TOC content
8-
const WHITELIST = [""];
4+
import { isWhitelistedDocNode, shouldIncludeTocNode } from "./toc-ignore";
95

106
type TocFilesMap = Map<string, Set<string>>;
117
type TocNamesByFileMap = Map<string, Map<string, Set<string>>>;
@@ -71,21 +67,6 @@ function sortTocNames(tocNames: Iterable<string>): string[] {
7167
});
7268
}
7369

74-
function shouldIncludeTocNode(config: PathConfig, relativePath: string): boolean {
75-
const filename = relativePath.split("/").pop() || relativePath;
76-
77-
// For tidb and tidb-in-kubernetes, only stable reads all TOCs.
78-
// Other versions/branches (including master/main) only read TOC.md.
79-
if (config.repo === Repo.tidb || config.repo === Repo.operator) {
80-
if (config.version !== "stable") {
81-
return filename === "TOC.md";
82-
}
83-
}
84-
85-
// tidbcloud reads all TOCs (except those filtered by isIgnoredTocRelativePath).
86-
return true;
87-
}
88-
8970
/**
9071
* Get files that should be built based on TOC content
9172
* Returns a Map where key is "locale/repo/version" and value is Set of file names
@@ -121,8 +102,6 @@ export async function getFilesFromTocs(
121102
const filteredTocNodes = tocNodes.filter(
122103
(node: TocQueryData["allMdx"]["nodes"][0]) => {
123104
const relativePath = node.parent?.relativePath || "";
124-
if (isIgnoredTocRelativePath(relativePath)) return false;
125-
126105
const { config } = generateConfig(node.slug);
127106
return shouldIncludeTocNode(config, relativePath);
128107
}
@@ -183,8 +162,8 @@ export function filterNodesByToc(
183162
): any[] {
184163
const skippedNodes: Map<string, string[]> = new Map();
185164
const filteredNodes = nodes.filter((node) => {
186-
// Check if file is in whitelist - if so, always build it
187-
if (WHITELIST.includes(node.name)) {
165+
// Check if file is whitelisted - if so, always build it
166+
if (isWhitelistedDocNode(node)) {
188167
node.tocNames = [];
189168
return true;
190169
}

gatsby/toc-ignore.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Repo, type PathConfig } from "../src/shared/interface";
2+
13
function parseCommaSeparatedEnv(name: string): string[] {
24
const raw = process.env[name];
35
if (!raw) return [];
@@ -26,3 +28,60 @@ export function isIgnoredTocRelativePath(relativePath: string): boolean {
2628
);
2729
}
2830

31+
export function shouldIncludeTocNode(
32+
config: PathConfig,
33+
relativePath: string
34+
): boolean {
35+
if (isIgnoredTocRelativePath(relativePath)) return false;
36+
37+
// For tidb and tidb-in-kubernetes, only stable reads all TOCs.
38+
// Other versions/branches (including master/main) only read TOC.md.
39+
if (config.repo === Repo.tidb || config.repo === Repo.operator) {
40+
if (config.version !== "stable") {
41+
const filename = relativePath.split("/").pop() || relativePath;
42+
return filename === "TOC.md";
43+
}
44+
}
45+
46+
// tidbcloud reads all TOCs.
47+
return true;
48+
}
49+
50+
function isBranchRootIndexSlug(slug: string): boolean {
51+
const segments = slug.split("/");
52+
return segments.length === 4 && segments[segments.length - 1] === "_index";
53+
}
54+
55+
export function isWhitelistedDocNode(node: {
56+
name: string;
57+
slug: string;
58+
pathConfig: PathConfig;
59+
}): boolean {
60+
// Only whitelisting `_index.md`-derived pages.
61+
if (node.name !== "") return false;
62+
63+
// tidbcloud's plan pages are not necessarily referenced by TOC links.
64+
// Keep the legacy behavior to always build `_index.md` pages.
65+
if (node.pathConfig.repo === Repo.tidbcloud) return true;
66+
67+
// Only stable has all `_index.md` pages always built.
68+
if (
69+
(node.pathConfig.repo === Repo.tidb ||
70+
node.pathConfig.repo === Repo.operator) &&
71+
node.pathConfig.version === "stable"
72+
) {
73+
return true;
74+
}
75+
76+
// For other versions/branches, only build branch-root `_index.md`, e.g.
77+
// `master/_index.md`; `master/ai/_index.md` should not be whitelisted.
78+
if (
79+
node.pathConfig.repo === Repo.tidb ||
80+
node.pathConfig.repo === Repo.operator
81+
) {
82+
return isBranchRootIndexSlug(node.slug);
83+
}
84+
85+
// Default: keep legacy behavior for other repos.
86+
return true;
87+
}

0 commit comments

Comments
 (0)