zenrows 2.0.2 → 2.0.3

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/dist/index.d.ts CHANGED
@@ -1,12 +1,748 @@
1
1
  import * as fetch_retry from 'fetch-retry';
2
2
  import fastq from 'fastq';
3
3
 
4
+ type JobType = "regular" | "scheduled";
5
+ type JobStatus = "open" | "closed" | "deleted";
6
+ type ScheduleState = "active" | "paused";
7
+ type RunStatus = "pending" | "running" | "completed" | "failed" | "stopped" | "deleted";
8
+ type TaskStatus = "pending" | "successful" | "failed";
9
+ type PauseState = "active" | "paused";
10
+ type IngestStatus = "pending" | "done";
11
+ type ExportStatus = "pending" | "running" | "completed" | "failed";
12
+ interface Spend {
13
+ credits: number;
14
+ cost: number;
15
+ }
16
+ interface TaskSpend {
17
+ total: Spend;
18
+ last_attempt: Spend;
19
+ }
20
+ interface RunStats {
21
+ total: number;
22
+ completed: number;
23
+ successful: number;
24
+ failed: number;
25
+ failure_reasons?: Record<string, number>;
26
+ spend?: Spend;
27
+ }
28
+ interface WebhookConfig {
29
+ url: string;
30
+ signature: boolean;
31
+ }
32
+ interface JobSchedule {
33
+ at?: string;
34
+ rate?: {
35
+ every: number;
36
+ unit: "minute" | "hour" | "day";
37
+ };
38
+ calendar?: {
39
+ times_of_day: string[];
40
+ cadence: {
41
+ daily?: object;
42
+ weekly?: {
43
+ days: string[];
44
+ };
45
+ monthly?: {
46
+ days: number[];
47
+ };
48
+ };
49
+ };
50
+ timezone?: string;
51
+ }
52
+ interface Run {
53
+ run_id: string;
54
+ job_id: string;
55
+ run_sequence: number;
56
+ status: RunStatus;
57
+ stats: RunStats;
58
+ last_batch_received?: boolean;
59
+ pause_state?: PauseState;
60
+ ingest_status?: IngestStatus;
61
+ failure_reason?: "insufficient_credits" | "subscription_inactive";
62
+ created_at?: string;
63
+ updated_at?: string;
64
+ }
65
+ interface Job {
66
+ job_id: string;
67
+ type: JobType;
68
+ status: JobStatus;
69
+ format?: string;
70
+ zenrows_params?: Record<string, string>;
71
+ external_id?: string;
72
+ name?: string;
73
+ metadata?: Record<string, string>;
74
+ schedule?: JobSchedule;
75
+ next_scheduled_run?: string;
76
+ schedule_state?: ScheduleState;
77
+ webhook?: WebhookConfig;
78
+ latest_run?: Run;
79
+ created_at?: string;
80
+ updated_at?: string;
81
+ }
82
+ interface ListJobsResponse {
83
+ jobs: Job[];
84
+ next_cursor?: string;
85
+ }
86
+ interface ListJobRunsResponse {
87
+ runs: Run[];
88
+ next_cursor?: string;
89
+ }
90
+ interface SubmitJobResponse {
91
+ job_id: string;
92
+ status: JobStatus;
93
+ latest_run?: Run;
94
+ accepted_tasks: number;
95
+ webhook?: WebhookConfig;
96
+ }
97
+ interface AddTasksResponse {
98
+ accepted_tasks: number;
99
+ job_status: JobStatus;
100
+ latest_run: Run;
101
+ }
102
+ interface RerunJobResponse {
103
+ job_id: string;
104
+ status: JobStatus;
105
+ latest_run: Run;
106
+ rerun_of?: string;
107
+ retried_tasks: number;
108
+ inherited_tasks: number;
109
+ }
110
+ interface ProblemJson {
111
+ type?: string;
112
+ title?: string;
113
+ status?: number;
114
+ code?: string;
115
+ detail?: string;
116
+ instance?: string;
117
+ }
118
+ interface TaskResult {
119
+ task_id: string;
120
+ external_id?: string;
121
+ run_id: string;
122
+ url: string;
123
+ metadata?: Record<string, string>;
124
+ method?: "GET" | "POST";
125
+ status: TaskStatus;
126
+ type?: string;
127
+ result_url?: string;
128
+ error?: ProblemJson;
129
+ source_run_id?: string;
130
+ spend?: TaskSpend;
131
+ }
132
+ interface ListResultsResponse {
133
+ results: TaskResult[];
134
+ next_cursor?: string;
135
+ }
136
+ interface TaskHistoryEvent {
137
+ started_at: string;
138
+ ended_at: string;
139
+ attempt: number;
140
+ error?: ProblemJson;
141
+ spend?: Spend;
142
+ }
143
+ interface TaskHistoryResponse {
144
+ events: TaskHistoryEvent[];
145
+ }
146
+ interface StartExportResponse {
147
+ export_id: string;
148
+ status: ExportStatus;
149
+ created_at: string;
150
+ expires_at: string;
151
+ }
152
+ interface Export {
153
+ export_id: string;
154
+ status: ExportStatus;
155
+ error?: string;
156
+ download_url?: string;
157
+ created_at: string;
158
+ expires_at: string;
159
+ }
160
+ interface FileInputUploadTarget {
161
+ method: "PUT";
162
+ url: string;
163
+ headers?: Record<string, string>;
164
+ expires_at: string;
165
+ }
166
+ interface CreateJobInputResponse {
167
+ file_input_id: string;
168
+ upload: FileInputUploadTarget;
169
+ expires_at: string;
170
+ }
171
+ interface HMACKeyMeta {
172
+ kid: string;
173
+ created_at: string;
174
+ }
175
+ interface HMACKeyList {
176
+ active?: HMACKeyMeta;
177
+ candidate?: HMACKeyMeta;
178
+ }
179
+ interface HMACKeyCreated {
180
+ kid: string;
181
+ secret: string;
182
+ created_at: string;
183
+ }
184
+ interface HMACKeyFinalized {
185
+ active_kid: string;
186
+ created_at: string;
187
+ }
188
+ interface TestWebhookResponse {
189
+ delivered: boolean;
190
+ event_id: string;
191
+ status_code?: number;
192
+ error?: string;
193
+ elapsed_ms: number;
194
+ }
195
+
196
+ declare const DEFAULT_MAX_FILES = 100000;
197
+ declare const DEFAULT_MAX_BYTES_PER_FILE: number;
198
+ declare const DEFAULT_MAX_COUNT_IN_MEMORY = 10000;
199
+ declare const DEFAULT_MAX_TOTAL_BYTES_IN_MEMORY: number;
200
+ interface DownloadedResult {
201
+ taskId: string;
202
+ externalId?: string;
203
+ url: string;
204
+ body: Buffer;
205
+ }
206
+ interface DownloadToDirOptions {
207
+ status?: string;
208
+ nameFn?: (task: TaskResult) => string;
209
+ useExternalId?: boolean;
210
+ concurrency?: number;
211
+ maxFiles?: number;
212
+ maxBytesPerFile?: number;
213
+ }
214
+ /** Write every task body in `results` to `targetDir`, one file per task. */
215
+ declare function downloadToDir(results: AsyncIterable<TaskResult>, targetDir: string, { nameFn, useExternalId, concurrency, maxFiles, maxBytesPerFile, }?: DownloadToDirOptions): Promise<number>;
216
+ interface DownloadToMemoryOptions {
217
+ concurrency?: number;
218
+ maxCount?: number;
219
+ maxTotalBytes?: number;
220
+ maxBytesPerFile?: number;
221
+ }
222
+ /** Load every task body in `results` into memory. */
223
+ declare function downloadToMemory(results: AsyncIterable<TaskResult>, { concurrency, maxCount, maxTotalBytes, maxBytesPerFile, }?: DownloadToMemoryOptions): Promise<DownloadedResult[]>;
224
+ declare function downloadTaskToFile(task: TaskResult, target: string): Promise<void>;
225
+ declare function downloadTaskToMemory(task: TaskResult): Promise<Buffer>;
226
+
227
+ /**
228
+ * Client-side cost estimation, mirroring the Python SDK's rate card exactly. Pure — no
229
+ * network call. Prices a job assuming every task succeeds once; `mode=auto` is billed
230
+ * dynamically post-factum and is reported as a [1, 25] credit range, everything else is exact.
231
+ */
232
+ declare const BASE_CREDITS = 1;
233
+ declare const JS_CREDITS = 5;
234
+ declare const PREMIUM_PROXY_CREDITS = 10;
235
+ declare const JS_AND_PROXY_CREDITS = 25;
236
+ declare const AUTO_MIN_CREDITS = 1;
237
+ declare const AUTO_MAX_CREDITS = 25;
238
+ type Tier = "base" | "js_render" | "premium_proxy" | "js_render+premium_proxy" | "auto";
239
+ type ParamValue = string | boolean | number | Record<string, string>;
240
+ type ParamMap = Record<string, ParamValue>;
241
+ interface EstimateTask {
242
+ zenrows_params?: ParamMap;
243
+ }
244
+ type TaskLike = string | EstimateTask | Record<string, unknown>;
245
+ interface CostLine {
246
+ tier: Tier;
247
+ count: number;
248
+ unitMin: number;
249
+ unitMax: number;
250
+ }
251
+ interface CostEstimate {
252
+ taskCount: number;
253
+ min: number;
254
+ max: number;
255
+ breakdown: CostLine[];
256
+ exact: boolean;
257
+ }
258
+ /**
259
+ * Estimate the credit cost of a job before submitting it. `tasks` accepts the same shapes
260
+ * `submitRegular` does: bare URL strings or task objects. Per-task `zenrows_params` override
261
+ * the job-level `zenrowsParams` on key collision (task wins), matching the worker's merge.
262
+ */
263
+ declare function estimateCost(tasks: Iterable<TaskLike>, zenrowsParams?: ParamMap): CostEstimate;
264
+
265
+ declare const DAYS_OF_WEEK: readonly ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
266
+ type DayOfWeek = (typeof DAYS_OF_WEEK)[number];
267
+ /**
268
+ * One-shot fire at a specific wall-clock time. `at` must be tz-naive: a plain ISO string
269
+ * with no `Z`/offset suffix, or a `Date` — in which case its LOCAL getters (not UTC) are
270
+ * read as the intended wall-clock time. `timezone` is the single authoritative interpreter,
271
+ * which is what keeps DST transitions deterministic; passing a `Date` does NOT mean "this
272
+ * instant" — it means "this wall-clock reading, in whatever zone `timezone` names."
273
+ */
274
+ declare class At {
275
+ readonly at: string;
276
+ readonly timezone: string;
277
+ constructor(at: string | Date, timezone: string);
278
+ toRequestBody(): JobSchedule;
279
+ }
280
+ /** Interval-based fire policy — every N units, no alignment to wall clock. */
281
+ declare class Rate {
282
+ readonly every: number;
283
+ readonly unit: "minute" | "hour" | "day";
284
+ constructor(every: number, unit: "minute" | "hour" | "day");
285
+ toRequestBody(): JobSchedule;
286
+ }
287
+ /** Fire every day. No knobs. */
288
+ declare class Daily {
289
+ }
290
+ /** Fire on specific days of the week. `days` must be non-empty, lower-case 3-letter names. */
291
+ declare class Weekly {
292
+ readonly days: DayOfWeek[];
293
+ constructor(days: DayOfWeek[]);
294
+ }
295
+ /** Fire on specific days of the month (1-31); days that don't exist in a given month are skipped. */
296
+ declare class Monthly {
297
+ readonly days: number[];
298
+ constructor(days: number[]);
299
+ }
300
+ type Cadence = Daily | Weekly | Monthly;
301
+ /** Calendar-style fire policy: a list of times-of-day on a daily/weekly/monthly cadence. */
302
+ declare class Calendar {
303
+ readonly timesOfDay: string[];
304
+ readonly cadence: Cadence;
305
+ readonly timezone: string;
306
+ constructor(timesOfDay: string[], cadence: Cadence, timezone: string);
307
+ toRequestBody(): JobSchedule;
308
+ }
309
+ type Schedule = At | Rate | Calendar;
310
+
311
+ interface BatchTaskLike {
312
+ url: string;
313
+ external_id?: string;
314
+ metadata?: Record<string, unknown>;
315
+ zenrows_params?: Record<string, unknown>;
316
+ }
317
+ /** A reference to a specific run by `(jobId, runId)`. No pause/stop — only the CURRENT run supports those. */
318
+ declare class RunRef {
319
+ #private;
320
+ readonly jobId: string;
321
+ readonly runId: string;
322
+ constructor(client: ZenRowsBatchClient, jobId: string, runId: string);
323
+ load(): Promise<RunHandle>;
324
+ delete(): Promise<void>;
325
+ results(options?: {
326
+ status?: string;
327
+ }): AsyncGenerator<TaskResult>;
328
+ taskHistory(taskId: string): Promise<TaskHistoryResponse>;
329
+ downloadToDir(targetDir: string, options?: DownloadToDirOptions & {
330
+ status?: string;
331
+ }): Promise<number>;
332
+ downloadToMemory(options?: DownloadToMemoryOptions & {
333
+ status?: string;
334
+ }): Promise<DownloadedResult[]>;
335
+ downloadTaskToFile(task: TaskResult, target: string): Promise<void>;
336
+ downloadTaskToMemory(task: TaskResult): Promise<Buffer>;
337
+ wait(options?: {
338
+ targetStatuses?: Set<string>;
339
+ failureStatuses?: Set<string>;
340
+ timeout?: number;
341
+ pollInterval?: number;
342
+ }): Promise<RunHandle>;
343
+ startExport(): Promise<ExportRef>;
344
+ export(exportId: string): ExportRef;
345
+ downloadAllResults(targetPath: string, options?: {
346
+ waitTimeout?: number;
347
+ pollInterval?: number;
348
+ }): Promise<string>;
349
+ }
350
+ declare class RunHandle extends RunRef {
351
+ readonly data: Run;
352
+ constructor(client: ZenRowsBatchClient, jobId: string, runId: string, data: Run);
353
+ get status(): RunStatus;
354
+ get stats(): RunStats;
355
+ }
356
+ declare class ExportRef {
357
+ #private;
358
+ readonly jobId: string;
359
+ readonly runId: string;
360
+ readonly exportId: string;
361
+ readonly startResponse?: StartExportResponse | undefined;
362
+ constructor(client: ZenRowsBatchClient, jobId: string, runId: string, exportId: string, startResponse?: StartExportResponse | undefined);
363
+ load(): Promise<ExportHandle>;
364
+ wait(options?: {
365
+ targetStatuses?: Set<string>;
366
+ timeout?: number;
367
+ pollInterval?: number;
368
+ }): Promise<ExportHandle>;
369
+ /** Stream the export zip to `targetPath`. The export must already be `completed`. */
370
+ downloadToPath(targetPath: string): Promise<string>;
371
+ }
372
+ declare class ExportHandle extends ExportRef {
373
+ readonly data: Export;
374
+ constructor(client: ZenRowsBatchClient, jobId: string, runId: string, exportId: string, data: Export, startResponse?: StartExportResponse);
375
+ get status(): ExportStatus;
376
+ }
377
+ /** Operations on a job's CURRENT run, reached via `job.run`. */
378
+ declare class CurrentRun {
379
+ #private;
380
+ readonly jobId: string;
381
+ constructor(client: ZenRowsBatchClient, jobId: string);
382
+ private currentRunId;
383
+ load(): Promise<RunHandle>;
384
+ pause(): Promise<RunHandle>;
385
+ resume(): Promise<RunHandle>;
386
+ stop(): Promise<RunHandle>;
387
+ cancel(): Promise<RunHandle>;
388
+ wait(options?: {
389
+ targetStatuses?: Set<string>;
390
+ failureStatuses?: Set<string>;
391
+ timeout?: number;
392
+ pollInterval?: number;
393
+ }): Promise<RunHandle>;
394
+ results(options?: {
395
+ status?: string;
396
+ }): AsyncGenerator<TaskResult>;
397
+ taskHistory(taskId: string): Promise<TaskHistoryResponse>;
398
+ downloadToDir(targetDir: string, options?: DownloadToDirOptions & {
399
+ status?: string;
400
+ }): Promise<number>;
401
+ downloadToMemory(options?: DownloadToMemoryOptions & {
402
+ status?: string;
403
+ }): Promise<DownloadedResult[]>;
404
+ downloadTaskToFile(task: TaskResult, target: string): Promise<void>;
405
+ downloadTaskToMemory(task: TaskResult): Promise<Buffer>;
406
+ startExport(): Promise<ExportRef>;
407
+ downloadAllResults(targetPath: string, options?: {
408
+ waitTimeout?: number;
409
+ pollInterval?: number;
410
+ }): Promise<string>;
411
+ }
412
+ /** Operations on a scheduled job's schedule, reached via `job.schedule`. Scheduled jobs only — regular jobs 409. */
413
+ declare class ScheduleControls {
414
+ #private;
415
+ readonly jobId: string;
416
+ constructor(client: ZenRowsBatchClient, jobId: string);
417
+ pause(): Promise<JobHandle>;
418
+ resume(): Promise<JobHandle>;
419
+ update(schedule: Schedule): Promise<JobHandle>;
420
+ }
421
+ /** A reference to a job by id — job-template operations, plus `run`/`schedule` sub-facets. */
422
+ declare class JobRef {
423
+ #private;
424
+ readonly jobId: string;
425
+ readonly submitResponse?: SubmitJobResponse | undefined;
426
+ private runFacet?;
427
+ private scheduleFacet?;
428
+ constructor(client: ZenRowsBatchClient, jobId: string, submitResponse?: SubmitJobResponse | undefined);
429
+ /** Operations on the CURRENT run — pause/resume/stop/wait/results/downloads/startExport. */
430
+ get run(): CurrentRun;
431
+ /** Operations on the schedule — pause/resume/update (scheduled jobs only). */
432
+ get schedule(): ScheduleControls;
433
+ /** The job status from the submit response — only known on refs from a `submit*` call. */
434
+ get status(): JobStatus | undefined;
435
+ get acceptedTasks(): number | undefined;
436
+ load(): Promise<JobHandle>;
437
+ close(): Promise<JobHandle>;
438
+ delete(): Promise<void>;
439
+ rerun(options?: {
440
+ status?: string | string[];
441
+ idempotencyKey?: string;
442
+ }): Promise<RunHandle>;
443
+ /** Shortcut for `rerun({ status: "failed" })` (or `"failed,pending"` with `includePending`). */
444
+ retryFailed(options?: {
445
+ includePending?: boolean;
446
+ idempotencyKey?: string;
447
+ }): Promise<RunHandle>;
448
+ addTasks(tasks: BatchTaskLike[], options?: {
449
+ lastBatch?: boolean;
450
+ }): Promise<{
451
+ accepted_tasks: number;
452
+ job_status: JobStatus;
453
+ latest_run: Run;
454
+ }>;
455
+ runs(pageSize?: number): AsyncGenerator<RunHandle>;
456
+ addFileInput(data: Uint8Array | string, options: {
457
+ fields: {
458
+ url: string | number;
459
+ external_id?: string | number;
460
+ };
461
+ header?: boolean;
462
+ delimiter?: string;
463
+ quote?: string;
464
+ }): Promise<string>;
465
+ getWebhook(): Promise<WebhookConfig>;
466
+ setWebhook(url: string, signature: boolean): Promise<WebhookConfig>;
467
+ deleteWebhook(): Promise<void>;
468
+ /** Block until the current run's async-carrier ingestion has finished writing task rows. */
469
+ waitForIngest(options?: {
470
+ timeout?: number;
471
+ pollInterval?: number;
472
+ maxPollInterval?: number;
473
+ }): Promise<JobHandle>;
474
+ }
475
+ declare class JobHandle extends JobRef {
476
+ readonly data: Job;
477
+ constructor(client: ZenRowsBatchClient, jobId: string, data: Job, submitResponse?: SubmitJobResponse);
478
+ get status(): JobStatus;
479
+ }
480
+
481
+ interface BatchClientConfig {
482
+ /** Override the Batch API base URL. Matches the Go/Python batch clients' base-URL override. */
483
+ baseURL?: string;
484
+ /** Retries for transient failures (429/502/503/504 + network errors) on idempotent requests. Default 3. */
485
+ retries?: number;
486
+ }
487
+ interface BatchTask {
488
+ url: string;
489
+ external_id?: string;
490
+ metadata?: Record<string, unknown>;
491
+ zenrows_params?: Record<string, unknown>;
492
+ }
493
+ interface BatchWebhookConfig {
494
+ url: string;
495
+ signature?: boolean;
496
+ }
497
+ interface SubmitJobOptions {
498
+ type?: JobType;
499
+ status?: JobStatus;
500
+ zenrows_params?: Record<string, unknown>;
501
+ tasks?: BatchTask[];
502
+ file_input_id?: string;
503
+ external_id?: string;
504
+ name?: string;
505
+ metadata?: Record<string, unknown>;
506
+ webhook?: BatchWebhookConfig;
507
+ idempotencyKey?: string;
508
+ /** Block until ingestion finishes for a large (202) submission — see `JobRef.waitForIngest`. */
509
+ waitForIngest?: boolean;
510
+ }
511
+ interface SubmitTypedOptions {
512
+ zenrowsParams?: ParamMap;
513
+ externalId?: string;
514
+ name?: string;
515
+ metadata?: Record<string, string>;
516
+ webhook?: BatchWebhookConfig;
517
+ idempotencyKey?: string;
518
+ waitForIngest?: boolean;
519
+ }
520
+ interface ListJobsOptions {
521
+ status?: JobStatus;
522
+ type?: JobType;
523
+ limit?: number;
524
+ cursor?: string;
525
+ }
526
+ interface GetResultsOptions {
527
+ runId?: string;
528
+ cursor?: string;
529
+ limit?: number;
530
+ status?: string;
531
+ }
532
+ interface WaitForRunOptions {
533
+ runId?: string;
534
+ targetStatuses?: Set<string>;
535
+ failureStatuses?: Set<string>;
536
+ timeout?: number;
537
+ pollInterval?: number;
538
+ maxPollInterval?: number;
539
+ }
540
+ type TaskInput = string | {
541
+ url: string;
542
+ external_id?: string;
543
+ metadata?: Record<string, unknown>;
544
+ };
545
+ /**
546
+ * Client for the Zenrows Batch API (async, job/run/task model). Usable standalone
547
+ * (`new ZenRowsBatchClient(apiKey)`, matching the Go and Python SDKs' batch clients) or via
548
+ * the `client.batch` convenience property on a `ZenRows` instance.
549
+ *
550
+ * The **main pattern** is resource-style: `job(id)` / `submit*` return a `JobRef` (id-only,
551
+ * no network); `getJob()` / `iterJobs()` return a loaded `JobHandle` with `.data`. Mutating
552
+ * operations (`close`, `run.stop`, …) return a FRESH handle carrying the server's updated
553
+ * state rather than mutating in place.
554
+ */
555
+ declare class ZenRowsBatchClient {
556
+ readonly apiKey: string;
557
+ private readonly transport;
558
+ constructor(apiKey: string, config?: BatchClientConfig);
559
+ submitJob(options?: SubmitJobOptions): Promise<JobRef>;
560
+ /** Submit a one-shot scraping job (closed, all tasks known upfront). */
561
+ submitRegular(urls?: TaskInput[], fileInputId?: string, opts?: SubmitTypedOptions): Promise<JobRef>;
562
+ /** Submit a streaming-style job that stays open for more tasks via `JobRef.addTasks`. */
563
+ submitOpen(urls?: TaskInput[], opts?: SubmitTypedOptions): Promise<JobRef>;
564
+ /** Submit a scheduled job. `schedule` is one of the `At`/`Rate`/`Calendar` builders. */
565
+ submitScheduled(schedule: Schedule, urls?: TaskInput[], fileInputId?: string, opts?: SubmitTypedOptions): Promise<JobRef>;
566
+ estimateCost(tasks: Iterable<TaskLike>, zenrowsParams?: ParamMap): CostEstimate;
567
+ /** A `JobRef` for an existing job with no network call — prefer this to act on a known id. */
568
+ job(jobId: string): JobRef;
569
+ getJob(jobId: string): Promise<JobHandle>;
570
+ listJobs(options?: ListJobsOptions): Promise<ListJobsResponse>;
571
+ iterJobs(options?: Omit<ListJobsOptions, "cursor">): AsyncGenerator<JobHandle>;
572
+ /** A `RunRef` for an existing run with no network call. */
573
+ run(jobId: string, runId: string): RunRef;
574
+ getRun(jobId: string, runId: string): Promise<RunHandle>;
575
+ listRuns(jobId: string, options?: {
576
+ limit?: number;
577
+ cursor?: string;
578
+ }): Promise<ListJobRunsResponse>;
579
+ iterRuns(jobId: string, pageSize?: number): AsyncGenerator<RunHandle>;
580
+ getResults(jobId: string, options?: GetResultsOptions): Promise<ListResultsResponse>;
581
+ iterResults(jobId: string, options?: {
582
+ runId?: string;
583
+ status?: string;
584
+ }): AsyncGenerator<TaskResult>;
585
+ /** Returns the scraped page's raw content as-is (HTML/text, not JSON). */
586
+ getTaskContent(jobId: string, taskId: string, options?: {
587
+ runId?: string;
588
+ }): Promise<string>;
589
+ getTaskHistory(jobId: string, taskId: string, options?: {
590
+ runId?: string;
591
+ }): Promise<TaskHistoryResponse>;
592
+ downloadToDir(jobId: string, runId: string | undefined, targetDir: string, opts?: DownloadToDirOptions): Promise<number>;
593
+ downloadToMemory(jobId: string, runId: string | undefined, opts?: DownloadToMemoryOptions & {
594
+ status?: string;
595
+ }): Promise<DownloadedResult[]>;
596
+ downloadTaskToFile(task: TaskResult, target: string): Promise<void>;
597
+ downloadTaskToMemory(task: TaskResult): Promise<Buffer>;
598
+ getJobWebhook(jobId: string): Promise<WebhookConfig>;
599
+ putJobWebhook(jobId: string, config: BatchWebhookConfig): Promise<WebhookConfig>;
600
+ deleteJobWebhook(jobId: string): Promise<void>;
601
+ testWebhook(config: BatchWebhookConfig): Promise<TestWebhookResponse>;
602
+ listHmacKeys(): Promise<HMACKeyList>;
603
+ /** Capture the returned `secret` HERE — it is not revealed again. */
604
+ rotateHmacKey(): Promise<HMACKeyCreated>;
605
+ finalizeHmacKey(): Promise<HMACKeyFinalized>;
606
+ cancelHmacRotation(): Promise<void>;
607
+ createJobInput(body: {
608
+ type: "csv";
609
+ csv: {
610
+ delimiter?: string;
611
+ quote?: string;
612
+ header?: boolean;
613
+ fields: {
614
+ url: string | number;
615
+ external_id?: string | number;
616
+ };
617
+ };
618
+ }): Promise<CreateJobInputResponse>;
619
+ /** Allocate a CSV slot + PUT the body. Returns the `file_input_id` to pass to `submitJob`. */
620
+ uploadCsv(data: Uint8Array | string, options: {
621
+ fields: {
622
+ url: string | number;
623
+ external_id?: string | number;
624
+ };
625
+ header?: boolean;
626
+ delimiter?: string;
627
+ quote?: string;
628
+ }): Promise<string>;
629
+ startResultsExport(jobId: string, runId: string): Promise<ExportRef>;
630
+ getResultsExport(jobId: string, runId: string, exportId: string): Promise<ExportHandle>;
631
+ waitForExport(jobId: string, runId: string, exportId: string, options?: {
632
+ targetStatuses?: Set<string>;
633
+ timeout?: number;
634
+ pollInterval?: number;
635
+ maxPollInterval?: number;
636
+ }): Promise<Export>;
637
+ /** Start an export, wait for it, and save the zip to `targetPath`. Capped at 1 GiB per run. */
638
+ downloadAllResults(jobId: string, runId: string, targetPath: string, options?: {
639
+ waitTimeout?: number;
640
+ pollInterval?: number;
641
+ }): Promise<string>;
642
+ waitForRun(jobId: string, options?: WaitForRunOptions): Promise<Run>;
643
+ /** @internal */
644
+ _getJobData(jobId: string): Promise<Job>;
645
+ /** @internal */
646
+ _getRunData(jobId: string, runId: string): Promise<Run>;
647
+ /** @internal */
648
+ _postClose(jobId: string): Promise<Job>;
649
+ /** @internal */
650
+ _postStop(jobId: string): Promise<Run>;
651
+ /** @internal */
652
+ _postPause(jobId: string): Promise<Run>;
653
+ /** @internal */
654
+ _postResume(jobId: string): Promise<Run>;
655
+ /** @internal */
656
+ _delete(jobId: string): Promise<void>;
657
+ /** @internal */
658
+ _deleteRun(jobId: string, runId: string): Promise<void>;
659
+ /** @internal */
660
+ _postRerun(jobId: string, options?: {
661
+ status?: string | string[];
662
+ idempotencyKey?: string;
663
+ }): Promise<RerunJobResponse>;
664
+ /** @internal */
665
+ _putSchedule(jobId: string, schedule: JobSchedule): Promise<Job>;
666
+ /** @internal */
667
+ _postScheduleState(jobId: string, state: "paused" | "active"): Promise<Job>;
668
+ /** @internal */
669
+ _postTasks(jobId: string, tasks: BatchTask[], options?: {
670
+ lastBatch?: boolean;
671
+ }): Promise<AddTasksResponse>;
672
+ /** @internal */
673
+ _postExportStart(jobId: string, runId: string): Promise<StartExportResponse>;
674
+ /** @internal */
675
+ _getExport(jobId: string, runId: string, exportId: string): Promise<Export>;
676
+ /** @internal */
677
+ _waitForRunRaw(jobId: string, options: WaitForRunOptions): Promise<Run>;
678
+ /** @internal */
679
+ _waitForIngestRaw(jobId: string, options?: {
680
+ timeout?: number;
681
+ pollInterval?: number;
682
+ maxPollInterval?: number;
683
+ }): Promise<Job>;
684
+ }
685
+
686
+ /**
687
+ * A non-2xx response from the Batch API, decoded as RFC 7807 `application/problem+json`
688
+ * where possible. `code` is the stable Problem `code` member (e.g. `file_input_not_found`) —
689
+ * safe to branch on; defaults to `"internal"` when the body wasn't valid Problem JSON.
690
+ */
691
+ declare class ZenRowsBatchError extends Error {
692
+ readonly status: number;
693
+ readonly problem: ProblemJson | undefined;
694
+ readonly code: string;
695
+ readonly extras: Record<string, unknown> | undefined;
696
+ constructor(status: number, problem: ProblemJson | undefined, extras?: Record<string, unknown>);
697
+ }
698
+ /**
699
+ * Parse a Problem+JSON error body. Tolerant of non-JSON bodies (production servers
700
+ * occasionally return a raw error page, e.g. from an edge proxy) — degrades to
701
+ * `undefined` rather than throwing.
702
+ */
703
+ declare function parseProblem(response: Response): Promise<{
704
+ problem: ProblemJson | undefined;
705
+ extras: Record<string, unknown> | undefined;
706
+ }>;
707
+
708
+ /** Raised when a waiter's `timeout` elapsed before the target state was reached. */
709
+ declare class WaiterTimeoutError extends Error {
710
+ constructor(message: string);
711
+ }
712
+ /** Raised when the resource entered one of the caller's `isFailure` states. */
713
+ declare class WaiterFailureError extends Error {
714
+ constructor(message: string);
715
+ }
716
+ interface PollUntilOptions<T> {
717
+ isDone(value: T): boolean;
718
+ isFailure?(value: T): boolean;
719
+ timeout?: number;
720
+ initialInterval?: number;
721
+ maxInterval?: number;
722
+ backoff?: number;
723
+ jitter?: number;
724
+ }
725
+ /**
726
+ * Generic poll loop. Calls `fetch()` repeatedly until `isDone(value)` (returns the value),
727
+ * `isFailure(value)` (throws `WaiterFailureError`), or `timeout` seconds elapse (throws
728
+ * `WaiterTimeoutError`). The wait between calls starts at `initialInterval`, multiplies by
729
+ * `backoff` each iteration, caps at `maxInterval`, and is jittered by ±`jitter` fraction so
730
+ * concurrent waiters don't synchronise into thundering-herd patterns against the API.
731
+ */
732
+ declare function pollUntil<T>(fetch: () => Promise<T> | T, { isDone, isFailure, timeout, initialInterval, maxInterval, backoff, jitter, }: PollUntilOptions<T>): Promise<T>;
733
+
4
734
  type HttpMethods = "GET" | "POST" | "PUT";
