zenrows 2.0.2 → 2.1.1

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