11import { SlashCommandBuilder } from "@discordjs/builders" ;
2- import { deleteButton , deleteButtonHandler } from "../../utils/CommandUtils" ;
2+ import { deleteButton } from "../../utils/CommandUtils" ;
33import { MessageActionRow , MessageEmbed , MessageSelectMenu } from "discord.js" ;
44import { gunzipSync } from "zlib" ;
55import { XMLParser } from "fast-xml-parser" ;
@@ -39,7 +39,8 @@ const command: Command = {
3939 const deleteButtonRow = new MessageActionRow ( ) . addComponents ( [ deleteButton ( interaction . user . id ) ] ) ;
4040 const query = interaction . options . getString ( "query" ) ;
4141 const { index, sitemap } = await getSources ( ) ;
42- const search : string [ ] = index . search ( query , { limit : 10 } ) . map ( ( id ) => sitemap [ < number > id ] . loc ) ;
42+ // Get the top 25 results
43+ const search : string [ ] = index . search ( query , { limit : 25 } ) . map ( ( id ) => sitemap [ < number > id ] . loc ) ;
4344 const embed = new MessageEmbed ( )
4445 . setColor ( MDN_BLUE_COLOR )
4546 . setAuthor ( { name : "MDN Documentation" , iconURL : MDN_ICON_URL } )
@@ -49,8 +50,9 @@ const command: Command = {
4950 embed . setColor ( 0xff0000 ) . setDescription ( "No results found..." ) ;
5051 await interaction . editReply ( { embeds : [ embed ] } ) . catch ( console . error ) ;
5152 return ;
52- } else if ( search . length === 1 ) {
53- const resultEmbed = await getSingleMDNSearchResults ( search [ 0 ] ) ;
53+ } else if ( search . length === 1 || search . includes ( query ) ) {
54+ // If there's an exact match
55+ const resultEmbed = await getSingleMDNSearchResults ( search . includes ( query ) ? query : search [ 0 ] ) ;
5456 if ( ! resultEmbed ) {
5557 await interaction . editReply ( { content : "Couldn't find any results" } ) . catch ( console . error ) ;
5658 return ;
@@ -109,15 +111,16 @@ const command: Command = {
109111 } ,
110112 } ,
111113 ] ,
112- buttons : [ { custom_id : "deletebtn" , run : deleteButtonHandler } ] ,
113114 autocomplete : [
114115 {
115116 focusedOption : "query" ,
116117 async run ( interaction , focusedOption ) {
117118 const query = focusedOption . value as string ;
118119 const { index, sitemap } = await getSources ( ) ;
119- const search = index . search ( query , { limit : 10 } ) . map ( ( id ) => {
120+ // The limit for autocomplete options is 25
121+ const search = index . search ( query , { limit : 25 } ) . map ( ( id ) => {
120122 const val = sitemap [ < number > id ] . loc ;
123+ // Values and names have a limit of 100 characters
121124 const parsed = val . length >= 99 ? val . split ( "/" ) . slice ( - 2 ) . join ( "/" ) : val ;
122125 return { name : parsed , value : parsed } ;
123126 } ) ;
@@ -131,9 +134,11 @@ const command: Command = {
131134export async function getSingleMDNSearchResults ( searchQuery : string ) {
132135 // Search for the match once again
133136 const { index, sitemap } = await getSources ( ) ;
134- const secondSearch = index . search ( searchQuery , { limit : 10 } ) . map ( ( id ) => sitemap [ < number > id ] . loc ) [ 0 ] ;
135-
136- const res = await fetch ( `${ MDN_BASE_URL + secondSearch } /index.json` ) . catch ( console . error ) ;
137+ // Search one more time
138+ const secondSearch = index . search ( searchQuery , { limit : 25 } ) . map ( ( id ) => sitemap [ < number > id ] . loc ) ;
139+ // Since it returns an array, the exact match might not be the first selection, if the exact match exists, fetch using that, if not get the first result
140+ const finalSelection = secondSearch . includes ( searchQuery ) ? searchQuery : secondSearch [ 0 ] ;
141+ const res = await fetch ( `${ MDN_BASE_URL + finalSelection } /index.json` ) . catch ( console . error ) ;
137142 if ( ! res || ! res ?. ok ) return null ;
138143 const resJSON = await res . json ?.( ) . catch ( console . error ) ;
139144 if ( ! res . json ) return null ;
@@ -154,8 +159,8 @@ export async function getSources(): Promise<typeof sources> {
154159
155160 const res = await fetch ( "https://developer.mozilla.org/sitemaps/en-us/sitemap.xml.gz" ) ;
156161 if ( ! res . ok ) return sources ; // Fallback to old sources if the new ones are not available for any reason
157- const something = new XMLParser ( ) . parse ( gunzipSync ( await res . buffer ( ) ) . toString ( ) ) ;
158- const sitemap : Sitemap < number > = something . urlset . url . map ( ( entry : SitemapEntry < string > ) => ( {
162+ const parsedSitemap = new XMLParser ( ) . parse ( gunzipSync ( await res . buffer ( ) ) . toString ( ) ) ;
163+ const sitemap : Sitemap < number > = parsedSitemap . urlset . url . map ( ( entry : SitemapEntry < string > ) => ( {
159164 loc : entry . loc . slice ( MDN_BASE_URL . length ) ,
160165 lastmod : new Date ( entry . lastmod ) . valueOf ( ) ,
161166 } ) ) ;
0 commit comments