scavio 0.24.0 → 0.25.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 CHANGED
@@ -261,6 +261,33 @@ await client.google.news({ query: "openai" });
261
261
  await client.google.trends({ query: "bitcoin" });
262
262
  ```
263
263
 
264
+ #### Migrating from the Google Custom Search JSON API (new in 0.25.0)
265
+
266
+ `google.customSearch` takes the Custom Search JSON API (`cse.list`) parameters and
267
+ returns the same `customsearch#search` response: `items[]` with `title`, `link`,
268
+ `snippet` and `displayLink`, `searchInformation.totalResults` and
269
+ `queries.nextPage`, so code that parsed Custom Search results keeps working.
270
+ Options are snake_case like the rest of this SDK and are sent as the CSE wire
271
+ names (`site_search` -> `siteSearch`, `date_restrict` -> `dateRestrict`). 1 credit.
272
+
273
+ ```typescript
274
+ const res = await client.google.customSearch({
275
+ q: "abortcontroller fetch timeout",
276
+ num: 5,
277
+ site_search: "stackoverflow.com", // enforced on the returned results
278
+ date_restrict: "y1",
279
+ });
280
+ for (const item of res.items ?? []) console.log(item.displayLink, item.title, item.link);
281
+ const next = res.queries.nextPage?.[0]?.startIndex;
282
+ ```
283
+
284
+ Not using this SDK? Keep your existing Custom Search code and change the host:
285
+ `https://api.scavio.dev/customsearch/v1?key=YOUR_SCAVIO_KEY&q=...`. `cx` is
286
+ accepted and ignored. Parameters that cannot be honoured (image search, `sort`,
287
+ `rights`) throw `BadRequestError` instead of being silently dropped. For the full
288
+ SERP (knowledge graph, AI overview, People Also Ask) use `google.search`.
289
+ [Docs](https://scavio.dev/docs/google-custom-search-api?utm_source=npm-scavio-js&utm_medium=package&utm_campaign=readme)
290
+
264
291
  ### Amazon
265
292
 
266
293
  Responses are normalized to a stable shape (see the breaking-change note
package/dist/index.cjs CHANGED
@@ -232,7 +232,7 @@ function parseRetryAfter(header) {
232
232
  var BASE_URL = "https://api.scavio.dev";
233
233
  var DEFAULT_TIMEOUT = 3e4;
234
234
  var DEFAULT_MAX_RETRIES = 2;
235
- var SDK_VERSION = true ? "0.24.0" : "0.0.0";
235
+ var SDK_VERSION = true ? "0.25.0" : "0.0.0";
236
236
  var USER_AGENT = `scavio-js/${SDK_VERSION}`;
237
237
  function isServerRuntime() {
238
238
  const g = globalThis;
@@ -421,6 +421,15 @@ var AmazonNamespace = class {
421
421
  };
422
422
 
423
423
  // src/namespaces/google.ts
424
+ var CUSTOM_SEARCH_WIRE = {
425
+ date_restrict: "dateRestrict",
426
+ site_search: "siteSearch",
427
+ site_search_filter: "siteSearchFilter",
428
+ exact_terms: "exactTerms",
429
+ exclude_terms: "excludeTerms",
430
+ or_terms: "orTerms",
431
+ file_type: "fileType"
432
+ };
424
433
  var GoogleNamespace = class {
425
434
  constructor(client) {
426
435
  this.client = client;
@@ -430,6 +439,21 @@ var GoogleNamespace = class {
430
439
  async search(options) {
431
440
  return this.client._post("/api/v2/google", options);
432
441
  }
442
+ /**
443
+ * Google search in the Custom Search JSON API format: a drop-in for cse.list.
444
+ * Returns customsearch#search (items[], searchInformation, queries.nextPage)
445
+ * plus a scavio billing object, so CSE parsing code keeps working. For the
446
+ * full SERP (knowledge graph, AI overview, People Also Ask) use search().
447
+ * Unsupported CSE params (image search, sort, rights) throw BadRequestError.
448
+ * 1 credit.
449
+ */
450
+ async customSearch(options) {
451
+ const body = {};
452
+ for (const [key, value] of Object.entries(options)) {
453
+ body[CUSTOM_SEARCH_WIRE[key] ?? key] = value;
454
+ }
455
+ return await this.client._post("/api/v1/google/customsearch", body);
456
+ }
433
457
  /** Google AI Mode answer. */
434
458
  async aiMode(options) {
435
459
  return this.client._post("/api/v2/google/ai-mode", options);
@@ -1192,14 +1216,14 @@ var LinkedInNamespace = class {
1192
1216
  return this.client._post("/api/v1/linkedin/post/comments", options);
1193
1217
  }
1194
1218
  /**
1195
- * @deprecated Retired by the upstream provider. Always returns HTTP 410 and is
1219
+ * @deprecated Retired. Always returns HTTP 410 and is
1196
1220
  * never billed.
1197
1221
  */
1198
1222
  async personContact(options) {
1199
1223
  return this.client._post("/api/v1/linkedin/person/contact", options);
1200
1224
  }
1201
1225
  /**
1202
- * @deprecated Retired by the upstream provider. Always returns HTTP 410 and is
1226
+ * @deprecated Retired. Always returns HTTP 410 and is
1203
1227
  * never billed. `company()` returns `featured_employees`, a small sample of
1204
1228
  * staff profiles.
1205
1229
  */
@@ -1207,21 +1231,21 @@ var LinkedInNamespace = class {
1207
1231
  return this.client._post("/api/v1/linkedin/company/people", options);
1208
1232
  }
1209
1233
  /**
1210
- * @deprecated Retired by the upstream provider. Always returns HTTP 410 and is
1234
+ * @deprecated Retired. Always returns HTTP 410 and is
1211
1235
  * never billed. Use `searchJobs()` with the company name as the search term.
1212
1236
  */
1213
1237
  async companyJobs(options) {
1214
1238
  return this.client._post("/api/v1/linkedin/company/jobs", options);
1215
1239
  }
1216
1240
  /**
1217
- * @deprecated Retired by the upstream provider. Always returns HTTP 410 and is
1241
+ * @deprecated Retired. Always returns HTTP 410 and is
1218
1242
  * never billed.
1219
1243
  */
1220
1244
  async searchPeople(options) {
1221
1245
  return this.client._post("/api/v1/linkedin/search/people", options);
1222
1246
  }
1223
1247
  /**
1224
- * @deprecated Retired by the upstream provider. Always returns HTTP 410 and is
1248
+ * @deprecated Retired. Always returns HTTP 410 and is
1225
1249
  * never billed.
1226
1250
  */
1227
1251
  async searchPosts(options) {
@@ -1481,7 +1505,7 @@ var TargetNamespace = class {
1481
1505
  * Paged with `page` + `count` (1-28, default 24). `seller_id` and
1482
1506
  * `seller_name` are null on first-party rows, which means "sold by Target".
1483
1507
  *
1484
- * Costs 1 credit. Typically ~9s - it runs through a headless browser.
1508
+ * Costs 1 credit. Typically ~9s.
1485
1509
  */
1486
1510
  async search(options) {
1487
1511
  return this.client._post("/api/v1/target/search", options);
@@ -1647,9 +1671,8 @@ var RedfinNamespace = class {
1647
1671
  * houses, schools, climate risk, walkability and location scores, sun
1648
1672
  * exposure, monthly weather, permits, zoning, comparable sales and photos.
1649
1673
  *
1650
- * Reads the property PAGE, whose inlined request cache replaces the ~40
1651
- * upstream calls that page made - which is why it is the same price as
1652
- * search().
1674
+ * Returns the whole property page in one call, which is why it is the same
1675
+ * price as search().
1653
1676
  *
1654
1677
  * Costs 1 credit. Single response, no pagination.
1655
1678
  */
@@ -1879,7 +1902,7 @@ var YelpNamespace = class {
1879
1902
  * count.
1880
1903
  *
1881
1904
  * `term` + `location` or `url` is required, and `location` is effectively
1882
- * mandatory - Yelp geolocates a location-less search off the proxy exit.
1905
+ * mandatory - without it Yelp picks a location itself.
1883
1906
  * Paged with `page`; the page size is fixed at 10.
1884
1907
  *
1885
1908
  * Costs 2 credits.
@@ -1951,8 +1974,7 @@ var IndeedNamespace = class {
1951
1974
  * employment types, benefits, geocoded address, employer rating, applicant
1952
1975
  * count and the original ATS link.
1953
1976
  *
1954
- * Single response, no pagination. An unknown job key is a real 404 that
1955
- * scrape.do BILLS - take `job_id` from a search row.
1977
+ * Single response, no pagination. An unknown job key is a real 404 and IS BILLED - take `job_id` from a search row.
1956
1978
  *
1957
1979
  * Costs 2 credits.
1958
1980
  */
@@ -1964,8 +1986,7 @@ var IndeedNamespace = class {
1964
1986
  * approval, overall and per-category ratings, reported salaries, open roles
1965
1987
  * and locations.
1966
1988
  *
1967
- * Single response, no pagination. An unknown company slug is a real 404
1968
- * that scrape.do BILLS.
1989
+ * Single response, no pagination. An unknown company slug is a real 404 and IS BILLED.
1969
1990
  *
1970
1991
  * Costs 2 credits.
1971
1992
  */
@@ -2013,7 +2034,7 @@ var GlassdoorNamespace = class {
2013
2034
  * server-rendered reviews, AND reviews_url / salaries_url.
2014
2035
  *
2015
2036
  * THE CHAINING ENDPOINT: pass reviews_url / salaries_url back as `url` on
2016
- * reviews() and salaries() to halve the upstream fetches. `employer_id` or
2037
+ * reviews() and salaries() to halve the lookups. `employer_id` or
2017
2038
  * `url` is required - `company` is cosmetic and does not satisfy it.
2018
2039
  *
2019
2040
  * Costs 1 credit. Single response, no pagination. Typically ~3-47s.
@@ -2337,7 +2358,7 @@ var SECNamespace = class {
2337
2358
  * filer had more.
2338
2359
  *
2339
2360
  * Costs 1 credit - including with `include_history`, which is the one call
2340
- * that can buy more than one upstream fetch.
2361
+ * that can buy more than one lookup.
2341
2362
  */
2342
2363
  async filings(options) {
2343
2364
  return this.client._post("/api/v1/sec/filings", options);