735
+ /** Extract mode — see https://docs.zenrows.com for what each mode returns. */
736
+ type ExtractMode = "auto" | "native" | "standard";
5
737
  interface ClientConfig {
6
738
  concurrency?: number;
7
739
  retries?: number;
8
740
  }
9
741
  interface ZenRowsConfig {
742
+ /** Set to "auto" to enable Adaptive Stealth Mode — Zenrows starts with the cheapest
743
+ * viable request configuration and escalates to js_render/premium_proxy only when the
744
+ * target needs it, billing only for the configuration that succeeds. */
745
+ mode?: "auto";
10
746
  autoparse?: boolean;
11
747
  css_extractor?: string;
12
748
  js_render?: boolean;
@@ -36,8 +772,41 @@ declare class ZenRows {
36
772
  data?: unknown;
37
773
  }, Response>;
38
774
  readonly fetchWithRetry: (input: string | URL | Request, init?: (RequestInit & fetch_retry.RequestInitRetryParams<typeof fetch>) | undefined) => Promise<Response>;
775
+ /** Client for the Batch API (async job/run/task model) — see `./batch.ts`. */
776
+ readonly batch: ZenRowsBatchClient;
39
777
  constructor(apiKey: string, clientConfig?: ClientConfig);
40
- get(url: string, config?: ZenRowsConfig, { headers }?: {
778
+ /**
779
+ * Fetch a URL through Zenrows — the main page-scraping product. This is the primary entry
780
+ * point; `get()` remains as a deprecated alias for existing callers.
781
+ */
782
+ fetch(url: string, config?: ZenRowsConfig, { headers }?: {
783
+ headers?: Headers;
784
+ }): Promise<Response>;
785
+ /** @deprecated Use `fetch()` instead. Kept for backward compatibility. */
786
+ get(url: string, config?: ZenRowsConfig, opts?: {
787
+ headers?: Headers;
788
+ }): Promise<Response>;
789
+ /**
790
+ * Fetch a URL and run it through Extract — Zenrows' AI-powered structured extraction
791
+ * (beta). `mode` defaults to `"auto"`; pass `"native"` or `"standard"` to pick a
792
+ * different extraction contract. This is a thin, typed wrapper over `fetch()` with the
793
+ * `extract` param set — no separate endpoint or auth.
794
+ *
795
+ * Also sends Adaptive Stealth Mode (`mode: "auto"`) by default, so a target that needs
796
+ * `js_render`/`premium_proxy` gets escalated automatically instead of failing with
797
+ * REQS002 — pass `adaptiveStealth: false` to disable that and set `js_render`/
798
+ * `premium_proxy` yourself.
799
+ *
800
+ * `extract=auto` is a domain-gated open beta: when the target domain isn't enabled yet,
801
+ * the API returns a 402 with `code: "AUTH010"`. By default this method catches that and
802
+ * retries once with `autoparse: true` instead of returning the error response — pass
803
+ * `fallbackToAutoparse: false` to disable that and get the raw AUTH010 response back.
804
+ */
805
+ extract(url: string, config?: ZenRowsConfig & {
806
+ extract?: ExtractMode;
807
+ fallbackToAutoparse?: boolean;
808
+ adaptiveStealth?: boolean;
809
+ }, opts?: {
41
810
  headers?: Headers;
42
811
  }): Promise<Response>;
43
812
  post(url: string, config?: ZenRowsConfig, { headers, data }?: {
@@ -47,4 +816,4 @@ declare class ZenRows {
47
816
  private worker;
48
817
  }
49
818
 
50
- export { ZenRows, type ZenRowsConfig };
819
+ export { AUTO_MAX_CREDITS, AUTO_MIN_CREDITS, type AddTasksResponse, At, BASE_CREDITS, type BatchClientConfig, type BatchTask, type BatchWebhookConfig, type Cadence, Calendar, type CostEstimate, type CostLine, type CreateJobInputResponse, CurrentRun, DEFAULT_MAX_BYTES_PER_FILE, DEFAULT_MAX_COUNT_IN_MEMORY, DEFAULT_MAX_FILES, DEFAULT_MAX_TOTAL_BYTES_IN_MEMORY, Daily, type DownloadToDirOptions, type DownloadToMemoryOptions, type DownloadedResult, type EstimateTask, type Export, ExportHandle, ExportRef, type ExportStatus, type ExtractMode, type FileInputUploadTarget, type GetResultsOptions, type HMACKeyCreated, type HMACKeyFinalized, type HMACKeyList, type HMACKeyMeta, type IngestStatus, JS_AND_PROXY_CREDITS, JS_CREDITS, type Job, JobHandle, JobRef, type JobSchedule, type JobStatus, type JobType, type ListJobRunsResponse, type ListJobsOptions, type ListJobsResponse, type ListResultsResponse, Monthly, PREMIUM_PROXY_CREDITS, type ParamMap, type ParamValue, type PauseState, type PollUntilOptions, type ProblemJson, Rate, type RerunJobResponse, type Run, RunHandle, RunRef, type RunStats, type RunStatus, type Schedule, type ScheduleState, type Spend, type StartExportResponse, type SubmitJobOptions, type SubmitJobResponse, type SubmitTypedOptions, type TaskHistoryEvent, type TaskHistoryResponse, type TaskLike, type TaskResult, type TaskSpend, type TaskStatus, type TestWebhookResponse, type Tier, type WaitForRunOptions, WaiterFailureError, WaiterTimeoutError, type WebhookConfig, Weekly, ZenRows, ZenRowsBatchClient, ZenRowsBatchError, type ZenRowsConfig, downloadTaskToFile, downloadTaskToMemory, downloadToDir, downloadToMemory, estimateCost, parseProblem, pollUntil };