@@ -27,6 +27,38 @@ interface ParserResult {
27
27
meta : string ;
28
28
}
29
29
30
+ interface SearchResponse {
31
+ query : string ;
32
+ locale : string ;
33
+ page : number ;
34
+ pages : number ;
35
+ starts : number ;
36
+ end : number ;
37
+ next : string ;
38
+ previous : string | null ;
39
+ count : number ;
40
+ filter : Array < {
41
+ name : string ;
42
+ slug : string ;
43
+ options : Array < {
44
+ name : string ;
45
+ slug : string ;
46
+ count : number ;
47
+ active : boolean ;
48
+ urls : {
49
+ active : string ;
50
+ inactive : string ;
51
+ } ;
52
+ } > ;
53
+ } > ;
54
+ documents : Array < {
55
+ title : string ;
56
+ slug : string ;
57
+ locale : string ;
58
+ excerpt : string ;
59
+ } > ;
60
+ }
61
+
30
62
interface ResultMeta {
31
63
getElementsByClassName ( cls : string ) : DOMParser . Node [ ] ;
32
64
}
@@ -75,6 +107,65 @@ const extractMetadataFromResult = (result: ResultMeta) => {
75
107
} ;
76
108
} ;
77
109
110
+ export const updatedQueryBuilder = (
111
+ searchUrl : typeof getSearchUrl = getSearchUrl ,
112
+ fetch : typeof useData = useData ,
113
+ waitForChosenResult : typeof getChosenResult = getChosenResult
114
+ ) => async ( msg : Message , searchTerm : string ) => {
115
+ const url = searchUrl ( provider , searchTerm ) ;
116
+ const { error, json } = await fetch < SearchResponse > ( url , 'json' ) ;
117
+ if ( ! error ) {
118
+ return msg . reply ( errors . invalidResponse ) ;
119
+ }
120
+
121
+ if ( json . documents . length === 0 ) {
122
+ const sentMsg = await msg . reply ( errors . noResults ( searchTerm ) ) ;
123
+ return delayedMessageAutoDeletion ( sentMsg ) ;
124
+ }
125
+
126
+ let preparedDescription = json . documents . map (
127
+ ( { title, excerpt, slug } , index ) =>
128
+ createMarkdownListItem (
129
+ index ,
130
+ createMarkdownLink (
131
+ adjustTitleLength ( [ `**${ title } **` , excerpt ] . join ( ' - ' ) ) ,
132
+ buildDirectUrl ( provider , slug )
133
+ )
134
+ )
135
+ ) ;
136
+
137
+ const expectedLength = preparedDescription . reduce (
138
+ ( sum , item ) => sum + item . length ,
139
+ 0
140
+ ) ;
141
+ if ( expectedLength + BASE_DESCRIPTION . length + 10 * '\n' . length > 2048 ) {
142
+ preparedDescription = preparedDescription . map ( string => {
143
+ // split at markdown link ending
144
+ const [ title , ...rest ] = string . split ( '...]' ) ;
145
+
146
+ // split title on title - excerpt glue
147
+ // concat with rest
148
+ // fix broken markdown link ending
149
+ return [ title . split ( ' - ' ) [ 0 ] , rest . join ( '' ) ] . join ( ']' ) ;
150
+ } ) ;
151
+ }
152
+
153
+ const sentMsg = await msg . channel . send (
154
+ createListEmbed ( {
155
+ description : createDescription ( preparedDescription ) ,
156
+ footerText : 'Powered by the search API' ,
157
+ provider,
158
+ searchTerm,
159
+ url,
160
+ } )
161
+ ) ;
162
+
163
+ const result = await waitForChosenResult ( sentMsg , msg , json . documents ) ;
164
+ if ( ! result ) {
165
+ return ;
166
+ }
167
+ } ;
168
+
78
169
/**
79
170
* Poor man's dependency injection without introducing classes, just use closures
80
171
* and higher order functions instead. Also provides a default so we don't have
0 commit comments