scrapebadger 0.51.1 → 0.53.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.
@@ -2084,6 +2084,29 @@ declare class ScrapeBadgerError extends Error {
2084
2084
  declare class AuthenticationError extends ScrapeBadgerError {
2085
2085
  constructor(message?: string);
2086
2086
  }
2087
+ /**
2088
+ * Raised when the API key is not permitted to call this API (HTTP 403,
2089
+ * `error: "insufficient_scope"`). Keys can be restricted to specific APIs in
2090
+ * the dashboard; a refused call is not charged.
2091
+ *
2092
+ * Extends `AuthenticationError`, which is what a 403 threw before 0.52.0.
2093
+ */
2094
+ declare class PermissionDeniedError extends AuthenticationError {
2095
+ /** The API the request needed, e.g. `"twitter"` */
2096
+ readonly requiredScope: string | undefined;
2097
+ /** The APIs this key may call */
2098
+ readonly allowedScopes: string[];
2099
+ constructor(message?: string, requiredScope?: string, allowedScopes?: string[]);
2100
+ }
2101
+ /**
2102
+ * Raised when the API key is restricted to IP addresses and this request came
2103
+ * from another one (HTTP 403, `error: "ip_not_allowed"`). Not charged.
2104
+ */
2105
+ declare class IPNotAllowedError extends PermissionDeniedError {
2106
+ /** The address ScrapeBadger saw (null when relayed, e.g. via the hosted MCP server) */
2107
+ readonly clientIp: string | null;
2108
+ constructor(message?: string, clientIp?: string | null);
2109
+ }
2087
2110
  /**
2088
2111
  * Raised when rate limit is exceeded.
2089
2112
  */
@@ -3152,4 +3175,4 @@ declare class TwitterClient {
3152
3175
  removeWebhookFromMonitor(webhookId: string, body?: unknown, params?: Record<string, string | number | boolean | undefined>): Promise<Record<string, unknown>>;
3153
3176
  }
3154
3177
 
3155
- export { type Article as $, AuthenticationError as A, BaseClient as B, ConflictError as C, type UserIds as D, type List as E, type CommunityBanner as F, GeoClient as G, type Hashtag as H, InsufficientCreditsError as I, type CommunityRule as J, type Community as K, ListsClient as L, type Media as M, NotFoundError as N, type CommunityMember as O, type PaginatedResponse as P, type QueryType as Q, type ResolvedConfig as R, type ScrapeBadgerConfig as S, TwitterClient as T, UsersClient as U, ValidationError as V, WebSocketStreamError as W, type Trend as X, type Location as Y, type PlaceTrends as Z, type Place as _, ScrapeBadgerError as a, type CommunityNote as a0, type Space as a1, type Broadcast as a2, type ApiResponse as a3, type ListResponse as a4, type MonitorStatus as a5, type StreamMonitor as a6, type StreamMonitorList as a7, type CreateMonitorParams as a8, type UpdateMonitorParams as a9, type StreamTweet as aa, type ConnectedEvent as ab, type PingEvent as ac, type TweetEvent as ad, type ErrorEvent as ae, type StreamEvent as af, type StreamEventType as ag, type DeliveryLog as ah, type DeliveryLogList as ai, type BillingLog as aj, type BillingLogList as ak, type ConnectOptions as al, type FilterRuleStatus as am, type FilterRuleResponse as an, type FilterRuleCreate as ao, type FilterRuleUpdate as ap, type FilterRulePricingTier as aq, type FilterRuleListResponse as ar, type FilterRuleValidateResponse as as, type FilterRuleDeliveryLog as at, type FilterRuleDeliveryLogListResponse as au, type FilterRulePricingTiersResponse as av, RateLimitError as b, ServerError as c, TimeoutError as d, AccountRestrictedError as e, type PaginationOptions as f, type IteratorOptions as g, collectAll as h, TweetsClient as i, CommunitiesClient as j, TrendsClient as k, type GeoSearchOptions as l, StreamClient as m, type StreamEmitter as n, SpacesClient as o, type TrendCategory as p, type CommunityTweetType as q, type PollOption as r, type Poll as s, type Url as t, type UserMention as u, verifyWebhookSignature as v, type TweetPlace as w, type Tweet as x, type User as y, type UserAbout as z };
3178
+ export { type PlaceTrends as $, AuthenticationError as A, BaseClient as B, ConflictError as C, type User as D, type UserAbout as E, type UserIds as F, GeoClient as G, type Hashtag as H, InsufficientCreditsError as I, type List as J, type CommunityBanner as K, ListsClient as L, type Media as M, NotFoundError as N, type CommunityRule as O, PermissionDeniedError as P, type QueryType as Q, type ResolvedConfig as R, type ScrapeBadgerConfig as S, TwitterClient as T, UsersClient as U, ValidationError as V, WebSocketStreamError as W, type Community as X, type CommunityMember as Y, type Trend as Z, type Location as _, ScrapeBadgerError as a, type Place as a0, type Article as a1, type CommunityNote as a2, type Space as a3, type Broadcast as a4, type ApiResponse as a5, type ListResponse as a6, type MonitorStatus as a7, type StreamMonitor as a8, type StreamMonitorList as a9, type CreateMonitorParams as aa, type UpdateMonitorParams as ab, type StreamTweet as ac, type ConnectedEvent as ad, type PingEvent as ae, type TweetEvent as af, type ErrorEvent as ag, type StreamEvent as ah, type StreamEventType as ai, type DeliveryLog as aj, type DeliveryLogList as ak, type BillingLog as al, type BillingLogList as am, type ConnectOptions as an, type FilterRuleStatus as ao, type FilterRuleResponse as ap, type FilterRuleCreate as aq, type FilterRuleUpdate as ar, type FilterRulePricingTier as as, type FilterRuleListResponse as at, type FilterRuleValidateResponse as au, type FilterRuleDeliveryLog as av, type FilterRuleDeliveryLogListResponse as aw, type FilterRulePricingTiersResponse as ax, RateLimitError as b, ServerError as c, TimeoutError as d, AccountRestrictedError as e, IPNotAllowedError as f, type PaginatedResponse as g, type PaginationOptions as h, type IteratorOptions as i, collectAll as j, TweetsClient as k, CommunitiesClient as l, TrendsClient as m, type GeoSearchOptions as n, StreamClient as o, type StreamEmitter as p, SpacesClient as q, type TrendCategory as r, type CommunityTweetType as s, type PollOption as t, type Poll as u, verifyWebhookSignature as v, type Url as w, type UserMention as x, type TweetPlace as y, type Tweet as z };
@@ -2084,6 +2084,29 @@ declare class ScrapeBadgerError extends Error {
2084
2084
  declare class AuthenticationError extends ScrapeBadgerError {
2085
2085
  constructor(message?: string);
2086
2086
  }
2087
+ /**
2088
+ * Raised when the API key is not permitted to call this API (HTTP 403,
2089
+ * `error: "insufficient_scope"`). Keys can be restricted to specific APIs in
2090
+ * the dashboard; a refused call is not charged.
2091
+ *
2092
+ * Extends `AuthenticationError`, which is what a 403 threw before 0.52.0.
2093
+ */
2094
+ declare class PermissionDeniedError extends AuthenticationError {
2095
+ /** The API the request needed, e.g. `"twitter"` */
2096
+ readonly requiredScope: string | undefined;
2097
+ /** The APIs this key may call */
2098
+ readonly allowedScopes: string[];
2099
+ constructor(message?: string, requiredScope?: string, allowedScopes?: string[]);
2100
+ }
2101
+ /**
2102
+ * Raised when the API key is restricted to IP addresses and this request came
2103
+ * from another one (HTTP 403, `error: "ip_not_allowed"`). Not charged.
2104
+ */
2105
+ declare class IPNotAllowedError extends PermissionDeniedError {
2106
+ /** The address ScrapeBadger saw (null when relayed, e.g. via the hosted MCP server) */
2107
+ readonly clientIp: string | null;
2108
+ constructor(message?: string, clientIp?: string | null);
2109
+ }
2087
2110
  /**
2088
2111
  * Raised when rate limit is exceeded.
2089
2112
  */
@@ -3152,4 +3175,4 @@ declare class TwitterClient {
3152
3175
  removeWebhookFromMonitor(webhookId: string, body?: unknown, params?: Record<string, string | number | boolean | undefined>): Promise<Record<string, unknown>>;
3153
3176
  }
3154
3177
 
3155
- export { type Article as $, AuthenticationError as A, BaseClient as B, ConflictError as C, type UserIds as D, type List as E, type CommunityBanner as F, GeoClient as G, type Hashtag as H, InsufficientCreditsError as I, type CommunityRule as J, type Community as K, ListsClient as L, type Media as M, NotFoundError as N, type CommunityMember as O, type PaginatedResponse as P, type QueryType as Q, type ResolvedConfig as R, type ScrapeBadgerConfig as S, TwitterClient as T, UsersClient as U, ValidationError as V, WebSocketStreamError as W, type Trend as X, type Location as Y, type PlaceTrends as Z, type Place as _, ScrapeBadgerError as a, type CommunityNote as a0, type Space as a1, type Broadcast as a2, type ApiResponse as a3, type ListResponse as a4, type MonitorStatus as a5, type StreamMonitor as a6, type StreamMonitorList as a7, type CreateMonitorParams as a8, type UpdateMonitorParams as a9, type StreamTweet as aa, type ConnectedEvent as ab, type PingEvent as ac, type TweetEvent as ad, type ErrorEvent as ae, type StreamEvent as af, type StreamEventType as ag, type DeliveryLog as ah, type DeliveryLogList as ai, type BillingLog as aj, type BillingLogList as ak, type ConnectOptions as al, type FilterRuleStatus as am, type FilterRuleResponse as an, type FilterRuleCreate as ao, type FilterRuleUpdate as ap, type FilterRulePricingTier as aq, type FilterRuleListResponse as ar, type FilterRuleValidateResponse as as, type FilterRuleDeliveryLog as at, type FilterRuleDeliveryLogListResponse as au, type FilterRulePricingTiersResponse as av, RateLimitError as b, ServerError as c, TimeoutError as d, AccountRestrictedError as e, type PaginationOptions as f, type IteratorOptions as g, collectAll as h, TweetsClient as i, CommunitiesClient as j, TrendsClient as k, type GeoSearchOptions as l, StreamClient as m, type StreamEmitter as n, SpacesClient as o, type TrendCategory as p, type CommunityTweetType as q, type PollOption as r, type Poll as s, type Url as t, type UserMention as u, verifyWebhookSignature as v, type TweetPlace as w, type Tweet as x, type User as y, type UserAbout as z };
3178
+ export { type PlaceTrends as $, AuthenticationError as A, BaseClient as B, ConflictError as C, type User as D, type UserAbout as E, type UserIds as F, GeoClient as G, type Hashtag as H, InsufficientCreditsError as I, type List as J, type CommunityBanner as K, ListsClient as L, type Media as M, NotFoundError as N, type CommunityRule as O, PermissionDeniedError as P, type QueryType as Q, type ResolvedConfig as R, type ScrapeBadgerConfig as S, TwitterClient as T, UsersClient as U, ValidationError as V, WebSocketStreamError as W, type Community as X, type CommunityMember as Y, type Trend as Z, type Location as _, ScrapeBadgerError as a, type Place as a0, type Article as a1, type CommunityNote as a2, type Space as a3, type Broadcast as a4, type ApiResponse as a5, type ListResponse as a6, type MonitorStatus as a7, type StreamMonitor as a8, type StreamMonitorList as a9, type CreateMonitorParams as aa, type UpdateMonitorParams as ab, type StreamTweet as ac, type ConnectedEvent as ad, type PingEvent as ae, type TweetEvent as af, type ErrorEvent as ag, type StreamEvent as ah, type StreamEventType as ai, type DeliveryLog as aj, type DeliveryLogList as ak, type BillingLog as al, type BillingLogList as am, type ConnectOptions as an, type FilterRuleStatus as ao, type FilterRuleResponse as ap, type FilterRuleCreate as aq, type FilterRuleUpdate as ar, type FilterRulePricingTier as as, type FilterRuleListResponse as at, type FilterRuleValidateResponse as au, type FilterRuleDeliveryLog as av, type FilterRuleDeliveryLogListResponse as aw, type FilterRulePricingTiersResponse as ax, RateLimitError as b, ServerError as c, TimeoutError as d, AccountRestrictedError as e, IPNotAllowedError as f, type PaginatedResponse as g, type PaginationOptions as h, type IteratorOptions as i, collectAll as j, TweetsClient as k, CommunitiesClient as l, TrendsClient as m, type GeoSearchOptions as n, StreamClient as o, type StreamEmitter as p, SpacesClient as q, type TrendCategory as r, type CommunityTweetType as s, type PollOption as t, type Poll as u, verifyWebhookSignature as v, type Url as w, type UserMention as x, type TweetPlace as y, type Tweet as z };
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BaseClient, T as TwitterClient, S as ScrapeBadgerConfig } from './index-Dz6kHfFt.cjs';
2
- export { e as AccountRestrictedError, a3 as ApiResponse, $ as Article, A as AuthenticationError, aj as BillingLog, ak as BillingLogList, a2 as Broadcast, j as CommunitiesClient, K as Community, F as CommunityBanner, O as CommunityMember, a0 as CommunityNote, J as CommunityRule, q as CommunityTweetType, C as ConflictError, al as ConnectOptions, ab as ConnectedEvent, a8 as CreateMonitorParams, ah as DeliveryLog, ai as DeliveryLogList, ae as ErrorEvent, ao as FilterRuleCreate, at as FilterRuleDeliveryLog, au as FilterRuleDeliveryLogListResponse, ar as FilterRuleListResponse, aq as FilterRulePricingTier, av as FilterRulePricingTiersResponse, an as FilterRuleResponse, am as FilterRuleStatus, ap as FilterRuleUpdate, as as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, I as InsufficientCreditsError, g as IteratorOptions, E as List, a4 as ListResponse, L as ListsClient, Y as Location, M as Media, a5 as MonitorStatus, N as NotFoundError, P as PaginatedResponse, f as PaginationOptions, ac as PingEvent, _ as Place, Z as PlaceTrends, s as Poll, r as PollOption, Q as QueryType, b as RateLimitError, R as ResolvedConfig, a as ScrapeBadgerError, c as ServerError, a1 as Space, o as SpacesClient, m as StreamClient, n as StreamEmitter, af as StreamEvent, ag as StreamEventType, a6 as StreamMonitor, a7 as StreamMonitorList, aa as StreamTweet, d as TimeoutError, X as Trend, p as TrendCategory, k as TrendsClient, x as Tweet, ad as TweetEvent, w as TweetPlace, i as TweetsClient, a9 as UpdateMonitorParams, t as Url, y as User, z as UserAbout, D as UserIds, u as UserMention, U as UsersClient, V as ValidationError, W as WebSocketStreamError, h as collectAll, v as verifyWebhookSignature } from './index-Dz6kHfFt.cjs';
1
+ import { B as BaseClient, T as TwitterClient, S as ScrapeBadgerConfig } from './index-DBk60c2e.cjs';
2
+ export { e as AccountRestrictedError, a5 as ApiResponse, a1 as Article, A as AuthenticationError, al as BillingLog, am as BillingLogList, a4 as Broadcast, l as CommunitiesClient, X as Community, K as CommunityBanner, Y as CommunityMember, a2 as CommunityNote, O as CommunityRule, s as CommunityTweetType, C as ConflictError, an as ConnectOptions, ad as ConnectedEvent, aa as CreateMonitorParams, aj as DeliveryLog, ak as DeliveryLogList, ag as ErrorEvent, aq as FilterRuleCreate, av as FilterRuleDeliveryLog, aw as FilterRuleDeliveryLogListResponse, at as FilterRuleListResponse, as as FilterRulePricingTier, ax as FilterRulePricingTiersResponse, ap as FilterRuleResponse, ao as FilterRuleStatus, ar as FilterRuleUpdate, au as FilterRuleValidateResponse, G as GeoClient, n as GeoSearchOptions, H as Hashtag, f as IPNotAllowedError, I as InsufficientCreditsError, i as IteratorOptions, J as List, a6 as ListResponse, L as ListsClient, _ as Location, M as Media, a7 as MonitorStatus, N as NotFoundError, g as PaginatedResponse, h as PaginationOptions, P as PermissionDeniedError, ae as PingEvent, a0 as Place, $ as PlaceTrends, u as Poll, t as PollOption, Q as QueryType, b as RateLimitError, R as ResolvedConfig, a as ScrapeBadgerError, c as ServerError, a3 as Space, q as SpacesClient, o as StreamClient, p as StreamEmitter, ah as StreamEvent, ai as StreamEventType, a8 as StreamMonitor, a9 as StreamMonitorList, ac as StreamTweet, d as TimeoutError, Z as Trend, r as TrendCategory, m as TrendsClient, z as Tweet, af as TweetEvent, y as TweetPlace, k as TweetsClient, ab as UpdateMonitorParams, w as Url, D as User, E as UserAbout, F as UserIds, x as UserMention, U as UsersClient, V as ValidationError, W as WebSocketStreamError, j as collectAll, v as verifyWebhookSignature } from './index-DBk60c2e.cjs';
3
3
  import 'node:events';
4
4
 
5
5
  /**
@@ -1498,11 +1498,25 @@ interface LensSearchParams {
1498
1498
  language?: string;
1499
1499
  gl?: string;
1500
1500
  hl?: string;
1501
- /** Bias towards shoppable product matches. */
1501
+ /**
1502
+ * Return only the tiles Google marked as buyable — those carrying a price
1503
+ * chip and stock status — drawn from the same grid with no extra request.
1504
+ * When the image has no shoppable matches the full grid is returned and
1505
+ * `warnings` says so.
1506
+ */
1502
1507
  product?: boolean;
1503
- /** Include the visual-matches carousel (default: true). */
1508
+ /**
1509
+ * Visual matches are the only surface this endpoint serves, so they are
1510
+ * always returned. `false` is echoed in `warnings`. (default: true)
1511
+ */
1504
1512
  visual_matches?: boolean;
1505
- /** Restrict to exact-match results only. */
1513
+ /**
1514
+ * Return just the pages hosting this image, each flagged `exact_match`,
1515
+ * instead of the broad visual grid — what a copyright or provenance
1516
+ * check needs. Google exposes this set for most images but not all (8 of 10
1517
+ * in our sampling); when it is unavailable the full grid is
1518
+ * returned and `warnings` says the filter was not applied.
1519
+ */
1506
1520
  exact_matches?: boolean;
1507
1521
  }
