recker 1.0.79 → 1.0.80-next.70ea84d

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 (196) hide show
  1. package/dist/browser/browser/mini.d.ts +2 -2
  2. package/dist/browser/browser/recker-mini.d.ts +8 -8
  3. package/dist/browser/browser/recker.d.ts +11 -8
  4. package/dist/browser/browser/recker.js +54 -6
  5. package/dist/browser/core/client.d.ts +15 -10
  6. package/dist/browser/core/client.js +54 -38
  7. package/dist/browser/index.iife.min.js +129 -130
  8. package/dist/browser/index.min.js +129 -130
  9. package/dist/browser/index.mini.iife.js +5697 -636
  10. package/dist/browser/index.mini.iife.min.js +47 -48
  11. package/dist/browser/index.mini.min.js +47 -48
  12. package/dist/browser/index.mini.umd.js +5697 -636
  13. package/dist/browser/index.mini.umd.min.js +47 -48
  14. package/dist/browser/index.umd.min.js +129 -130
  15. package/dist/browser/mini.d.ts +2 -2
  16. package/dist/browser/plugins/proxy-rotator.d.ts +2 -2
  17. package/dist/browser/plugins/proxy-rotator.js +6 -28
  18. package/dist/browser/recker-mini.d.ts +8 -8
  19. package/dist/browser/recker.d.ts +11 -8
  20. package/dist/browser/recker.js +54 -6
  21. package/dist/browser/scrape/document.js +2 -2
  22. package/dist/browser/scrape/element.js +7 -1
  23. package/dist/browser/scrape/parser/nodes/html.js +1 -1
  24. package/dist/browser/scrape/spider.d.ts +52 -0
  25. package/dist/browser/scrape/spider.js +620 -38
  26. package/dist/browser/scrape/types.d.ts +2 -0
  27. package/dist/browser/search/google.d.ts +26 -1
  28. package/dist/browser/search/google.js +427 -45
  29. package/dist/browser/seo/analyzer.d.ts +1 -0
  30. package/dist/browser/seo/analyzer.js +144 -1
  31. package/dist/browser/seo/index.d.ts +1 -1
  32. package/dist/browser/seo/keyword-campaign-analyzer.d.ts +2 -0
  33. package/dist/browser/seo/keyword-campaign-analyzer.js +538 -0
  34. package/dist/browser/seo/keyword-campaign-seed-advanced.d.ts +17 -0
  35. package/dist/browser/seo/keyword-campaign-seed-advanced.js +269 -0
  36. package/dist/browser/seo/keyword-campaign-seed-core.d.ts +29 -0
  37. package/dist/browser/seo/keyword-campaign-seed-core.js +525 -0
  38. package/dist/browser/seo/keyword-campaign-shared.d.ts +165 -0
  39. package/dist/browser/seo/keyword-campaign-shared.js +59 -0
  40. package/dist/browser/seo/keyword-campaign.d.ts +4 -107
  41. package/dist/browser/seo/keyword-campaign.js +2 -380
  42. package/dist/browser/seo/keywords.js +5 -22
  43. package/dist/browser/seo/types.d.ts +19 -0
  44. package/dist/browser/transport/curl.d.ts +5 -1
  45. package/dist/browser/transport/curl.js +207 -50
  46. package/dist/browser/transport/undici.d.ts +4 -3
  47. package/dist/browser/transport/undici.js +123 -49
  48. package/dist/browser/types/index.d.ts +9 -3
  49. package/dist/browser/utils/binary-manager.js +26 -3
  50. package/dist/browser/utils/block-detector.d.ts +8 -0
  51. package/dist/browser/utils/block-detector.js +542 -7
  52. package/dist/cli/commands/hls-runner.js +5 -4
  53. package/dist/cli/commands/live-runner.js +5 -4
  54. package/dist/cli/commands/loadtest-runner.js +3 -2
  55. package/dist/cli/commands/search.d.ts +2 -0
  56. package/dist/cli/commands/search.js +105 -0
  57. package/dist/cli/commands/seo-runner.js +9 -7
  58. package/dist/cli/commands/seo.js +140 -1
  59. package/dist/cli/commands/serve.js +75 -131
  60. package/dist/cli/commands/server-runner.js +59 -82
  61. package/dist/cli/commands/spider-runner.d.ts +37 -1
  62. package/dist/cli/commands/spider-runner.js +134 -10
  63. package/dist/cli/commands/spider.d.ts +18 -1
  64. package/dist/cli/commands/spider.js +457 -27
  65. package/dist/cli/events/handlers/cli.js +30 -1
  66. package/dist/cli/events/handlers/tui.js +26 -0
  67. package/dist/cli/events/types.d.ts +27 -0
  68. package/dist/cli/handler.d.ts +2 -12
  69. package/dist/cli/handler.js +20 -15
  70. package/dist/cli/handlers/protocols.js +39 -12
  71. package/dist/cli/handlers/search.d.ts +2 -0
  72. package/dist/cli/handlers/search.js +171 -0
  73. package/dist/cli/handlers/seo-analyze.d.ts +1 -0
  74. package/dist/cli/handlers/seo-analyze.js +666 -0
  75. package/dist/cli/handlers/seo-robots.d.ts +1 -0
  76. package/dist/cli/handlers/seo-robots.js +76 -0
  77. package/dist/cli/handlers/seo-serp.d.ts +54 -0
  78. package/dist/cli/handlers/seo-serp.js +243 -0
  79. package/dist/cli/handlers/seo-sitemap.d.ts +1 -0
  80. package/dist/cli/handlers/seo-sitemap.js +55 -0
  81. package/dist/cli/handlers/seo-spider.d.ts +1 -0
  82. package/dist/cli/handlers/seo-spider.js +334 -0
  83. package/dist/cli/handlers/seo.d.ts +8 -4
  84. package/dist/cli/handlers/seo.js +294 -442
  85. package/dist/cli/handlers/spider.js +94 -17
  86. package/dist/cli/handlers/streaming.js +5 -1
  87. package/dist/cli/index.js +11 -2
  88. package/dist/cli/presets.d.ts +1 -1
  89. package/dist/cli/presets.js +15 -4
  90. package/dist/cli/tui/app.js +6 -1
  91. package/dist/cli/tui/components/rich-response.d.ts +72 -0
  92. package/dist/cli/tui/components/rich-response.js +117 -0
  93. package/dist/cli/tui/executor-commands/background.js +30 -24
  94. package/dist/cli/tui/executor-commands/testing.js +3 -2
  95. package/dist/cli/tui/hooks/useDomains.d.ts +17 -0
  96. package/dist/cli/tui/hooks/useHelp.js +15 -2
  97. package/dist/cli/tui/job-manager.d.ts +4 -4
  98. package/dist/cli/tui/job-manager.js +5 -1
  99. package/dist/cli/tui/spider-tui.d.ts +63 -0
  100. package/dist/cli/tui/spider-tui.js +120 -2
  101. package/dist/cli/types.d.ts +12 -0
  102. package/dist/cli/types.js +1 -0
  103. package/dist/cli/utils/option-helpers.d.ts +10 -0
  104. package/dist/cli/utils/option-helpers.js +63 -0
  105. package/dist/cli/utils/score-color.d.ts +11 -0
  106. package/dist/cli/utils/score-color.js +11 -0
  107. package/dist/cli/utils/serp-campaign.d.ts +53 -0
  108. package/dist/cli/utils/serp-campaign.js +53 -0
  109. package/dist/cli/utils/serp-config.d.ts +26 -0
  110. package/dist/cli/utils/serp-config.js +125 -0
  111. package/dist/core/client.d.ts +15 -10
  112. package/dist/core/client.js +54 -38
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.js +1 -0
  115. package/dist/mcp/cli.js +35 -34
  116. package/dist/mcp/client.d.ts +2 -2
  117. package/dist/mcp/client.js +20 -2
  118. package/dist/mcp/contract.d.ts +1 -1
  119. package/dist/mcp/profiles.js +5 -1
  120. package/dist/mcp/prompts/index.js +8 -4
  121. package/dist/mcp/resources/index.js +46 -23
  122. package/dist/mcp/server.js +9 -6
  123. package/dist/mcp/tools/protocols.js +9 -2
  124. package/dist/mcp/tools/registry.js +13 -3
  125. package/dist/mcp/tools/seo.js +427 -2
  126. package/dist/mcp/types.d.ts +5 -1
  127. package/dist/plugins/proxy-rotator.d.ts +2 -2
  128. package/dist/plugins/proxy-rotator.js +6 -28
  129. package/dist/raffel/client.d.ts +38 -0
  130. package/dist/raffel/client.js +282 -0
  131. package/dist/raffel/index.d.ts +2 -0
  132. package/dist/raffel/index.js +2 -0
  133. package/dist/raffel/types.d.ts +40 -0
  134. package/dist/raffel/types.js +14 -0
  135. package/dist/recker.d.ts +13 -7
  136. package/dist/recker.js +58 -6
  137. package/dist/scrape/document.js +2 -2
  138. package/dist/scrape/element.js +7 -1
  139. package/dist/scrape/parser/nodes/html.js +1 -1
  140. package/dist/scrape/spider.d.ts +52 -0
  141. package/dist/scrape/spider.js +620 -38
  142. package/dist/scrape/types.d.ts +2 -0
  143. package/dist/search/google.d.ts +26 -1
  144. package/dist/search/google.js +427 -45
  145. package/dist/search/index.d.ts +1 -1
  146. package/dist/seo/analyzer.d.ts +1 -0
  147. package/dist/seo/analyzer.js +144 -1
  148. package/dist/seo/index.d.ts +1 -1
  149. package/dist/seo/keyword-campaign-analyzer.d.ts +2 -0
  150. package/dist/seo/keyword-campaign-analyzer.js +538 -0
  151. package/dist/seo/keyword-campaign-seed-advanced.d.ts +17 -0
  152. package/dist/seo/keyword-campaign-seed-advanced.js +269 -0
  153. package/dist/seo/keyword-campaign-seed-core.d.ts +29 -0
  154. package/dist/seo/keyword-campaign-seed-core.js +525 -0
  155. package/dist/seo/keyword-campaign-shared.d.ts +165 -0
  156. package/dist/seo/keyword-campaign-shared.js +59 -0
  157. package/dist/seo/keyword-campaign.d.ts +4 -107
  158. package/dist/seo/keyword-campaign.js +2 -380
  159. package/dist/seo/keywords.js +5 -22
  160. package/dist/seo/types.d.ts +19 -0
  161. package/dist/template/index.d.ts +1 -1
  162. package/dist/template/types.d.ts +0 -2
  163. package/dist/testing/index.d.ts +1 -22
  164. package/dist/testing/index.js +1 -11
  165. package/dist/transport/curl.d.ts +5 -1
  166. package/dist/transport/curl.js +207 -50
  167. package/dist/transport/undici.d.ts +4 -3
  168. package/dist/transport/undici.js +123 -49
  169. package/dist/types/index.d.ts +9 -3
  170. package/dist/utils/binary-manager.js +26 -3
  171. package/dist/utils/block-detector.d.ts +8 -0
  172. package/dist/utils/block-detector.js +542 -7
  173. package/dist/version.js +1 -1
  174. package/package.json +12 -1
  175. package/dist/testing/mock-dns-server.d.ts +0 -69
  176. package/dist/testing/mock-dns-server.js +0 -269
  177. package/dist/testing/mock-ftp-server.d.ts +0 -89
  178. package/dist/testing/mock-ftp-server.js +0 -562
  179. package/dist/testing/mock-hls-server.d.ts +0 -80
  180. package/dist/testing/mock-hls-server.js +0 -381
  181. package/dist/testing/mock-http-server.d.ts +0 -124
  182. package/dist/testing/mock-http-server.js +0 -343
  183. package/dist/testing/mock-proxy-server.d.ts +0 -108
  184. package/dist/testing/mock-proxy-server.js +0 -615
  185. package/dist/testing/mock-sse-server.d.ts +0 -76
  186. package/dist/testing/mock-sse-server.js +0 -291
  187. package/dist/testing/mock-telnet-server.d.ts +0 -59
  188. package/dist/testing/mock-telnet-server.js +0 -274
  189. package/dist/testing/mock-udp-server.d.ts +0 -43
  190. package/dist/testing/mock-udp-server.js +0 -188
  191. package/dist/testing/mock-websocket-server.d.ts +0 -76
  192. package/dist/testing/mock-websocket-server.js +0 -334
  193. package/dist/testing/mock-whois-server.d.ts +0 -56
  194. package/dist/testing/mock-whois-server.js +0 -234
  195. package/dist/testing/proxy-certs.d.ts +0 -19
  196. package/dist/testing/proxy-certs.js +0 -208
