From fecf50a3166455be3a0f3c92f4b6088f24477ad2 Mon Sep 17 00:00:00 2001 From: Manan Tank Date: Thu, 25 Apr 2024 05:47:25 +0530 Subject: [PATCH] Fix different APIs with same name sharing same page in references --- .../TDoc/utils/getSidebarLinkgroups.ts | 22 +++++++--- .../references/components/TDoc/utils/slugs.ts | 40 ++++++------------- .../components/TDoc/utils/uniqueSlugger.ts | 23 +++++++++++ 3 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 src/app/references/components/TDoc/utils/uniqueSlugger.ts diff --git a/src/app/references/components/TDoc/utils/getSidebarLinkgroups.ts b/src/app/references/components/TDoc/utils/getSidebarLinkgroups.ts index bf641696..9132a0c2 100644 --- a/src/app/references/components/TDoc/utils/getSidebarLinkgroups.ts +++ b/src/app/references/components/TDoc/utils/getSidebarLinkgroups.ts @@ -5,6 +5,7 @@ import { SidebarLink, } from "../../../../../components/others/Sidebar"; import { subgroups } from "./subgroups"; +import { uniqueSlugger } from "./uniqueSlugger"; const tagsToGroup = { "@contract": "Contract", @@ -120,6 +121,17 @@ function getCustomTag(doc: SomeDoc): [TagKey, string | undefined] | undefined { export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { const linkGroups: LinkGroup[] = []; + const generatedLinks = new Set(); + + const getLink = (href: string) => { + const link = uniqueSlugger({ + base: href, + isUnique: (s) => !generatedLinks.has(s), + }); + + generatedLinks.add(link); + return link; + }; // group links by tags function createSubGroups(key: keyof typeof subgroups, docs: SomeDoc[]) { @@ -155,7 +167,7 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { ([extensionName, docs]) => { const links = docs.map((d) => ({ name: d.name, - href: `${path}/${extensionName.toLowerCase()}/${d.name}`, + href: getLink(`${path}/${extensionName.toLowerCase()}/${d.name}`), })); return { name: extensionName, @@ -166,7 +178,7 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { if (!linkGroups.find((group) => group.name === name)) { linkGroups.push({ name: name, - href: `${path}/${key}`, + href: getLink(`${path}/${key}`), links: [{ name: "Extensions", links: extensionLinkGroups }], }); } else { @@ -224,7 +236,7 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { name: tagsToGroup[tag], links: groupDocs.map((d) => ({ name: d.name, - href: `${path}/${d.name}`, + href: getLink(`${path}/${d.name}`), })), }); }; @@ -236,7 +248,7 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { ungroupedLinks.forEach((d) => { links.push({ name: d.name, - href: `${path}/${d.name}`, + href: getLink(`${path}/${d.name}`), }); }); @@ -251,7 +263,7 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) { linkGroups.push({ name: name, links: links, - href: `${path}/${key}`, + href: getLink(`${path}/${key}`), }); } } diff --git a/src/app/references/components/TDoc/utils/slugs.ts b/src/app/references/components/TDoc/utils/slugs.ts index 13e31eea..7bed6551 100644 --- a/src/app/references/components/TDoc/utils/slugs.ts +++ b/src/app/references/components/TDoc/utils/slugs.ts @@ -2,33 +2,10 @@ import { SomeDoc } from "@/app/references/components/TDoc/types"; import { TransformedDoc } from "typedoc-better-json"; import { getExtensionName } from "./getSidebarLinkgroups"; import { subgroups } from "./subgroups"; +import { uniqueSlugger } from "./uniqueSlugger"; export function fetchAllSlugs(doc: TransformedDoc) { - const names: string[] = []; - - for (const key in doc) { - const value = doc[key as keyof TransformedDoc]; - if (Array.isArray(value)) { - value.forEach((v) => { - if (v.kind === "function") { - const extensionBlockTag = v.signatures - ?.find((s) => s.blockTags?.some((tag) => tag.tag === "@extension")) - ?.blockTags?.find((tag) => tag.tag === "@extension"); - - if (extensionBlockTag) { - const extensionName = getExtensionName(extensionBlockTag); - if (extensionName) { - names.push(`${extensionName.toLowerCase()}/${v.name}`); - // skip to next loop - return; - } - } - } - - names.push(v.name); - }); - } - } + const names = Object.keys(getSlugToDocMap(doc)); // add slugs for category pages for (const _key in subgroups) { @@ -44,6 +21,13 @@ export function fetchAllSlugs(doc: TransformedDoc) { export function getSlugToDocMap(doc: TransformedDoc) { const slugToDocMap: Record = {}; + const ensureUniqueSlug = (slug: string) => { + return uniqueSlugger({ + base: slug, + isUnique: (s) => !(s in slugToDocMap), + }); + }; + for (const key in doc) { const value = doc[key as keyof TransformedDoc]; if (Array.isArray(value)) { @@ -58,13 +42,15 @@ export function getSlugToDocMap(doc: TransformedDoc) { if (extensionName) { const name = `${extensionName.toLowerCase()}/${v.name}`; - slugToDocMap[name] = v; + slugToDocMap[ensureUniqueSlug(name)] = v; + // skip to next loop return; } } } - slugToDocMap[v.name] = v; + + slugToDocMap[ensureUniqueSlug(v.name)] = v; }); } } diff --git a/src/app/references/components/TDoc/utils/uniqueSlugger.ts b/src/app/references/components/TDoc/utils/uniqueSlugger.ts new file mode 100644 index 00000000..edcb3de1 --- /dev/null +++ b/src/app/references/components/TDoc/utils/uniqueSlugger.ts @@ -0,0 +1,23 @@ +export function uniqueSlugger(options: { + base: string; + isUnique: (slug: string) => boolean; +}) { + const limit = 10; + const { base, isUnique } = options; + + // if slug is unique, save it and return + if (isUnique(base)) { + return base; + } + + // build a new slug by adding -n where n is the first number that makes the slug unique + let i = 2; + while (!isUnique(`${base}-${i}`)) { + i++; + if (i > limit) { + throw new Error(`Too many duplicates found for slug: ${base}`); + } + } + + return `${base}-${i}`; +}