Skip to content

Commit 436c954

Browse files
committed
fix(discorddocs): consider upstream format
* new route format * handle parense in titles for matches
1 parent 5e1f5fc commit 436c954

File tree

3 files changed

+52
-69
lines changed

3 files changed

+52
-69
lines changed

src/functions/algoliaResponse.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ export async function algoliaResponse(
3737
},
3838
}).then(async (res) => res.json())) as AlgoliaHit;
3939

40-
const docsBody = hit.url.includes('discord.com') ? await fetchDocsBody(hit.url) : null;
41-
const headlineSuffix =
42-
docsBody?.heading?.verb && docsBody?.heading.route
43-
? inlineCode(`${docsBody.heading.verb} ${docsBody.heading.route}`.replaceAll('\\', ''))
44-
: null;
40+
const docsSection = hit.url.includes('discord.com') ? await fetchDocsBody(hit.url) : null;
41+
42+
const headlineSuffix = docsSection?.route
43+
? inlineCode(`${docsSection.route.verb} ${docsSection.route.path}`.replaceAll('\\', ''))
44+
: null;
4545

4646
const contentParts = [
4747
`<:${emojiName}:${emojiId}> ${bold(resolveHitToNamestring(hit))}${headlineSuffix ? ` ${headlineSuffix}` : ''}`,
48-
hit.content?.length ? `${truncate(decode(hit.content), 300)}` : docsBody?.lines.at(0),
48+
hit.content?.length ? `${truncate(decode(hit.content), 300)}` : docsSection?.lines.at(0),
4949
`${hyperlink('read more', hideLinkEmbed(hit.url))}`,
5050
].filter(Boolean) as string[];
5151