@@ -6,8 +6,8 @@ export declare class MiniRequestPromise<T = unknown> implements Promise<Response
6
6
  private readonly p;
7
7
  constructor(promise: Promise<Response>);
8
8
  get [Symbol.toStringTag](): string;
9
- then<TResult1 = Response, TResult2 = never>(onfulfilled?: ((value: Response) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
10
- catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<Response | TResult>;
9
+ then<TResult1 = Response, TResult2 = never>(onfulfilled?: ((value: Response) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
10
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<Response | TResult>;
11
11
  finally(onfinally?: (() => void) | null): Promise<Response>;
12
12
  json<R = T>(): Promise<R>;
13
13
  text(): Promise<string>;
@@ -1,6 +1,6 @@
1
- import { Plugin } from '../types/index.js';
1
+ import type { Plugin, ProxyOptions } from '../types/index.js';
2
2
  export interface ProxyRotatorOptions {
3
- proxies: string[];
3
+ proxies: (string | ProxyOptions)[];
4
4
  strategy?: 'round-robin' | 'random';
5
5
  failover?: boolean;
6
6
  }
@@ -1,35 +1,13 @@
1
- import { ProxyAgent } from 'undici';
2
1
  export function proxyRotatorPlugin(options) {
3
- const proxies = options.proxies.map(url => ({
4
- url,
5
- agent: new ProxyAgent(url),
6
- failures: 0
7
- }));
8
- let index = 0;
9
- const getNextProxy = () => {
10
- if (proxies.length === 0)
11
- return null;
12
- let selected;
2
+ return (client) => {
13
3
  if (options.strategy === 'random') {
14
- selected = proxies[Math.floor(Math.random() * proxies.length)];
4
+ const shuffled = [...options.proxies].sort(() => Math.random() - 0.5);
5
+ client.defaults = client.defaults ?? {};
6
+ client.defaults.proxy = shuffled;
15
7
  }
16
8
  else {
17
- selected = proxies[index];
18
- index = (index + 1) % proxies.length;
9
+ client.defaults = client.defaults ?? {};
10
+ client.defaults.proxy = options.proxies;
19
11
  }
20
- return selected;
21
- };
22
- return (client) => {
23
- client.beforeRequest((req) => {
24
- const proxy = getNextProxy();
25
- if (proxy) {
26
- req._dispatcher = proxy.agent;
27
- req._proxyUrl = proxy.url;
28
- }
29
- });
30
- client.onError((err, req) => {
31
- if (options.failover && req._proxyUrl) {
32
- }
33
- });
34
12
  };
35
13
  }
@@ -2,14 +2,14 @@ import { Client, type ExtendedClientOptions } from '../core/client.js';
2
2
  import { type RequestPromise } from '../core/request-promise.js';
3
3
  import type { RequestOptions } from '../types/index.js';
4
4
  import { simulateNetwork } from '../plugins/network-simulation.js';
5
- export declare function get(url: string, options?: RequestOptions): RequestPromise;
6
- export declare function post(url: string, options?: RequestOptions): RequestPromise;
7
- export declare function put(url: string, options?: RequestOptions): RequestPromise;
8
- export declare function patch(url: string, options?: RequestOptions): RequestPromise;
9
- export declare function del(url: string, options?: RequestOptions): RequestPromise;
10
- export declare function head(url: string, options?: RequestOptions): RequestPromise;
11
- export declare function options(url: string, options?: RequestOptions): RequestPromise;
12
- export declare function purge(url: string, options?: RequestOptions): RequestPromise;
5
+ export declare function get<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
6
+ export declare function post<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
7
+ export declare function put<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
8
+ export declare function patch<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
9
+ export declare function del<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
10
+ export declare function head<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
11
+ export declare function options<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
12
+ export declare function purge<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
13
13
  export declare function ws(url: string, protocols?: string | string[]): WebSocket;
14
14
  export declare const recker: {
15
15
  get: typeof get;
@@ -4,14 +4,17 @@ import type { RequestOptions } from '../types/index.js';
4
4
  import { analyzeSeo } from '../seo/analyzer.js';
5
5
  import { createAI } from '../ai/index.js';
6
6
  import { simulateNetwork } from '../plugins/network-simulation.js';
7
- export declare function get(url: string, options?: RequestOptions): RequestPromise;
8
- export declare function post(url: string, options?: RequestOptions): RequestPromise;
9
- export declare function put(url: string, options?: RequestOptions): RequestPromise;
10
- export declare function patch(url: string, options?: RequestOptions): RequestPromise;
11
- export declare function del(url: string, options?: RequestOptions): RequestPromise;
12
- export declare function head(url: string, options?: RequestOptions): RequestPromise;
13
- export declare function options(url: string, options?: RequestOptions): RequestPromise;
14
- export declare function purge(url: string, options?: RequestOptions): RequestPromise;
7
+ export declare function get<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
8
+ export declare function post<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
9
+ export declare function post<T = unknown>(url: string, body?: unknown, options?: RequestOptions): RequestPromise<T>;
10
+ export declare function put<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
11
+ export declare function put<T = unknown>(url: string, body?: unknown, options?: RequestOptions): RequestPromise<T>;
12
+ export declare function patch<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
13
+ export declare function patch<T = unknown>(url: string, body?: unknown, options?: RequestOptions): RequestPromise<T>;
14
+ export declare function del<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
15
+ export declare function head<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
16
+ export declare function options<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
17
+ export declare function purge<T = unknown>(url: string, options?: RequestOptions): RequestPromise<T>;
15
18
  export declare function ws(url: string, protocols?: string | string[]): WebSocket;
16
19
  export declare const recker: {
17
20
  get: typeof get;
@@ -5,6 +5,51 @@ import { createAI } from '../ai/index.js';
5
5
  import { harRecorder } from '../plugins/har-recorder.js';
6
6
  import { simulateNetwork } from '../plugins/network-simulation.js';
7
7
  let _defaultClient = null;
8
+ const REQUEST_OPTIONS_HINTS = new Set([
9
+ 'method',
10
+ 'headers',
11
+ 'body',
12
+ 'json',
13
+ 'form',
14
+ 'xml',
15
+ 'yaml',
16
+ 'csv',
17
+ 'timeout',
18
+ 'params',
19
+ 'searchParams',
20
+ 'retry',
21
+ 'hooks',
22
+ 'throwHttpErrors',
23
+ 'signal',
24
+ 'http2',
25
+ 'followRedirects',
26
+ 'maxRedirects',
27
+ 'beforeRedirect',
28
+ 'maxResponseSize',
29
+ 'useCurl',
30
+ 'proxy',
31
+ 'dns',
32
+ 'tls',
33
+ 'policySource',
34
+ 'policyTags',
35
+ 'traceId',
36
+ 'correlationId',
37
+ 'tenant',
38
+ 'retryOn404',
39
+ 'retryOn5xx',
40
+ ]);
41
+ function isRequestOptions(value) {
42
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
43
+ return false;
44
+ }
45
+ return Object.keys(value).some((key) => REQUEST_OPTIONS_HINTS.has(key));
46
+ }
47
+ function resolveRequestBodyAndOptions(bodyOrOptions, options) {
48
+ if (options === undefined && isRequestOptions(bodyOrOptions)) {
49
+ return { body: undefined, options: bodyOrOptions };
50
+ }
51
+ return { body: bodyOrOptions, options: options || {} };
52
+ }
8
53
  function getDefaultClient() {
9
54
  if (!_defaultClient) {
10
55
  _defaultClient = createClient({
@@ -16,14 +61,17 @@ function getDefaultClient() {
16
61
  export function get(url, options) {
17
62
  return getDefaultClient().get(url, options);
18
63
  }
19
- export function post(url, options) {
20
- return getDefaultClient().post(url, options);
64
+ export function post(url, bodyOrOptions, options) {
65
+ const resolved = resolveRequestBodyAndOptions(bodyOrOptions, options);
66
+ return getDefaultClient().post(url, resolved.body, resolved.options);
21
67
  }
22
- export function put(url, options) {
23
- return getDefaultClient().put(url, options);
68
+ export function put(url, bodyOrOptions, options) {
69
+ const resolved = resolveRequestBodyAndOptions(bodyOrOptions, options);
70
+ return getDefaultClient().put(url, resolved.body, resolved.options);
24
71
  }
25
- export function patch(url, options) {
26
- return getDefaultClient().patch(url, options);
72
+ export function patch(url, bodyOrOptions, options) {
73
+ const resolved = resolveRequestBodyAndOptions(bodyOrOptions, options);
74
+ return getDefaultClient().patch(url, resolved.body, resolved.options);
27
75
  }
28
76
  export function del(url, options) {
29
77
  return getDefaultClient().delete(url, options);
@@ -9,11 +9,11 @@ export class ScrapeDocument {
9
9
  this.options = options || {};
10
10
  }
11
11
  static async create(html, options) {
12
- const root = parse(html);
12
+ const root = parse(html, options?.parserOptions);
13
13
  return new ScrapeDocument(root, options);
14
14
  }
15
15
  static createSync(html, options) {
16
- const root = parse(html);
16
+ const root = parse(html, options?.parserOptions);
17
17
  return new ScrapeDocument(root, options);
18
18
  }
19
19
  select(selector) {
@@ -16,8 +16,14 @@ export class ScrapeElement {
16
16
  }
17
17
  find(selector) {
18
18
  const found = [];
19
+ const seen = new Set();
19
20
  this.elements.forEach((el) => {
20
- found.push(...el.querySelectorAll(selector));
21
+ el.querySelectorAll(selector).forEach((match) => {
22
+ if (!seen.has(match)) {
23
+ seen.add(match);
24
+ found.push(match);
25
+ }
26
+ });
21
27
  });
22
28
  return new ScrapeElement(found);
23
29
  }
@@ -8,7 +8,7 @@ import Node from './node.js';
8
8
  import TextNode from './text.js';
9
9
  import NodeType from './type.js';
10
10
  function decode(val) {
11
- return JSON.parse(JSON.stringify(he.decode(val)));
11
+ return he.decode(val);
12
12
  }
13
13
  const Htags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup'];
14
14
  const Dtags = ['details', 'dialog', 'dd', 'div', 'dt'];
@@ -1,6 +1,9 @@
1
1
  import type { ExtractedLink, ExtractionSchema } from './types.js';
2
+ import type { Options as ParserOptions } from './parser/index.js';
2
3
  import { type SitemapUrl } from '../seo/validators/sitemap.js';
4
+ import { type CaptchaDetectionResult, type BlockDetectionResult } from '../utils/block-detector.js';
3
5
  export type SpiderTransport = 'auto' | 'undici' | 'curl';
6
+ type CaptchaProvider = CaptchaDetectionResult['provider'];
4
7
  export interface SpiderOptions {
5
8
  maxDepth?: number;
6
9
  maxPages?: number;
@@ -11,14 +14,31 @@ export interface SpiderOptions {
11
14
  exclude?: RegExp[];
12
15
  include?: RegExp[];
13
16
  userAgent?: string;
17
+ rotateUserAgent?: boolean;
18
+ randomizeHeaders?: boolean;
19
+ maxRetryAttempts?: number;
20
+ baseRetryDelayMs?: number;
21
+ maxRetryDelayMs?: number;
22
+ retryBackoffMultiplier?: number;
23
+ retryJitterMs?: number;
24
+ maxDomainBlockStrikes?: number;
14
25
  respectRobotsTxt?: boolean;
15
26
  useSitemap?: boolean;
16
27
  sitemapUrl?: string;
17
28
  transport?: SpiderTransport;
29
+ preferCurlFirst?: boolean;
18
30
  onPage?: (result: SpiderPageResult) => void;
19
31
  onPageWithHtml?: (result: SpiderPageResult, html: string) => void | Promise<void>;
32
+ onCaptchaDetected?: (result: {
33
+ url: string;
34
+ status: number;
35
+ confidence: number;
36
+ provider?: CaptchaProvider;
37
+ usedCurl: boolean;
38
+ }) => void | Promise<void>;
20
39
  onProgress?: (progress: SpiderProgress) => void;
21
40
  extract?: string[] | ExtractionSchema;
41
+ parserOptions?: Partial<ParserOptions>;
22
42
  }
23
43
  export interface SpiderPageResult {
24
44
  url: string;
@@ -56,6 +76,25 @@ export interface SpiderPageResult {
56
76
  total?: number;
57
77
  };
58
78
  fetchedAt?: number;
79
+ security?: {
80
+ blocked: boolean;
81
+ reason?: BlockDetectionResult['reason'];
82
+ confidence?: number;
83
+ captchaDetected?: boolean;
84
+ captchaProvider?: CaptchaProvider;
85
+ attempts?: number;
86
+ retryCount?: number;
87
+ retryAfterMs?: number;
88
+ transport?: SpiderTransport;
89
+ blockedByCaptcha?: boolean;
90
+ lastStatus?: number;
91
+ lastTransport?: SpiderTransport;
92
+ };
93
+ resources?: {
94
+ images: number;
95
+ scripts: number;
96
+ stylesheets: number;
97
+ };
59
98
  extracted?: Record<string, unknown>;
60
99
  }
61
100
  export interface SpiderProgress {
@@ -118,6 +157,7 @@ export declare class Spider {
118
157
  private blockedDomains;
119
158
  private curlTransport;
120
159
  private curlAvailable;
160
+ private domainStates;
121
161
  private sitemapUrls;
122
162
  private sitemapUrlSet;
123
163
  private robotsData;
@@ -132,8 +172,20 @@ export declare class Spider {
132
172
  private buildRobotsAnalysis;
133
173
  private fetchPage;
134
174
  private crawlPage;
175
+ private getOrCreateDomainState;
176
+ private recordTransportResult;
177
+ private isRetryableStatus;
178
+ private buildRequestHeaders;
179
+ private shouldUseCurlForHost;
180
+ private waitForDomainPenalty;
181
+ private registerDomainBlock;
182
+ private registerDomainSuccess;
183
+ private getCaptchaRetryMultiplier;
184
+ private registerDomainChallenge;
185
+ private getRetryWait;
135
186
  abort(): void;
136
187
  isRunning(): boolean;
137
188
  getProgress(): SpiderProgress;
138
189
  }
139
190
  export declare function spider(url: string, options?: SpiderOptions): Promise<SpiderResult>;
191
+ export {};