@datafuel/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -24,7 +24,8 @@ interface Proxy {
24
24
  asn?: string;
25
25
  /**
26
26
  * Sticky session: the same exit across requests, `ttl` in seconds. Read by
27
- * `scrape` and `map` only, and sent in attributes rather than the envelope.
27
+ * `scrape`, `map`, URL jobs and crawls, and sent in attributes rather than
28
+ * the envelope.
28
29
  */
29
30
  sessionId?: string;
30
31
  ttl?: number;
@@ -53,6 +54,7 @@ interface ScrapeOptions {
53
54
  jsRendering?: boolean;
54
55
  waitFor?: string;
55
56
  waitForTimeoutMs?: number;
57
+ /** An object keyed by action, e.g. `{ click: "#more" }`. `df.jsInstructions()` lists them. */
56
58
  jsInstructions?: unknown;
57
59
  blockResource?: string;
58
60
  /** Markdown only: always render just the `<main>` / `<article>` container. */
@@ -198,6 +200,9 @@ interface CrawlStatus {
198
200
  total_cost: number;
199
201
  /** Whether the crawl reached a final state. */
200
202
  done: boolean;
203
+ /** RFC 3339. */
204
+ created_at?: string;
205
+ updated_at?: string;
201
206
  }
202
207
  /** One page of crawl results. */
203
208
  interface CrawlResultsPage {
@@ -220,6 +225,11 @@ interface JobStatus {
220
225
  total_cost: number;
221
226
  done: boolean;
222
227
  }
228
+ /** A cancelled job or crawl: its final progress and what was refunded. */
229
+ interface CancelResult extends JobStatus {
230
+ refunded_tasks: number;
231
+ refunded_credits: number;
232
+ }
223
233
  /** Every task of a job. A job completes even when some of its tasks failed. */
224
234
  interface JobResults {
225
235
  id: string;
@@ -228,6 +238,168 @@ interface JobResults {
228
238
  tasks_complete: number;
229
239
  tasks: Result[];
230
240
  }
241
+ /** A task type, as the list and analytics filters take it. */
242
+ type TaskType = "unlocker" | "llm_scraping" | "serp" | "map" | "crawl" | (string & {});
243
+ /** Filters shared by {@link DataFuel.listJobs} and {@link DataFuel.listTasks}. */
244
+ interface ListOptions {
245
+ status?: Status;
246
+ type?: TaskType;
247
+ /** Created on or after this day (UTC). A Date is sent as its UTC day. */
248
+ startDate?: string | Date;
249
+ /** Created on or before this day (UTC, inclusive). */
250
+ endDate?: string | Date;
251
+ /** Items per page. API default 50, max 200. */
252
+ limit?: number;
253
+ /** `nextCursor` of the previous page. */
254
+ cursor?: string;
255
+ }
256
+ /** {@link ListOptions} plus the job or crawl the tasks belong to. */
257
+ interface ListTasksOptions extends ListOptions {
258
+ jobId?: string;
259
+ }
260
+ /** A job or crawl in a list, with the same counters as {@link JobStatus}. */
261
+ interface JobSummary extends JobStatus {
262
+ id: string;
263
+ /** `crawl` for a crawl, otherwise the task type of the batch. */
264
+ type: TaskType;
265
+ /** RFC 3339. */
266
+ created_at: string;
267
+ updated_at: string;
268
+ }
269
+ /** One page of jobs, newest first. */
270
+ interface JobsPage {
271
+ jobs: JobSummary[];
272
+ /** Absent on the last page. */
273
+ nextCursor?: string;
274
+ }
275
+ /** A task in a list. It has no result: fetch that with {@link DataFuel.getTask}. */
276
+ interface TaskSummary {
277
+ id: string;
278
+ /** `null` for a task created on its own rather than by a job or crawl. */
279
+ job_id: string | null;
280
+ type: TaskType;
281
+ status: Status;
282
+ /** Absent for `llm_scraping` and `serp`. */
283
+ url?: string;
284
+ /** Charged when queued; a failed task is refunded. */
285
+ credit_cost: number;
286
+ /** RFC 3339. */
287
+ created_at: string;
288
+ processed_at?: string;
289
+ failed_at?: string;
290
+ }
291
+ /** One page of tasks, newest first. */
292
+ interface TasksPage {
293
+ tasks: TaskSummary[];
294
+ /** Absent on the last page. */
295
+ nextCursor?: string;
296
+ }
297
+ /** What moved credits on the account. */
298
+ type TransactionOperation = "plan_assignment" | "purchase" | "usage" | "refund" | "topup" | "expiry" | "adjustment" | (string & {});
299
+ /** Filters and paging for {@link DataFuel.transactions}. */
300
+ interface TransactionsOptions {
301
+ operation?: TransactionOperation;
302
+ startDate?: string | Date;
303
+ endDate?: string | Date;
304
+ /** 1-based. API default 1. */
305
+ page?: number;
306
+ /** API default 10, max 200. */
307
+ limit?: number;
308
+ }
309
+ /** One credit movement. `amount` is negative for usage and expiry. */
310
+ interface Transaction {
311
+ id: number;
312
+ amount: number;
313
+ operation: TransactionOperation;
314
+ /** What `reference_id` points to, e.g. `task_id` or `job_id`. */
315
+ reference_type: string;
316
+ reference_id: string;
317
+ /** The balance right after this movement. */
318
+ balance_after?: number;
319
+ /** RFC 3339. */
320
+ created_at: string;
321
+ }
322
+ /** Total of one operation over the whole filtered range, not just the page. */
323
+ interface TransactionSum {
324
+ operation: TransactionOperation;
325
+ total: number;
326
+ count: number;
327
+ }
328
+ /** One page of credit movements, newest first. */
329
+ interface TransactionsPage {
330
+ transactions: Transaction[];
331
+ /** Movements matching the filters across all pages. */
332
+ total_count: number;
333
+ sums: TransactionSum[];
334
+ }
335
+ /** Range and grouping for {@link DataFuel.analytics}. */
336
+ interface AnalyticsOptions {
337
+ /** API default 30 days ago. The range may span at most 365 days. */
338
+ startDate?: string | Date;
339
+ /** Inclusive. API default today. */
340
+ endDate?: string | Date;
341
+ /** Time series bucket. API default `daily`. */
342
+ interval?: "hourly" | "daily" | "weekly" | "monthly";
343
+ /** Restrict to one task type. */
344
+ module?: TaskType;
345
+ }
346
+ /** Task counts and net credits of one slice. Failed tasks are refunded and count 0 credits. */
347
+ interface AnalyticsCounts {
348
+ total: number;
349
+ completed: number;
350
+ failed: number;
351
+ credits_used: number;
352
+ }
353
+ /** Tasks by the HTTP status the target answered. `status_code` 0 means no answer (timeout, DNS). */
354
+ interface StatusCodeBreakdown {
355
+ status_code: number;
356
+ count: number;
357
+ completed: number;
358
+ failed: number;
359
+ credits_used: number;
360
+ avg_credits_per_request: number;
361
+ }
362
+ /** The same figures for the equally long period before, and the change in percent. */
363
+ interface PreviousPeriod {
364
+ credits_used: number;
365
+ fulfilled_requests: number;
366
+ failed_requests: number;
367
+ failed_percentage: number;
368
+ efficiency_score: number;
369
+ credits_used_change: number;
370
+ fulfilled_requests_change: number;
371
+ failed_requests_change: number;
372
+ efficiency_score_change: number;
373
+ }
374
+ /** Usage over a date range. Percentages are 0-100. */
375
+ interface Analytics {
376
+ summary: {
377
+ total_tasks: number;
378
+ credits_used: number;
379
+ fulfilled_requests: number;
380
+ failed_requests: number;
381
+ failed_percentage: number;
382
+ success_rate: number;
383
+ efficiency_score: number;
384
+ avg_credits_per_request: number;
385
+ avg_duration_ms: number;
386
+ previous_period?: PreviousPeriod | null;
387
+ };
388
+ timeseries: (AnalyticsCounts & {
389
+ period: string;
390
+ })[];
391
+ by_module: (AnalyticsCounts & {
392
+ module: string;
393
+ success_rate: number;
394
+ avg_credits_per_request: number;
395
+ avg_duration_ms: number;
396
+ status_codes: StatusCodeBreakdown[];
397
+ })[];
398
+ top_targets: (AnalyticsCounts & {
399
+ target: string;
400
+ })[];
401
+ by_status_code: StatusCodeBreakdown[];
402
+ }
231
403
  /** The account behind the API key. */
232
404
  interface Profile {
233
405
  email: string;
@@ -237,6 +409,39 @@ interface Profile {
237
409
  credit_balance: number;
238
410
  monthly_credit_limit: number;
239
411
  }
412
+ /** One argument of a browser action. */
413
+ interface JsInstructionArg {
414
+ name: string;
415
+ type: string;
416
+ values?: string[];
417
+ required: boolean;
418
+ }
419
+ /** One browser action `jsInstructions` accepts. */
420
+ interface JsInstruction {
421
+ action: string;
422
+ description: string;
423
+ /** Shape of the value: scalar, array or object. */
424
+ value: string;
425
+ args: JsInstructionArg[];
426
+ /** Whether it can target an element inside an iframe. */
427
+ iframe: boolean;
428
+ example: unknown;
429
+ }
430
+ /** A named proxy location: a city, or an ASN. */
431
+ interface ProxyLocation {
432
+ code: string;
433
+ name: string;
434
+ }
435
+ /** A proxy country with its regions and their cities. */
436
+ interface ProxyCountry {
437
+ code: string;
438
+ name: string;
439
+ regions: {
440
+ code: string;
441
+ name: string;
442
+ cities: ProxyLocation[];
443
+ }[];
444
+ }
240
445
  /** One task type or LLM engine, and whether it accepts new work. */
241
446
  interface Capability {
242
447
  name: string;
@@ -265,13 +470,14 @@ declare class Capabilities {
265
470
 
266
471
  declare const DEFAULT_BASE_URL = "https://scraping-api.datafuel.ai/api/v1";
267
472
  /** Kept in step with package.json by a test; see test/hardening.test.ts. */
268
- declare const VERSION = "0.1.0";
473
+ declare const VERSION = "0.2.0";
269
474
  /** Options for the llm_scraping module, which reads its proxy country here. */
270
475
  interface AskOptions {
271
476
  engine: Engine | string;
272
477
  websearch?: boolean;
273
478
  followUp?: string;
274
479
  country?: string;
480
+ location?: string;
275
481
  format?: string;
276
482
  }
277
483
  /** Options for `map`. */
@@ -303,6 +509,40 @@ interface CrawlOptions extends ScrapeOptions {
303
509
  /** Pages in flight, default 5. */
304
510
  concurrency?: number;
305
511
  }
512
+ /** Options for `search`, the Google SERP module. Proxy type is not used. */
513
+ interface SearchOptions {
514
+ /** Google `gl`, e.g. "us". */
515
+ country?: string;
516
+ /** Google `hl`, e.g. "en". */
517
+ language?: string;
518
+ /** Canonical location name. Give at most one of location, uule, lat/lon. */
519
+ location?: string;
520
+ /** 1-based, default 1. */
521
+ page?: number;
522
+ /** e.g. "google.de". */
523
+ googleDomain?: string;
524
+ uule?: string;
525
+ lat?: number;
526
+ lon?: number;
527
+ /** Metres around lat/lon or location, max 1000. */
528
+ radius?: number;
529
+ cr?: string;
530
+ lr?: string;
531
+ tbs?: string;
532
+ safe?: "active" | "off";
533
+ nfpr?: boolean;
534
+ filter?: boolean;
535
+ uds?: string;
536
+ kgmid?: string;
537
+ si?: string;
538
+ ludocid?: string;
539
+ lsig?: string;
540
+ ibp?: string;
541
+ /** Exit country of the request. */
542
+ proxyCountry?: string;
543
+ /** Default json. */
544
+ format?: "json" | "html" | "markdown";
545
+ }
306
546
 
307
547
  /** The client. It only moves bytes; `core` decides what goes on the wire. */
308
548
 
@@ -332,7 +572,8 @@ interface ClientOptions {
332
572
  *
333
573
  * Pick the call by the shape of the work: one URL is {@link scrape}, a site's
334
574
  * URL list is {@link map}, many pages from a start URL is {@link crawl}, a list
335
- * of known URLs is {@link runJob}, a question for an AI engine is {@link ask}.
575
+ * of known URLs is {@link runJob}, a question for an AI engine is {@link ask}, a
576
+ * Google search is {@link search}.
336
577
  *
337
578
  * Every write carries an `Idempotency-Key`, generated per request, so a retry
338
579
  * attaches to the task already running instead of charging twice.
@@ -375,6 +616,8 @@ declare class DataFuel {
375
616
  getTask(taskId: string, options?: CallOptions): Promise<Result>;
376
617
  /** Send a prompt to an AI engine and return its answer. */
377
618
  ask(prompt: string, options: AskOptions & CallOptions): Promise<Result>;
619
+ /** Run a Google search and return the results page, parsed to JSON by default. */
620
+ search(query: string, options?: SearchOptions & CallOptions): Promise<Result>;
378
621
  /**
379
622
  * List the URLs of a site without scraping them.
380
623
  *
@@ -390,6 +633,11 @@ declare class DataFuel {
390
633
  * refunded. Unset limits use the API defaults: 100 pages, depth 3, 5 in flight.
391
634
  */
392
635
  startCrawl(url: string, options?: CrawlOptions & CallOptions): Promise<string>;
636
+ /**
637
+ * Stop a crawl. Queued pages are refunded, pages in flight finish and bill.
638
+ * Throws {@link JobNotCancellable} when it already finished.
639
+ */
640
+ cancelCrawl(crawlId: string, options?: CallOptions): Promise<CancelResult>;
393
641
  /** Return the progress of a crawl. */
394
642
  getCrawl(crawlId: string, options?: CallOptions): Promise<CrawlStatus>;
395
643
  /** One page of results, in discovery order. `limit` unset uses the API default. */
@@ -430,8 +678,17 @@ declare class DataFuel {
430
678
  createAskJob(prompts: string[], options: AskOptions & CallOptions & {
431
679
  sequential?: boolean;
432
680
  }): Promise<string>;
681
+ /** Queue a batch of Google searches and return the job id. */
682
+ createSearchJob(queries: string[], options?: SearchOptions & CallOptions & {
683
+ sequential?: boolean;
684
+ }): Promise<string>;
433
685
  /** Return the progress of a job. */
434
686
  getJob(jobId: string, options?: CallOptions): Promise<JobStatus>;
687
+ /**
688
+ * Stop a job. Queued tasks are refunded, tasks in flight finish and bill.
689
+ * Throws {@link JobNotCancellable} when it already finished.
690
+ */
691
+ cancelJob(jobId: string, options?: CallOptions): Promise<CancelResult>;
435
692
  /**
436
693
  * Return the per-task results of a job.
437
694
  *
@@ -439,6 +696,13 @@ declare class DataFuel {
439
696
  * `task.raiseForStatus()` per task.
440
697
  */
441
698
  jobResults(jobId: string, options?: CallOptions): Promise<JobResults>;
699
+ /** One page of your jobs and crawls, newest first. Pass `nextCursor` back as `cursor`. */
700
+ listJobs(options?: ListOptions & CallOptions): Promise<JobsPage>;
701
+ /**
702
+ * One page of your tasks, newest first, including those of jobs and crawls.
703
+ * Items carry no result: fetch it with {@link getTask}.
704
+ */
705
+ listTasks(options?: ListTasksOptions & CallOptions): Promise<TasksPage>;
442
706
  /** Poll until the job is done. Without `timeoutMs` it waits indefinitely. */
443
707
  waitJob(jobId: string, options?: CallOptions): Promise<JobStatus>;
444
708
  /** Create a job, wait for it, and return its results. */
@@ -449,10 +713,31 @@ declare class DataFuel {
449
713
  runAskJob(prompts: string[], options: AskOptions & CallOptions & {
450
714
  sequential?: boolean;
451
715
  }): Promise<JobResults>;
452
- /** Which task types and LLM engines are switched on right now. */
716
+ /** Create a search job, wait for it, and return its results. */
717
+ runSearchJob(queries: string[], options?: SearchOptions & CallOptions & {
718
+ sequential?: boolean;
719
+ }): Promise<JobResults>;
720
+ /** Which task types and LLM engines are switched on right now. Needs no key. */
453
721
  capabilities(options?: CallOptions): Promise<Capabilities>;
722
+ /** The browser actions `jsInstructions` accepts, with their arguments. Needs no key. */
723
+ jsInstructions(options?: CallOptions): Promise<JsInstruction[]>;
724
+ /** Countries, regions and cities a proxy type can exit from. */
725
+ proxyLocations(options?: CallOptions & {
726
+ proxyType?: string;
727
+ }): Promise<ProxyCountry[]>;
728
+ /** ASNs a proxy type can exit from in one country (ISO 3166-1 alpha-2). */
729
+ proxyAsns(country: string, options?: CallOptions & {
730
+ proxyType?: string;
731
+ }): Promise<ProxyLocation[]>;
454
732
  /** Remaining credits. */
455
733
  balance(options?: CallOptions): Promise<number>;
734
+ /**
735
+ * Credit movements, newest first: purchases, usage, refunds, expiry.
736
+ * `sums` totals each operation over the whole range, not just this page.
737
+ */
738
+ transactions(options?: TransactionsOptions & CallOptions): Promise<TransactionsPage>;
739
+ /** Usage over a date range: totals, a time series and breakdowns. Default: the last 30 days. */
740
+ analytics(options?: AnalyticsOptions & CallOptions): Promise<Analytics>;
456
741
  /** The account behind the API key. */
457
742
  me(options?: CallOptions): Promise<Profile>;
458
743
  /**
@@ -486,10 +771,12 @@ declare class NoApiKey extends DataFuelError {
486
771
  /** The request never got an answer: DNS, connection, abort, read timeout. */
487
772
  declare class TransportError extends DataFuelError {
488
773
  }
774
+ /** The `code` of an API error. The API may add codes; unknown ones pass through. */
775
+ type ErrorCode = "UNAUTHORIZED" | "INVALID_API_KEY" | "FORBIDDEN" | "INSUFFICIENT_CREDITS" | "RATE_LIMIT_EXCEEDED" | "CONCURRENCY_LIMIT_REACHED" | "INVALID_REQUEST_BODY" | "INVALID_ATTRIBUTES" | "MISSING_TARGET" | "UNSUPPORTED_TASK_TYPE" | "JOB_REQUIRES_MULTIPLE_TARGETS" | "INVALID_IDEMPOTENCY_KEY" | "IDEMPOTENCY_KEY_REUSED" | "INVALID_TASK_ID" | "INVALID_JOB_ID" | "TASK_NOT_FOUND" | "JOB_NOT_FOUND" | "CRAWL_NOT_FOUND" | "JOB_NOT_CANCELLABLE" | "INVALID_CRAWL_PATTERN" | "CRAWL_UNSUPPORTED_OPTION" | "INVALID_CURSOR" | "INVALID_QUERY_PARAM" | "INVALID_PROXY_TYPE" | "INVALID_COUNTRY" | "INVALID_DATE_FORMAT" | "INVALID_DATE_RANGE" | "INVALID_INTERVAL" | "MODULE_UNAVAILABLE" | "ENGINE_UNAVAILABLE" | "API_KEY_RESET_FAILED" | "TASK_RESULT_TIMEOUT" | "INTERNAL_ERROR" | (string & {});
489
776
  /** A non-2xx answer from the API itself. */
490
777
  declare class APIError extends DataFuelError {
491
778
  readonly status: number;
492
- readonly code: string;
779
+ readonly code: ErrorCode;
493
780
  /** Seconds the API asked us to wait, from Retry-After. 0 when absent. */
494
781
  readonly retryAfter: number;
495
782
  constructor(status: number, code: string, message: string, retryAfter?: number);
@@ -497,6 +784,9 @@ declare class APIError extends DataFuelError {
497
784
  /** 401: the API key is missing or invalid. */
498
785
  declare class Unauthorized extends APIError {
499
786
  }
787
+ /** 403 FORBIDDEN: the account is inactive. */
788
+ declare class Forbidden extends APIError {
789
+ }
500
790
  /** 404: unknown id, or one that belongs to another account. */
501
791
  declare class NotFound extends APIError {
502
792
  }
@@ -512,7 +802,10 @@ declare class InvalidAttributes extends APIError {
512
802
  /** 422: the key was already used for a different request. */
513
803
  declare class IdempotencyKeyReused extends APIError {
514
804
  }
515
- /** 503: an operator switched something off. The message carries the reason. */
805
+ /** 409 JOB_NOT_CANCELLABLE: the job or crawl already finished. */
806
+ declare class JobNotCancellable extends APIError {
807
+ }
808
+ /** 503: an operator switched something off, or a dependency is down. The message carries the reason. */
516
809
  declare class Unavailable extends APIError {
517
810
  }
518
811
  /** 503 MODULE_UNAVAILABLE: this task type is switched off. Nothing was charged. */
@@ -551,4 +844,4 @@ declare class WaitTimeout extends DataFuelError {
551
844
  constructor(message: string, id?: string, status?: unknown);
552
845
  }
553
846
 
554
- export { type AI, APIError, type AskOptions, Blocked, type CallOptions, Capabilities, type Capability, type ClientOptions, type CrawlOptions, CrawlPage, type CrawlResult, type CrawlResultsPage, type CrawlStatus, DEFAULT_BASE_URL, DataFuel, DataFuelError, type Engine, EngineUnavailable, type Format, IdempotencyKeyReused, InsufficientCredits, InvalidAttributes, type JobResults, type JobStatus, type Link, type MapOptions, ModuleUnavailable, NoApiKey, NotFound, type Payload, type Profile, type Proxy, type ProxyType, RateLimited, Result, type ScrapeOptions, type SiteMap, type Status, TaskFailed, TransportError, Unauthorized, Unavailable, VERSION, WaitTimeout, isDone };
847
+ export { type AI, APIError, type Analytics, type AnalyticsCounts, type AnalyticsOptions, type AskOptions, Blocked, type CallOptions, type CancelResult, Capabilities, type Capability, type ClientOptions, type CrawlOptions, CrawlPage, type CrawlResult, type CrawlResultsPage, type CrawlStatus, DEFAULT_BASE_URL, DataFuel, DataFuelError, type Engine, EngineUnavailable, type ErrorCode, Forbidden, type Format, IdempotencyKeyReused, InsufficientCredits, InvalidAttributes, JobNotCancellable, type JobResults, type JobStatus, type JobSummary, type JobsPage, type JsInstruction, type JsInstructionArg, type Link, type ListOptions, type ListTasksOptions, type MapOptions, ModuleUnavailable, NoApiKey, NotFound, type Payload, type PreviousPeriod, type Profile, type Proxy, type ProxyCountry, type ProxyLocation, type ProxyType, RateLimited, Result, type ScrapeOptions, type SearchOptions, type SiteMap, type Status, type StatusCodeBreakdown, TaskFailed, type TaskSummary, type TaskType, type TasksPage, type Transaction, type TransactionOperation, type TransactionSum, type TransactionsOptions, type TransactionsPage, TransportError, Unauthorized, Unavailable, VERSION, WaitTimeout, isDone };