1- import { toTitlecase } from './misc.js' ;
21import { 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-
113export 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
5632type ParsedSection = {
57- heading : Heading | null ;
5833 headline : string ;
5934 lines : string [ ] ;
35+ route ?: Route ;
6036} ;
6137
6238function 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+
6949const IGNORE_LINE_PREFIXES = [ '>' , '---' , '|' , '!' ] ;
7050
7151export 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 = / < R o u t e m e t h o d = " (?< verb > \w { 3 , 6 } ) " > \/ (?< path > .* ) < \/ R o u t e > / . 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-
150130export 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