1508
1522
  /**
@@ -1792,12 +1806,20 @@ declare class JobsClient {
1792
1806
  * parsed from. `related_searches` chips come alongside. Legacy
1793
1807
  * `results` alias retained for backwards compat.
1794
1808
  *
1809
+ * Also carries a `warnings` array naming any parameter that could not be
1810
+ * applied. `exact_matches: true` returns just the pages hosting the image,
1811
+ * flagged `exact_match`, for most images; when Google does not expose that
1812
+ * set the grid comes back and `warnings` says so. `product: true` narrows the same grid to the tiles Google marked
1813
+ * buyable.
1814
+ *
1795
1815
  * @example
1796
1816
  * ```typescript
1797
1817
  * const out = await client.google.lens.search({
1798
1818
  * url: "https://example.com/photo.jpg",
1799
- * product: true, // bias towards shoppable matches
1819
+ * query: "wallpaper", // text refinement — honoured
1800
1820
  * });
1821
+ * // GoogleResponse is Record<string, unknown>, so narrow before use.
1822
+ * console.warn(out.warnings as string[] | undefined);
1801
1823
  * for (const match of out.lens_results) {
1802
1824
  * console.log(match.title, match.price?.value, match.price?.currency);
1803
1825
  * }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BaseClient, T as TwitterClient, S as ScrapeBadgerConfig } from './index-Dz6kHfFt.js';
2
- export { e as AccountRestrictedError, a3 as ApiResponse, $ as Article, A as AuthenticationError, aj as BillingLog, ak as BillingLogList, a2 as Broadcast, j as CommunitiesClient, K as Community, F as CommunityBanner, O as CommunityMember, a0 as CommunityNote, J as CommunityRule, q as CommunityTweetType, C as ConflictError, al as ConnectOptions, ab as ConnectedEvent, a8 as CreateMonitorParams, ah as DeliveryLog, ai as DeliveryLogList, ae as ErrorEvent, ao as FilterRuleCreate, at as FilterRuleDeliveryLog, au as FilterRuleDeliveryLogListResponse, ar as FilterRuleListResponse, aq as FilterRulePricingTier, av as FilterRulePricingTiersResponse, an as FilterRuleResponse, am as FilterRuleStatus, ap as FilterRuleUpdate, as as FilterRuleValidateResponse, G as GeoClient, l as GeoSearchOptions, H as Hashtag, I as InsufficientCreditsError, g as IteratorOptions, E as List, a4 as ListResponse, L as ListsClient, Y as Location, M as Media, a5 as MonitorStatus, N as NotFoundError, P as PaginatedResponse, f as PaginationOptions, ac as PingEvent, _ as Place, Z as PlaceTrends, s as Poll, r as PollOption, Q as QueryType, b as RateLimitError, R as ResolvedConfig, a as ScrapeBadgerError, c as ServerError, a1 as Space, o as SpacesClient, m as StreamClient, n as StreamEmitter, af as StreamEvent, ag as StreamEventType, a6 as StreamMonitor, a7 as StreamMonitorList, aa as StreamTweet, d as TimeoutError, X as Trend, p as TrendCategory, k as TrendsClient, x as Tweet, ad as TweetEvent, w as TweetPlace, i as TweetsClient, a9 as UpdateMonitorParams, t as Url, y as User, z as UserAbout, D as UserIds, u as UserMention, U as UsersClient, V as ValidationError, W as WebSocketStreamError, h as collectAll, v as verifyWebhookSignature } from './index-Dz6kHfFt.js';
1
+ import { B as BaseClient, T as TwitterClient, S as ScrapeBadgerConfig } from './index-DBk60c2e.js';
2
+ export { e as AccountRestrictedError, a5 as ApiResponse, a1 as Article, A as AuthenticationError, al as BillingLog, am as BillingLogList, a4 as Broadcast, l as CommunitiesClient, X as Community, K as CommunityBanner, Y as CommunityMember, a2 as CommunityNote, O as CommunityRule, s as CommunityTweetType, C as ConflictError, an as ConnectOptions, ad as ConnectedEvent, aa as CreateMonitorParams, aj as DeliveryLog, ak as DeliveryLogList, ag as ErrorEvent, aq as FilterRuleCreate, av as FilterRuleDeliveryLog, aw as FilterRuleDeliveryLogListResponse, at as FilterRuleListResponse, as as FilterRulePricingTier, ax as FilterRulePricingTiersResponse, ap as FilterRuleResponse, ao as FilterRuleStatus, ar as FilterRuleUpdate, au as FilterRuleValidateResponse, G as GeoClient, n as GeoSearchOptions, H as Hashtag, f as IPNotAllowedError, I as InsufficientCreditsError, i as IteratorOptions, J as List, a6 as ListResponse, L as ListsClient, _ as Location, M as Media, a7 as MonitorStatus, N as NotFoundError, g as PaginatedResponse, h as PaginationOptions, P as PermissionDeniedError, ae as PingEvent, a0 as Place, $ as PlaceTrends, u as Poll, t as PollOption, Q as QueryType, b as RateLimitError, R as ResolvedConfig, a as ScrapeBadgerError, c as ServerError, a3 as Space, q as SpacesClient, o as StreamClient, p as StreamEmitter, ah as StreamEvent, ai as StreamEventType, a8 as StreamMonitor, a9 as StreamMonitorList, ac as StreamTweet, d as TimeoutError, Z as Trend, r as TrendCategory, m as TrendsClient, z as Tweet, af as TweetEvent, y as TweetPlace, k as TweetsClient, ab as UpdateMonitorParams, w as Url, D as User, E as UserAbout, F as UserIds, x as UserMention, U as UsersClient, V as ValidationError, W as WebSocketStreamError, j as collectAll, v as verifyWebhookSignature } from './index-DBk60c2e.js';
3
3
  import 'node:events';
4
4
 
5
5
  /**
@@ -1498,11 +1498,25 @@ interface LensSearchParams {
1498
1498
  language?: string;
1499
1499
  gl?: string;
1500
1500
  hl?: string;
1501
- /** Bias towards shoppable product matches. */
1501
+ /**
1502
+ * Return only the tiles Google marked as buyable — those carrying a price
1503
+ * chip and stock status — drawn from the same grid with no extra request.
1504
+ * When the image has no shoppable matches the full grid is returned and
1505
+ * `warnings` says so.
1506
+ */
1502
1507
  product?: boolean;
