thordata-js-sdk 0.2.0 → 0.3.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.
Files changed (51) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +235 -123
  3. package/dist/examples/basic_serp.js +3 -3
  4. package/dist/examples/basic_serp.js.map +1 -1
  5. package/dist/examples/location_api.js +47 -0
  6. package/dist/examples/location_api.js.map +1 -0
  7. package/dist/examples/proxy_datacenter.js +1 -1
  8. package/dist/examples/proxy_datacenter.js.map +1 -1
  9. package/dist/examples/proxy_isp.js +1 -1
  10. package/dist/examples/proxy_isp.js.map +1 -1
  11. package/dist/examples/proxy_mobile.js +1 -1
  12. package/dist/examples/proxy_mobile.js.map +1 -1
  13. package/dist/examples/proxy_residential.js +2 -2
  14. package/dist/examples/proxy_residential.js.map +1 -1
  15. package/dist/examples/serp_google_news.d.ts +0 -6
  16. package/dist/examples/serp_google_news.js +7 -10
  17. package/dist/examples/serp_google_news.js.map +1 -1
  18. package/dist/src/client.d.ts +110 -6
  19. package/dist/src/client.js +185 -42
  20. package/dist/src/client.js.map +1 -1
  21. package/dist/src/enums.d.ts +221 -3
  22. package/dist/src/enums.js +291 -2
  23. package/dist/src/enums.js.map +1 -1
  24. package/dist/src/errors.d.ts +37 -5
  25. package/dist/src/errors.js +61 -17
  26. package/dist/src/errors.js.map +1 -1
  27. package/dist/src/index.d.ts +7 -5
  28. package/dist/src/index.js +21 -5
  29. package/dist/src/index.js.map +1 -1
  30. package/dist/src/models.d.ts +137 -12
  31. package/dist/src/models.js +1 -0
  32. package/dist/src/models.js.map +1 -1
  33. package/dist/src/proxy.d.ts +59 -0
  34. package/dist/src/proxy.js +83 -11
  35. package/dist/src/proxy.js.map +1 -1
  36. package/dist/src/retry.d.ts +25 -3
  37. package/dist/src/retry.js +16 -0
  38. package/dist/src/retry.js.map +1 -1
  39. package/dist/src/thordata.d.ts +5 -2
  40. package/dist/src/thordata.js +36 -6
  41. package/dist/src/thordata.js.map +1 -1
  42. package/dist/src/utils.d.ts +18 -8
  43. package/dist/src/utils.js +58 -34
  44. package/dist/src/utils.js.map +1 -1
  45. package/package.json +5 -6
  46. package/dist/examples/proxy_demo.js +0 -69
  47. package/dist/examples/proxy_demo.js.map +0 -1
  48. package/dist/examples/proxy_ip_check.d.ts +0 -1
  49. package/dist/examples/proxy_ip_check.js +0 -37
  50. package/dist/examples/proxy_ip_check.js.map +0 -1
  51. /package/dist/examples/{proxy_demo.d.ts → location_api.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location_api.js","sourceRoot":"","sources":["../../examples/location_api.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAE9B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAEnC,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,CAAC,MAAM,YAAY,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CACT,eAAe,SAAS;SACrB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;SAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IAEF,qBAAqB;IACrB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CACT,eAAe,MAAM;SAClB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IAEF,6BAA6B;IAC7B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CACT,eAAe,MAAM;SAClB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SACvB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IAEF,mBAAmB;IACnB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CACT,eAAe,IAAI;SAChB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;SAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -11,7 +11,7 @@ async function main() {
11
11
  const testUrl = "http://httpbin.org/ip";
12
12
  console.log("Datacenter Proxy Demo\n");
13
13
  const proxy = Thordata.Proxy.datacenterFromEnv();
14
- const result = await client.request(testUrl, { proxy });
14
+ const result = (await client.request(testUrl, { proxy }));
15
15
  console.log("Datacenter IP:", result.origin);
16
16
  }
17
17
  main().catch(console.error);
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_datacenter.js","sourceRoot":"","sources":["../../examples/proxy_datacenter.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;QACzF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"proxy_datacenter.js","sourceRoot":"","sources":["../../examples/proxy_datacenter.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAM9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;QACzF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAoB,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -13,7 +13,7 @@ async function main() {
13
13
  const testUrl = "http://httpbin.org/ip";
14
14
  console.log("Static ISP Proxy Demo\n");
15
15
  const proxy = Thordata.Proxy.ispFromEnv();
16
- const result = await client.request(testUrl, { proxy });
16
+ const result = (await client.request(testUrl, { proxy }));
17
17
  console.log("Static ISP IP:", result.origin);
18
18
  console.log("Expected IP :", process.env.THORDATA_ISP_HOST);
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_isp.js","sourceRoot":"","sources":["../../examples/proxy_isp.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,IACE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC9B,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAClC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAClC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;QAC/F,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC/D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"proxy_isp.js","sourceRoot":"","sources":["../../examples/proxy_isp.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAExB,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAM9C,KAAK,UAAU,IAAI;IACjB,IACE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC9B,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAClC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAClC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;QAC/F,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAoB,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC/D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -11,7 +11,7 @@ async function main() {
11
11
  const testUrl = "http://httpbin.org/ip";
12
12
  console.log("Mobile Proxy Demo\n");
13
13
  const proxy = Thordata.Proxy.mobileFromEnv().country("gb");
14
- const result = await client.request(testUrl, { proxy });
14
+ const result = (await client.request(testUrl, { proxy }));
15
15
  console.log("UK Mobile IP:", result.origin);
16
16
  }
17
17
  main().catch(console.error);
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_mobile.js","sourceRoot":"","sources":["../../examples/proxy_mobile.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"proxy_mobile.js","sourceRoot":"","sources":["../../examples/proxy_mobile.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAM9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAoB,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -12,7 +12,7 @@ async function main() {
12
12
  console.log("Residential Proxy Demo\n");
13
13
  // Basic usage
14
14
  const proxy1 = Thordata.Proxy.residentialFromEnv().country("us");
15
- const r1 = await client.request(testUrl, { proxy: proxy1 });
15
+ const r1 = (await client.request(testUrl, { proxy: proxy1 }));
16
16
  console.log("US Residential IP:", r1.origin);
17
17
  // With sticky session
18
18
  const proxy2 = Thordata.Proxy.residentialFromEnv()
@@ -20,7 +20,7 @@ async function main() {
20
20
  .city("tokyo")
21
21
  .session("my_session")
22
22
  .sticky(30);
23
- const r2 = await client.request(testUrl, { proxy: proxy2 });
23
+ const r2 = (await client.request(testUrl, { proxy: proxy2 }));
24
24
  console.log("Tokyo Sticky IP :", r2.origin);
25
25
  }
26
26
  main().catch(console.error);
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_residential.js","sourceRoot":"","sources":["../../examples/proxy_residential.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;QAC3F,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,cAAc;IACd,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAE7C,sBAAsB;IACtB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,EAAE;SAC/C,OAAO,CAAC,IAAI,CAAC;SACb,IAAI,CAAC,OAAO,CAAC;SACb,OAAO,CAAC,YAAY,CAAC;SACrB,MAAM,CAAC,EAAE,CAAC,CAAC;IACd,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"proxy_residential.js","sourceRoot":"","sources":["../../examples/proxy_residential.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAM9C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;QAC3F,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,cAAc;IACd,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAoB,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAE7C,sBAAsB;IACtB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,EAAE;SAC/C,OAAO,CAAC,IAAI,CAAC;SACb,IAAI,CAAC,OAAO,CAAC;SACb,OAAO,CAAC,YAAY,CAAC;SACrB,MAAM,CAAC,EAAE,CAAC,CAAC;IACd,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAoB,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -1,7 +1 @@
1
- /**
2
- * SERP Google News Demo
3
- *
4
- * Usage:
5
- * npx ts-node examples/serp_google_news.ts
6
- */
7
1
  import "dotenv/config";
@@ -1,9 +1,4 @@
1
- /**
2
- * SERP Google News Demo
3
- *
4
- * Usage:
5
- * npx ts-node examples/serp_google_news.ts
6
- */
1
+ // examples/serp_google_news.ts
7
2
  import "dotenv/config";
8
3
  import { ThordataClient, Engine } from "../src/index.js";
9
4
  async function main() {
@@ -29,7 +24,8 @@ async function main() {
29
24
  printNewsResults(results);
30
25
  }
31
26
  catch (e) {
32
- console.error("❌ Search failed:", e.message);
27
+ const error = e;
28
+ console.error("❌ Search failed:", error.message);
33
29
  }
34
30
  // 2. Advanced News Filters
35
31
  console.log("\n📰 2. Advanced Filters (Sort by Date)");
@@ -40,16 +36,17 @@ async function main() {
40
36
  country: "us",
41
37
  language: "en",
42
38
  num: 5,
43
- so: 1, // Sort by date
39
+ so: 1,
44
40
  });
45
41
  printNewsResults(results);
46
42
  }
47
43
  catch (e) {
48
- console.error("❌ Advanced search failed:", e.message);
44
+ const error = e;
45
+ console.error("❌ Advanced search failed:", error.message);
49
46
  }
50
47
  }
51
48
  function printNewsResults(results) {
52
- const news = results?.news ?? [];
49
+ const news = (results?.news ?? []);
53
50
  console.log(`✅ Found ${news.length} news items:`);
54
51
  news.slice(0, 5).forEach((item) => {
55
52
  console.log(` ${item.rank}. [${item.source}] ${item.title}`);
@@ -1 +1 @@
1
- {"version":3,"file":"serp_google_news.js","sourceRoot":"","sources":["../../examples/serp_google_news.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,CAAC;KACd,CAAC,CAAC;IAEH,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACtC,KAAK,EAAE,eAAe;YACtB,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,CAAC;SACP,CAAC,CAAC;QACH,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACtC,KAAK,EAAE,yBAAyB;YAChC,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,CAAC;YACN,EAAE,EAAE,CAAC,EAAE,eAAe;SACvB,CAAC,CAAC;QACH,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAY;IACpC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC;IAElD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAS,EAAE,EAAE;QACrC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"serp_google_news.js","sourceRoot":"","sources":["../../examples/serp_google_news.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,CAAC;KACd,CAAC,CAAC;IAEH,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACtC,KAAK,EAAE,eAAe;YACtB,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,CAAC;SACP,CAAC,CAAC;QACH,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,CAAU,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACtC,KAAK,EAAE,yBAAyB;YAChC,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,CAAC;YACN,EAAE,EAAE,CAAC;SACN,CAAC,CAAC;QACH,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,CAAU,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAUD,SAAS,gBAAgB,CAAC,OAAgC;IACxD,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAe,CAAC;IAEjD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC;IAElD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
@@ -1,15 +1,33 @@
1
- import { SerpOptions, UniversalOptions, ScraperTaskOptions, WaitForTaskOptions } from "./models.js";
1
+ import { SerpOptions, UniversalOptions, ScraperTaskOptions, WaitForTaskOptions, ProxyTypeParam, CountryInfo, StateInfo, CityInfo, AsnInfo } from "./models.js";
2
2
  import { type ThordataBaseUrls } from "./endpoints.js";
3
3
  import { Proxy } from "./proxy.js";
4
+ /**
5
+ * Configuration options for ThordataClient.
6
+ */
4
7
  export interface ThordataClientConfig {
8
+ /** API token for SERP and Universal APIs */
5
9
  scraperToken: string;
10
+ /** Public token for Web Scraper API and Location API */
6
11
  publicToken?: string;
12
+ /** Public key for Web Scraper API and Location API */
7
13
  publicKey?: string;
14
+ /** Request timeout in milliseconds (default: 30000) */
8
15
  timeoutMs?: number;
16
+ /** Maximum number of retries on failure (default: 0) */
9
17
  maxRetries?: number;
18
+ /** Custom base URLs for API endpoints */
10
19
  baseUrls?: Partial<ThordataBaseUrls>;
20
+ /** Custom User-Agent string */
11
21
  userAgent?: string;
22
+ /**
23
+ * Whether to verify SSL certificates (default: true).
24
+ * Set to false only for testing with self-signed certificates.
25
+ */
26
+ verifySsl?: boolean;
12
27
  }
28
+ /**
29
+ * Main client for interacting with Thordata APIs.
30
+ */
13
31
  export declare class ThordataClient {
14
32
  private scraperToken;
15
33
  private publicToken?;
@@ -26,19 +44,105 @@ export declare class ThordataClient {
26
44
  private scraperDownloadUrl;
27
45
  constructor(config: ThordataClientConfig);
28
46
  /**
29
- * Internal helper to execute request with retry logic
47
+ * Execute request with retry logic.
30
48
  */
31
49
  private execute;
32
- serpSearch(options: SerpOptions): Promise<any>;
33
- universalScrape(options: UniversalOptions): Promise<string | Buffer>;
50
+ /**
51
+ * Perform a search using the SERP API.
52
+ *
53
+ * Supported engines: google, bing, yandex, duckduckgo
54
+ * Plus Google specialized engines: google_news, google_shopping, etc.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Basic Google search
59
+ * const results = await client.serpSearch({
60
+ * query: "pizza",
61
+ * engine: Engine.GOOGLE,
62
+ * country: "us",
63
+ * });
64
+ *
65
+ * // Google News (recommended: use dedicated engine)
66
+ * const news = await client.serpSearch({
67
+ * query: "AI regulation",
68
+ * engine: Engine.GOOGLE_NEWS,
69
+ * });
70
+ * ```
71
+ */
72
+ serpSearch(options: SerpOptions): Promise<Record<string, unknown>>;
73
+ /**
74
+ * Scrape a URL using the Universal/Web Unlocker API.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * // Basic HTML scraping
79
+ * const html = await client.universalScrape({
80
+ * url: "https://example.com",
81
+ * jsRender: false,
82
+ * });
83
+ *
84
+ * // With JS rendering and wait for element
85
+ * const html = await client.universalScrape({
86
+ * url: "https://example.com/spa",
87
+ * jsRender: true,
88
+ * waitFor: ".main-content",
89
+ * });
90
+ *
91
+ * // Screenshot
92
+ * const png = await client.universalScrape({
93
+ * url: "https://example.com",
94
+ * jsRender: true,
95
+ * outputFormat: "png",
96
+ * });
97
+ * ```
98
+ */
99
+ universalScrape(options: UniversalOptions): Promise<string | Buffer | Record<string, unknown>>;
100
+ /**
101
+ * Create a new Web Scraper task.
102
+ */
34
103
  createScraperTask(options: ScraperTaskOptions): Promise<string>;
104
+ /**
105
+ * Verify that public credentials are available.
106
+ */
35
107
  private requirePublicCreds;
108
+ /**
109
+ * Get the status of a Web Scraper task.
110
+ */
36
111
  getTaskStatus(taskId: string): Promise<string>;
112
+ /**
113
+ * Get the download URL for a completed task's results.
114
+ */
37
115
  getTaskResult(taskId: string, fileType?: "json" | "csv" | "xlsx"): Promise<string>;
116
+ /**
117
+ * Wait for a task to complete.
118
+ */
38
119
  waitForTask(taskId: string, options?: WaitForTaskOptions): Promise<string>;
120
+ /**
121
+ * Make an HTTP request through a proxy.
122
+ */
39
123
  request(url: string, config?: {
40
124
  proxy?: Proxy;
41
125
  timeout?: number;
42
- [key: string]: any;
43
- }): Promise<any>;
126
+ [key: string]: unknown;
127
+ }): Promise<unknown>;
128
+ /**
129
+ * Internal method to call locations API.
130
+ */
131
+ private getLocations;
132
+ /**
133
+ * List all supported countries for a proxy type.
134
+ */
135
+ listCountries(proxyType?: ProxyTypeParam): Promise<CountryInfo[]>;
136
+ /**
137
+ * List states/regions for a country.
138
+ */
139
+ listStates(countryCode: string, proxyType?: ProxyTypeParam): Promise<StateInfo[]>;
140
+ /**
141
+ * List cities for a country (and optionally state).
142
+ */
143
+ listCities(countryCode: string, stateCode?: string, proxyType?: ProxyTypeParam): Promise<CityInfo[]>;
144
+ /**
145
+ * List ASNs for a country.
146
+ */
147
+ listAsns(countryCode: string, proxyType?: ProxyTypeParam): Promise<AsnInfo[]>;
44
148
  }
@@ -2,11 +2,22 @@
2
2
  import axios from "axios";
3
3
  import https from "node:https";
4
4
  import { Engine, TaskStatus } from "./enums.js";
5
- import { ThordataError, ThordataTimeoutError } from "./errors.js";
6
- import { buildAuthHeaders, buildPublicHeaders, handleAxiosError, toFormBody, raiseForCode, safeParseJson, withRetry, } from "./utils.js";
5
+ import { ThordataError, ThordataTimeoutError, ThordataConfigError } from "./errors.js";
6
+ import { buildAuthHeaders, buildPublicHeaders, handleAxiosError, toFormBody, raiseForCode, safeParseJson, withRetry, buildUserAgent, } from "./utils.js";
7
7
  import { resolveBaseUrls } from "./endpoints.js";
8
- import { buildUserAgent } from "./utils.js";
9
8
  import { Proxy } from "./proxy.js";
9
+ /**
10
+ * Normalize proxy type parameter to numeric value.
11
+ */
12
+ function normalizeProxyType(proxyType) {
13
+ if (typeof proxyType === "number") {
14
+ return proxyType;
15
+ }
16
+ return proxyType === "residential" ? 1 : 2;
17
+ }
18
+ /**
19
+ * Main client for interacting with Thordata APIs.
20
+ */
10
21
  export class ThordataClient {
11
22
  scraperToken;
12
23
  publicToken;
@@ -23,15 +34,17 @@ export class ThordataClient {
23
34
  scraperDownloadUrl;
24
35
  constructor(config) {
25
36
  if (!config.scraperToken) {
26
- throw new ThordataError("scraperToken is required");
37
+ throw new ThordataConfigError("scraperToken is required");
27
38
  }
28
39
  this.scraperToken = config.scraperToken;
29
40
  this.publicToken = config.publicToken;
30
41
  this.publicKey = config.publicKey;
31
42
  this.timeoutMs = config.timeoutMs ?? 30000;
32
- this.maxRetries = config.maxRetries ?? 0; // Default: no retry
43
+ this.maxRetries = config.maxRetries ?? 0;
44
+ const verifySsl = config.verifySsl ?? true;
33
45
  this.http = axios.create({
34
46
  timeout: this.timeoutMs,
47
+ httpsAgent: new https.Agent({ rejectUnauthorized: verifySsl }),
35
48
  });
36
49
  this.baseUrls = resolveBaseUrls(process.env, config.baseUrls);
37
50
  this.serpUrl = `${this.baseUrls.scraperapiBaseUrl}/request`;
@@ -39,16 +52,12 @@ export class ThordataClient {
39
52
  this.universalUrl = `${this.baseUrls.universalapiBaseUrl}/request`;
40
53
  this.scraperStatusUrl = `${this.baseUrls.webScraperApiBaseUrl}/tasks-status`;
41
54
  this.scraperDownloadUrl = `${this.baseUrls.webScraperApiBaseUrl}/tasks-download`;
42
- this.userAgent =
43
- config.userAgent ??
44
- buildUserAgent(
45
- // fallback: avoid relying on npm_package_version in runtime
46
- process.env.npm_package_version || "0.0.0");
47
- // Set default headers for all requests
55
+ const pkgVersion = process.env.npm_package_version || "0.0.0";
56
+ this.userAgent = config.userAgent ?? buildUserAgent(pkgVersion);
48
57
  this.http.defaults.headers.common["User-Agent"] = this.userAgent;
49
58
  }
50
59
  /**
51
- * Internal helper to execute request with retry logic
60
+ * Execute request with retry logic.
52
61
  */
53
62
  async execute(requestFn) {
54
63
  return withRetry(async () => {
@@ -63,16 +72,39 @@ export class ThordataClient {
63
72
  // --------------------------
64
73
  // 1) SERP API
65
74
  // --------------------------
75
+ /**
76
+ * Perform a search using the SERP API.
77
+ *
78
+ * Supported engines: google, bing, yandex, duckduckgo
79
+ * Plus Google specialized engines: google_news, google_shopping, etc.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // Basic Google search
84
+ * const results = await client.serpSearch({
85
+ * query: "pizza",
86
+ * engine: Engine.GOOGLE,
87
+ * country: "us",
88
+ * });
89
+ *
90
+ * // Google News (recommended: use dedicated engine)
91
+ * const news = await client.serpSearch({
92
+ * query: "AI regulation",
93
+ * engine: Engine.GOOGLE_NEWS,
94
+ * });
95
+ * ```
96
+ */
66
97
  async serpSearch(options) {
67
98
  const { query, engine = Engine.GOOGLE, num, start, country, language, searchType, device, renderJs, noCache, outputFormat = "json", ...extra } = options;
68
99
  if (!query) {
69
- throw new ThordataError("query is required for serpSearch");
100
+ throw new ThordataConfigError("query is required for serpSearch");
70
101
  }
71
102
  const engineStr = String(engine).toLowerCase();
72
103
  const payload = {
73
104
  engine: engineStr,
74
105
  json: outputFormat.toLowerCase() === "html" ? "0" : "1",
75
106
  };
107
+ // Yandex uses 'text' instead of 'q'
76
108
  if (engineStr === "yandex") {
77
109
  payload.text = query;
78
110
  }
@@ -87,15 +119,9 @@ export class ThordataClient {
87
119
  payload.gl = country.toLowerCase();
88
120
  if (language)
89
121
  payload.hl = language.toLowerCase();
122
+ // tbm parameter (only for specific Google engines)
90
123
  if (searchType) {
91
- const st = searchType.toLowerCase();
92
- const tbmMap = {
93
- images: "isch",
94
- shopping: "shop",
95
- news: "nws",
96
- videos: "vid",
97
- };
98
- payload.tbm = tbmMap[st] ?? st;
124
+ payload.tbm = searchType.toLowerCase();
99
125
  }
100
126
  if (device)
101
127
  payload.device = device.toLowerCase();
@@ -126,15 +152,46 @@ export class ThordataClient {
126
152
  // --------------------------
127
153
  // 2) Universal / Web Unlocker
128
154
  // --------------------------
155
+ /**
156
+ * Scrape a URL using the Universal/Web Unlocker API.
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * // Basic HTML scraping
161
+ * const html = await client.universalScrape({
162
+ * url: "https://example.com",
163
+ * jsRender: false,
164
+ * });
165
+ *
166
+ * // With JS rendering and wait for element
167
+ * const html = await client.universalScrape({
168
+ * url: "https://example.com/spa",
169
+ * jsRender: true,
170
+ * waitFor: ".main-content",
171
+ * });
172
+ *
173
+ * // Screenshot
174
+ * const png = await client.universalScrape({
175
+ * url: "https://example.com",
176
+ * jsRender: true,
177
+ * outputFormat: "png",
178
+ * });
179
+ * ```
180
+ */
129
181
  async universalScrape(options) {
130
182
  const { url, jsRender = false, outputFormat = "html", country, blockResources, cleanContent, wait, waitFor, headers: customHeaders, cookies, ...extra } = options;
131
183
  if (!url) {
132
- throw new ThordataError("url is required for universalScrape");
184
+ throw new ThordataConfigError("url is required for universalScrape");
185
+ }
186
+ const format = String(outputFormat).toLowerCase();
187
+ // Validate output format
188
+ if (format !== "html" && format !== "png") {
189
+ throw new ThordataConfigError(`Invalid outputFormat: "${outputFormat}". Supported values: "html", "png"`);
133
190
  }
134
191
  const payload = {
135
192
  url,
136
193
  js_render: jsRender ? "True" : "False",
137
- type: outputFormat.toLowerCase(),
194
+ type: format,
138
195
  };
139
196
  if (country)
140
197
  payload.country = country.toLowerCase();
@@ -146,27 +203,30 @@ export class ThordataClient {
146
203
  payload.wait = String(wait);
147
204
  if (waitFor)
148
205
  payload.wait_for = waitFor;
149
- if (customHeaders && customHeaders.length > 0)
206
+ if (customHeaders && customHeaders.length > 0) {
150
207
  payload.headers = JSON.stringify(customHeaders);
151
- if (cookies && cookies.length > 0)
208
+ }
209
+ if (cookies && cookies.length > 0) {
152
210
  payload.cookies = JSON.stringify(cookies);
211
+ }
153
212
  Object.assign(payload, extra);
154
213
  const headers = buildAuthHeaders(this.scraperToken);
155
214
  return this.execute(async () => {
156
215
  const res = await this.http.post(this.universalUrl, toFormBody(payload), {
157
216
  headers,
158
- responseType: outputFormat.toLowerCase() === "png" ? "arraybuffer" : "json",
217
+ responseType: format === "png" ? "arraybuffer" : "json",
159
218
  });
160
- if (outputFormat.toLowerCase() === "png") {
219
+ if (format === "png") {
161
220
  return Buffer.from(res.data);
162
221
  }
163
222
  const data = safeParseJson(res.data);
164
- if (data && typeof data === "object" && "code" in data && data.code !== 200) {
165
- raiseForCode("Universal API error", data, res.status);
166
- }
167
- if (outputFormat.toLowerCase() === "json") {
168
- return data;
223
+ if (data && typeof data === "object" && "code" in data) {
224
+ const dataObj = data;
225
+ if (dataObj.code !== 200) {
226
+ raiseForCode("Universal API error", dataObj, res.status);
227
+ }
169
228
  }
229
+ // Return HTML string
170
230
  if (data && typeof data === "object" && "html" in data) {
171
231
  return data.html;
172
232
  }
@@ -176,6 +236,9 @@ export class ThordataClient {
176
236
  // --------------------------
177
237
  // 3) Web Scraper API
178
238
  // --------------------------
239
+ /**
240
+ * Create a new Web Scraper task.
241
+ */
179
242
  async createScraperTask(options) {
180
243
  const { fileName, spiderId, spiderName, parameters, universalParams, includeErrors = true, } = options;
181
244
  const payload = {
@@ -205,11 +268,17 @@ export class ThordataClient {
205
268
  return String(taskId);
206
269
  });
207
270
  }
271
+ /**
272
+ * Verify that public credentials are available.
273
+ */
208
274
  requirePublicCreds() {
209
275
  if (!this.publicToken || !this.publicKey) {
210
- throw new ThordataError("publicToken and publicKey are required for Web Scraper public API calls");
276
+ throw new ThordataConfigError("publicToken and publicKey are required for Web Scraper public API calls");
211
277
  }
212
278
  }
279
+ /**
280
+ * Get the status of a Web Scraper task.
281
+ */
213
282
  async getTaskStatus(taskId) {
214
283
  this.requirePublicCreds();
215
284
  const headers = buildPublicHeaders(this.publicToken, this.publicKey);
@@ -227,6 +296,9 @@ export class ThordataClient {
227
296
  return TaskStatus.UNKNOWN;
228
297
  });
229
298
  }
299
+ /**
300
+ * Get the download URL for a completed task's results.
301
+ */
230
302
  async getTaskResult(taskId, fileType = "json") {
231
303
  this.requirePublicCreds();
232
304
  const headers = buildPublicHeaders(this.publicToken, this.publicKey);
@@ -234,13 +306,16 @@ export class ThordataClient {
234
306
  return this.execute(async () => {
235
307
  const res = await this.http.post(this.scraperDownloadUrl, toFormBody(payload), { headers });
236
308
  const data = safeParseJson(res.data);
237
- if (data?.code === 200 && data?.data?.download) {
238
- return data.data.download;
309
+ const dataObj = data?.data;
310
+ if (data?.code === 200 && dataObj?.download) {
311
+ return dataObj.download;
239
312
  }
240
313
  raiseForCode("Get task result failed", data, res.status);
241
- return ""; // unreachable
242
314
  });
243
315
  }
316
+ /**
317
+ * Wait for a task to complete.
318
+ */
244
319
  async waitForTask(taskId, options = {}) {
245
320
  const pollIntervalMs = options.pollIntervalMs ?? 5000;
246
321
  const maxWaitMs = options.maxWaitMs ?? 10 * 60 * 1000;
@@ -265,22 +340,90 @@ export class ThordataClient {
265
340
  // --------------------------
266
341
  // 4) Proxy Network
267
342
  // --------------------------
343
+ /**
344
+ * Make an HTTP request through a proxy.
345
+ */
268
346
  async request(url, config = {}) {
269
347
  if (!url) {
270
- throw new ThordataError("url is required for request");
348
+ throw new ThordataConfigError("url is required for request");
271
349
  }
350
+ const { proxy, timeout, ...rest } = config;
272
351
  const axiosConfig = {
273
- ...config,
274
- timeout: config.timeout ?? this.timeoutMs,
275
- httpsAgent: new https.Agent({ rejectUnauthorized: false }),
352
+ ...rest,
353
+ timeout: timeout ?? this.timeoutMs,
276
354
  };
277
- if (config.proxy instanceof Proxy) {
278
- axiosConfig.proxy = config.proxy.toAxiosConfig();
355
+ if (proxy instanceof Proxy) {
356
+ axiosConfig.proxy = proxy.toAxiosConfig();
279
357
  }
280
358
  return this.execute(async () => {
281
359
  const res = await this.http.get(url, axiosConfig);
282
360
  return res.data;
283
361
  });
284
362
  }
363
+ // --------------------------
364
+ // 5) Location API
365
+ // --------------------------
366
+ /**
367
+ * Internal method to call locations API.
368
+ */
369
+ async getLocations(endpoint, params = {}) {
370
+ this.requirePublicCreds();
371
+ const queryParams = new URLSearchParams({
372
+ token: this.publicToken,
373
+ key: this.publicKey,
374
+ ...Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)])),
375
+ });
376
+ const url = `${this.baseUrls.locationsBaseUrl}/${endpoint}?${queryParams.toString()}`;
377
+ return this.execute(async () => {
378
+ const res = await this.http.get(url);
379
+ const data = safeParseJson(res.data);
380
+ if (data?.code === 200 && Array.isArray(data.data)) {
381
+ return data.data;
382
+ }
383
+ if (Array.isArray(data)) {
384
+ return data;
385
+ }
386
+ raiseForCode(`Location API (${endpoint}) failed`, data, res.status);
387
+ });
388
+ }
389
+ /**
390
+ * List all supported countries for a proxy type.
391
+ */
392
+ async listCountries(proxyType = "residential") {
393
+ return this.getLocations("countries", {
394
+ proxy_type: normalizeProxyType(proxyType),
395
+ });
396
+ }
397
+ /**
398
+ * List states/regions for a country.
399
+ */
400
+ async listStates(countryCode, proxyType = "residential") {
401
+ return this.getLocations("states", {
402
+ proxy_type: normalizeProxyType(proxyType),
403
+ country_code: countryCode.toUpperCase(),
404
+ });
405
+ }
406
+ /**
407
+ * List cities for a country (and optionally state).
408
+ */
409
+ async listCities(countryCode, stateCode, proxyType = "residential") {
410
+ const params = {
411
+ proxy_type: normalizeProxyType(proxyType),
412
+ country_code: countryCode.toUpperCase(),
413
+ };
414
+ if (stateCode) {
415
+ params.state_code = stateCode.toLowerCase();
416
+ }
417
+ return this.getLocations("cities", params);
418
+ }
419
+ /**
420
+ * List ASNs for a country.
421
+ */
422
+ async listAsns(countryCode, proxyType = "residential") {
423
+ return this.getLocations("asn", {
424
+ proxy_type: normalizeProxyType(proxyType),
425
+ country_code: countryCode.toUpperCase(),
426
+ });
427
+ }
285
428
  }
286
429
  //# sourceMappingURL=client.js.map