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,213 @@
|
|
|
1
|
+
import { YouTubeError } from './errors.js';
|
|
2
|
+
export function youtubeObject(value) {
|
|
3
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function fail(label) { throw new YouTubeError(`Malformed YouTube ${label}`, 'parse'); }
|
|
6
|
+
function optionalString(value) { return typeof value === 'string' ? value : undefined; }
|
|
7
|
+
function requiredString(value, name) { return typeof value === 'string' && value.length > 0 ? value : fail(name); }
|
|
8
|
+
function numeric(value) {
|
|
9
|
+
const result = typeof value === 'string' && /^\d+$/.test(value) ? Number(value) : value;
|
|
10
|
+
return typeof result === 'number' && Number.isFinite(result) && result >= 0 ? result : undefined;
|
|
11
|
+
}
|
|
12
|
+
export function youtubeText(value) {
|
|
13
|
+
if (!youtubeObject(value))
|
|
14
|
+
return undefined;
|
|
15
|
+
if (typeof value.simpleText === 'string')
|
|
16
|
+
return value.simpleText;
|
|
17
|
+
if (Array.isArray(value.runs))
|
|
18
|
+
return value.runs.map(run => youtubeObject(run) && typeof run.text === 'string' ? run.text : '').join('');
|
|
19
|
+
if (typeof value.content === 'string')
|
|
20
|
+
return value.content;
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function thumbnails(value) {
|
|
24
|
+
if (!youtubeObject(value) || !Array.isArray(value.thumbnails))
|
|
25
|
+
return [];
|
|
26
|
+
return value.thumbnails.flatMap(item => youtubeObject(item) && typeof item.url === 'string' ? [{ url: item.url.startsWith('//') ? `https:${item.url}` : item.url, width: numeric(item.width), height: numeric(item.height) }] : []);
|
|
27
|
+
}
|
|
28
|
+
export function extractYouTubeJson(html, variable) {
|
|
29
|
+
const escaped = variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
30
|
+
const pattern = new RegExp(`(?:var\\s+)?${escaped}\\s*=\\s*|window\\[["']${escaped}["']\\]\\s*=\\s*`, 'g');
|
|
31
|
+
let match;
|
|
32
|
+
while ((match = pattern.exec(html))) {
|
|
33
|
+
const start = pattern.lastIndex;
|
|
34
|
+
if (html[start] !== '{')
|
|
35
|
+
continue;
|
|
36
|
+
let depth = 0, quoted = false, escapedCharacter = false;
|
|
37
|
+
for (let index = start; index < html.length; index++) {
|
|
38
|
+
const character = html[index];
|
|
39
|
+
if (quoted) {
|
|
40
|
+
if (escapedCharacter)
|
|
41
|
+
escapedCharacter = false;
|
|
42
|
+
else if (character === '\\')
|
|
43
|
+
escapedCharacter = true;
|
|
44
|
+
else if (character === '"')
|
|
45
|
+
quoted = false;
|
|
46
|
+
}
|
|
47
|
+
else if (character === '"')
|
|
48
|
+
quoted = true;
|
|
49
|
+
else if (character === '{')
|
|
50
|
+
depth++;
|
|
51
|
+
else if (character === '}' && --depth === 0) {
|
|
52
|
+
try {
|
|
53
|
+
const value = JSON.parse(html.slice(start, index + 1));
|
|
54
|
+
return youtubeObject(value) ? value : fail(variable);
|
|
55
|
+
}
|
|
56
|
+
catch (cause) {
|
|
57
|
+
throw new YouTubeError(`Malformed YouTube ${variable} JSON`, 'parse', undefined, undefined, { cause });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return fail(variable);
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
export function parseVideo(raw, id, initialData) {
|
|
66
|
+
if (!youtubeObject(raw) || !youtubeObject(raw.playabilityStatus))
|
|
67
|
+
return fail('player response');
|
|
68
|
+
const playability = raw.playabilityStatus;
|
|
69
|
+
const details = youtubeObject(raw.videoDetails) ? raw.videoDetails : {};
|
|
70
|
+
if (details.videoId !== undefined && details.videoId !== id)
|
|
71
|
+
return fail('player video ID');
|
|
72
|
+
const captionContainer = youtubeObject(raw.captions) && youtubeObject(raw.captions.playerCaptionsTracklistRenderer) ? raw.captions.playerCaptionsTracklistRenderer : undefined;
|
|
73
|
+
const captions = !Array.isArray(captionContainer?.captionTracks) ? [] : captionContainer.captionTracks.map(value => {
|
|
74
|
+
if (!youtubeObject(value))
|
|
75
|
+
return fail('caption track');
|
|
76
|
+
return { languageCode: requiredString(value.languageCode, 'caption language'), name: youtubeText(value.name) ?? '', baseUrl: requiredString(value.baseUrl, 'caption URL'), kind: optionalString(value.kind), isTranslatable: typeof value.isTranslatable === 'boolean' ? value.isTranslatable : undefined, raw: value };
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
id: optionalString(details.videoId) ?? id,
|
|
80
|
+
url: `https://www.youtube.com/watch?v=${id}`,
|
|
81
|
+
title: optionalString(details.title), author: optionalString(details.author), channelId: optionalString(details.channelId),
|
|
82
|
+
description: optionalString(details.shortDescription), lengthSeconds: numeric(details.lengthSeconds), viewCount: optionalString(details.viewCount),
|
|
83
|
+
keywords: Array.isArray(details.keywords) ? details.keywords.filter((value) => typeof value === 'string') : undefined,
|
|
84
|
+
isLiveContent: typeof details.isLiveContent === 'boolean' ? details.isLiveContent : undefined,
|
|
85
|
+
thumbnails: thumbnails(details.thumbnail),
|
|
86
|
+
playability: { status: requiredString(playability.status, 'playability status'), reason: optionalString(playability.reason), raw: playability },
|
|
87
|
+
captions, raw, initialData,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function ownerId(value) {
|
|
91
|
+
if (!youtubeObject(value) || !Array.isArray(value.runs))
|
|
92
|
+
return undefined;
|
|
93
|
+
for (const run of value.runs) {
|
|
94
|
+
if (youtubeObject(run) && youtubeObject(run.navigationEndpoint) && youtubeObject(run.navigationEndpoint.browseEndpoint))
|
|
95
|
+
return optionalString(run.navigationEndpoint.browseEndpoint.browseId);
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
function searchItem(type, raw) {
|
|
100
|
+
const id = requiredString(raw[type === 'video' ? 'videoId' : 'channelId'], 'search result ID');
|
|
101
|
+
const title = youtubeText(raw.title) ?? fail('search result title');
|
|
102
|
+
const owner = raw.ownerText ?? raw.longBylineText ?? raw.shortBylineText;
|
|
103
|
+
return {
|
|
104
|
+
type, id, title,
|
|
105
|
+
url: type === 'video' ? `https://www.youtube.com/watch?v=${id}` : `https://www.youtube.com/channel/${id}`,
|
|
106
|
+
description: youtubeText(raw.descriptionSnippet), author: youtubeText(owner), channelId: type === 'channel' ? id : ownerId(owner),
|
|
107
|
+
duration: youtubeText(raw.lengthText), viewCount: youtubeText(raw.viewCountText), publishedTime: youtubeText(raw.publishedTimeText),
|
|
108
|
+
thumbnails: thumbnails(raw.thumbnail ?? (Array.isArray(raw.thumbnails) ? raw.thumbnails[0] : undefined)), raw,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function path(value, ...keys) {
|
|
112
|
+
for (const key of keys)
|
|
113
|
+
value = typeof key === 'number' && Array.isArray(value) ? value[key] : typeof key === 'string' && youtubeObject(value) ? value[key] : undefined;
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
function playlistLockup(raw) {
|
|
117
|
+
const id = requiredString(raw.contentId, 'playlist ID');
|
|
118
|
+
const metadata = path(raw, 'metadata', 'lockupMetadataViewModel');
|
|
119
|
+
const rows = path(metadata, 'metadata', 'contentMetadataViewModel', 'metadataRows');
|
|
120
|
+
const byline = Array.isArray(rows) ? rows.find(row => path(row, 'lockupContentMetadataRowExtension', 'contentType') === 'METADATA_ROW_CONTENT_TYPE_BYLINE') : undefined;
|
|
121
|
+
const author = path(byline, 'metadataParts', 0, 'text');
|
|
122
|
+
return {
|
|
123
|
+
type: 'playlist', id,
|
|
124
|
+
title: requiredString(youtubeText(path(metadata, 'title')), 'playlist title'),
|
|
125
|
+
url: `https://www.youtube.com/playlist?list=${id}`,
|
|
126
|
+
author: youtubeText(author),
|
|
127
|
+
channelId: optionalString(path(author, 'commandRuns', 0, 'onTap', 'innertubeCommand', 'browseEndpoint', 'browseId')),
|
|
128
|
+
thumbnails: thumbnails({ thumbnails: path(raw, 'contentImage', 'collectionThumbnailViewModel', 'primaryThumbnail', 'thumbnailViewModel', 'image', 'sources') }),
|
|
129
|
+
raw,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export function parseSearch(raw, client) {
|
|
133
|
+
if (!youtubeObject(raw))
|
|
134
|
+
return fail('search response');
|
|
135
|
+
const primary = youtubeObject(raw.contents) && youtubeObject(raw.contents.twoColumnSearchResultsRenderer) ? raw.contents.twoColumnSearchResultsRenderer.primaryContents : undefined;
|
|
136
|
+
const actions = raw.onResponseReceivedCommands ?? raw.onResponseReceivedActions;
|
|
137
|
+
if (!youtubeObject(primary) && !Array.isArray(actions))
|
|
138
|
+
return fail('search results');
|
|
139
|
+
const items = [];
|
|
140
|
+
const seen = new Set();
|
|
141
|
+
let token;
|
|
142
|
+
const stack = [primary ?? actions];
|
|
143
|
+
while (stack.length) {
|
|
144
|
+
const value = stack.pop();
|
|
145
|
+
if (Array.isArray(value)) {
|
|
146
|
+
for (let i = value.length - 1; i >= 0; i--)
|
|
147
|
+
stack.push(value[i]);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (!youtubeObject(value))
|
|
151
|
+
continue;
|
|
152
|
+
if (youtubeObject(value.continuationCommand) && typeof value.continuationCommand.token === 'string')
|
|
153
|
+
token ??= value.continuationCommand.token;
|
|
154
|
+
if (youtubeObject(value.lockupViewModel) && value.lockupViewModel.contentType === 'LOCKUP_CONTENT_TYPE_PLAYLIST') {
|
|
155
|
+
const item = playlistLockup(value.lockupViewModel);
|
|
156
|
+
if (!seen.has(`playlist:${item.id}`)) {
|
|
157
|
+
items.push(item);
|
|
158
|
+
seen.add(`playlist:${item.id}`);
|
|
159
|
+
}
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const entry = ['video', 'channel'].find(type => youtubeObject(value[`${type}Renderer`]));
|
|
163
|
+
if (entry) {
|
|
164
|
+
const item = searchItem(entry, value[`${entry}Renderer`]);
|
|
165
|
+
const key = `${entry}:${item.id}`;
|
|
166
|
+
if (!seen.has(key)) {
|
|
167
|
+
items.push(item);
|
|
168
|
+
seen.add(key);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
for (const [key, child] of Object.entries(value).reverse()) {
|
|
173
|
+
if (!/adSlotRenderer|promotedSparklesWebRenderer|searchPyvRenderer|adMetadata|loggingDirectives|trackingParams/.test(key))
|
|
174
|
+
stack.push(child);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { items, estimatedResults: optionalString(raw.estimatedResults), continuation: token ? { token, client } : undefined, raw };
|
|
178
|
+
}
|
|
179
|
+
export function extractYouTubeClient(html) {
|
|
180
|
+
const pattern = /ytcfg\.set\s*\(/g;
|
|
181
|
+
let match;
|
|
182
|
+
while ((match = pattern.exec(html))) {
|
|
183
|
+
const config = extractYouTubeJson(`config=${html.slice(pattern.lastIndex).trimStart()}`, 'config');
|
|
184
|
+
if (!config || !youtubeObject(config.INNERTUBE_CONTEXT) || !youtubeObject(config.INNERTUBE_CONTEXT.client))
|
|
185
|
+
continue;
|
|
186
|
+
const client = config.INNERTUBE_CONTEXT.client;
|
|
187
|
+
if (client.clientName !== 'WEB')
|
|
188
|
+
return fail('unsupported anonymous client');
|
|
189
|
+
return { clientName: 'WEB', clientVersion: requiredString(client.clientVersion, 'client version'), hl: optionalString(client.hl), gl: optionalString(client.gl), visitorData: optionalString(client.visitorData) };
|
|
190
|
+
}
|
|
191
|
+
return fail('anonymous client configuration');
|
|
192
|
+
}
|
|
193
|
+
export function parseYouTubeVideoId(value) {
|
|
194
|
+
if (typeof value !== 'string')
|
|
195
|
+
throw new TypeError('A YouTube video ID or URL is required');
|
|
196
|
+
if (/^[A-Za-z0-9_-]{11}$/.test(value))
|
|
197
|
+
return value;
|
|
198
|
+
let url;
|
|
199
|
+
try {
|
|
200
|
+
url = new URL(value);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
throw new TypeError('Invalid YouTube video ID or URL');
|
|
204
|
+
}
|
|
205
|
+
if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password || url.port)
|
|
206
|
+
throw new TypeError('Invalid YouTube video URL');
|
|
207
|
+
const host = url.hostname.toLowerCase();
|
|
208
|
+
const id = host === 'youtu.be' ? url.pathname.slice(1) : ['youtube.com', 'www.youtube.com', 'm.youtube.com', 'www.youtube-nocookie.com'].includes(host) ? url.pathname === '/watch' ? url.searchParams.get('v') : /^\/(?:shorts|embed|live)\/([A-Za-z0-9_-]{11})\/?$/.exec(url.pathname)?.[1] : undefined;
|
|
209
|
+
if (typeof id !== 'string' || !/^[A-Za-z0-9_-]{11}$/.test(id))
|
|
210
|
+
throw new TypeError('Invalid YouTube video URL');
|
|
211
|
+
return id;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=parsers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/youtube/parsers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export interface YouTubeConfig {
|
|
2
|
+
fetch?: typeof globalThis.fetch;
|
|
3
|
+
locale?: string;
|
|
4
|
+
region?: string;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface YouTubeRequestOptions {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
export interface YouTubeThumbnail {
|
|
11
|
+
url: string;
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface YouTubeCaptionTrack {
|
|
16
|
+
languageCode: string;
|
|
17
|
+
name: string;
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
kind?: string;
|
|
20
|
+
isTranslatable?: boolean;
|
|
21
|
+
raw: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface YouTubeVideo {
|
|
24
|
+
id: string;
|
|
25
|
+
url: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
author?: string;
|
|
28
|
+
channelId?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
lengthSeconds?: number;
|
|
31
|
+
viewCount?: string;
|
|
32
|
+
keywords?: string[];
|
|
33
|
+
isLiveContent?: boolean;
|
|
34
|
+
thumbnails: YouTubeThumbnail[];
|
|
35
|
+
playability: {
|
|
36
|
+
status: string;
|
|
37
|
+
reason?: string;
|
|
38
|
+
raw: Record<string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
captions: YouTubeCaptionTrack[];
|
|
41
|
+
raw: Record<string, unknown>;
|
|
42
|
+
initialData?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export interface YouTubeSearchItem {
|
|
45
|
+
type: 'video' | 'channel' | 'playlist';
|
|
46
|
+
id: string;
|
|
47
|
+
title: string;
|
|
48
|
+
url: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
author?: string;
|
|
51
|
+
channelId?: string;
|
|
52
|
+
duration?: string;
|
|
53
|
+
viewCount?: string;
|
|
54
|
+
publishedTime?: string;
|
|
55
|
+
thumbnails: YouTubeThumbnail[];
|
|
56
|
+
raw: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface YouTubeSearchCursor {
|
|
59
|
+
token: string;
|
|
60
|
+
client: {
|
|
61
|
+
clientName: 'WEB';
|
|
62
|
+
clientVersion: string;
|
|
63
|
+
hl?: string;
|
|
64
|
+
gl?: string;
|
|
65
|
+
visitorData?: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export interface YouTubeSearchPage {
|
|
69
|
+
items: YouTubeSearchItem[];
|
|
70
|
+
estimatedResults?: string;
|
|
71
|
+
continuation?: YouTubeSearchCursor;
|
|
72
|
+
raw: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
export interface YouTubeOEmbed {
|
|
75
|
+
title: string;
|
|
76
|
+
author_name: string;
|
|
77
|
+
author_url: string;
|
|
78
|
+
type: string;
|
|
79
|
+
height: number;
|
|
80
|
+
width: number;
|
|
81
|
+
version: string;
|
|
82
|
+
provider_name: string;
|
|
83
|
+
provider_url: string;
|
|
84
|
+
thumbnail_height: number;
|
|
85
|
+
thumbnail_width: number;
|
|
86
|
+
thumbnail_url: string;
|
|
87
|
+
html: string;
|
|
88
|
+
[key: string]: unknown;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/youtube/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/youtube/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { YouTubeClient } from './youtube/client.js';
|
|
2
|
+
export { YouTubeError } from './youtube/errors.js';
|
|
3
|
+
export type { YouTubeErrorKind } from './youtube/errors.js';
|
|
4
|
+
export { parseYouTubeVideoId } from './youtube/parsers.js';
|
|
5
|
+
export type * from './youtube/types.js';
|
|
6
|
+
import { YouTubeClient } from './youtube/client.js';
|
|
7
|
+
import type { YouTubeConfig } from './youtube/types.js';
|
|
8
|
+
export declare function youtube(config?: YouTubeConfig): YouTubeClient;
|
|
9
|
+
//# sourceMappingURL=youtube.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube.d.ts","sourceRoot":"","sources":["../src/youtube.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,mBAAmB,oBAAoB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,wBAAgB,OAAO,CAAC,MAAM,GAAE,aAAkB,GAAG,aAAa,CAAsC"}
|
package/dist/youtube.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { YouTubeClient } from './youtube/client.js';
|
|
2
|
+
export { YouTubeError } from './youtube/errors.js';
|
|
3
|
+
export { parseYouTubeVideoId } from './youtube/parsers.js';
|
|
4
|
+
import { YouTubeClient } from './youtube/client.js';
|
|
5
|
+
export function youtube(config = {}) { return new YouTubeClient(config); }
|
|
6
|
+
//# sourceMappingURL=youtube.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube.js","sourceRoot":"","sources":["../src/youtube.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,UAAU,OAAO,CAAC,SAAwB,EAAE,IAAmB,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC"}
|
package/docs/books.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Google Books public metadata
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { googleBooks } from 'googlemaps-kit/books';
|
|
5
|
+
|
|
6
|
+
const book = await googleBooks().get('zyTCAlFPjgYC');
|
|
7
|
+
console.log(book.title, book.authors, book.identifiers, book.pageCount);
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
This client reads an observed public bibliographic page at `books.google.com/books?id=...&hl=en`. It returns the title, bibliographic title, authors, publisher/year, edition, ISBNs, page count, optional description, canonical link and original table values. Fields missing from the page remain undefined or empty. It does not retrieve book pages, full text, purchased content, account libraries or previews.
|
|
11
|
+
|
|
12
|
+
The web metadata request succeeded anonymously on October 29, 2026. The documented Books v1 search and volume endpoints returned HTTP 429 quota errors from the same environment. This module uses the verified web surface; it is not a wrapper presented as successful v1 API access. Search by query, browsing bookshelves, v1 API operations and broad pagination are outside the current implementation.
|
|
13
|
+
|
|
14
|
+
`googleBooks({ fetch?, timeoutMs? })` accepts an injected fetch and defaults to a 30-second request deadline including the response body. `get(id, { signal? })` accepts a Google volume ID, requests the English page, and makes no automatic retries. Unknown layouts, mismatched volume IDs and HTTP failures throw `GoogleWebError` rather than returning empty fabricated metadata. Regional redirects are handled by normal fetch behavior; bibliographic parsing is verified only for the captured page structure.
|
|
15
|
+
|
|
16
|
+
`parseGoogleBooksHtml(html, id)` exposes the same parser for saved HTML. It never executes scripts. Sanitized actual fixture provenance is in `tests/fixtures/books/README.md`.
|
|
17
|
+
|
|
18
|
+
See the [independent research ledger](./google-ai-books-research.md) for observed behavior and unresolved gaps.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Weather, Air Quality and Cloud Vision access boundaries
|
|
2
|
+
|
|
3
|
+
Audited on 2026-10-29. These products have supported Google APIs with project
|
|
4
|
+
identity and billing/quota rules. A public consumer widget is a different
|
|
5
|
+
contract from those APIs.
|
|
6
|
+
|
|
7
|
+
## Direct API observations
|
|
8
|
+
|
|
9
|
+
Requests deliberately supplied no API key, OAuth token or account cookies:
|
|
10
|
+
|
|
11
|
+
| API | Request | Observed result |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| Weather current conditions | `GET weather.googleapis.com/v1/currentConditions:lookup` with location | HTTP 403, `PERMISSION_DENIED`, consumer identity required |
|
|
14
|
+
| Air Quality current conditions | `POST airquality.googleapis.com/v1/currentConditions:lookup` with JSON location | HTTP 403, `PERMISSION_DENIED`, consumer identity required |
|
|
15
|
+
| Vision text detection | `POST vision.googleapis.com/v1/images:annotate` with Google's public logo URL | HTTP 403, `PERMISSION_DENIED`, consumer identity required |
|
|
16
|
+
|
|
17
|
+
These failures establish that the tested official routes do not accept
|
|
18
|
+
unregistered callers. They do not establish successful access to the protected
|
|
19
|
+
data. No project credential was borrowed or extracted and no supported API's
|
|
20
|
+
paid feature is claimed anonymously available.
|
|
21
|
+
|
|
22
|
+
## Existing consumer capabilities
|
|
23
|
+
|
|
24
|
+
`maps.environment.weather.getCurrentConditions` parses the weather chip from a
|
|
25
|
+
Maps viewport response. It requires a current in-page viewport `psi` supplied
|
|
26
|
+
by the caller or a `psiProvider`. It does not produce a full forecast. A bare
|
|
27
|
+
degree symbol has no established Celsius/Fahrenheit meaning, so the parser now
|
|
28
|
+
preserves the value/display while leaving `unit` unset unless C or F is explicit.
|
|
29
|
+
|
|
30
|
+
A fresh ordinary Maps viewport capture for HSR Layout on 2026-10-29 returned
|
|
31
|
+
the expected cache-metadata stub followed by two populated responses. The
|
|
32
|
+
existing parser extracted `HSR Layout`, `28°`, and `Sunny`. This revalidates the
|
|
33
|
+
bounded current-condition chip contract, not a forecast or numerical AQI API.
|
|
34
|
+
|
|
35
|
+
`maps.environment.airQuality.getHeatmapTile` reads the existing raster overlay
|
|
36
|
+
surface. A tile is not a numerical point AQI lookup, and a returned placeholder
|
|
37
|
+
does not prove meaningful overlay coverage. The existing batchexecute parser
|
|
38
|
+
remains a separate partially established, session-dependent interface.
|
|
39
|
+
|
|
40
|
+
## Corrected supported-API contracts
|
|
41
|
+
|
|
42
|
+
The audit identified two existing request bugs and added offline regressions:
|
|
43
|
+
|
|
44
|
+
- Air Quality `lookup` now sends Google's documented JSON POST location instead
|
|
45
|
+
of GET query parameters. It accepts only a caller-configured API key.
|
|
46
|
+
- Weather `lookupForecast` now calls `forecast/days:lookup`, returning actual
|
|
47
|
+
daily records rather than calling current conditions. It accepts `days` and
|
|
48
|
+
`pageSize` from 1 to 10 and an optional `pageToken`, preserving Google's
|
|
49
|
+
pagination response. It still requires the caller's API credential.
|
|
50
|
+
|
|
51
|
+
The shared Maps HTTP client now has `postJson`, which preserves scheduling,
|
|
52
|
+
authentication options, error handling and statistics while parsing ordinary
|
|
53
|
+
JSON objects. Automatic retries are disabled by default for JSON POSTs.
|
|
54
|
+
These request fixes were tested offline; a successful authenticated/billable
|
|
55
|
+
Weather/Air Quality response was not claimed or attempted in this pass.
|
|
56
|
+
|
|
57
|
+
References: [Weather daily forecast](https://developers.google.com/maps/documentation/weather/reference/rest/v1/forecast.days/lookup),
|
|
58
|
+
[Weather setup](https://developers.google.com/maps/documentation/weather/get-api-key),
|
|
59
|
+
[Air Quality current conditions](https://developers.google.com/maps/documentation/air-quality/reference/rest/v1/currentConditions/lookup),
|
|
60
|
+
[Air Quality authentication](https://developers.google.com/maps/documentation/air-quality/get-api-key),
|
|
61
|
+
[Vision pricing](https://cloud.google.com/vision/pricing).
|
|
62
|
+
|
|
63
|
+
Consumer Lens is investigated separately from Cloud Vision. Similar OCR or
|
|
64
|
+
visual-search capabilities do not establish identical output, licensed data,
|
|
65
|
+
throughput, model selection or paid API parity.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Google Finance consumer client
|
|
2
|
+
|
|
3
|
+
Investigated and verified on **2026-10-29**, build
|
|
4
|
+
`boq_finhub-uiserver_20261026.07_p0`. This client implements the public consumer
|
|
5
|
+
quote, instrument-suggestion, and sampled-price chart surfaces. It does not
|
|
6
|
+
claim to reproduce all of Google Finance, provide a licensed market-data feed,
|
|
7
|
+
or expose paid/AI research features.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { finance } from 'googlemaps-kit/finance';
|
|
11
|
+
|
|
12
|
+
const client = finance();
|
|
13
|
+
const quote = await client.quote('GOOGL:NASDAQ');
|
|
14
|
+
const suggestions = await client.search('Microsoft');
|
|
15
|
+
const chart = await client.chart('GOOGL:NASDAQ', { range: '1M' });
|
|
16
|
+
|
|
17
|
+
console.log(quote.price, quote.currency, quote.time);
|
|
18
|
+
console.log(quote.extendedMarket);
|
|
19
|
+
console.log(suggestions.matches);
|
|
20
|
+
console.log(chart.sessions.flatMap(session => session.points));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Instrument strings use **symbol:exchange** order, as Google Finance URLs do.
|
|
24
|
+
Objects `{ symbol: 'GOOGL', exchange: 'NASDAQ' }` are also accepted. `search`
|
|
25
|
+
returns identifiable instrument suggestions, deduplicating repeated UI groups;
|
|
26
|
+
it does not return an arbitrary natural-language or AI answer.
|
|
27
|
+
|
|
28
|
+
Configuration supports `fetch`, `timeoutMs`, `language`, and `userAgent`.
|
|
29
|
+
Methods accept an `AbortSignal`. Requests have a body-read deadline and do not
|
|
30
|
+
automatically retry a block or failure. `FinanceError` exports the shared
|
|
31
|
+
`GoogleWebError` class with `kind`, optional HTTP `status`, `rpcCode`, and
|
|
32
|
+
`retryAfterMs`. Rate-limit/automated-query responses remain errors.
|
|
33
|
+
|
|
34
|
+
## Runtime and static evidence
|
|
35
|
+
|
|
36
|
+
- Ordinary headless Chromium rendered a complete GOOGL quote page. A generic
|
|
37
|
+
non-browser user agent had previously received an unsupported-client page.
|
|
38
|
+
The client therefore uses the exact captured browser user-agent family for
|
|
39
|
+
device negotiation; users may override it. Runtime browser evidence:
|
|
40
|
+
`ev_8b8ce4e3adf9f17541b4db84cde49b10828e312435ad8735c6596efac93c2ccd`.
|
|
41
|
+
- REA analyzed **66 observed scripts**, providing static descriptors and field
|
|
42
|
+
access evidence:
|
|
43
|
+
`ev_681d6f6b8601b800f9884383e2c34fd76024911ff6b8305bd91f61b0f7c97950`.
|
|
44
|
+
Static analysis does not establish endpoint execution; direct HTTP replay
|
|
45
|
+
below supplies the runtime verification.
|
|
46
|
+
- Direct anonymous HTTP replay returned 200 with real data for quote summary,
|
|
47
|
+
search suggestions, pricing details, and all eight chart ranges. No API key
|
|
48
|
+
or signed-in cookies were supplied. The complete client also passed an
|
|
49
|
+
opted-in live test for quote, search, and monthly chart.
|
|
50
|
+
- Original runtime HTML, requests, responses, and scripts remain in untracked
|
|
51
|
+
scratch storage. Offline tests use copied public-data payloads under
|
|
52
|
+
`tests/fixtures/finance/`; shipped code has no dependency on scratch files.
|
|
53
|
+
|
|
54
|
+
## Verified protocol
|
|
55
|
+
|
|
56
|
+
Bootstrap `https://www.google.com/finance/?hl=en` and read `WIZ_global_data`:
|
|
57
|
+
`eptZe=/finance/_/FinHubUi/`, `FdrFJe` session, and `cfb2h` build. Calls POST
|
|
58
|
+
form-encoded `f.req` to
|
|
59
|
+
`https://www.google.com/finance/_/FinHubUi/data/batchexecute`, passing `rpcids`,
|
|
60
|
+
`source-path`, `f.sid`, `bl`, `hl`, and `rt=c`. Responses contain XSSI-prefixed,
|
|
61
|
+
framed `wrb.fr` JSON payloads. Captured anonymous requests omitted `at`.
|
|
62
|
+
|
|
63
|
+
| RPC | Shipped descriptor | Verified arguments | Client method |
|
|
64
|
+
| --- | --- | --- | --- |
|
|
65
|
+
| `gCvqoe` | `/FinanceHubService.ListEntitySummary` | `[[[null,[symbol,exchange]]]]` | `quote` |
|
|
66
|
+
| `XB3kn` | `/FinanceHubService.GetSearchSuggestions` | `[query,null,1]` | `search` |
|
|
67
|
+
| `c2u4wc` | `/FinanceHubService.ListHistoricalPricingData` | `[[[null,[symbol,exchange]]],rangeEnum]` | `chart` |
|
|
68
|
+
| `dlNq8b` | Pricing-detail surface | `[[[null,[symbol,exchange]]],1,1,1]` | Captured and replayed; not exposed by this client |
|
|
69
|
+
|
|
70
|
+
Browser traffic also registered and sometimes executed earnings/research RPCs,
|
|
71
|
+
including `Xs5i3b` (GetEarningsTranscriptHighlights), `Iaiw6c` (GetEarningsFiles),
|
|
72
|
+
and `TNo8E` (GetRelatedEarnings). Those are not the quote/search endpoints and
|
|
73
|
+
are not part of the public SDK contract. No claim of paid research parity is
|
|
74
|
+
made from their presence in a bundle.
|
|
75
|
+
|
|
76
|
+
### Quote fields
|
|
77
|
+
|
|
78
|
+
`gCvqoe` response field 1 is repeated EntitySummary; each entry's field 1 is a
|
|
79
|
+
security node. The following are one-based security field numbers:
|
|
80
|
+
|
|
81
|
+
| Field | Meaning established by capture and renderer |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| 1 | Entity ID |
|
|
84
|
+
| 2 | `[symbol,exchange]` |
|
|
85
|
+
| 3 | Display name |
|
|
86
|
+
| 5 | Currency |
|
|
87
|
+
| 6 | Regular price tuple `[price,change,changePercent,...]` |
|
|
88
|
+
| 8 | Previous close |
|
|
89
|
+
| 12 | Reported data timestamp `[seconds,nanos]` |
|
|
90
|
+
| 13 | Exchange time-zone name |
|
|
91
|
+
| 14 | UTC offset seconds |
|
|
92
|
+
| 17 | Extended-session price tuple |
|
|
93
|
+
| 18 | Regular price timestamp |
|
|
94
|
+
| 19 | Extended-session price timestamp |
|
|
95
|
+
| 25 | Source enum; returned as an opaque code when present |
|
|
96
|
+
|
|
97
|
+
The successful GOOGL capture contained regular price **324.89 USD** and
|
|
98
|
+
extended price **292.50 USD**. These are fixture observations, not current
|
|
99
|
+
recommendations or promised live prices. The parser keeps them separate and
|
|
100
|
+
preserves zero prices/changes and original precision.
|
|
101
|
+
|
|
102
|
+
`reportedTime`, `time`, and `extendedMarket.time` are distinct source values.
|
|
103
|
+
The payload does not establish a guaranteed delay interval, so `delayStatus`
|
|
104
|
+
is `not-disclosed`; the SDK does not label every quote real-time. Some exchanges
|
|
105
|
+
or instruments can be delayed, missing, or unsupported. See Google's
|
|
106
|
+
[Finance data disclaimer](https://www.google.com/googlefinance/disclaimer/) and
|
|
107
|
+
[GOOGLEFINANCE limitations](https://support.google.com/docs/answer/3093281?hl=en).
|
|
108
|
+
The Sheets function and this consumer web transport are separate interfaces.
|
|
109
|
+
|
|
110
|
+
### Historical charts
|
|
111
|
+
|
|
112
|
+
The UI's range enum is statically explicit and each range was replayed
|
|
113
|
+
successfully for GOOGL:
|
|
114
|
+
|
|
115
|
+
| Range | Enum | Observed interval seconds | Observed points |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| `1D` | 1 | 60 | 632 across regular and extended sessions |
|
|
118
|
+
| `5D` | 2 | 1800 | 70 |
|
|
119
|
+
| `1M` | 3 | 86400 | 23 |
|
|
120
|
+
| `6M` | 4 | 86400 | 128 |
|
|
121
|
+
| `YTD` | 5 | 86400 | 209 |
|
|
122
|
+
| `1Y` | 6 | 86400 | 252 |
|
|
123
|
+
| `5Y` | 7 | 604800 | 262 |
|
|
124
|
+
| `MAX` | 8 | 604800 | 1159 |
|
|
125
|
+
|
|
126
|
+
These intervals/counts describe the captured responses and may vary. `MAX`
|
|
127
|
+
does not imply a complete daily trading history. The response's field 4 groups
|
|
128
|
+
session headers and points. Each point is `[DateTime,priceTuple,volume]`.
|
|
129
|
+
DateTime months are one-based, and field 8 contains a UTC-offset message;
|
|
130
|
+
converting to ISO time must apply that offset rather than the execution host's
|
|
131
|
+
time zone. Session codes remain numeric: `1` and `3` were observed for regular
|
|
132
|
+
and extended data in the day capture.
|
|
133
|
+
|
|
134
|
+
Only verified price, time, and volume are normalized for chart points. Other
|
|
135
|
+
price-tuple values vary with the selected chart baseline and remain available
|
|
136
|
+
in `raw`, avoiding an incorrect “percent change” interpretation.
|
|
137
|
+
|
|
138
|
+
## Validation and limits
|
|
139
|
+
|
|
140
|
+
Sixteen offline unit tests cover captured layouts, duplicate suggestions,
|
|
141
|
+
regular/extended separation, zero values, UTC offsets, malformed/missing data,
|
|
142
|
+
the request envelope, blocking, cancellation, and local validation.
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
npx vitest run tests/unit/finance
|
|
146
|
+
GMAPS_LIVE=1 FINANCE_LIVE=1 npx vitest run tests/live/finance.test.ts
|
|
147
|
+
npm run type-check
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
All passed during implementation. Live tests require explicit opt-in and are
|
|
151
|
+
excluded from the ordinary unit suite. Authentication-gated portfolios,
|
|
152
|
+
watchlists, premium research, AI generation, and undocumented tuple fields
|
|
153
|
+
remain outside this client's verified scope.
|
package/docs/finance.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Google Finance
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { finance } from 'googlemaps-kit/finance';
|
|
5
|
+
|
|
6
|
+
const market = finance();
|
|
7
|
+
const quote = await market.quote('GOOGL:NASDAQ');
|
|
8
|
+
console.log(quote.name, quote.price, quote.currency, quote.time);
|
|
9
|
+
console.log(quote.extendedMarket);
|
|
10
|
+
|
|
11
|
+
const matches = await market.search('Microsoft');
|
|
12
|
+
const chart = await market.chart('GOOGL:NASDAQ', { range: '1M' });
|
|
13
|
+
console.log(matches.matches, chart.sessions);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Instrument strings use `symbol:exchange`, matching the website's quote URL.
|
|
17
|
+
Objects `{ symbol, exchange }` are also accepted. Charts support `1D`, `5D`,
|
|
18
|
+
`1M`, `6M`, `YTD`, `1Y`, `5Y`, and `MAX`. Their sampling interval and available
|
|
19
|
+
session groups come from Google, not a locally reconstructed price history.
|
|
20
|
+
|
|
21
|
+
Quote results separate regular and extended-session prices and timestamps.
|
|
22
|
+
They also preserve currency, previous close, source-reported time, exchange
|
|
23
|
+
timezone and UTC offset where returned. `delayStatus` is `not-disclosed`;
|
|
24
|
+
the client does not infer that a quote is real-time. Raw positional payloads
|
|
25
|
+
remain available on all results.
|
|
26
|
+
|
|
27
|
+
Configuration accepts `fetch`, `timeoutMs` (default 30 seconds), `language`
|
|
28
|
+
(default `en`) and `userAgent`. The default user agent is the ordinary browser
|
|
29
|
+
used for the successful capture, because Google served an unsupported-device
|
|
30
|
+
page to a generic HTTP client. All methods accept `signal`; requests are not
|
|
31
|
+
automatically retried. `FinanceError` exposes `kind`, HTTP `status`, RPC code
|
|
32
|
+
and `retryAfterMs` where available. A captured missing-instrument status is
|
|
33
|
+
reported with RPC code 5.
|
|
34
|
+
|
|
35
|
+
This is a public quote/search/chart interface, with no API key or browser
|
|
36
|
+
runtime dependency. It does not implement portfolios, account operations,
|
|
37
|
+
AI investment answers, every asset type, fundamentals or exchange-data
|
|
38
|
+
licensing. See Google's [data information](https://www.google.com/googlefinance/disclaimer/)
|
|
39
|
+
and the [protocol research](finance-research.md) for exact contracts, live
|
|
40
|
+
evidence and remaining limits.
|
|
41
|
+
|
|
42
|
+
Run all public-client probes with `npm run test:google-public:live` or Finance
|
|
43
|
+
alone with `GMAPS_LIVE=1 FINANCE_LIVE=1 npx vitest run tests/live/finance.test.ts`.
|