@microlink/google 0.0.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +0 -0
- package/package.json +50 -24
- package/src/css/style.css +1152 -0
- package/src/index.d.ts +327 -0
- package/src/index.js +51 -25
- package/src/js/main.js +397 -0
- package/src/main.mjs +7 -0
- package/README.md +0 -163
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
type Period = 'hour' | 'day' | 'week' | 'month' | 'year'
|
|
2
|
+
|
|
3
|
+
type Type =
|
|
4
|
+
| 'search'
|
|
5
|
+
| 'news'
|
|
6
|
+
| 'images'
|
|
7
|
+
| 'videos'
|
|
8
|
+
| 'places'
|
|
9
|
+
| 'maps'
|
|
10
|
+
| 'shopping'
|
|
11
|
+
| 'scholar'
|
|
12
|
+
| 'patents'
|
|
13
|
+
| 'autocomplete'
|
|
14
|
+
|
|
15
|
+
interface TypeToPage {
|
|
16
|
+
search: SearchPage
|
|
17
|
+
news: NewsPage
|
|
18
|
+
images: ImagesPage
|
|
19
|
+
videos: VideosPage
|
|
20
|
+
places: PlacesPage
|
|
21
|
+
maps: MapsPage
|
|
22
|
+
shopping: ShoppingPage
|
|
23
|
+
scholar: ScholarPage
|
|
24
|
+
patents: PatentsPage
|
|
25
|
+
autocomplete: AutocompletePage
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type Location =
|
|
29
|
+
| 'af' | 'al' | 'dz' | 'as' | 'ad' | 'ao' | 'ai' | 'aq' | 'ag' | 'ar'
|
|
30
|
+
| 'am' | 'aw' | 'au' | 'at' | 'az' | 'bs' | 'bh' | 'bd' | 'bb' | 'by'
|
|
31
|
+
| 'be' | 'bz' | 'bj' | 'bm' | 'bt' | 'bo' | 'ba' | 'bw' | 'bv' | 'br'
|
|
32
|
+
| 'io' | 'bn' | 'bg' | 'bf' | 'bi' | 'kh' | 'cm' | 'ca' | 'cv' | 'ky'
|
|
33
|
+
| 'cf' | 'td' | 'cl' | 'cn' | 'cx' | 'cc' | 'co' | 'km' | 'cg' | 'cd'
|
|
34
|
+
| 'ck' | 'cr' | 'ci' | 'hr' | 'cu' | 'cy' | 'cz' | 'dk' | 'dj' | 'dm'
|
|
35
|
+
| 'do' | 'ec' | 'eg' | 'sv' | 'gq' | 'er' | 'ee' | 'et' | 'fk' | 'fo'
|
|
36
|
+
| 'fj' | 'fi' | 'fr' | 'gf' | 'pf' | 'tf' | 'ga' | 'gm' | 'ge' | 'de'
|
|
37
|
+
| 'gh' | 'gi' | 'gr' | 'gl' | 'gd' | 'gp' | 'gu' | 'gt' | 'gn' | 'gw'
|
|
38
|
+
| 'gy' | 'ht' | 'hm' | 'va' | 'hn' | 'hk' | 'hu' | 'is' | 'in' | 'id'
|
|
39
|
+
| 'ir' | 'iq' | 'ie' | 'il' | 'it' | 'jm' | 'jp' | 'jo' | 'kz' | 'ke'
|
|
40
|
+
| 'ki' | 'kp' | 'kr' | 'kw' | 'kg' | 'la' | 'lv' | 'lb' | 'ls' | 'lr'
|
|
41
|
+
| 'ly' | 'li' | 'lt' | 'lu' | 'mo' | 'mk' | 'mg' | 'mw' | 'my' | 'mv'
|
|
42
|
+
| 'ml' | 'mt' | 'mh' | 'mq' | 'mr' | 'mu' | 'yt' | 'mx' | 'fm' | 'md'
|
|
43
|
+
| 'mc' | 'mn' | 'ms' | 'ma' | 'mz' | 'mm' | 'na' | 'nr' | 'np' | 'nl'
|
|
44
|
+
| 'an' | 'nc' | 'nz' | 'ni' | 'ne' | 'ng' | 'nu' | 'nf' | 'mp' | 'no'
|
|
45
|
+
| 'om' | 'pk' | 'pw' | 'ps' | 'pa' | 'pg' | 'py' | 'pe' | 'ph' | 'pn'
|
|
46
|
+
| 'pl' | 'pt' | 'pr' | 'qa' | 're' | 'ro' | 'ru' | 'rw' | 'sh' | 'kn'
|
|
47
|
+
| 'lc' | 'pm' | 'vc' | 'ws' | 'sm' | 'st' | 'sa' | 'sn' | 'rs' | 'sc'
|
|
48
|
+
| 'sl' | 'sg' | 'sk' | 'si' | 'sb' | 'so' | 'za' | 'gs' | 'es' | 'lk'
|
|
49
|
+
| 'sd' | 'sr' | 'sj' | 'sz' | 'se' | 'ch' | 'sy' | 'tw' | 'tj' | 'tz'
|
|
50
|
+
| 'th' | 'tl' | 'tg' | 'tk' | 'to' | 'tt' | 'tn' | 'tr' | 'tm' | 'tc'
|
|
51
|
+
| 'tv' | 'ug' | 'ua' | 'ae' | 'gb' | 'us' | 'um' | 'uy' | 'uz' | 'vu'
|
|
52
|
+
| 've' | 'vn' | 'vg' | 'vi' | 'wf' | 'eh' | 'ye' | 'zm' | 'zw'
|
|
53
|
+
|
|
54
|
+
interface Options {
|
|
55
|
+
type?: Type
|
|
56
|
+
limit?: number
|
|
57
|
+
location?: Location
|
|
58
|
+
period?: Period
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface Sitelink {
|
|
62
|
+
title: string
|
|
63
|
+
link: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface KnowledgeGraph {
|
|
67
|
+
title?: string
|
|
68
|
+
type?: string
|
|
69
|
+
website?: string
|
|
70
|
+
image?: { url: string }
|
|
71
|
+
description?: string
|
|
72
|
+
descriptionSource?: string
|
|
73
|
+
descriptionLink?: string
|
|
74
|
+
attributes?: Record<string, string>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface PeopleAlsoAsk {
|
|
78
|
+
question: string
|
|
79
|
+
snippet: string
|
|
80
|
+
title: string
|
|
81
|
+
link: string
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface RelatedSearch {
|
|
85
|
+
query: string
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface SearchResult {
|
|
89
|
+
title: string
|
|
90
|
+
url: string
|
|
91
|
+
description: string
|
|
92
|
+
html(): Promise<string>
|
|
93
|
+
markdown(): Promise<string>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface SearchPage {
|
|
97
|
+
results: SearchResult[]
|
|
98
|
+
knowledgeGraph?: KnowledgeGraph
|
|
99
|
+
peopleAlsoAsk?: PeopleAlsoAsk[]
|
|
100
|
+
relatedSearches?: RelatedSearch[]
|
|
101
|
+
html(): Promise<string>
|
|
102
|
+
markdown(): Promise<string>
|
|
103
|
+
next(): Promise<SearchPage>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface NewsResult {
|
|
107
|
+
title: string
|
|
108
|
+
url: string
|
|
109
|
+
description: string
|
|
110
|
+
date: string
|
|
111
|
+
publisher: string
|
|
112
|
+
image?: { url: string }
|
|
113
|
+
html(): Promise<string>
|
|
114
|
+
markdown(): Promise<string>
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface NewsPage {
|
|
118
|
+
results: NewsResult[]
|
|
119
|
+
html(): Promise<string>
|
|
120
|
+
markdown(): Promise<string>
|
|
121
|
+
next(): Promise<NewsPage>
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
interface ImageResult {
|
|
125
|
+
title: string
|
|
126
|
+
url: string
|
|
127
|
+
image: { url: string; width: number; height: number }
|
|
128
|
+
thumbnail: { url: string; width: number; height: number }
|
|
129
|
+
google?: { url: string }
|
|
130
|
+
creator?: string
|
|
131
|
+
credit?: string
|
|
132
|
+
html(): Promise<string>
|
|
133
|
+
markdown(): Promise<string>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface ImagesPage {
|
|
137
|
+
results: ImageResult[]
|
|
138
|
+
html(): Promise<string>
|
|
139
|
+
markdown(): Promise<string>
|
|
140
|
+
next(): Promise<ImagesPage>
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface VideoResult {
|
|
144
|
+
title: string
|
|
145
|
+
url: string
|
|
146
|
+
description: string
|
|
147
|
+
image?: { url: string }
|
|
148
|
+
video?: { url: string }
|
|
149
|
+
duration?: number
|
|
150
|
+
duration_pretty?: string
|
|
151
|
+
publisher?: string
|
|
152
|
+
channel?: string
|
|
153
|
+
date?: string
|
|
154
|
+
html(): Promise<string>
|
|
155
|
+
markdown(): Promise<string>
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface VideosPage {
|
|
159
|
+
results: VideoResult[]
|
|
160
|
+
html(): Promise<string>
|
|
161
|
+
markdown(): Promise<string>
|
|
162
|
+
next(): Promise<VideosPage>
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface PlaceResult {
|
|
166
|
+
title: string
|
|
167
|
+
address: string
|
|
168
|
+
latitude: number
|
|
169
|
+
longitude: number
|
|
170
|
+
phone?: { number: string }
|
|
171
|
+
url?: string
|
|
172
|
+
cid: string
|
|
173
|
+
html(): Promise<string>
|
|
174
|
+
markdown(): Promise<string>
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
interface PlacesPage {
|
|
178
|
+
results: PlaceResult[]
|
|
179
|
+
html(): Promise<string>
|
|
180
|
+
markdown(): Promise<string>
|
|
181
|
+
next(): Promise<PlacesPage>
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface MapPlaceResult {
|
|
185
|
+
title: string
|
|
186
|
+
address: string
|
|
187
|
+
latitude: number
|
|
188
|
+
longitude: number
|
|
189
|
+
rating?: number
|
|
190
|
+
ratingCount?: number
|
|
191
|
+
price?: { level: string }
|
|
192
|
+
type?: string
|
|
193
|
+
types?: string[]
|
|
194
|
+
url?: string
|
|
195
|
+
phone?: { number: string }
|
|
196
|
+
description?: string
|
|
197
|
+
opening?: { hours: Record<string, string> }
|
|
198
|
+
thumbnail?: { url: string }
|
|
199
|
+
cid: string
|
|
200
|
+
fid?: string
|
|
201
|
+
place?: { id: string }
|
|
202
|
+
html(): Promise<string>
|
|
203
|
+
markdown(): Promise<string>
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface MapsPage {
|
|
207
|
+
results: MapPlaceResult[]
|
|
208
|
+
html(): Promise<string>
|
|
209
|
+
markdown(): Promise<string>
|
|
210
|
+
next(): Promise<MapsPage>
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
interface ShoppingResult {
|
|
214
|
+
title: string
|
|
215
|
+
url: string
|
|
216
|
+
publisher: string
|
|
217
|
+
price: { symbol: string; amount: number }
|
|
218
|
+
image?: { url: string }
|
|
219
|
+
rating?: { score: number; total: number; reviews?: number }
|
|
220
|
+
id?: string
|
|
221
|
+
html(): Promise<string>
|
|
222
|
+
markdown(): Promise<string>
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
interface ShoppingPage {
|
|
226
|
+
results: ShoppingResult[]
|
|
227
|
+
html(): Promise<string>
|
|
228
|
+
markdown(): Promise<string>
|
|
229
|
+
next(): Promise<ShoppingPage>
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface ScholarResult {
|
|
233
|
+
title: string
|
|
234
|
+
url: string
|
|
235
|
+
description: string
|
|
236
|
+
publisher: string
|
|
237
|
+
year: number
|
|
238
|
+
citations: number
|
|
239
|
+
pdf?: { url: string }
|
|
240
|
+
id: string
|
|
241
|
+
html(): Promise<string>
|
|
242
|
+
markdown(): Promise<string>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
interface ScholarPage {
|
|
246
|
+
results: ScholarResult[]
|
|
247
|
+
html(): Promise<string>
|
|
248
|
+
markdown(): Promise<string>
|
|
249
|
+
next(): Promise<ScholarPage>
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface PatentResult {
|
|
253
|
+
title: string
|
|
254
|
+
description: string
|
|
255
|
+
url: string
|
|
256
|
+
priority: { date: string }
|
|
257
|
+
filing: { date: string }
|
|
258
|
+
grant?: { date: string }
|
|
259
|
+
publication: { date: string; number: string }
|
|
260
|
+
inventor: string
|
|
261
|
+
assignee: string
|
|
262
|
+
language: string
|
|
263
|
+
pdf?: { url: string }
|
|
264
|
+
thumbnail?: { url: string }
|
|
265
|
+
figures?: Array<{ image: { url: string }; thumbnail: { url: string } }>
|
|
266
|
+
id?: string
|
|
267
|
+
html(): Promise<string>
|
|
268
|
+
markdown(): Promise<string>
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
interface PatentsPage {
|
|
272
|
+
results: PatentResult[]
|
|
273
|
+
html(): Promise<string>
|
|
274
|
+
markdown(): Promise<string>
|
|
275
|
+
next(): Promise<PatentsPage>
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
interface SuggestionResult {
|
|
279
|
+
value: string
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
interface AutocompletePage {
|
|
283
|
+
results: SuggestionResult[]
|
|
284
|
+
html(): Promise<string>
|
|
285
|
+
markdown(): Promise<string>
|
|
286
|
+
next(): Promise<AutocompletePage>
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
interface GoogleClient {
|
|
290
|
+
<K extends Type>(
|
|
291
|
+
query: string,
|
|
292
|
+
options: Omit<Options, 'type'> & { type: K }
|
|
293
|
+
): Promise<TypeToPage[K]>
|
|
294
|
+
(query: string, options?: Options): Promise<SearchPage>
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
interface ContextOptions {
|
|
298
|
+
apiKey?: string
|
|
299
|
+
endpoint?: string
|
|
300
|
+
timeout?: number
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export declare const DOMAIN: string
|
|
304
|
+
|
|
305
|
+
export declare function buildPath(
|
|
306
|
+
query: string,
|
|
307
|
+
limit?: number,
|
|
308
|
+
location?: string
|
|
309
|
+
): string
|
|
310
|
+
|
|
311
|
+
export declare function buildUrl(
|
|
312
|
+
query: string,
|
|
313
|
+
options?: {
|
|
314
|
+
limit?: number
|
|
315
|
+
location?: string
|
|
316
|
+
type?: Type
|
|
317
|
+
period?: Period
|
|
318
|
+
}
|
|
319
|
+
): URL
|
|
320
|
+
|
|
321
|
+
interface createGoogleClient {
|
|
322
|
+
(options?: ContextOptions): GoogleClient
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
declare const createGoogleClient: createGoogleClient
|
|
326
|
+
|
|
327
|
+
export default createGoogleClient
|
package/src/index.js
CHANGED
|
@@ -4,51 +4,77 @@ const mql = require('@microlink/mql')
|
|
|
4
4
|
|
|
5
5
|
const DOMAIN = 'microlink.google'
|
|
6
6
|
|
|
7
|
-
const buildPath = (query, limit,
|
|
8
|
-
[encodeURIComponent(query).replace(/%20/g, '+'), limit,
|
|
7
|
+
const buildPath = (query, limit, location) =>
|
|
8
|
+
[encodeURIComponent(query).replace(/%20/g, '+'), limit, location]
|
|
9
9
|
.filter(v => v !== undefined)
|
|
10
10
|
.join('/')
|
|
11
11
|
|
|
12
|
-
const buildUrl = (query, { limit,
|
|
13
|
-
const url = new URL(`https://${DOMAIN}/${buildPath(query, limit,
|
|
14
|
-
if (
|
|
12
|
+
const buildUrl = (query, { limit, location, type, period } = {}) => {
|
|
13
|
+
const url = new URL(`https://${DOMAIN}/${buildPath(query, limit, location)}`)
|
|
14
|
+
if (type) url.searchParams.set('type', type)
|
|
15
15
|
if (period) url.searchParams.set('period', period)
|
|
16
|
-
if (domain) url.searchParams.set('domain', domain)
|
|
17
16
|
return url
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
const
|
|
19
|
+
const resultUrl = result => result.url
|
|
20
|
+
|
|
21
|
+
const fetchDataField = async (url, mqlOpts, field, attr) => {
|
|
22
|
+
const { data } = await mql(url, {
|
|
23
|
+
...mqlOpts,
|
|
24
|
+
data: { [field]: { attr } }
|
|
25
|
+
})
|
|
26
|
+
return data[field]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const fetchPage = async (url, mqlOpts, offset, query) => {
|
|
21
30
|
url.searchParams.set('start', String(offset))
|
|
22
31
|
const { data } = await mql(url.toString(), mqlOpts)
|
|
23
|
-
const { results,
|
|
32
|
+
const { results, ...extra } = data
|
|
24
33
|
|
|
25
34
|
return {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
...extra,
|
|
36
|
+
html: () =>
|
|
37
|
+
fetchDataField(
|
|
38
|
+
`https://www.google.com/search?q=${encodeURIComponent(query)}`,
|
|
39
|
+
mqlOpts,
|
|
40
|
+
'content',
|
|
41
|
+
'html'
|
|
42
|
+
),
|
|
43
|
+
markdown: () =>
|
|
44
|
+
fetchDataField(
|
|
45
|
+
`https://www.google.com/search?q=${encodeURIComponent(query)}`,
|
|
46
|
+
mqlOpts,
|
|
47
|
+
'markdown',
|
|
48
|
+
'markdown'
|
|
49
|
+
),
|
|
50
|
+
results: results.map(result => {
|
|
51
|
+
const url = resultUrl(result)
|
|
52
|
+
return {
|
|
53
|
+
...result,
|
|
54
|
+
...(url && {
|
|
55
|
+
html: () => fetchDataField(url, mqlOpts, 'content', 'html'),
|
|
56
|
+
markdown: () => fetchDataField(url, mqlOpts, 'markdown', 'markdown')
|
|
33
57
|
})
|
|
34
|
-
return data.content
|
|
35
58
|
}
|
|
36
|
-
})
|
|
59
|
+
}),
|
|
37
60
|
next: () =>
|
|
38
|
-
fetchPage(
|
|
61
|
+
fetchPage(
|
|
62
|
+
new URL(url.toString()),
|
|
63
|
+
mqlOpts,
|
|
64
|
+
offset + results.length,
|
|
65
|
+
query
|
|
66
|
+
)
|
|
39
67
|
}
|
|
40
68
|
}
|
|
41
69
|
|
|
42
|
-
|
|
43
|
-
return async (
|
|
44
|
-
query,
|
|
45
|
-
|
|
46
|
-
) => {
|
|
47
|
-
const url = buildUrl(query, { limit, lang, device, period, domain })
|
|
48
|
-
return fetchPage(url, { ...ctxOpts, ...opts }, 0)
|
|
70
|
+
const createGoogleClient = ctxOpts => {
|
|
71
|
+
return async (query, { limit, location, type, period, ...opts } = {}) => {
|
|
72
|
+
const url = buildUrl(query, { limit, location, type, period })
|
|
73
|
+
return fetchPage(url, { ...ctxOpts, ...opts }, 0, query)
|
|
49
74
|
}
|
|
50
75
|
}
|
|
51
76
|
|
|
77
|
+
module.exports = createGoogleClient
|
|
52
78
|
module.exports.buildPath = buildPath
|
|
53
79
|
module.exports.buildUrl = buildUrl
|
|
54
80
|
module.exports.DOMAIN = DOMAIN
|