firecrawl 4.39.0 → 4.41.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/README.md +46 -0
- package/dist/{chunk-4DPCCKWG.js → chunk-I2DFXQYR.js} +1 -1
- package/dist/index.cjs +169 -10
- package/dist/index.d.cts +167 -13
- package/dist/index.d.ts +167 -13
- package/dist/index.js +168 -10
- package/dist/{package-D2QZMRW7.js → package-V72LKFNW.js} +1 -1
- package/package.json +1 -1
- package/pnpm-workspace.yaml +2 -2
- package/src/__tests__/unit/v2/extract.unit.test.ts +23 -0
- package/src/__tests__/unit/v2/threat-protection.unit.test.ts +18 -1
- package/src/__tests__/unit/v2/tools.unit.test.ts +297 -0
- package/src/v2/client.ts +39 -3
- package/src/v2/methods/extract.ts +2 -1
- package/src/v2/methods/scrape.ts +3 -1
- package/src/v2/methods/search.ts +8 -1
- package/src/v2/methods/tools.ts +137 -0
- package/src/v2/types.ts +186 -9
- package/src/v2/utils/errorHandler.ts +19 -3
package/src/v2/types.ts
CHANGED
|
@@ -188,6 +188,16 @@ export interface AuditMetadata {
|
|
|
188
188
|
username: string;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* OCR raster images (PNG, JPEG, JPEG 2000, TIFF, GIF, BMP, WebP, AVIF) as
|
|
193
|
+
* one-page documents. Part of the default parsers list next to "pdf"; takes
|
|
194
|
+
* no options, so the string "image" is equivalent. Omit it from an explicit
|
|
195
|
+
* list to keep image URLs failing as unsupported files.
|
|
196
|
+
*/
|
|
197
|
+
export type ImageParser = {
|
|
198
|
+
type: "image";
|
|
199
|
+
};
|
|
200
|
+
|
|
191
201
|
export type PDFParser = {
|
|
192
202
|
type: "pdf";
|
|
193
203
|
mode?: "fast" | "auto" | "ocr";
|
|
@@ -249,7 +259,7 @@ export interface ScrapeOptions {
|
|
|
249
259
|
timeout?: number;
|
|
250
260
|
waitFor?: number;
|
|
251
261
|
mobile?: boolean;
|
|
252
|
-
parsers?: Array<string | PDFParser>;
|
|
262
|
+
parsers?: Array<string | PDFParser | ImageParser>;
|
|
253
263
|
actions?: ActionOption[];
|
|
254
264
|
location?: LocationConfig;
|
|
255
265
|
skipTlsVerification?: boolean;
|
|
@@ -275,6 +285,10 @@ export interface ScrapeOptions {
|
|
|
275
285
|
};
|
|
276
286
|
integration?: string;
|
|
277
287
|
origin?: string;
|
|
288
|
+
/** Include domain-matched Alexandria tools for this URL in `tools`. Default off. */
|
|
289
|
+
domainTools?: boolean;
|
|
290
|
+
/** Summary by default; compact returns identity and description, full includes contracts. */
|
|
291
|
+
toolDetail?: "compact" | "summary" | "full";
|
|
278
292
|
}
|
|
279
293
|
|
|
280
294
|
export type RedactPIIEntity =
|
|
@@ -304,8 +318,14 @@ export interface RedactPIIOptions {
|
|
|
304
318
|
* fields you provide replace the team policy's values.
|
|
305
319
|
*/
|
|
306
320
|
export interface ThreatProtectionOptions {
|
|
307
|
-
/**
|
|
308
|
-
|
|
321
|
+
/**
|
|
322
|
+
* "off" disables scanning for this request; "manual-only" enforces only the
|
|
323
|
+
* blacklist / whitelist / blocked TLDs (no provider scan, no scan fee);
|
|
324
|
+
* "normal" scans with Google Web Risk; "zscaler" classifies through your
|
|
325
|
+
* organization's Zscaler connection. Enforced teams may raise the mode per
|
|
326
|
+
* request but never lower it.
|
|
327
|
+
*/
|
|
328
|
+
mode?: "off" | "manual-only" | "normal" | "zscaler";
|
|
309
329
|
/** Block verdicts at or above this risk score (integer 0-100). */
|
|
310
330
|
riskScoreThreshold?: number;
|
|
311
331
|
/** Exact domains or globs like "*.example.com" to always block (max 1000). */
|
|
@@ -340,6 +360,7 @@ export type ParseOptions = Omit<
|
|
|
340
360
|
| "lockdown"
|
|
341
361
|
| "proxy"
|
|
342
362
|
| "threatProtection"
|
|
363
|
+
| "toolDetail"
|
|
343
364
|
> & {
|
|
344
365
|
formats?: ParseFormatOption[];
|
|
345
366
|
proxy?: "basic" | "auto";
|
|
@@ -685,6 +706,8 @@ export interface Document {
|
|
|
685
706
|
pages?: PdfPage[];
|
|
686
707
|
/** Typed PDF layout blocks, present only when `parsers[].blocks` is true. */
|
|
687
708
|
blocks?: PdfPageBlocks[];
|
|
709
|
+
/** Present when `domainTools` discovered contracts matching this URL. */
|
|
710
|
+
tools?: DiscoveredTool[];
|
|
688
711
|
}
|
|
689
712
|
|
|
690
713
|
// Pagination configuration for auto-fetching pages from v2 endpoints that return a `next` URL
|
|
@@ -797,9 +820,130 @@ export interface SearchResultImages {
|
|
|
797
820
|
}
|
|
798
821
|
|
|
799
822
|
export interface SearchData {
|
|
823
|
+
warning?: string;
|
|
800
824
|
web?: Array<SearchResultWeb | Document>;
|
|
801
825
|
news?: Array<SearchResultNews | Document>;
|
|
802
826
|
images?: Array<SearchResultImages | Document>;
|
|
827
|
+
tools?: DiscoveredTool[];
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/** A complete tool contract returned by semantic or contextual discovery. */
|
|
831
|
+
export interface DiscoveredTool {
|
|
832
|
+
next?: AlexandriaCall;
|
|
833
|
+
id?: string;
|
|
834
|
+
provider: string;
|
|
835
|
+
capability: string;
|
|
836
|
+
name?: string;
|
|
837
|
+
description: string;
|
|
838
|
+
creditsCost?: number;
|
|
839
|
+
perRecord?: boolean;
|
|
840
|
+
options?: Array<{
|
|
841
|
+
name: string;
|
|
842
|
+
type: string;
|
|
843
|
+
required?: boolean;
|
|
844
|
+
[key: string]: unknown;
|
|
845
|
+
}>;
|
|
846
|
+
requiresOneOf?: string[][];
|
|
847
|
+
response?: {
|
|
848
|
+
about?: string;
|
|
849
|
+
key?: string;
|
|
850
|
+
fields?: Array<{ name: string; type: string; [key: string]: unknown }>;
|
|
851
|
+
[key: string]: unknown;
|
|
852
|
+
};
|
|
853
|
+
examples?: Partial<Record<"javascript" | "python" | "curl", string>> &
|
|
854
|
+
Record<string, string>;
|
|
855
|
+
example?: {
|
|
856
|
+
recordedAt: string;
|
|
857
|
+
request: Record<string, unknown>;
|
|
858
|
+
response: unknown;
|
|
859
|
+
};
|
|
860
|
+
label?: string;
|
|
861
|
+
whenToUse?: string;
|
|
862
|
+
returns?: unknown;
|
|
863
|
+
discovery?: unknown;
|
|
864
|
+
attribution?: unknown;
|
|
865
|
+
matchedBy?: Array<"semantic" | "domain">;
|
|
866
|
+
matchedUrls?: string[];
|
|
867
|
+
concept?: string;
|
|
868
|
+
cohorts?: string[];
|
|
869
|
+
similarity?: number;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
export interface FindToolsOptions {
|
|
873
|
+
urls?: string[];
|
|
874
|
+
providers?: string[];
|
|
875
|
+
categories?: string[];
|
|
876
|
+
groups?: string[];
|
|
877
|
+
capabilities?: string[];
|
|
878
|
+
level?: "providers" | "groups" | "tools";
|
|
879
|
+
expand?: Array<"options" | "response" | "examples">;
|
|
880
|
+
limit?: number;
|
|
881
|
+
offset?: number;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
export interface FindToolsData {
|
|
885
|
+
level: "providers" | "groups" | "tools";
|
|
886
|
+
items: Array<{
|
|
887
|
+
id: string;
|
|
888
|
+
name: string;
|
|
889
|
+
next?: AlexandriaCall;
|
|
890
|
+
execute?: Pick<AlexandriaCall, "provider" | "capability">;
|
|
891
|
+
[key: string]: unknown;
|
|
892
|
+
}>;
|
|
893
|
+
total: number;
|
|
894
|
+
next: AlexandriaCall | null;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
export interface AlexandriaScrapeRequest extends AlexandriaOptions {
|
|
898
|
+
alexandria: AlexandriaCall | AlexandriaCall[];
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
export interface AlexandriaCall {
|
|
902
|
+
provider: string;
|
|
903
|
+
capability: string;
|
|
904
|
+
options?: Record<string, unknown>;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
export interface AlexandriaScrapeError {
|
|
908
|
+
code: string;
|
|
909
|
+
message: string;
|
|
910
|
+
status?: number;
|
|
911
|
+
/** Present when credits were captured before the failure. */
|
|
912
|
+
chargeId?: string;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
export type AlexandriaScrapeResult =
|
|
916
|
+
| {
|
|
917
|
+
provider: string;
|
|
918
|
+
capability: string;
|
|
919
|
+
creditsCost: number;
|
|
920
|
+
data: unknown;
|
|
921
|
+
records?: number;
|
|
922
|
+
upstreamStatus?: number;
|
|
923
|
+
recordedAt?: string;
|
|
924
|
+
error?: undefined;
|
|
925
|
+
[key: string]: unknown;
|
|
926
|
+
}
|
|
927
|
+
| {
|
|
928
|
+
provider?: string;
|
|
929
|
+
capability?: string;
|
|
930
|
+
error: AlexandriaScrapeError;
|
|
931
|
+
[key: string]: unknown;
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
export interface AlexandriaScrapeData {
|
|
935
|
+
scrapeId: string;
|
|
936
|
+
requestId: string;
|
|
937
|
+
alexandria: AlexandriaScrapeResult[];
|
|
938
|
+
creditsCost: number;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
export interface AlexandriaOptions {
|
|
942
|
+
/** Reuse this ID with the identical payload when retrying an execution. */
|
|
943
|
+
requestId?: string;
|
|
944
|
+
timeout?: number;
|
|
945
|
+
integration?: string;
|
|
946
|
+
origin?: string;
|
|
803
947
|
}
|
|
804
948
|
|
|
805
949
|
/**
|
|
@@ -830,8 +974,13 @@ export interface CategoryOption {
|
|
|
830
974
|
|
|
831
975
|
export interface SearchRequest {
|
|
832
976
|
query: string;
|
|
977
|
+
/** Include domain-matched tools in tools alongside semantic matches. */
|
|
978
|
+
domainTools?: boolean;
|
|
979
|
+
/** Compact by default; summary adds metadata, full includes contracts. */
|
|
980
|
+
toolDetail?: "compact" | "summary" | "full";
|
|
833
981
|
sources?: Array<
|
|
834
|
-
"web" | "news" | "images" |
|
|
982
|
+
"web" | "news" | "images" | "alexandria"
|
|
983
|
+
| { type: "web" | "news" | "images" | "alexandria" }
|
|
835
984
|
>;
|
|
836
985
|
/**
|
|
837
986
|
* Narrow web search by category. See {@link CategoryOption}.
|
|
@@ -855,7 +1004,7 @@ export interface SearchRequest {
|
|
|
855
1004
|
timeout?: number; // ms
|
|
856
1005
|
/** Generate query-relevant highlights for search results. Defaults to true. */
|
|
857
1006
|
highlights?: boolean;
|
|
858
|
-
scrapeOptions?: ScrapeOptions
|
|
1007
|
+
scrapeOptions?: Omit<ScrapeOptions, "toolDetail">;
|
|
859
1008
|
/**
|
|
860
1009
|
* Enterprise search options. Use `["zdr"]` for end-to-end Zero Data
|
|
861
1010
|
* Retention or `["anon"]` for anonymized search. Must be enabled for
|
|
@@ -884,7 +1033,7 @@ export interface CrawlOptions {
|
|
|
884
1033
|
delay?: number | null;
|
|
885
1034
|
maxConcurrency?: number | null;
|
|
886
1035
|
webhook?: string | WebhookConfig | null;
|
|
887
|
-
scrapeOptions?: ScrapeOptions | null;
|
|
1036
|
+
scrapeOptions?: Omit<ScrapeOptions, "toolDetail"> | null;
|
|
888
1037
|
regexOnFullURL?: boolean;
|
|
889
1038
|
zeroDataRetention?: boolean;
|
|
890
1039
|
integration?: string;
|
|
@@ -908,7 +1057,7 @@ export interface CrawlJob {
|
|
|
908
1057
|
}
|
|
909
1058
|
|
|
910
1059
|
export interface BatchScrapeOptions {
|
|
911
|
-
options?: ScrapeOptions
|
|
1060
|
+
options?: Omit<ScrapeOptions, "toolDetail">;
|
|
912
1061
|
webhook?: string | WebhookConfig;
|
|
913
1062
|
appendToId?: string;
|
|
914
1063
|
ignoreInvalidURLs?: boolean;
|
|
@@ -1058,7 +1207,7 @@ export interface MonitorScrapeTarget {
|
|
|
1058
1207
|
id?: string;
|
|
1059
1208
|
type: "scrape";
|
|
1060
1209
|
urls: string[];
|
|
1061
|
-
scrapeOptions?: ScrapeOptions
|
|
1210
|
+
scrapeOptions?: Omit<ScrapeOptions, "toolDetail">;
|
|
1062
1211
|
}
|
|
1063
1212
|
|
|
1064
1213
|
export interface MonitorCrawlTarget {
|
|
@@ -1066,7 +1215,7 @@ export interface MonitorCrawlTarget {
|
|
|
1066
1215
|
type: "crawl";
|
|
1067
1216
|
url: string;
|
|
1068
1217
|
crawlOptions?: CrawlOptions;
|
|
1069
|
-
scrapeOptions?: ScrapeOptions
|
|
1218
|
+
scrapeOptions?: Omit<ScrapeOptions, "toolDetail">;
|
|
1070
1219
|
}
|
|
1071
1220
|
|
|
1072
1221
|
export interface MonitorSearchTarget {
|
|
@@ -1707,17 +1856,43 @@ export interface ErrorDetails {
|
|
|
1707
1856
|
status?: number;
|
|
1708
1857
|
}
|
|
1709
1858
|
|
|
1859
|
+
/** An out-of-band step the API requires before the request can succeed. */
|
|
1860
|
+
export interface RequiresAction {
|
|
1861
|
+
type: "accept_terms" | (string & {});
|
|
1862
|
+
terms?: string;
|
|
1863
|
+
version?: string;
|
|
1864
|
+
url?: string;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
export function parseRequiresAction(value: unknown): RequiresAction | undefined {
|
|
1868
|
+
if (!value || typeof value !== "object") return undefined;
|
|
1869
|
+
const record = value as Record<string, unknown>;
|
|
1870
|
+
if (typeof record.type !== "string") return undefined;
|
|
1871
|
+
const action: RequiresAction = { type: record.type };
|
|
1872
|
+
if (typeof record.terms === "string") action.terms = record.terms;
|
|
1873
|
+
if (typeof record.version === "string") action.version = record.version;
|
|
1874
|
+
if (typeof record.url === "string") action.url = record.url;
|
|
1875
|
+
return action;
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1710
1878
|
export class SdkError extends Error {
|
|
1879
|
+
requestId?: string;
|
|
1711
1880
|
status?: number;
|
|
1712
1881
|
code?: string;
|
|
1713
1882
|
details?: unknown;
|
|
1714
1883
|
jobId?: string;
|
|
1884
|
+
/** Present on exchange-mediated scrape failures that already captured credits. */
|
|
1885
|
+
chargeId?: string;
|
|
1886
|
+
/** Present when the API needs an out-of-band step first, such as accepting provider terms. */
|
|
1887
|
+
requiresAction?: RequiresAction;
|
|
1715
1888
|
constructor(
|
|
1716
1889
|
message: string,
|
|
1717
1890
|
status?: number,
|
|
1718
1891
|
code?: string,
|
|
1719
1892
|
details?: unknown,
|
|
1720
1893
|
jobId?: string,
|
|
1894
|
+
chargeId?: string,
|
|
1895
|
+
requiresAction?: RequiresAction,
|
|
1721
1896
|
) {
|
|
1722
1897
|
super(message);
|
|
1723
1898
|
this.name = "FirecrawlSdkError";
|
|
@@ -1725,6 +1900,8 @@ export class SdkError extends Error {
|
|
|
1725
1900
|
this.code = code;
|
|
1726
1901
|
this.details = details;
|
|
1727
1902
|
this.jobId = jobId;
|
|
1903
|
+
this.chargeId = chargeId;
|
|
1904
|
+
this.requiresAction = requiresAction;
|
|
1728
1905
|
}
|
|
1729
1906
|
}
|
|
1730
1907
|
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { type AxiosError, type AxiosResponse } from "axios";
|
|
2
|
-
import { SdkError, JobTimeoutError } from "../types";
|
|
2
|
+
import { SdkError, JobTimeoutError, parseRequiresAction } from "../types";
|
|
3
3
|
|
|
4
4
|
export function throwForBadResponse(resp: AxiosResponse, action: string): never {
|
|
5
5
|
const status = resp.status;
|
|
6
6
|
const body = resp.data || {};
|
|
7
7
|
const msg = body?.error || body?.message || `Request failed (${status}) while trying to ${action}`;
|
|
8
|
-
throw new SdkError(
|
|
8
|
+
throw new SdkError(
|
|
9
|
+
msg,
|
|
10
|
+
status,
|
|
11
|
+
body?.code,
|
|
12
|
+
body?.details,
|
|
13
|
+
undefined,
|
|
14
|
+
body?.chargeId,
|
|
15
|
+
parseRequiresAction(body?.requiresAction),
|
|
16
|
+
);
|
|
9
17
|
}
|
|
10
18
|
|
|
11
19
|
export function normalizeAxiosError(err: AxiosError, action: string): never {
|
|
@@ -13,7 +21,15 @@ export function normalizeAxiosError(err: AxiosError, action: string): never {
|
|
|
13
21
|
const body: any = err.response?.data;
|
|
14
22
|
const message = body?.error || err.message || `Request failed${status ? ` (${status})` : ""} while trying to ${action}`;
|
|
15
23
|
const code = (body?.code as string) || err.code;
|
|
16
|
-
throw new SdkError(
|
|
24
|
+
throw new SdkError(
|
|
25
|
+
message,
|
|
26
|
+
status,
|
|
27
|
+
code,
|
|
28
|
+
body?.details ?? body,
|
|
29
|
+
undefined,
|
|
30
|
+
body?.chargeId,
|
|
31
|
+
parseRequiresAction(body?.requiresAction),
|
|
32
|
+
);
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
export function isRetryableError(err: any): boolean {
|