googlemaps-kit 0.5.0 → 0.7.0
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/README.md +56 -3
- package/dist/advanced/parsers.d.ts +1 -1
- package/dist/advanced/parsers.d.ts.map +1 -1
- package/dist/advanced/parsers.js +1 -1
- package/dist/advanced/parsers.js.map +1 -1
- package/dist/advanced.d.ts +2 -2
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js.map +1 -1
- package/dist/books.d.ts +30 -0
- package/dist/books.d.ts.map +1 -0
- package/dist/books.js +77 -0
- package/dist/books.js.map +1 -0
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +9 -11
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/tui/app.d.ts.map +1 -1
- package/dist/cli/tui/app.js +7 -7
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli.js +14 -11
- package/dist/cli.js.map +1 -1
- package/dist/client/gmaps-client.d.ts +7 -29
- package/dist/client/gmaps-client.d.ts.map +1 -1
- package/dist/client/gmaps-client.js +15 -131
- package/dist/client/gmaps-client.js.map +1 -1
- package/dist/client/http-client.d.ts +3 -1
- package/dist/client/http-client.d.ts.map +1 -1
- package/dist/client/http-client.js +14 -3
- package/dist/client/http-client.js.map +1 -1
- package/dist/client/intent.d.ts +1 -11
- package/dist/client/intent.d.ts.map +1 -1
- package/dist/client/intent.js +17 -13
- package/dist/client/intent.js.map +1 -1
- package/dist/client/maps-tools.d.ts +8 -4
- package/dist/client/maps-tools.d.ts.map +1 -1
- package/dist/client/maps-tools.js +20 -11
- package/dist/client/maps-tools.js.map +1 -1
- package/dist/client/namespaces.d.ts +51 -19
- package/dist/client/namespaces.d.ts.map +1 -1
- package/dist/client/namespaces.js +82 -28
- package/dist/client/namespaces.js.map +1 -1
- package/dist/client/place-workflows.d.ts +7 -0
- package/dist/client/place-workflows.d.ts.map +1 -0
- package/dist/client/place-workflows.js +113 -0
- package/dist/client/place-workflows.js.map +1 -0
- package/dist/finance/client.d.ts +19 -0
- package/dist/finance/client.d.ts.map +1 -0
- package/dist/finance/client.js +75 -0
- package/dist/finance/client.js.map +1 -0
- package/dist/finance/parsers.d.ts +13 -0
- package/dist/finance/parsers.d.ts.map +1 -0
- package/dist/finance/parsers.js +146 -0
- package/dist/finance/parsers.js.map +1 -0
- package/dist/finance/types.d.ts +76 -0
- package/dist/finance/types.d.ts.map +1 -0
- package/dist/finance/types.js +2 -0
- package/dist/finance/types.js.map +1 -0
- package/dist/finance.d.ts +5 -0
- package/dist/finance.d.ts.map +1 -0
- package/dist/finance.js +4 -0
- package/dist/finance.js.map +1 -0
- package/dist/flights/client.d.ts +9 -0
- package/dist/flights/client.d.ts.map +1 -0
- package/dist/flights/client.js +14 -0
- package/dist/flights/client.js.map +1 -0
- package/dist/flights/parsers.d.ts +11 -0
- package/dist/flights/parsers.d.ts.map +1 -0
- package/dist/flights/parsers.js +64 -0
- package/dist/flights/parsers.js.map +1 -0
- package/dist/flights/types.d.ts +52 -0
- package/dist/flights/types.d.ts.map +1 -0
- package/dist/flights/types.js +2 -0
- package/dist/flights/types.js.map +1 -0
- package/dist/flights.d.ts +5 -0
- package/dist/flights.d.ts.map +1 -0
- package/dist/flights.js +4 -0
- package/dist/flights.js.map +1 -0
- package/dist/gemini-web/client.d.ts +16 -0
- package/dist/gemini-web/client.d.ts.map +1 -0
- package/dist/gemini-web/client.js +110 -0
- package/dist/gemini-web/client.js.map +1 -0
- package/dist/gemini-web/parsers.d.ts +5 -0
- package/dist/gemini-web/parsers.d.ts.map +1 -0
- package/dist/gemini-web/parsers.js +62 -0
- package/dist/gemini-web/parsers.js.map +1 -0
- package/dist/gemini-web/types.d.ts +47 -0
- package/dist/gemini-web/types.d.ts.map +1 -0
- package/dist/gemini-web/types.js +2 -0
- package/dist/gemini-web/types.js.map +1 -0
- package/dist/gemini-web.d.ts +5 -0
- package/dist/gemini-web.d.ts.map +1 -0
- package/dist/gemini-web.js +4 -0
- package/dist/gemini-web.js.map +1 -0
- package/dist/google-search/client.d.ts +16 -0
- package/dist/google-search/client.d.ts.map +1 -0
- package/dist/google-search/client.js +117 -0
- package/dist/google-search/client.js.map +1 -0
- package/dist/google-search/errors.d.ts +8 -0
- package/dist/google-search/errors.d.ts.map +1 -0
- package/dist/google-search/errors.js +13 -0
- package/dist/google-search/errors.js.map +1 -0
- package/dist/google-search/html.d.ts +12 -0
- package/dist/google-search/html.d.ts.map +1 -0
- package/dist/google-search/html.js +135 -0
- package/dist/google-search/html.js.map +1 -0
- package/dist/google-search/parsers.d.ts +6 -0
- package/dist/google-search/parsers.d.ts.map +1 -0
- package/dist/google-search/parsers.js +177 -0
- package/dist/google-search/parsers.js.map +1 -0
- package/dist/google-search/types.d.ts +66 -0
- package/dist/google-search/types.d.ts.map +1 -0
- package/dist/google-search/types.js +2 -0
- package/dist/google-search/types.js.map +1 -0
- package/dist/google-search.d.ts +6 -0
- package/dist/google-search.d.ts.map +1 -0
- package/dist/google-search.js +4 -0
- package/dist/google-search.js.map +1 -0
- package/dist/hotels/client.d.ts +9 -0
- package/dist/hotels/client.d.ts.map +1 -0
- package/dist/hotels/client.js +14 -0
- package/dist/hotels/client.js.map +1 -0
- package/dist/hotels/parsers.d.ts +7 -0
- package/dist/hotels/parsers.d.ts.map +1 -0
- package/dist/hotels/parsers.js +74 -0
- package/dist/hotels/parsers.js.map +1 -0
- package/dist/hotels/types.d.ts +55 -0
- package/dist/hotels/types.d.ts.map +1 -0
- package/dist/hotels/types.js +2 -0
- package/dist/hotels/types.js.map +1 -0
- package/dist/hotels.d.ts +4 -0
- package/dist/hotels.d.ts.map +1 -0
- package/dist/hotels.js +3 -0
- package/dist/hotels.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/known-surfaces.d.ts +35 -5
- package/dist/known-surfaces.d.ts.map +1 -1
- package/dist/known-surfaces.js +35 -5
- package/dist/known-surfaces.js.map +1 -1
- package/dist/lens/client.d.ts +14 -0
- package/dist/lens/client.d.ts.map +1 -0
- package/dist/lens/client.js +116 -0
- package/dist/lens/client.js.map +1 -0
- package/dist/lens/errors.d.ts +8 -0
- package/dist/lens/errors.d.ts.map +1 -0
- package/dist/lens/errors.js +13 -0
- package/dist/lens/errors.js.map +1 -0
- package/dist/lens/types.d.ts +27 -0
- package/dist/lens/types.d.ts.map +1 -0
- package/dist/lens/types.js +2 -0
- package/dist/lens/types.js.map +1 -0
- package/dist/lens.d.ts +8 -0
- package/dist/lens.d.ts.map +1 -0
- package/dist/lens.js +5 -0
- package/dist/lens.js.map +1 -0
- package/dist/news.d.ts +46 -0
- package/dist/news.d.ts.map +1 -0
- package/dist/news.js +202 -0
- package/dist/news.js.map +1 -0
- package/dist/pagespeed/client.d.ts +28 -0
- package/dist/pagespeed/client.d.ts.map +1 -0
- package/dist/pagespeed/client.js +222 -0
- package/dist/pagespeed/client.js.map +1 -0
- package/dist/pagespeed/errors.d.ts +9 -0
- package/dist/pagespeed/errors.d.ts.map +1 -0
- package/dist/pagespeed/errors.js +15 -0
- package/dist/pagespeed/errors.js.map +1 -0
- package/dist/pagespeed/parsers.d.ts +7 -0
- package/dist/pagespeed/parsers.d.ts.map +1 -0
- package/dist/pagespeed/parsers.js +236 -0
- package/dist/pagespeed/parsers.js.map +1 -0
- package/dist/pagespeed/types.d.ts +156 -0
- package/dist/pagespeed/types.d.ts.map +1 -0
- package/dist/pagespeed/types.js +2 -0
- package/dist/pagespeed/types.js.map +1 -0
- package/dist/pagespeed/wire.d.ts +10 -0
- package/dist/pagespeed/wire.d.ts.map +1 -0
- package/dist/pagespeed/wire.js +96 -0
- package/dist/pagespeed/wire.js.map +1 -0
- package/dist/pagespeed.d.ts +6 -0
- package/dist/pagespeed.d.ts.map +1 -0
- package/dist/pagespeed.js +4 -0
- package/dist/pagespeed.js.map +1 -0
- package/dist/parsers/geocode.d.ts.map +1 -1
- package/dist/parsers/geocode.js +30 -1
- package/dist/parsers/geocode.js.map +1 -1
- package/dist/parsers/reviews.d.ts +8 -1
- package/dist/parsers/reviews.d.ts.map +1 -1
- package/dist/parsers/reviews.js +46 -9
- package/dist/parsers/reviews.js.map +1 -1
- package/dist/platform/catalog.d.ts +18 -0
- package/dist/platform/catalog.d.ts.map +1 -0
- package/dist/platform/catalog.js +320 -0
- package/dist/platform/catalog.js.map +1 -0
- package/dist/platform/parity.d.ts +12 -0
- package/dist/platform/parity.d.ts.map +1 -0
- package/dist/platform/parity.js +25 -0
- package/dist/platform/parity.js.map +1 -0
- package/dist/services/elevation.d.ts +6 -4
- package/dist/services/elevation.d.ts.map +1 -1
- package/dist/services/elevation.js +39 -4
- package/dist/services/elevation.js.map +1 -1
- package/dist/services/environment/air-quality.d.ts +39 -0
- package/dist/services/environment/air-quality.d.ts.map +1 -0
- package/dist/services/environment/air-quality.js +82 -0
- package/dist/services/environment/air-quality.js.map +1 -0
- package/dist/services/environment/weather.d.ts +42 -0
- package/dist/services/environment/weather.d.ts.map +1 -0
- package/dist/services/environment/weather.js +63 -0
- package/dist/services/environment/weather.js.map +1 -0
- package/dist/services/geocode.d.ts +5 -1
- package/dist/services/geocode.d.ts.map +1 -1
- package/dist/services/geocode.js +13 -0
- package/dist/services/geocode.js.map +1 -1
- package/dist/services/keyed.d.ts +80 -0
- package/dist/services/keyed.d.ts.map +1 -0
- package/dist/services/keyed.js +152 -0
- package/dist/services/keyed.js.map +1 -0
- package/dist/services/knowledge.d.ts +6 -2
- package/dist/services/knowledge.d.ts.map +1 -1
- package/dist/services/knowledge.js +30 -5
- package/dist/services/knowledge.js.map +1 -1
- package/dist/services/mobility.d.ts.map +1 -1
- package/dist/services/mobility.js +13 -2
- package/dist/services/mobility.js.map +1 -1
- package/dist/services/nearby-search.d.ts +32 -0
- package/dist/services/nearby-search.d.ts.map +1 -0
- package/dist/services/nearby-search.js +85 -0
- package/dist/services/nearby-search.js.map +1 -0
- package/dist/services/panorama.d.ts +8 -1
- package/dist/services/panorama.d.ts.map +1 -1
- package/dist/services/panorama.js +48 -0
- package/dist/services/panorama.js.map +1 -1
- package/dist/services/photos.d.ts.map +1 -1
- package/dist/services/photos.js +9 -2
- package/dist/services/photos.js.map +1 -1
- package/dist/services/places.d.ts.map +1 -1
- package/dist/services/places.js +1 -0
- package/dist/services/places.js.map +1 -1
- package/dist/services/reviews.d.ts.map +1 -1
- package/dist/services/reviews.js +4 -1
- package/dist/services/reviews.js.map +1 -1
- package/dist/services/search.d.ts +8 -3
- package/dist/services/search.d.ts.map +1 -1
- package/dist/services/search.js +28 -9
- package/dist/services/search.js.map +1 -1
- package/dist/translate.d.ts +75 -0
- package/dist/translate.d.ts.map +1 -0
- package/dist/translate.js +126 -0
- package/dist/translate.js.map +1 -0
- package/dist/travel-google/common.d.ts +24 -0
- package/dist/travel-google/common.d.ts.map +1 -0
- package/dist/travel-google/common.js +72 -0
- package/dist/travel-google/common.js.map +1 -0
- package/dist/trends/client.d.ts +17 -0
- package/dist/trends/client.d.ts.map +1 -0
- package/dist/trends/client.js +86 -0
- package/dist/trends/client.js.map +1 -0
- package/dist/trends/errors.d.ts +8 -0
- package/dist/trends/errors.d.ts.map +1 -0
- package/dist/trends/errors.js +13 -0
- package/dist/trends/errors.js.map +1 -0
- package/dist/trends/links.d.ts +8 -0
- package/dist/trends/links.d.ts.map +1 -0
- package/dist/trends/links.js +71 -0
- package/dist/trends/links.js.map +1 -0
- package/dist/trends/parsers.d.ts +5 -0
- package/dist/trends/parsers.d.ts.map +1 -0
- package/dist/trends/parsers.js +126 -0
- package/dist/trends/parsers.js.map +1 -0
- package/dist/trends/types.d.ts +71 -0
- package/dist/trends/types.d.ts.map +1 -0
- package/dist/trends/types.js +2 -0
- package/dist/trends/types.js.map +1 -0
- package/dist/trends.d.ts +9 -0
- package/dist/trends.d.ts.map +1 -0
- package/dist/trends.js +8 -0
- package/dist/trends.js.map +1 -0
- package/dist/types/common.d.ts +28 -2
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js.map +1 -1
- package/dist/types/directions.d.ts +1 -1
- package/dist/types/directions.d.ts.map +1 -1
- package/dist/types/dx.d.ts +23 -10
- package/dist/types/dx.d.ts.map +1 -1
- package/dist/types/panorama.d.ts +19 -0
- package/dist/types/panorama.d.ts.map +1 -1
- package/dist/types/reviews.d.ts +3 -4
- package/dist/types/reviews.d.ts.map +1 -1
- package/dist/types/suggest.d.ts +4 -6
- package/dist/types/suggest.d.ts.map +1 -1
- package/dist/utils/google-web.d.ts +24 -0
- package/dist/utils/google-web.d.ts.map +1 -0
- package/dist/utils/google-web.js +150 -0
- package/dist/utils/google-web.js.map +1 -0
- package/dist/utils/place-ref.d.ts +14 -4
- package/dist/utils/place-ref.d.ts.map +1 -1
- package/dist/utils/place-ref.js +49 -1
- package/dist/utils/place-ref.js.map +1 -1
- package/dist/youtube/client.d.ts +19 -0
- package/dist/youtube/client.d.ts.map +1 -0
- package/dist/youtube/client.js +115 -0
- package/dist/youtube/client.js.map +1 -0
- package/dist/youtube/errors.d.ts +8 -0
- package/dist/youtube/errors.d.ts.map +1 -0
- package/dist/youtube/errors.js +13 -0
- package/dist/youtube/errors.js.map +1 -0
- package/dist/youtube/parsers.d.ts +9 -0
- package/dist/youtube/parsers.d.ts.map +1 -0
- package/dist/youtube/parsers.js +213 -0
- package/dist/youtube/parsers.js.map +1 -0
- package/dist/youtube/types.d.ts +90 -0
- package/dist/youtube/types.d.ts.map +1 -0
- package/dist/youtube/types.js +2 -0
- package/dist/youtube/types.js.map +1 -0
- package/dist/youtube.d.ts +9 -0
- package/dist/youtube.d.ts.map +1 -0
- package/dist/youtube.js +6 -0
- package/dist/youtube.js.map +1 -0
- package/docs/books.md +18 -0
- package/docs/environment-research.md +65 -0
- package/docs/finance-research.md +153 -0
- package/docs/finance.md +43 -0
- package/docs/gemini-web.md +36 -0
- package/docs/google-ai-books-research.md +53 -0
- package/docs/google-media-research.md +105 -0
- package/docs/google-search-research.md +36 -0
- package/docs/google-search.md +53 -0
- package/docs/google-services-research.md +135 -0
- package/docs/google-travel-research.md +86 -0
- package/docs/internal/reverse-engineering.md +85 -0
- package/docs/lens.md +54 -0
- package/docs/maps-revalidation.md +31 -0
- package/docs/news.md +35 -0
- package/docs/pagespeed-research.md +153 -0
- package/docs/pagespeed.md +135 -0
- package/docs/reviews-research.md +33 -0
- package/docs/translate.md +78 -0
- package/docs/trends-research.md +82 -0
- package/docs/trends.md +75 -0
- package/docs/youtube.md +72 -0
- package/package.json +77 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/gemini-web/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtH,OAAO,KAAK,EAAwB,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAoB7I,iGAAiG;AACjG,qBAAa,eAAe;IAMd,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,UAAU,CAAS;gBAEE,MAAM,GAAE,eAAoB;IAMnD,OAAO,CAAC,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIjF,iGAAiG;IAC3F,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAqDvG;AAED,wBAAgB,SAAS,CAAC,MAAM,GAAE,eAAoB,GAAG,eAAe,CAAwC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { googleWebText, GoogleWebError, positiveTimeout } from '../utils/google-web.js';
|
|
2
|
+
import { parseGeminiWebBootstrap, parseGeminiWebConversationHtml } from './parsers.js';
|
|
3
|
+
function checkAbort(signal) { if (signal.aborted)
|
|
4
|
+
throw signal.reason; }
|
|
5
|
+
async function interruptible(promise, signal) {
|
|
6
|
+
checkAbort(signal);
|
|
7
|
+
let abort = () => { };
|
|
8
|
+
const interrupted = new Promise((_resolve, reject) => { abort = () => reject(signal.reason); signal.addEventListener('abort', abort, { once: true }); });
|
|
9
|
+
try {
|
|
10
|
+
return await Promise.race([promise, interrupted]);
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
signal.removeEventListener('abort', abort);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function delay(ms, signal) {
|
|
17
|
+
checkAbort(signal);
|
|
18
|
+
let timer;
|
|
19
|
+
const waiting = new Promise(resolve => { timer = setTimeout(resolve, ms); });
|
|
20
|
+
try {
|
|
21
|
+
await interruptible(waiting, signal);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Uses the caller's browser for actual generation; static HTTP bootstrap is inspection only. */
|
|
28
|
+
export class GeminiWebClient {
|
|
29
|
+
config;
|
|
30
|
+
fetcher;
|
|
31
|
+
timeoutMs;
|
|
32
|
+
intervalMs;
|
|
33
|
+
generating = false;
|
|
34
|
+
constructor(config = {}) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.fetcher = config.fetch ?? globalThis.fetch;
|
|
37
|
+
this.timeoutMs = positiveTimeout(config.timeoutMs ?? 90_000);
|
|
38
|
+
this.intervalMs = positiveTimeout(config.pollIntervalMs ?? 500);
|
|
39
|
+
}
|
|
40
|
+
async inspect(options = {}) {
|
|
41
|
+
return parseGeminiWebBootstrap(await googleWebText(this.fetcher, new URL('https://gemini.google.com/app?hl=en'), { method: 'GET' }, this.timeoutMs, options.signal));
|
|
42
|
+
}
|
|
43
|
+
/** Submits to the existing browser conversation and waits for a new completed model response. */
|
|
44
|
+
async generate(prompt, options = {}) {
|
|
45
|
+
if (typeof prompt !== 'string' || !prompt.trim())
|
|
46
|
+
throw new TypeError('Gemini prompt must not be empty');
|
|
47
|
+
const page = this.config.page;
|
|
48
|
+
if (!page)
|
|
49
|
+
throw new TypeError('Gemini generation requires a caller-owned browser Page; HTTP bootstrap alone cannot generate an answer');
|
|
50
|
+
if (this.generating)
|
|
51
|
+
throw new TypeError('This Gemini browser conversation already has a generation in progress');
|
|
52
|
+
const timeoutMs = positiveTimeout(options.timeoutMs ?? this.timeoutMs);
|
|
53
|
+
if (options.signal?.aborted)
|
|
54
|
+
throw options.signal.reason;
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const abort = () => controller.abort(options.signal?.reason);
|
|
57
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
58
|
+
const timer = setTimeout(() => controller.abort(new GoogleWebError('Gemini browser generation timed out', 'timeout')), timeoutMs);
|
|
59
|
+
const expiresAt = Date.now() + timeoutMs;
|
|
60
|
+
this.generating = true;
|
|
61
|
+
try {
|
|
62
|
+
if (!/^https:\/\/gemini\.google\.com\/app(?:[/?#]|$)/.test(page.url())) {
|
|
63
|
+
await interruptible(page.goto('https://gemini.google.com/app?hl=en', { waitUntil: 'domcontentloaded', timeout: timeoutMs }), controller.signal);
|
|
64
|
+
}
|
|
65
|
+
let composer;
|
|
66
|
+
while (!composer) {
|
|
67
|
+
checkAbort(controller.signal);
|
|
68
|
+
if (/^https:\/\/(?:accounts|consent)\.google\.com\//.test(page.url()) || /^https:\/\/gemini\.google\.com\/sorry\//.test(page.url()))
|
|
69
|
+
throw new GoogleWebError('Gemini browser requires sign-in, consent or an access challenge', 'blocked');
|
|
70
|
+
const candidates = page.locator('[contenteditable="true"][role="textbox"]');
|
|
71
|
+
const count = await interruptible(candidates.count(), controller.signal);
|
|
72
|
+
for (let index = 0; index < count; index++) {
|
|
73
|
+
const candidate = candidates.nth(index);
|
|
74
|
+
if (await interruptible(candidate.isVisible(), controller.signal)) {
|
|
75
|
+
composer = candidate;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!composer)
|
|
80
|
+
await delay(this.intervalMs, controller.signal);
|
|
81
|
+
}
|
|
82
|
+
const before = parseGeminiWebConversationHtml(await interruptible(page.content(), controller.signal));
|
|
83
|
+
const priorModels = before.filter(message => message.role === 'model').length;
|
|
84
|
+
checkAbort(controller.signal);
|
|
85
|
+
await interruptible(composer.fill(prompt, { timeout: Math.max(1, expiresAt - Date.now()) }), controller.signal);
|
|
86
|
+
checkAbort(controller.signal);
|
|
87
|
+
await interruptible(composer.press('Enter', { timeout: Math.max(1, expiresAt - Date.now()) }), controller.signal);
|
|
88
|
+
while (true) {
|
|
89
|
+
checkAbort(controller.signal);
|
|
90
|
+
const messages = parseGeminiWebConversationHtml(await interruptible(page.content(), controller.signal));
|
|
91
|
+
const models = messages.filter(message => message.role === 'model');
|
|
92
|
+
let latestUser = messages.length - 1;
|
|
93
|
+
while (latestUser >= 0 && messages[latestUser].role !== 'user')
|
|
94
|
+
latestUser--;
|
|
95
|
+
const answer = messages[messages.length - 1];
|
|
96
|
+
if (models.length > priorModels && latestUser >= 0 && messages[latestUser].text.replace(/\s+/g, ' ').trim() === prompt.replace(/\s+/g, ' ').trim() && answer?.role === 'model' && answer.complete) {
|
|
97
|
+
return { text: answer.text, responseId: answer.id, conversationUrl: page.url() };
|
|
98
|
+
}
|
|
99
|
+
await delay(this.intervalMs, controller.signal);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
this.generating = false;
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
options.signal?.removeEventListener('abort', abort);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function geminiWeb(config = {}) { return new GeminiWebClient(config); }
|
|
110
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/gemini-web/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GeminiWebBootstrap, GeminiWebMessage } from './types.js';
|
|
2
|
+
export declare function parseGeminiWebBootstrap(html: string): GeminiWebBootstrap;
|
|
3
|
+
/** Extracts observed user/model containers; busy or unfinished responses are never marked complete. */
|
|
4
|
+
export declare function parseGeminiWebConversationHtml(html: string): GeminiWebMessage[];
|
|
5
|
+
//# sourceMappingURL=parsers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/gemini-web/parsers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEvE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAOxE;AAgBD,uGAAuG;AACvG,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAqB/E"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { decodeEntities, descendants, parseHtml, visibleText } from '../google-search/html.js';
|
|
2
|
+
import { googleBootstrap, GoogleWebError } from '../utils/google-web.js';
|
|
3
|
+
export function parseGeminiWebBootstrap(html) {
|
|
4
|
+
const data = googleBootstrap(html);
|
|
5
|
+
if (typeof data.cfb2h !== 'string')
|
|
6
|
+
throw new GoogleWebError('Gemini bootstrap has no build', 'parse');
|
|
7
|
+
return {
|
|
8
|
+
build: data.cfb2h, hasSession: typeof data.FdrFJe === 'string',
|
|
9
|
+
hasPromptToken: typeof data.SNlM0e === 'string' && data.SNlM0e.length > 0, generation: 'unverified',
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function responseText(node) {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
const stack = [node];
|
|
15
|
+
while (stack.length > 0) {
|
|
16
|
+
const value = stack.pop();
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
|
+
chunks.push(value);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (/^(?:script|style|template|noscript)$/.test(value.tag) || value.attrs.hidden !== undefined || value.attrs['aria-hidden'] === 'true' || /display\s*:\s*none|visibility\s*:\s*hidden/i.test(value.attrs.style ?? ''))
|
|
22
|
+
continue;
|
|
23
|
+
const block = /^(?:p|div|br|li|pre|h[1-6])$/.test(value.tag);
|
|
24
|
+
if (block) {
|
|
25
|
+
chunks.push('\n');
|
|
26
|
+
stack.push('\n');
|
|
27
|
+
}
|
|
28
|
+
for (let i = value.children.length - 1; i >= 0; i--)
|
|
29
|
+
stack.push(value.children[i]);
|
|
30
|
+
}
|
|
31
|
+
return decodeEntities(chunks.join('')).replace(/[\t\f\v ]+/g, ' ').replace(/ *\n */g, '\n').replace(/\n{3,}/g, '\n\n').trim();
|
|
32
|
+
}
|
|
33
|
+
/** Extracts observed user/model containers; busy or unfinished responses are never marked complete. */
|
|
34
|
+
export function parseGeminiWebConversationHtml(html) {
|
|
35
|
+
if (typeof html !== 'string' || html.length > 10_000_000)
|
|
36
|
+
throw new GoogleWebError('Unsupported Gemini HTML size', 'parse');
|
|
37
|
+
const nodes = descendants(parseHtml(html));
|
|
38
|
+
const messages = [];
|
|
39
|
+
for (const node of nodes) {
|
|
40
|
+
if (node.tag === 'user-query') {
|
|
41
|
+
const lines = descendants(node).filter(child => /(?:^|\s)query-text-line(?:\s|$)/.test(child.attrs.class ?? ''));
|
|
42
|
+
const text = lines.map(visibleText).join('\n');
|
|
43
|
+
if (text)
|
|
44
|
+
messages.push({ role: 'user', text });
|
|
45
|
+
}
|
|
46
|
+
else if (node.tag === 'model-response') {
|
|
47
|
+
const children = descendants(node);
|
|
48
|
+
const content = children.find(child => child.tag === 'message-content');
|
|
49
|
+
if (!content)
|
|
50
|
+
continue;
|
|
51
|
+
const markdown = descendants(content).find(child => /(?:^|\s)markdown(?:\s|$)/.test(child.attrs.class ?? ''));
|
|
52
|
+
if (!markdown)
|
|
53
|
+
continue;
|
|
54
|
+
const text = responseText(markdown);
|
|
55
|
+
const finished = children.some(child => /(?:^|\s)response-footer(?:\s|$)/.test(child.attrs.class ?? '') && /(?:^|\s)complete(?:\s|$)/.test(child.attrs.class ?? ''));
|
|
56
|
+
if (text)
|
|
57
|
+
messages.push({ role: 'model', text, complete: markdown.attrs['aria-busy'] === 'false' && finished, id: content.attrs.id });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return messages;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=parsers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/gemini-web/parsers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { GoogleWebConfig, GoogleWebRequestOptions } from '../utils/google-web.js';
|
|
2
|
+
export interface GeminiBrowserLocator {
|
|
3
|
+
count(): Promise<number>;
|
|
4
|
+
nth(index: number): GeminiBrowserLocator;
|
|
5
|
+
isVisible(): Promise<boolean>;
|
|
6
|
+
fill(value: string, options?: {
|
|
7
|
+
timeout?: number;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
press(key: string, options?: {
|
|
10
|
+
timeout?: number;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/** The subset of a browser Page needed to use the observed anonymous Gemini composer. */
|
|
14
|
+
export interface GeminiBrowserPage {
|
|
15
|
+
url(): string;
|
|
16
|
+
goto(url: string, options?: {
|
|
17
|
+
waitUntil?: 'domcontentloaded';
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}): Promise<unknown>;
|
|
20
|
+
content(): Promise<string>;
|
|
21
|
+
locator(selector: string): GeminiBrowserLocator;
|
|
22
|
+
}
|
|
23
|
+
export interface GeminiWebConfig extends GoogleWebConfig {
|
|
24
|
+
page?: GeminiBrowserPage;
|
|
25
|
+
pollIntervalMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface GeminiWebBootstrap {
|
|
28
|
+
build: string;
|
|
29
|
+
hasSession: boolean;
|
|
30
|
+
hasPromptToken: boolean;
|
|
31
|
+
generation: 'unverified';
|
|
32
|
+
}
|
|
33
|
+
export interface GeminiWebMessage {
|
|
34
|
+
role: 'user' | 'model';
|
|
35
|
+
text: string;
|
|
36
|
+
complete?: boolean;
|
|
37
|
+
id?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface GeminiWebGenerationOptions extends GoogleWebRequestOptions {
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface GeminiWebGeneration {
|
|
43
|
+
text: string;
|
|
44
|
+
responseId?: string;
|
|
45
|
+
conversationUrl: string;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gemini-web/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,MAAM,WAAW,oBAAoB;IACnC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAC;IACzC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED,yFAAyF;AACzF,MAAM,WAAW,iBAAiB;IAChC,GAAG,IAAI,MAAM,CAAC;IACd,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,kBAAkB,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACjD;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,0BAA2B,SAAQ,uBAAuB;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/gemini-web/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { GeminiWebClient, geminiWeb } from './gemini-web/client.js';
|
|
2
|
+
export { parseGeminiWebBootstrap, parseGeminiWebConversationHtml } from './gemini-web/parsers.js';
|
|
3
|
+
export { GoogleWebError } from './utils/google-web.js';
|
|
4
|
+
export type * from './gemini-web/types.js';
|
|
5
|
+
//# sourceMappingURL=gemini-web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-web.d.ts","sourceRoot":"","sources":["../src/gemini-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,mBAAmB,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-web.js","sourceRoot":"","sources":["../src/gemini-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GoogleAutocompleteResponse, GoogleSearchConfig, GoogleSearchOptions, GoogleSearchResponse, GoogleSuggestOptions } from './types.js';
|
|
2
|
+
/** Anonymous public Search and autocomplete requests; access challenges are returned explicitly. */
|
|
3
|
+
export declare class GoogleSearchClient {
|
|
4
|
+
private readonly fetcher;
|
|
5
|
+
private readonly language;
|
|
6
|
+
private readonly country;
|
|
7
|
+
private readonly timeoutMs;
|
|
8
|
+
constructor(config?: GoogleSearchConfig);
|
|
9
|
+
/** Requests Search HTML; JavaScript challenges and unsupported markup are not treated as empty results. */
|
|
10
|
+
search(query: string, options?: GoogleSearchOptions): Promise<GoogleSearchResponse>;
|
|
11
|
+
/** Fetches Google's anonymous public autocomplete suggestions without a Search page or API key. */
|
|
12
|
+
suggest(query: string, options?: GoogleSuggestOptions): Promise<GoogleAutocompleteResponse>;
|
|
13
|
+
private request;
|
|
14
|
+
}
|
|
15
|
+
export declare function googleSearch(config?: GoogleSearchConfig): GoogleSearchClient;
|
|
16
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/google-search/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAmBlJ,oGAAoG;AACpG,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,GAAE,kBAAuB;IAO3C,2GAA2G;IACrG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsB7F,mGAAmG;IAC7F,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC;YAcvF,OAAO;CAiCtB;AAED,wBAAgB,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,kBAAkB,CAEhF"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { GoogleSearchError } from './errors.js';
|
|
2
|
+
import { parseGoogleAutocomplete, parseGoogleSearchHtml } from './parsers.js';
|
|
3
|
+
function positive(value) {
|
|
4
|
+
if (!Number.isFinite(value) || value <= 0 || value > 2_147_483_647)
|
|
5
|
+
throw new RangeError('timeoutMs must be positive and no greater than 2147483647');
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
function queryValue(query) {
|
|
9
|
+
if (typeof query !== 'string' || !query.trim())
|
|
10
|
+
throw new TypeError('A nonempty search query is required');
|
|
11
|
+
return query;
|
|
12
|
+
}
|
|
13
|
+
function retryAfter(value) {
|
|
14
|
+
if (!value)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (/^\d+(?:\.\d+)?$/.test(value))
|
|
17
|
+
return Number(value) * 1000;
|
|
18
|
+
const timestamp = Date.parse(value);
|
|
19
|
+
return Number.isFinite(timestamp) ? Math.max(0, timestamp - Date.now()) : undefined;
|
|
20
|
+
}
|
|
21
|
+
/** Anonymous public Search and autocomplete requests; access challenges are returned explicitly. */
|
|
22
|
+
export class GoogleSearchClient {
|
|
23
|
+
fetcher;
|
|
24
|
+
language;
|
|
25
|
+
country;
|
|
26
|
+
timeoutMs;
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
this.fetcher = config.fetch ?? globalThis.fetch;
|
|
29
|
+
this.language = config.language ?? 'en';
|
|
30
|
+
this.country = config.country ?? 'us';
|
|
31
|
+
this.timeoutMs = positive(config.timeoutMs ?? 20_000);
|
|
32
|
+
}
|
|
33
|
+
/** Requests Search HTML; JavaScript challenges and unsupported markup are not treated as empty results. */
|
|
34
|
+
async search(query, options = {}) {
|
|
35
|
+
const endpoint = new URL('https://www.google.com/search');
|
|
36
|
+
endpoint.searchParams.set('q', queryValue(query));
|
|
37
|
+
endpoint.searchParams.set('hl', options.language ?? this.language);
|
|
38
|
+
endpoint.searchParams.set('gl', options.country ?? this.country);
|
|
39
|
+
if (options.start !== undefined) {
|
|
40
|
+
if (!Number.isSafeInteger(options.start) || options.start < 0)
|
|
41
|
+
throw new RangeError('start must be a nonnegative safe integer');
|
|
42
|
+
endpoint.searchParams.set('start', String(options.start));
|
|
43
|
+
}
|
|
44
|
+
if (options.safe !== undefined) {
|
|
45
|
+
if (options.safe !== 'active' && options.safe !== 'off')
|
|
46
|
+
throw new TypeError('safe must be active or off');
|
|
47
|
+
endpoint.searchParams.set('safe', options.safe);
|
|
48
|
+
}
|
|
49
|
+
const { response, body } = await this.request(endpoint, options.signal, true);
|
|
50
|
+
const report = parseGoogleSearchHtml(body, {
|
|
51
|
+
sourceUrl: response.url || endpoint.toString(), query, httpStatus: response.status, includeRawHtml: options.includeRawHtml,
|
|
52
|
+
});
|
|
53
|
+
const delay = retryAfter(response.headers.get('Retry-After'));
|
|
54
|
+
if (delay !== undefined)
|
|
55
|
+
report.retryAfterMs = delay;
|
|
56
|
+
return report;
|
|
57
|
+
}
|
|
58
|
+
/** Fetches Google's anonymous public autocomplete suggestions without a Search page or API key. */
|
|
59
|
+
async suggest(query, options = {}) {
|
|
60
|
+
const endpoint = new URL('https://suggestqueries.google.com/complete/search');
|
|
61
|
+
endpoint.searchParams.set('client', 'firefox');
|
|
62
|
+
endpoint.searchParams.set('q', queryValue(query));
|
|
63
|
+
endpoint.searchParams.set('hl', options.language ?? this.language);
|
|
64
|
+
endpoint.searchParams.set('gl', options.country ?? this.country);
|
|
65
|
+
const { body } = await this.request(endpoint, options.signal);
|
|
66
|
+
let raw;
|
|
67
|
+
try {
|
|
68
|
+
raw = JSON.parse(body);
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
throw new GoogleSearchError('Invalid autocomplete JSON', 'parse', undefined, undefined, { cause });
|
|
72
|
+
}
|
|
73
|
+
return parseGoogleAutocomplete(raw);
|
|
74
|
+
}
|
|
75
|
+
async request(url, signal, allowBlocked = false) {
|
|
76
|
+
if (signal?.aborted)
|
|
77
|
+
throw signal.reason;
|
|
78
|
+
const controller = new AbortController();
|
|
79
|
+
const abort = () => controller.abort(signal?.reason);
|
|
80
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
81
|
+
const timer = setTimeout(() => controller.abort(new GoogleSearchError('Google Search request timed out', 'timeout')), this.timeoutMs);
|
|
82
|
+
timer.unref?.();
|
|
83
|
+
let rejectAbort;
|
|
84
|
+
const interrupted = new Promise((_resolve, reject) => { rejectAbort = reject; });
|
|
85
|
+
const abortRequest = () => rejectAbort?.(controller.signal.reason);
|
|
86
|
+
controller.signal.addEventListener('abort', abortRequest, { once: true });
|
|
87
|
+
try {
|
|
88
|
+
const { response, body } = await Promise.race([
|
|
89
|
+
(async () => {
|
|
90
|
+
const response = await this.fetcher(url.toString(), { method: 'GET', signal: controller.signal });
|
|
91
|
+
return { response, body: await response.text() };
|
|
92
|
+
})(),
|
|
93
|
+
interrupted,
|
|
94
|
+
]);
|
|
95
|
+
if (!response.ok && !(allowBlocked && [403, 429].includes(response.status))) {
|
|
96
|
+
throw new GoogleSearchError(`Google Search HTTP ${response.status}`, 'http', response.status, retryAfter(response.headers.get('Retry-After')));
|
|
97
|
+
}
|
|
98
|
+
return { response, body };
|
|
99
|
+
}
|
|
100
|
+
catch (cause) {
|
|
101
|
+
if (controller.signal.aborted)
|
|
102
|
+
throw controller.signal.reason;
|
|
103
|
+
if (cause instanceof GoogleSearchError)
|
|
104
|
+
throw cause;
|
|
105
|
+
throw new GoogleSearchError('Google Search network request failed', 'network', undefined, undefined, { cause });
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
signal?.removeEventListener('abort', abort);
|
|
110
|
+
controller.signal.removeEventListener('abort', abortRequest);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function googleSearch(config = {}) {
|
|
115
|
+
return new GoogleSearchClient(config);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/google-search/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type GoogleSearchErrorKind = 'http' | 'network' | 'parse' | 'timeout';
|
|
2
|
+
export declare class GoogleSearchError extends Error {
|
|
3
|
+
readonly kind: GoogleSearchErrorKind;
|
|
4
|
+
readonly status?: number | undefined;
|
|
5
|
+
readonly retryAfterMs?: number | undefined;
|
|
6
|
+
constructor(message: string, kind: GoogleSearchErrorKind, status?: number | undefined, retryAfterMs?: number | undefined, options?: ErrorOptions);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/google-search/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,IAAI,EAAE,qBAAqB;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM;gBAH9B,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,qBAAqB,EAC3B,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,YAAY,CAAC,EAAE,MAAM,YAAA,EAC9B,OAAO,CAAC,EAAE,YAAY;CAKzB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class GoogleSearchError extends Error {
|
|
2
|
+
kind;
|
|
3
|
+
status;
|
|
4
|
+
retryAfterMs;
|
|
5
|
+
constructor(message, kind, status, retryAfterMs, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.kind = kind;
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.retryAfterMs = retryAfterMs;
|
|
10
|
+
this.name = 'GoogleSearchError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/google-search/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAG/B;IACA;IACA;IAJX,YACE,OAAe,EACN,IAA2B,EAC3B,MAAe,EACf,YAAqB,EAC9B,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QALf,SAAI,GAAJ,IAAI,CAAuB;QAC3B,WAAM,GAAN,MAAM,CAAS;QACf,iBAAY,GAAZ,YAAY,CAAS;QAI9B,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface HtmlNode {
|
|
2
|
+
tag: string;
|
|
3
|
+
attrs: Record<string, string>;
|
|
4
|
+
parent?: HtmlNode;
|
|
5
|
+
children: Array<HtmlNode | string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function decodeEntities(value: string): string;
|
|
8
|
+
export declare function parseHtml(html: string): HtmlNode;
|
|
9
|
+
export declare function descendants(node: HtmlNode): HtmlNode[];
|
|
10
|
+
export declare function visibleText(node: HtmlNode): string;
|
|
11
|
+
export declare function ancestor(node: HtmlNode, predicate: (candidate: HtmlNode) => boolean, boundary?: HtmlNode): HtmlNode | undefined;
|
|
12
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/google-search/html.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC;CACpC;AAWD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMpD;AAaD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CA+ChD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAUtD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAWlD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,SAAS,EAAE,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAO/H"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const entities = {
|
|
2
|
+
amp: '&', lt: '<', gt: '>', quot: '"', apos: "'", nbsp: ' ',
|
|
3
|
+
hellip: '…', ndash: '–', mdash: '—', rsquo: '’', lsquo: '‘',
|
|
4
|
+
rdquo: '”', ldquo: '“', bull: '•', middot: '·', copy: '©', reg: '®',
|
|
5
|
+
};
|
|
6
|
+
const voidTags = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
|
|
7
|
+
const ignoredTags = new Set(['script', 'style', 'template', 'noscript']);
|
|
8
|
+
export function decodeEntities(value) {
|
|
9
|
+
return value.replace(/&(#x[\da-f]+|#\d+|[a-z]+);/gi, (match, entity) => {
|
|
10
|
+
if (!entity.startsWith('#'))
|
|
11
|
+
return entities[entity] ?? match;
|
|
12
|
+
const code = entity[1]?.toLowerCase() === 'x' ? Number.parseInt(entity.slice(2), 16) : Number(entity.slice(1));
|
|
13
|
+
return code > 0 && code <= 0x10ffff && !(code >= 0xd800 && code <= 0xdfff) ? String.fromCodePoint(code) : '�';
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function tagEnd(html, start) {
|
|
17
|
+
let quote;
|
|
18
|
+
for (let i = start; i < html.length; i++) {
|
|
19
|
+
const character = html[i];
|
|
20
|
+
if (quote) {
|
|
21
|
+
if (character === quote)
|
|
22
|
+
quote = undefined;
|
|
23
|
+
}
|
|
24
|
+
else if (character === '"' || character === "'")
|
|
25
|
+
quote = character;
|
|
26
|
+
else if (character === '>')
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
export function parseHtml(html) {
|
|
32
|
+
const root = { tag: '#document', attrs: {}, children: [] };
|
|
33
|
+
const stack = [root];
|
|
34
|
+
const lower = html.toLowerCase();
|
|
35
|
+
let cursor = 0;
|
|
36
|
+
while (cursor < html.length) {
|
|
37
|
+
const open = html.indexOf('<', cursor);
|
|
38
|
+
const parent = stack[stack.length - 1];
|
|
39
|
+
if (open === -1) {
|
|
40
|
+
parent.children.push(html.slice(cursor));
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (open > cursor)
|
|
44
|
+
parent.children.push(html.slice(cursor, open));
|
|
45
|
+
if (html.startsWith('<!--', open)) {
|
|
46
|
+
const end = html.indexOf('-->', open + 4);
|
|
47
|
+
cursor = end === -1 ? html.length : end + 3;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const end = tagEnd(html, open + 1);
|
|
51
|
+
if (end === -1) {
|
|
52
|
+
parent.children.push(html.slice(open));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
const token = html.slice(open + 1, end);
|
|
56
|
+
const match = /^(\/?)\s*([a-z][a-z\d:-]*)\b/i.exec(token);
|
|
57
|
+
cursor = end + 1;
|
|
58
|
+
if (!match)
|
|
59
|
+
continue;
|
|
60
|
+
const tag = match[2].toLowerCase();
|
|
61
|
+
if (match[1]) {
|
|
62
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
63
|
+
if (stack[i].tag === tag) {
|
|
64
|
+
stack.length = i;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const attrs = Object.create(null);
|
|
71
|
+
const pattern = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g;
|
|
72
|
+
pattern.lastIndex = match[0].length;
|
|
73
|
+
let attribute;
|
|
74
|
+
while ((attribute = pattern.exec(token))) {
|
|
75
|
+
const name = attribute[1].toLowerCase();
|
|
76
|
+
if (!(name in attrs))
|
|
77
|
+
attrs[name] = decodeEntities(attribute[2] ?? attribute[3] ?? attribute[4] ?? '');
|
|
78
|
+
}
|
|
79
|
+
const node = { tag, attrs, children: [], parent };
|
|
80
|
+
parent.children.push(node);
|
|
81
|
+
if (ignoredTags.has(tag)) {
|
|
82
|
+
const close = lower.indexOf(`</${tag}`, cursor);
|
|
83
|
+
if (close !== -1) {
|
|
84
|
+
const closeEnd = tagEnd(html, close + 2);
|
|
85
|
+
cursor = closeEnd === -1 ? html.length : closeEnd + 1;
|
|
86
|
+
}
|
|
87
|
+
else
|
|
88
|
+
cursor = html.length;
|
|
89
|
+
}
|
|
90
|
+
else if (!voidTags.has(tag) && !token.endsWith('/'))
|
|
91
|
+
stack.push(node);
|
|
92
|
+
}
|
|
93
|
+
return root;
|
|
94
|
+
}
|
|
95
|
+
export function descendants(node) {
|
|
96
|
+
const found = [];
|
|
97
|
+
const stack = [...node.children].reverse();
|
|
98
|
+
while (stack.length > 0) {
|
|
99
|
+
const value = stack.pop();
|
|
100
|
+
if (typeof value !== 'object' || ignoredTags.has(value.tag) || value.attrs.hidden !== undefined || value.attrs['aria-hidden'] === 'true' || /display\s*:\s*none|visibility\s*:\s*hidden/i.test(value.attrs.style ?? ''))
|
|
101
|
+
continue;
|
|
102
|
+
found.push(value);
|
|
103
|
+
for (let i = value.children.length - 1; i >= 0; i--)
|
|
104
|
+
stack.push(value.children[i]);
|
|
105
|
+
}
|
|
106
|
+
return found;
|
|
107
|
+
}
|
|
108
|
+
export function visibleText(node) {
|
|
109
|
+
const text = [];
|
|
110
|
+
const stack = [node];
|
|
111
|
+
while (stack.length > 0) {
|
|
112
|
+
const value = stack.pop();
|
|
113
|
+
if (typeof value === 'string') {
|
|
114
|
+
text.push(value);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (ignoredTags.has(value.tag) || value.attrs.hidden !== undefined || value.attrs['aria-hidden'] === 'true' || /display\s*:\s*none|visibility\s*:\s*hidden/i.test(value.attrs.style ?? ''))
|
|
118
|
+
continue;
|
|
119
|
+
if (/^(?:br|div|p|li|section|h[1-6])$/.test(value.tag))
|
|
120
|
+
text.push(' ');
|
|
121
|
+
for (let i = value.children.length - 1; i >= 0; i--)
|
|
122
|
+
stack.push(value.children[i]);
|
|
123
|
+
}
|
|
124
|
+
return decodeEntities(text.join('')).replace(/\s+/g, ' ').trim();
|
|
125
|
+
}
|
|
126
|
+
export function ancestor(node, predicate, boundary) {
|
|
127
|
+
let current = node;
|
|
128
|
+
while (current && current !== boundary) {
|
|
129
|
+
if (predicate(current))
|
|
130
|
+
return current;
|
|
131
|
+
current = current.parent;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=html.js.map
|