1503
- /** Include the visual-matches carousel (default: true). */
1508
+ /**
1509
+ * Visual matches are the only surface this endpoint serves, so they are
1510
+ * always returned. `false` is echoed in `warnings`. (default: true)
1511
+ */
1504
1512
  visual_matches?: boolean;
1505
- /** Restrict to exact-match results only. */
1513
+ /**
1514
+ * Return just the pages hosting this image, each flagged `exact_match`,
1515
+ * instead of the broad visual grid — what a copyright or provenance
1516
+ * check needs. Google exposes this set for most images but not all (8 of 10
1517
+ * in our sampling); when it is unavailable the full grid is
1518
+ * returned and `warnings` says the filter was not applied.
1519
+ */
1506
1520
  exact_matches?: boolean;
1507
1521
  }
1508
1522
  /**
@@ -1792,12 +1806,20 @@ declare class JobsClient {
1792
1806
  * parsed from. `related_searches` chips come alongside. Legacy
1793
1807
  * `results` alias retained for backwards compat.
1794
1808
  *
1809
+ * Also carries a `warnings` array naming any parameter that could not be
1810
+ * applied. `exact_matches: true` returns just the pages hosting the image,
1811
+ * flagged `exact_match`, for most images; when Google does not expose that
1812
+ * set the grid comes back and `warnings` says so. `product: true` narrows the same grid to the tiles Google marked
1813
+ * buyable.
1814
+ *
1795
1815
  * @example
1796
1816
  * ```typescript
1797
1817
  * const out = await client.google.lens.search({
1798
1818
  * url: "https://example.com/photo.jpg",
1799
- * product: true, // bias towards shoppable matches
1819
+ * query: "wallpaper", // text refinement — honoured
1800
1820
  * });
1821
+ * // GoogleResponse is Record<string, unknown>, so narrow before use.
1822
+ * console.warn(out.warnings as string[] | undefined);
1801
1823
  * for (const match of out.lens_results) {
1802
1824
  * console.log(match.title, match.price?.value, match.price?.currency);
1803
1825
  * }
package/dist/index.js CHANGED
@@ -26,6 +26,29 @@ var AuthenticationError = class _AuthenticationError extends ScrapeBadgerError {
26
26
  Object.setPrototypeOf(this, _AuthenticationError.prototype);
27
27
  }
28
28
  };
29
+ var PermissionDeniedError = class _PermissionDeniedError extends AuthenticationError {
30
+ /** The API the request needed, e.g. `"twitter"` */
31
+ requiredScope;
32
+ /** The APIs this key may call */
33
+ allowedScopes;
34
+ constructor(message = "This API key is not permitted to call this API.", requiredScope, allowedScopes = []) {
35
+ super(message);
36
+ this.name = "PermissionDeniedError";
37
+ this.requiredScope = requiredScope;
38
+ this.allowedScopes = allowedScopes;
39
+ Object.setPrototypeOf(this, _PermissionDeniedError.prototype);
40
+ }
41
+ };
42
+ var IPNotAllowedError = class _IPNotAllowedError extends PermissionDeniedError {
43
+ /** The address ScrapeBadger saw (null when relayed, e.g. via the hosted MCP server) */
44
+ clientIp;
45
+ constructor(message = "This API key may not be used from this IP address.", clientIp = null) {
46
+ super(message);
47
+ this.name = "IPNotAllowedError";
48
+ this.clientIp = clientIp;
49
+ Object.setPrototypeOf(this, _IPNotAllowedError.prototype);
50
+ }
51
+ };
29
52
  var RateLimitError = class _RateLimitError extends ScrapeBadgerError {
30
53
  /** Unix timestamp when the rate limit resets */
31
54
  retryAfter;
@@ -341,6 +364,16 @@ var BaseClient = class _BaseClient {
341
364
  case 402:
342
365
  throw new InsufficientCreditsError(message, errorData.credits_balance);
343
366
  case 403:
367
+ if (errorData.error === "ip_not_allowed") {
368
+ throw new IPNotAllowedError(message, errorData.client_ip ?? null);
369
+ }
370
+ if (errorData.error === "insufficient_scope") {
371
+ throw new PermissionDeniedError(
372
+ message,
373
+ errorData.required_scope,
374
+ errorData.allowed_scopes ?? []
375
+ );
376
+ }
344
377
  if (message.toLowerCase().includes("restricted")) {
345
378
  throw new AccountRestrictedError(message, errorData.reason);
346
379
  }
@@ -9097,6 +9130,7 @@ exports.GoogleShoppingClient = ShoppingClient;
9097
9130
  exports.GoogleShortsClient = ShortsClient;
9098
9131
  exports.GoogleTrendsClient = TrendsClient2;
9099
9132
  exports.GoogleVideosClient = VideosClient;
9133
+ exports.IPNotAllowedError = IPNotAllowedError;
9100
9134
  exports.ImmobiliareClient = ImmobiliareClient;
9101
9135
  exports.InstagramAudioClient = AudioClient;
9102
9136
  exports.InstagramClient = InstagramClient;
@@ -9119,6 +9153,7 @@ exports.LoopNetListingsClient = ListingsClient2;
9119
9153
  exports.LoopNetReferenceClient = ReferenceClient15;
9120
9154
  exports.LoopNetSearchClient = SearchClient18;
9121
9155
  exports.NotFoundError = NotFoundError;
9156
+ exports.PermissionDeniedError = PermissionDeniedError;
9122
9157
  exports.RateLimitError = RateLimitError;
9123
9158
  exports.RealtorClient = RealtorClient;
9124
9159
  exports.RealtorPropertiesClient = PropertiesClient;