Skip to content

Commit c3c4ed3

Browse files
committed
fix: improve path segment extraction for multi-instance docs
Refactors the path extraction logic in both index.ts and sidebars/index.ts to use segment-by-segment matching instead of string splitting. This fixes edge cases where docPath appears multiple times in outputDir or when paths have inconsistent leading/trailing slashes. Changes: - Normalize paths by removing leading ./ and leading/trailing slashes - Match docPath segments within outputDir segments sequentially - Clean up double slashes in the resulting infoBasePath Fixes #1305
1 parent 6cd891e commit c3c4ed3

2 files changed

Lines changed: 41 additions & 17 deletions

File tree

packages/docusaurus-plugin-openapi-docs/src/index.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -368,17 +368,25 @@ custom_edit_url: null
368368
let infoBasePath = `${outputDir}/${item.infoId}`;
369369
if (docRouteBasePath) {
370370
// Safely extract path segment, handling cases where docPath may not be in outputDir
371-
const outputSegment =
372-
docPath && outputDir.includes(docPath)
373-
? (outputDir.split(docPath)[1]?.replace(/^\/+/g, "") ?? "")
374-
: outputDir
375-
.slice(outputDir.indexOf("/", 1))
376-
.replace(/^\/+/g, "");
377-
infoBasePath =
378-
`${docRouteBasePath}/${outputSegment}/${item.infoId}`.replace(
379-
/^\/+/g,
380-
""
381-
);
371+
const normalize = (p: string): string =>
372+
p.replace(/^\.\//, "").replace(/^\/+|\/+$/g, "");
373+
const outputSegments = normalize(outputDir).split("/").filter(Boolean);
374+
let outputSegment = outputSegments.slice(1).join("/"); // fallback
375+
if (docPath) {
376+
const docSegments = normalize(docPath).split("/").filter(Boolean);
377+
for (let i = 0; i <= outputSegments.length - docSegments.length; i++) {
378+
const match = docSegments.every(
379+
(seg, j) => outputSegments[i + j] === seg
380+
);
381+
if (match) {
382+
outputSegment = outputSegments.slice(i + docSegments.length).join("/");
383+
break;
384+
}
385+
}
386+
}
387+
infoBasePath = `${docRouteBasePath}/${outputSegment}/${item.infoId}`
388+
.replace(/^\/+/g, "")
389+
.replace(/\/+/g, "/");
382390
}
383391
if (item.infoId) item.infoPath = infoBasePath;
384392
}

packages/docusaurus-plugin-openapi-docs/src/sidebars/index.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,29 @@ function groupByTags(
130130
output: string,
131131
doc: string | undefined
132132
): string => {
133-
if (doc && output.includes(doc)) {
134-
return output.split(doc)[1]?.replace(/^\/+/g, "") ?? "";
133+
// Normalize path: remove leading ./ and leading/trailing slashes
134+
const normalize = (p: string): string =>
135+
p.replace(/^\.\//, "").replace(/^\/+|\/+$/g, "");
136+
137+
const outputSegments = normalize(output).split("/").filter(Boolean);
138+
139+
if (doc) {
140+
const docSegments = normalize(doc).split("/").filter(Boolean);
141+
142+
// Find where docSegments sequence appears in outputSegments
143+
for (let i = 0; i <= outputSegments.length - docSegments.length; i++) {
144+
const match = docSegments.every(
145+
(seg, j) => outputSegments[i + j] === seg
146+
);
147+
if (match) {
148+
// Return everything after the matched sequence
149+
return outputSegments.slice(i + docSegments.length).join("/");
150+
}
151+
}
135152
}
136-
const slashIndex = output.indexOf("/", 1);
137-
return slashIndex === -1
138-
? ""
139-
: output.slice(slashIndex).replace(/^\/+/g, "");
153+
154+
// Fallback: return everything after first segment
155+
return outputSegments.slice(1).join("/");
140156
};
141157

142158
const basePath = getBasePathFromOutput(outputDir, docPath);

0 commit comments

Comments
 (0)