src/functions/oramaResponse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export async function oramaResponse(res: Response, resultUrl: string, user?: str
5858
const section = findRelevantDocsSection(parsed.anchor ? `#${parsed.anchor}` : parsed.endpoint ?? '', docsContents);
5959

6060
if (section) {
61-
const title = section.heading?.label ?? parsed.endpoint ?? 'No Title';
61+
const title = section.headline ?? parsed.endpoint ?? 'No Title';
6262
contentParts.push(`<:guide:${EMOJI_ID_GUIDE}> ${bold(title)}`);
6363
}
6464

src/util/discordDocs.ts

Lines changed: 45 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
import { toTitlecase } from './misc.js';
21
import { urlOption } from './url.js';
32

4-
export function toMdFilename(name: string) {
5-
return name
6-
.split('-')
7-
.map((part) => toTitlecase(part))
8-
.join('_');
9-
}
10-
113
export function resolveResourceFromDocsURL(link: string) {
124
const url = urlOption(link);
135
if (!url) {
@@ -19,44 +11,28 @@ export function resolveResourceFromDocsURL(link: string) {
1911
return null;
2012
}
2113

22-
return {
23-
docsAnchor: url.hash,
24-
githubUrl: `https://raw.githubusercontent.com/discord/discord-api-docs/main/${pathParts
25-
.slice(0, -1)
26-
.join('/')}/${toMdFilename(pathParts.at(-1)!)}.md`,
27-
};
28-
}
29-
30-
type Heading = {
31-
docs_anchor?: string;
32-
label: string;
33-
route?: string;
34-
verb?: string;
35-
};
36-
37-
function parseHeadline(text: string): Heading | null {
38-
const match = /#{1,7} (?<label>.+) % (?<verb>\w{3,6}) (?<route>.*)|#{1,7} (?<onlylabel>.+)/g.exec(text);
39-
if (!match?.groups) {
40-
return null;
41-
}
42-
43-
const { groups } = match;
44-
const label = groups.label ?? groups.onlylabel;
14+
const docsAnchor = url.hash;
15+
const githubUrl = `https://raw.githubusercontent.com/discord/discord-api-docs/main/${pathParts
16+
.slice(0, -1)
17+
.join('/')}/${pathParts.at(-1)!}.md`;
4518

4619
return {
47-
docs_anchor: `#${label.replaceAll(' ', '-').replaceAll(':', '').toLowerCase()}`,
48-
label,
49-
verb: groups.verb,
50-
route: groups.route,
20+
docsAnchor,
21+
githubUrl,
5122
};
5223
}
5324

54-
// https://raw.githubusercontent.com/discord/discord-api-docs/main/docs/resources/User.md
25+
// https://raw.githubusercontent.com/discord/discord-api-docs/main/docs/resources/user.mdx
26+
27+
type Route = {
28+
verb: string;
29+
path: string;
30+
};
5531

5632
type ParsedSection = {
57-
heading: Heading | null;
5833
headline: string;
5934
lines: string[];
35+
route?: Route;
6036
};
6137

6238
function cleanLine(line: string) {
@@ -66,17 +42,21 @@ function cleanLine(line: string) {
6642
.trim();
6743
}
6844

45+
function formatRoutePath(path: string) {
46+
return path.replaceAll(/\[(.*?)\]\(.*?\)/g, '$1');
47+
}
48+
6949
const IGNORE_LINE_PREFIXES = ['>', '---', '|', '!'];
7050

7151
export function parseSections(content: string): ParsedSection[] {
7252
const res = [];
7353
const section: ParsedSection = {
74-
heading: null,
7554
lines: [],
7655
headline: '',
7756
};
7857

7958
let withinPreamble = false;
59+
let withinAdmonition = false;
8060
let index = 0;
8161
for (const line of content.split('\n')) {
8262
const cleanedLine = cleanLine(line);
@@ -92,7 +72,15 @@ export function parseSections(content: string): ParsedSection[] {
9272
if (withinPreamble && line.startsWith('title:')) {
9373
const titleName = line.replace('title: ', '');
9474
section.headline = titleName;
95-
section.heading = { label: titleName };
75+
}
76+
77+
if (line.startsWith(':::')) {
78+
withinAdmonition = !withinAdmonition;
79+
continue;
80+
}
81+
82+
if (withinAdmonition) {
83+
continue;
9684
}
9785

9886
index++;
@@ -107,14 +95,21 @@ export function parseSections(content: string): ParsedSection[] {
10795
res.push({ ...section });
10896

10997
section.lines = [];
110-
section.heading = null;
11198
section.headline = '';
11299
}
113100

114-
section.headline = cleanedLine;
115-
const parsedHeading = parseHeadline(cleanedLine);
116-
if (parsedHeading) {
117-
section.heading = parsedHeading;
101+
section.headline = cleanedLine.replace(/^#+ ?/, '').replaceAll(/[()]/g, '');
102+
continue;
103+
}
104+
105+
if (line.startsWith('<Route')) {
106+
const match = /<Route method="(?<verb>\w{3,6})">\/(?<path>.*)<\/Route>/.exec(line);
107+
108+
if (match) {
109+
section.route = {
110+
verb: match.groups?.['verb']!,
111+
path: formatRoutePath(match.groups?.['path']!),
112+
};
118113
}
119114

120115
continue;
@@ -125,33 +120,20 @@ export function parseSections(content: string): ParsedSection[] {
125120
}
126121
}
127122

128-
if (section.heading) {
123+
if (section.headline?.length) {
129124
res.push({ ...section });
130125
}
131126

132127
return res;
133128
}
134129

135-
function compressAnchor(anchor: string) {
136-
return anchor.replaceAll('-', '');
137-
}
138-
139-
function anchorsCompressedEqual(one?: string, other?: string) {
140-
if (!one || !other) {
141-
return false;
142-
}
143-
144-
const one_ = compressAnchor(one);
145-
const other_ = compressAnchor(other);
146-
147-
return one_ === other_;
148-
}
149-
150130
export function findRelevantDocsSection(query: string, docsMd: string) {
151131
const sections = parseSections(docsMd);
132+
152133
for (const section of sections) {
153-
const anchor = section.heading?.docs_anchor ?? section.headline.toLowerCase();
154-
if (anchor.startsWith(query) || anchorsCompressedEqual(anchor, query)) {
134+
const anchor = `#${section.headline.toLowerCase().replaceAll(' ', '-').replaceAll(':', '')}`;
135+
136+
if (anchor == query) {
155137
return section;
156138
}
157139
}
@@ -171,6 +153,7 @@ export async function fetchDocsBody(link: string) {
171153

172154
return res.text();
173155
});
156+
174157
const section = findRelevantDocsSection(githubResource.docsAnchor, docsMd);
175158

176159
if (section) {

0 commit comments

Comments
 (0)