firecrawl 4.42.0 → 4.42.2
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 +7 -0
- package/dist/{chunk-OCJTYRX5.js → chunk-XZ5XI5DK.js} +2 -2
- package/dist/index.cjs +38 -5
- package/dist/index.d.cts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.js +38 -5
- package/dist/{package-ECWDBUY3.js → package-JVVNUZPT.js} +1 -1
- package/package.json +2 -2
- package/pnpm-workspace.yaml +9 -2
- package/src/__tests__/e2e/v2/parse.test.ts +26 -0
- package/src/__tests__/unit/v1/next-url-pinning.test.ts +81 -0
- package/src/__tests__/unit/v2/next-url-pinning.test.ts +104 -0
- package/src/__tests__/unit/v2/parse-formats.unit.test.ts +84 -0
- package/src/utils/apiOrigin.ts +19 -0
- package/src/v1/index.ts +7 -3
- package/src/v2/client.ts +10 -1
- package/src/v2/methods/agent.ts +1 -0
- package/src/v2/methods/batch.ts +1 -1
- package/src/v2/methods/crawl.ts +1 -1
- package/src/v2/methods/parse.ts +12 -1
- package/src/v2/types.ts +22 -0
- package/src/v2/utils/httpClient.ts +2 -0
package/README.md
CHANGED
|
@@ -102,6 +102,13 @@ const parsed = await app.parse(
|
|
|
102
102
|
console.log(parsed.markdown);
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
To see which file formats `parse` accepts, call `getParseFormats`. Each entry has `format`, `kind` (for example, `document` or `image`), `extensions`, `mimeTypes`, and `available` (false when the format is not enabled on this deployment).
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
const formats = await app.getParseFormats();
|
|
109
|
+
console.log(formats.filter((f) => f.available).map((f) => f.format));
|
|
110
|
+
```
|
|
111
|
+
|
|
105
112
|
### Crawling a Website
|
|
106
113
|
|
|
107
114
|
To crawl a website with error handling, use the `crawl` method. It takes the starting URL and optional parameters, including limits and per‑page `scrapeOptions`.
|
|
@@ -12,7 +12,7 @@ var require_package = __commonJS({
|
|
|
12
12
|
"package.json"(exports, module) {
|
|
13
13
|
module.exports = {
|
|
14
14
|
name: "@mendable/firecrawl-js",
|
|
15
|
-
version: "4.42.
|
|
15
|
+
version: "4.42.2",
|
|
16
16
|
description: "JavaScript SDK for the Firecrawl API: web scraping, crawling, web search, and scientific literature search over a research paper index of PubMed, bioRxiv, medRxiv and arXiv abstracts",
|
|
17
17
|
main: "dist/index.js",
|
|
18
18
|
types: "dist/index.d.ts",
|
|
@@ -38,7 +38,7 @@ var require_package = __commonJS({
|
|
|
38
38
|
author: "Mendable.ai",
|
|
39
39
|
license: "MIT",
|
|
40
40
|
dependencies: {
|
|
41
|
-
axios: "1.
|
|
41
|
+
axios: "1.20.0",
|
|
42
42
|
firecrawl: "4.30.1",
|
|
43
43
|
"typescript-event-target": "^1.1.1",
|
|
44
44
|
zod: "^3.23.8",
|
package/dist/index.cjs
CHANGED
|
@@ -39,7 +39,7 @@ var require_package = __commonJS({
|
|
|
39
39
|
"package.json"(exports2, module2) {
|
|
40
40
|
module2.exports = {
|
|
41
41
|
name: "@mendable/firecrawl-js",
|
|
42
|
-
version: "4.42.
|
|
42
|
+
version: "4.42.2",
|
|
43
43
|
description: "JavaScript SDK for the Firecrawl API: web scraping, crawling, web search, and scientific literature search over a research paper index of PubMed, bioRxiv, medRxiv and arXiv abstracts",
|
|
44
44
|
main: "dist/index.js",
|
|
45
45
|
types: "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@ var require_package = __commonJS({
|
|
|
65
65
|
author: "Mendable.ai",
|
|
66
66
|
license: "MIT",
|
|
67
67
|
dependencies: {
|
|
68
|
-
axios: "1.
|
|
68
|
+
axios: "1.20.0",
|
|
69
69
|
firecrawl: "4.30.1",
|
|
70
70
|
"typescript-event-target": "^1.1.1",
|
|
71
71
|
zod: "^3.23.8",
|
|
@@ -150,6 +150,21 @@ function getVersion() {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
// src/utils/apiOrigin.ts
|
|
154
|
+
function pinToApiOrigin(apiUrl, url) {
|
|
155
|
+
const normalized = url.replace(/[\t\n\r]/g, "").replace(/^[\u0000-\u0020]+/, "");
|
|
156
|
+
if (!/^([a-z][a-z\d+\-.]*:|[\\/]{2})/i.test(normalized)) return url;
|
|
157
|
+
const base = URL.canParse(apiUrl) ? new URL(apiUrl) : null;
|
|
158
|
+
if (!base?.host) {
|
|
159
|
+
throw new Error(`apiUrl must be an absolute URL, got ${JSON.stringify(apiUrl)}`);
|
|
160
|
+
}
|
|
161
|
+
const target = new URL(normalized, base);
|
|
162
|
+
const pinned = new URL(base.origin);
|
|
163
|
+
pinned.pathname = target.pathname;
|
|
164
|
+
pinned.search = target.search;
|
|
165
|
+
return pinned.href;
|
|
166
|
+
}
|
|
167
|
+
|
|
153
168
|
// src/v2/utils/httpClient.ts
|
|
154
169
|
var HttpClient = class {
|
|
155
170
|
instance;
|
|
@@ -190,6 +205,7 @@ var HttpClient = class {
|
|
|
190
205
|
config.headers = {
|
|
191
206
|
...config.headers || {}
|
|
192
207
|
};
|
|
208
|
+
if (config.url) config.url = pinToApiOrigin(this.apiUrl, config.url);
|
|
193
209
|
let lastError;
|
|
194
210
|
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
195
211
|
try {
|
|
@@ -770,6 +786,16 @@ async function parse(http, file, options) {
|
|
|
770
786
|
throw err;
|
|
771
787
|
}
|
|
772
788
|
}
|
|
789
|
+
async function getParseFormats(http) {
|
|
790
|
+
try {
|
|
791
|
+
const res = await http.get("/v2/parse/formats");
|
|
792
|
+
if (res.status !== 200 || !res.data?.success) throwForBadResponse(res, "get parse formats");
|
|
793
|
+
return res.data.data?.formats ?? [];
|
|
794
|
+
} catch (err) {
|
|
795
|
+
if (err?.isAxiosError) return normalizeAxiosError(err, "get parse formats");
|
|
796
|
+
throw err;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
773
799
|
|
|
774
800
|
// src/v2/methods/search.ts
|
|
775
801
|
function prepareSearchPayload(req) {
|
|
@@ -2352,6 +2378,13 @@ var FirecrawlClient = class {
|
|
|
2352
2378
|
async parse(file, options) {
|
|
2353
2379
|
return parse(this.http, file, options);
|
|
2354
2380
|
}
|
|
2381
|
+
/**
|
|
2382
|
+
* List the file formats the parse endpoint accepts on this deployment.
|
|
2383
|
+
* @returns Formats with their kind, extensions, MIME types, and availability.
|
|
2384
|
+
*/
|
|
2385
|
+
async getParseFormats() {
|
|
2386
|
+
return getParseFormats(this.http);
|
|
2387
|
+
}
|
|
2355
2388
|
// Search
|
|
2356
2389
|
/**
|
|
2357
2390
|
* Search the web and optionally scrape each result.
|
|
@@ -3020,7 +3053,7 @@ var FirecrawlApp = class {
|
|
|
3020
3053
|
throw new FirecrawlError("No crawl ID provided", 400);
|
|
3021
3054
|
}
|
|
3022
3055
|
const headers = this.prepareHeaders();
|
|
3023
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}
|
|
3056
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}`, this.apiUrl);
|
|
3024
3057
|
if (skip !== void 0) {
|
|
3025
3058
|
targetURL.searchParams.set("skip", skip.toString());
|
|
3026
3059
|
}
|
|
@@ -3265,7 +3298,7 @@ var FirecrawlApp = class {
|
|
|
3265
3298
|
throw new FirecrawlError("No batch scrape ID provided", 400);
|
|
3266
3299
|
}
|
|
3267
3300
|
const headers = this.prepareHeaders();
|
|
3268
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}
|
|
3301
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}`, this.apiUrl);
|
|
3269
3302
|
if (skip !== void 0) {
|
|
3270
3303
|
targetURL.searchParams.set("skip", skip.toString());
|
|
3271
3304
|
}
|
|
@@ -3477,7 +3510,7 @@ var FirecrawlApp = class {
|
|
|
3477
3510
|
*/
|
|
3478
3511
|
async getRequest(url, headers) {
|
|
3479
3512
|
try {
|
|
3480
|
-
return await import_axios3.default.get(url, { headers });
|
|
3513
|
+
return await import_axios3.default.get(pinToApiOrigin(this.apiUrl, url), { headers });
|
|
3481
3514
|
} catch (error) {
|
|
3482
3515
|
if (error instanceof import_axios3.AxiosError && error.response) {
|
|
3483
3516
|
return error.response;
|
package/dist/index.d.cts
CHANGED
|
@@ -267,6 +267,17 @@ type ParseOptions = Omit<ScrapeOptions, "formats" | "waitFor" | "mobile" | "acti
|
|
|
267
267
|
formats?: ParseFormatOption[];
|
|
268
268
|
proxy?: "basic" | "auto";
|
|
269
269
|
};
|
|
270
|
+
/** A file format accepted by the parse endpoint. */
|
|
271
|
+
interface ParseFormatInfo {
|
|
272
|
+
/** Format identifier, e.g. "pdf". */
|
|
273
|
+
format: string;
|
|
274
|
+
kind: "document" | "image" | (string & {});
|
|
275
|
+
/** File extensions including the leading dot, e.g. ".pdf". */
|
|
276
|
+
extensions: string[];
|
|
277
|
+
mimeTypes: string[];
|
|
278
|
+
/** False when the format is recognized but not enabled on this deployment. */
|
|
279
|
+
available: boolean;
|
|
280
|
+
}
|
|
270
281
|
interface WebhookConfig {
|
|
271
282
|
url: string;
|
|
272
283
|
headers?: Record<string, string>;
|
|
@@ -1409,6 +1420,11 @@ interface AgentStatusResponse {
|
|
|
1409
1420
|
status: "processing" | "completed" | "failed";
|
|
1410
1421
|
error?: string;
|
|
1411
1422
|
data?: unknown;
|
|
1423
|
+
/** Best-effort result on a failed run; never a completed `data` value. */
|
|
1424
|
+
partial?: unknown;
|
|
1425
|
+
/** Schema validity of `partial`, when a schema was supplied. */
|
|
1426
|
+
partialSchemaValid?: boolean;
|
|
1427
|
+
stopReason?: "credit_limit_reached";
|
|
1412
1428
|
/**
|
|
1413
1429
|
* Server-provided model name. Widened past the request-side union on
|
|
1414
1430
|
* purpose: new models ship without an SDK release, so pinning this to known
|
|
@@ -1447,6 +1463,9 @@ interface AgentThreadRun {
|
|
|
1447
1463
|
message: string | null;
|
|
1448
1464
|
/** Only present when the request asked for includeData. */
|
|
1449
1465
|
data?: unknown;
|
|
1466
|
+
partial?: unknown;
|
|
1467
|
+
partialSchemaValid?: boolean;
|
|
1468
|
+
stopReason?: "credit_limit_reached";
|
|
1450
1469
|
suggestions?: AgentSuggestion[] | null;
|
|
1451
1470
|
pendingApproval?: PendingApproval | null;
|
|
1452
1471
|
exchange?: AgentExchangeSummary | null;
|
|
@@ -1676,6 +1695,8 @@ interface CrawlErrorsResponse$1 {
|
|
|
1676
1695
|
url: string;
|
|
1677
1696
|
code?: string;
|
|
1678
1697
|
error: string;
|
|
1698
|
+
/** Present when the page needs provider terms accepted first. */
|
|
1699
|
+
requiresAction?: RequiresAction;
|
|
1679
1700
|
}[];
|
|
1680
1701
|
robotsBlocked: string[];
|
|
1681
1702
|
}
|
|
@@ -1997,11 +2018,11 @@ declare class HttpClient {
|
|
|
1997
2018
|
getTimeoutMs(): number;
|
|
1998
2019
|
private request;
|
|
1999
2020
|
private sleep;
|
|
2000
|
-
post<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2001
|
-
postMultipart<T = any>(endpoint: string, formData: FormData, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2002
|
-
get<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}>>;
|
|
2003
|
-
delete<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}>>;
|
|
2004
|
-
patch<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2021
|
+
post<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2022
|
+
postMultipart<T = any>(endpoint: string, formData: FormData, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2023
|
+
get<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2024
|
+
delete<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2025
|
+
patch<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2005
2026
|
prepareHeaders(idempotencyKey?: string): Record<string, string>;
|
|
2006
2027
|
}
|
|
2007
2028
|
|
|
@@ -2056,6 +2077,7 @@ declare function prepareAgentPayload(args: {
|
|
|
2056
2077
|
origin?: string;
|
|
2057
2078
|
maxCredits?: number;
|
|
2058
2079
|
strictConstrainToURLs?: boolean;
|
|
2080
|
+
/** Defaults to spark-2. "spark-1-pro" and "spark-1-mini" are deprecated and run spark-2. */
|
|
2059
2081
|
model?: "spark-1-pro" | "spark-1-mini" | "spark-2";
|
|
2060
2082
|
effort?: AgentEffort;
|
|
2061
2083
|
webhook?: string | AgentWebhookConfig;
|
|
@@ -2282,6 +2304,11 @@ declare class FirecrawlClient {
|
|
|
2282
2304
|
json?: InferredJsonFromOptions<Opts>;
|
|
2283
2305
|
}>;
|
|
2284
2306
|
parse(file: ParseFile, options?: ParseOptions): Promise<Document>;
|
|
2307
|
+
/**
|
|
2308
|
+
* List the file formats the parse endpoint accepts on this deployment.
|
|
2309
|
+
* @returns Formats with their kind, extensions, MIME types, and availability.
|
|
2310
|
+
*/
|
|
2311
|
+
getParseFormats(): Promise<ParseFormatInfo[]>;
|
|
2285
2312
|
/**
|
|
2286
2313
|
* Search the web and optionally scrape each result.
|
|
2287
2314
|
* @param query Search query string.
|
|
@@ -2993,6 +3020,8 @@ interface CrawlErrorsResponse {
|
|
|
2993
3020
|
url: string;
|
|
2994
3021
|
code?: string;
|
|
2995
3022
|
error: string;
|
|
3023
|
+
/** Present when the page needs provider terms accepted first. */
|
|
3024
|
+
requiresAction?: RequiresAction;
|
|
2996
3025
|
}[];
|
|
2997
3026
|
/**
|
|
2998
3027
|
* URLs blocked by robots.txt
|
|
@@ -3528,4 +3557,4 @@ declare class Firecrawl extends FirecrawlClient {
|
|
|
3528
3557
|
get v1(): FirecrawlApp;
|
|
3529
3558
|
}
|
|
3530
3559
|
|
|
3531
|
-
export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentEffort, type AgentExchangeOptions, type AgentExchangeSummary, type AgentListItem, type AgentListOptions, type AgentListResponse, type AgentMode, type AgentOnTermsRequired, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentSkippedProvider, type AgentSnapshotResponse, type AgentStatusResponse, type AgentSuggestion, type AgentTermsGate, type AgentTermsRequiredAction, type AgentThread, type AgentThreadResponse, type AgentThreadRun, type AgentTraceActiveBrowserSession, type AgentTraceAgentFinishedEvent, type AgentTraceAgentIdentity, type AgentTraceAgentRole, type AgentTraceAgentStartedEvent, type AgentTraceArtifactChange, type AgentTraceArtifactUpdatedEvent, type AgentTraceBrowserSessionFinishedEvent, type AgentTraceBrowserSessionStartedEvent, type AgentTraceError, type AgentTraceErrorOccurredEvent, type AgentTraceEvent, type AgentTraceProgressReportedEvent, type AgentTraceReasoningSummaryEvent, type AgentTraceResponse, type AgentTraceRunCancelRequestedEvent, type AgentTraceRunFinishedEvent, type AgentTraceRunStartedEvent, type AgentTraceToolCallFinishedEvent, type AgentTraceToolCallStartedEvent, type AgentWebhookConfig, type AgentWebhookEvent, type AlexandriaCall, type AlexandriaOptions, type AlexandriaScrapeData, type AlexandriaScrapeError, type AlexandriaScrapeRequest, type AlexandriaScrapeResult, type AttributesFormat, type AuditMetadata$1 as AuditMetadata, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreateMonitorRequest, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type DeveloperSearchLicenseDisclosure, type DeveloperSearchOptions, type DeveloperSearchPassage, type DeveloperSearchRepoStatus, type DeveloperSearchResponse, type DeveloperSearchResult, type DeveloperSearchSourceStatus, type DeveloperSearchType, type DiscoveredTool, type Document, type DocumentMetadata, type EndpointFeedbackEndpoint, type EndpointFeedbackRequest, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, type FeedbackMissingContent, type FeedbackRating, type FeedbackResponse, type FeedbackValuableSource, type FindToolsData, type FindToolsOptions, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientInput, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, type GetMonitorCheckOptions, type GetPaperOptions, type GitHubScoreBreakdown, type GitHubSearchItem, type GitHubSearchResponse, type HighlightsFormat, type IdMap, type ImageParser, JobTimeoutError, type JsonFormat, type ListMonitorChecksOptions, type ListMonitorsOptions, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type MenuAvailability, type MenuImage, type MenuItem, type MenuItemIdentifiers, type MenuMerchant, type MenuPrice, type MenuProfile, type MenuSection, type Monitor, type MonitorCheck, type MonitorCheckDetail, type MonitorCheckPage, type MonitorCrawlTarget, type MonitorCrawlTargetResult, type MonitorEmailNotification, type MonitorEmailRecipientSubscription, type MonitorJsonFieldDiff, type MonitorNotification, type MonitorPageDiff, type MonitorPageJudgment, type MonitorPageSnapshot, type MonitorSchedule, type MonitorScrapeTarget, type MonitorScrapeTargetResult, type MonitorSearchTarget, type MonitorSearchTargetResult, type MonitorSummary, type MonitorTarget, type MonitorTargetResult, type MonitorWebhookConfig, type PDFAction, type PDFParser, type PaginationConfig, type PaperMetadata, type PaperMetadataResponse, type PaperResult, type PaperSignals, type ParseFile, type ParseFileData, type ParseFormat, type ParseFormatOption, type ParseFormatString, type ParseOptions, type Passage, type PdfBlockConfidence, type PdfBlockItem, type PdfPage, type PdfPageBlocks, type PendingApproval, type PendingApprovalCall, type PendingCallsApproval, type PendingTermsApproval, type PressAction, type ProductAvailability, type ProductImage, type ProductPrice, type ProductProfile, type ProductSale, type ProductVariant, type QueryFormat, type QuestionFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ReadPaperResponse, type RedactPIIEntity, type RedactPIIOptions, type RequiresAction, ResearchClient, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchFeedbackRequest, type SearchGithubOptions, type SearchPapersOptions, type SearchPapersResponse, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type SimilarPapersOptions, type SimilarPapersResponse, type ThreatProtectionOptions, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type UpdateMonitorRequest, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default, parseRequiresAction };
|
|
3560
|
+
export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentEffort, type AgentExchangeOptions, type AgentExchangeSummary, type AgentListItem, type AgentListOptions, type AgentListResponse, type AgentMode, type AgentOnTermsRequired, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentSkippedProvider, type AgentSnapshotResponse, type AgentStatusResponse, type AgentSuggestion, type AgentTermsGate, type AgentTermsRequiredAction, type AgentThread, type AgentThreadResponse, type AgentThreadRun, type AgentTraceActiveBrowserSession, type AgentTraceAgentFinishedEvent, type AgentTraceAgentIdentity, type AgentTraceAgentRole, type AgentTraceAgentStartedEvent, type AgentTraceArtifactChange, type AgentTraceArtifactUpdatedEvent, type AgentTraceBrowserSessionFinishedEvent, type AgentTraceBrowserSessionStartedEvent, type AgentTraceError, type AgentTraceErrorOccurredEvent, type AgentTraceEvent, type AgentTraceProgressReportedEvent, type AgentTraceReasoningSummaryEvent, type AgentTraceResponse, type AgentTraceRunCancelRequestedEvent, type AgentTraceRunFinishedEvent, type AgentTraceRunStartedEvent, type AgentTraceToolCallFinishedEvent, type AgentTraceToolCallStartedEvent, type AgentWebhookConfig, type AgentWebhookEvent, type AlexandriaCall, type AlexandriaOptions, type AlexandriaScrapeData, type AlexandriaScrapeError, type AlexandriaScrapeRequest, type AlexandriaScrapeResult, type AttributesFormat, type AuditMetadata$1 as AuditMetadata, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreateMonitorRequest, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type DeveloperSearchLicenseDisclosure, type DeveloperSearchOptions, type DeveloperSearchPassage, type DeveloperSearchRepoStatus, type DeveloperSearchResponse, type DeveloperSearchResult, type DeveloperSearchSourceStatus, type DeveloperSearchType, type DiscoveredTool, type Document, type DocumentMetadata, type EndpointFeedbackEndpoint, type EndpointFeedbackRequest, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, type FeedbackMissingContent, type FeedbackRating, type FeedbackResponse, type FeedbackValuableSource, type FindToolsData, type FindToolsOptions, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientInput, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, type GetMonitorCheckOptions, type GetPaperOptions, type GitHubScoreBreakdown, type GitHubSearchItem, type GitHubSearchResponse, type HighlightsFormat, type IdMap, type ImageParser, JobTimeoutError, type JsonFormat, type ListMonitorChecksOptions, type ListMonitorsOptions, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type MenuAvailability, type MenuImage, type MenuItem, type MenuItemIdentifiers, type MenuMerchant, type MenuPrice, type MenuProfile, type MenuSection, type Monitor, type MonitorCheck, type MonitorCheckDetail, type MonitorCheckPage, type MonitorCrawlTarget, type MonitorCrawlTargetResult, type MonitorEmailNotification, type MonitorEmailRecipientSubscription, type MonitorJsonFieldDiff, type MonitorNotification, type MonitorPageDiff, type MonitorPageJudgment, type MonitorPageSnapshot, type MonitorSchedule, type MonitorScrapeTarget, type MonitorScrapeTargetResult, type MonitorSearchTarget, type MonitorSearchTargetResult, type MonitorSummary, type MonitorTarget, type MonitorTargetResult, type MonitorWebhookConfig, type PDFAction, type PDFParser, type PaginationConfig, type PaperMetadata, type PaperMetadataResponse, type PaperResult, type PaperSignals, type ParseFile, type ParseFileData, type ParseFormat, type ParseFormatInfo, type ParseFormatOption, type ParseFormatString, type ParseOptions, type Passage, type PdfBlockConfidence, type PdfBlockItem, type PdfPage, type PdfPageBlocks, type PendingApproval, type PendingApprovalCall, type PendingCallsApproval, type PendingTermsApproval, type PressAction, type ProductAvailability, type ProductImage, type ProductPrice, type ProductProfile, type ProductSale, type ProductVariant, type QueryFormat, type QuestionFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ReadPaperResponse, type RedactPIIEntity, type RedactPIIOptions, type RequiresAction, ResearchClient, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchFeedbackRequest, type SearchGithubOptions, type SearchPapersOptions, type SearchPapersResponse, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type SimilarPapersOptions, type SimilarPapersResponse, type ThreatProtectionOptions, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type UpdateMonitorRequest, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default, parseRequiresAction };
|
package/dist/index.d.ts
CHANGED
|
@@ -267,6 +267,17 @@ type ParseOptions = Omit<ScrapeOptions, "formats" | "waitFor" | "mobile" | "acti
|
|
|
267
267
|
formats?: ParseFormatOption[];
|
|
268
268
|
proxy?: "basic" | "auto";
|
|
269
269
|
};
|
|
270
|
+
/** A file format accepted by the parse endpoint. */
|
|
271
|
+
interface ParseFormatInfo {
|
|
272
|
+
/** Format identifier, e.g. "pdf". */
|
|
273
|
+
format: string;
|
|
274
|
+
kind: "document" | "image" | (string & {});
|
|
275
|
+
/** File extensions including the leading dot, e.g. ".pdf". */
|
|
276
|
+
extensions: string[];
|
|
277
|
+
mimeTypes: string[];
|
|
278
|
+
/** False when the format is recognized but not enabled on this deployment. */
|
|
279
|
+
available: boolean;
|
|
280
|
+
}
|
|
270
281
|
interface WebhookConfig {
|
|
271
282
|
url: string;
|
|
272
283
|
headers?: Record<string, string>;
|
|
@@ -1409,6 +1420,11 @@ interface AgentStatusResponse {
|
|
|
1409
1420
|
status: "processing" | "completed" | "failed";
|
|
1410
1421
|
error?: string;
|
|
1411
1422
|
data?: unknown;
|
|
1423
|
+
/** Best-effort result on a failed run; never a completed `data` value. */
|
|
1424
|
+
partial?: unknown;
|
|
1425
|
+
/** Schema validity of `partial`, when a schema was supplied. */
|
|
1426
|
+
partialSchemaValid?: boolean;
|
|
1427
|
+
stopReason?: "credit_limit_reached";
|
|
1412
1428
|
/**
|
|
1413
1429
|
* Server-provided model name. Widened past the request-side union on
|
|
1414
1430
|
* purpose: new models ship without an SDK release, so pinning this to known
|
|
@@ -1447,6 +1463,9 @@ interface AgentThreadRun {
|
|
|
1447
1463
|
message: string | null;
|
|
1448
1464
|
/** Only present when the request asked for includeData. */
|
|
1449
1465
|
data?: unknown;
|
|
1466
|
+
partial?: unknown;
|
|
1467
|
+
partialSchemaValid?: boolean;
|
|
1468
|
+
stopReason?: "credit_limit_reached";
|
|
1450
1469
|
suggestions?: AgentSuggestion[] | null;
|
|
1451
1470
|
pendingApproval?: PendingApproval | null;
|
|
1452
1471
|
exchange?: AgentExchangeSummary | null;
|
|
@@ -1676,6 +1695,8 @@ interface CrawlErrorsResponse$1 {
|
|
|
1676
1695
|
url: string;
|
|
1677
1696
|
code?: string;
|
|
1678
1697
|
error: string;
|
|
1698
|
+
/** Present when the page needs provider terms accepted first. */
|
|
1699
|
+
requiresAction?: RequiresAction;
|
|
1679
1700
|
}[];
|
|
1680
1701
|
robotsBlocked: string[];
|
|
1681
1702
|
}
|
|
@@ -1997,11 +2018,11 @@ declare class HttpClient {
|
|
|
1997
2018
|
getTimeoutMs(): number;
|
|
1998
2019
|
private request;
|
|
1999
2020
|
private sleep;
|
|
2000
|
-
post<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2001
|
-
postMultipart<T = any>(endpoint: string, formData: FormData, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2002
|
-
get<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}>>;
|
|
2003
|
-
delete<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}>>;
|
|
2004
|
-
patch<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}>>;
|
|
2021
|
+
post<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2022
|
+
postMultipart<T = any>(endpoint: string, formData: FormData, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2023
|
+
get<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2024
|
+
delete<T = any>(endpoint: string, headers?: Record<string, string>): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2025
|
+
patch<T = any>(endpoint: string, body: Record<string, unknown>, options?: RequestOptions): Promise<AxiosResponse<T, any, {}, any>>;
|
|
2005
2026
|
prepareHeaders(idempotencyKey?: string): Record<string, string>;
|
|
2006
2027
|
}
|
|
2007
2028
|
|
|
@@ -2056,6 +2077,7 @@ declare function prepareAgentPayload(args: {
|
|
|
2056
2077
|
origin?: string;
|
|
2057
2078
|
maxCredits?: number;
|
|
2058
2079
|
strictConstrainToURLs?: boolean;
|
|
2080
|
+
/** Defaults to spark-2. "spark-1-pro" and "spark-1-mini" are deprecated and run spark-2. */
|
|
2059
2081
|
model?: "spark-1-pro" | "spark-1-mini" | "spark-2";
|
|
2060
2082
|
effort?: AgentEffort;
|
|
2061
2083
|
webhook?: string | AgentWebhookConfig;
|
|
@@ -2282,6 +2304,11 @@ declare class FirecrawlClient {
|
|
|
2282
2304
|
json?: InferredJsonFromOptions<Opts>;
|
|
2283
2305
|
}>;
|
|
2284
2306
|
parse(file: ParseFile, options?: ParseOptions): Promise<Document>;
|
|
2307
|
+
/**
|
|
2308
|
+
* List the file formats the parse endpoint accepts on this deployment.
|
|
2309
|
+
* @returns Formats with their kind, extensions, MIME types, and availability.
|
|
2310
|
+
*/
|
|
2311
|
+
getParseFormats(): Promise<ParseFormatInfo[]>;
|
|
2285
2312
|
/**
|
|
2286
2313
|
* Search the web and optionally scrape each result.
|
|
2287
2314
|
* @param query Search query string.
|
|
@@ -2993,6 +3020,8 @@ interface CrawlErrorsResponse {
|
|
|
2993
3020
|
url: string;
|
|
2994
3021
|
code?: string;
|
|
2995
3022
|
error: string;
|
|
3023
|
+
/** Present when the page needs provider terms accepted first. */
|
|
3024
|
+
requiresAction?: RequiresAction;
|
|
2996
3025
|
}[];
|
|
2997
3026
|
/**
|
|
2998
3027
|
* URLs blocked by robots.txt
|
|
@@ -3528,4 +3557,4 @@ declare class Firecrawl extends FirecrawlClient {
|
|
|
3528
3557
|
get v1(): FirecrawlApp;
|
|
3529
3558
|
}
|
|
3530
3559
|
|
|
3531
|
-
export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentEffort, type AgentExchangeOptions, type AgentExchangeSummary, type AgentListItem, type AgentListOptions, type AgentListResponse, type AgentMode, type AgentOnTermsRequired, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentSkippedProvider, type AgentSnapshotResponse, type AgentStatusResponse, type AgentSuggestion, type AgentTermsGate, type AgentTermsRequiredAction, type AgentThread, type AgentThreadResponse, type AgentThreadRun, type AgentTraceActiveBrowserSession, type AgentTraceAgentFinishedEvent, type AgentTraceAgentIdentity, type AgentTraceAgentRole, type AgentTraceAgentStartedEvent, type AgentTraceArtifactChange, type AgentTraceArtifactUpdatedEvent, type AgentTraceBrowserSessionFinishedEvent, type AgentTraceBrowserSessionStartedEvent, type AgentTraceError, type AgentTraceErrorOccurredEvent, type AgentTraceEvent, type AgentTraceProgressReportedEvent, type AgentTraceReasoningSummaryEvent, type AgentTraceResponse, type AgentTraceRunCancelRequestedEvent, type AgentTraceRunFinishedEvent, type AgentTraceRunStartedEvent, type AgentTraceToolCallFinishedEvent, type AgentTraceToolCallStartedEvent, type AgentWebhookConfig, type AgentWebhookEvent, type AlexandriaCall, type AlexandriaOptions, type AlexandriaScrapeData, type AlexandriaScrapeError, type AlexandriaScrapeRequest, type AlexandriaScrapeResult, type AttributesFormat, type AuditMetadata$1 as AuditMetadata, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreateMonitorRequest, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type DeveloperSearchLicenseDisclosure, type DeveloperSearchOptions, type DeveloperSearchPassage, type DeveloperSearchRepoStatus, type DeveloperSearchResponse, type DeveloperSearchResult, type DeveloperSearchSourceStatus, type DeveloperSearchType, type DiscoveredTool, type Document, type DocumentMetadata, type EndpointFeedbackEndpoint, type EndpointFeedbackRequest, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, type FeedbackMissingContent, type FeedbackRating, type FeedbackResponse, type FeedbackValuableSource, type FindToolsData, type FindToolsOptions, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientInput, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, type GetMonitorCheckOptions, type GetPaperOptions, type GitHubScoreBreakdown, type GitHubSearchItem, type GitHubSearchResponse, type HighlightsFormat, type IdMap, type ImageParser, JobTimeoutError, type JsonFormat, type ListMonitorChecksOptions, type ListMonitorsOptions, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type MenuAvailability, type MenuImage, type MenuItem, type MenuItemIdentifiers, type MenuMerchant, type MenuPrice, type MenuProfile, type MenuSection, type Monitor, type MonitorCheck, type MonitorCheckDetail, type MonitorCheckPage, type MonitorCrawlTarget, type MonitorCrawlTargetResult, type MonitorEmailNotification, type MonitorEmailRecipientSubscription, type MonitorJsonFieldDiff, type MonitorNotification, type MonitorPageDiff, type MonitorPageJudgment, type MonitorPageSnapshot, type MonitorSchedule, type MonitorScrapeTarget, type MonitorScrapeTargetResult, type MonitorSearchTarget, type MonitorSearchTargetResult, type MonitorSummary, type MonitorTarget, type MonitorTargetResult, type MonitorWebhookConfig, type PDFAction, type PDFParser, type PaginationConfig, type PaperMetadata, type PaperMetadataResponse, type PaperResult, type PaperSignals, type ParseFile, type ParseFileData, type ParseFormat, type ParseFormatOption, type ParseFormatString, type ParseOptions, type Passage, type PdfBlockConfidence, type PdfBlockItem, type PdfPage, type PdfPageBlocks, type PendingApproval, type PendingApprovalCall, type PendingCallsApproval, type PendingTermsApproval, type PressAction, type ProductAvailability, type ProductImage, type ProductPrice, type ProductProfile, type ProductSale, type ProductVariant, type QueryFormat, type QuestionFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ReadPaperResponse, type RedactPIIEntity, type RedactPIIOptions, type RequiresAction, ResearchClient, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchFeedbackRequest, type SearchGithubOptions, type SearchPapersOptions, type SearchPapersResponse, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type SimilarPapersOptions, type SimilarPapersResponse, type ThreatProtectionOptions, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type UpdateMonitorRequest, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default, parseRequiresAction };
|
|
3560
|
+
export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentEffort, type AgentExchangeOptions, type AgentExchangeSummary, type AgentListItem, type AgentListOptions, type AgentListResponse, type AgentMode, type AgentOnTermsRequired, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentSkippedProvider, type AgentSnapshotResponse, type AgentStatusResponse, type AgentSuggestion, type AgentTermsGate, type AgentTermsRequiredAction, type AgentThread, type AgentThreadResponse, type AgentThreadRun, type AgentTraceActiveBrowserSession, type AgentTraceAgentFinishedEvent, type AgentTraceAgentIdentity, type AgentTraceAgentRole, type AgentTraceAgentStartedEvent, type AgentTraceArtifactChange, type AgentTraceArtifactUpdatedEvent, type AgentTraceBrowserSessionFinishedEvent, type AgentTraceBrowserSessionStartedEvent, type AgentTraceError, type AgentTraceErrorOccurredEvent, type AgentTraceEvent, type AgentTraceProgressReportedEvent, type AgentTraceReasoningSummaryEvent, type AgentTraceResponse, type AgentTraceRunCancelRequestedEvent, type AgentTraceRunFinishedEvent, type AgentTraceRunStartedEvent, type AgentTraceToolCallFinishedEvent, type AgentTraceToolCallStartedEvent, type AgentWebhookConfig, type AgentWebhookEvent, type AlexandriaCall, type AlexandriaOptions, type AlexandriaScrapeData, type AlexandriaScrapeError, type AlexandriaScrapeRequest, type AlexandriaScrapeResult, type AttributesFormat, type AuditMetadata$1 as AuditMetadata, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreateMonitorRequest, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type DeveloperSearchLicenseDisclosure, type DeveloperSearchOptions, type DeveloperSearchPassage, type DeveloperSearchRepoStatus, type DeveloperSearchResponse, type DeveloperSearchResult, type DeveloperSearchSourceStatus, type DeveloperSearchType, type DiscoveredTool, type Document, type DocumentMetadata, type EndpointFeedbackEndpoint, type EndpointFeedbackRequest, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, type FeedbackMissingContent, type FeedbackRating, type FeedbackResponse, type FeedbackValuableSource, type FindToolsData, type FindToolsOptions, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientInput, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, type GetMonitorCheckOptions, type GetPaperOptions, type GitHubScoreBreakdown, type GitHubSearchItem, type GitHubSearchResponse, type HighlightsFormat, type IdMap, type ImageParser, JobTimeoutError, type JsonFormat, type ListMonitorChecksOptions, type ListMonitorsOptions, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type MenuAvailability, type MenuImage, type MenuItem, type MenuItemIdentifiers, type MenuMerchant, type MenuPrice, type MenuProfile, type MenuSection, type Monitor, type MonitorCheck, type MonitorCheckDetail, type MonitorCheckPage, type MonitorCrawlTarget, type MonitorCrawlTargetResult, type MonitorEmailNotification, type MonitorEmailRecipientSubscription, type MonitorJsonFieldDiff, type MonitorNotification, type MonitorPageDiff, type MonitorPageJudgment, type MonitorPageSnapshot, type MonitorSchedule, type MonitorScrapeTarget, type MonitorScrapeTargetResult, type MonitorSearchTarget, type MonitorSearchTargetResult, type MonitorSummary, type MonitorTarget, type MonitorTargetResult, type MonitorWebhookConfig, type PDFAction, type PDFParser, type PaginationConfig, type PaperMetadata, type PaperMetadataResponse, type PaperResult, type PaperSignals, type ParseFile, type ParseFileData, type ParseFormat, type ParseFormatInfo, type ParseFormatOption, type ParseFormatString, type ParseOptions, type Passage, type PdfBlockConfidence, type PdfBlockItem, type PdfPage, type PdfPageBlocks, type PendingApproval, type PendingApprovalCall, type PendingCallsApproval, type PendingTermsApproval, type PressAction, type ProductAvailability, type ProductImage, type ProductPrice, type ProductProfile, type ProductSale, type ProductVariant, type QueryFormat, type QuestionFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ReadPaperResponse, type RedactPIIEntity, type RedactPIIOptions, type RequiresAction, ResearchClient, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchFeedbackRequest, type SearchGithubOptions, type SearchPapersOptions, type SearchPapersResponse, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type SimilarPapersOptions, type SimilarPapersResponse, type ThreatProtectionOptions, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type UpdateMonitorRequest, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default, parseRequiresAction };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_package
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XZ5XI5DK.js";
|
|
4
4
|
|
|
5
5
|
// src/v2/utils/httpClient.ts
|
|
6
6
|
import axios from "axios";
|
|
@@ -18,6 +18,21 @@ function getVersion() {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// src/utils/apiOrigin.ts
|
|
22
|
+
function pinToApiOrigin(apiUrl, url) {
|
|
23
|
+
const normalized = url.replace(/[\t\n\r]/g, "").replace(/^[\u0000-\u0020]+/, "");
|
|
24
|
+
if (!/^([a-z][a-z\d+\-.]*:|[\\/]{2})/i.test(normalized)) return url;
|
|
25
|
+
const base = URL.canParse(apiUrl) ? new URL(apiUrl) : null;
|
|
26
|
+
if (!base?.host) {
|
|
27
|
+
throw new Error(`apiUrl must be an absolute URL, got ${JSON.stringify(apiUrl)}`);
|
|
28
|
+
}
|
|
29
|
+
const target = new URL(normalized, base);
|
|
30
|
+
const pinned = new URL(base.origin);
|
|
31
|
+
pinned.pathname = target.pathname;
|
|
32
|
+
pinned.search = target.search;
|
|
33
|
+
return pinned.href;
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
// src/v2/utils/httpClient.ts
|
|
22
37
|
var HttpClient = class {
|
|
23
38
|
instance;
|
|
@@ -58,6 +73,7 @@ var HttpClient = class {
|
|
|
58
73
|
config.headers = {
|
|
59
74
|
...config.headers || {}
|
|
60
75
|
};
|
|
76
|
+
if (config.url) config.url = pinToApiOrigin(this.apiUrl, config.url);
|
|
61
77
|
let lastError;
|
|
62
78
|
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
63
79
|
try {
|
|
@@ -638,6 +654,16 @@ async function parse(http, file, options) {
|
|
|
638
654
|
throw err;
|
|
639
655
|
}
|
|
640
656
|
}
|
|
657
|
+
async function getParseFormats(http) {
|
|
658
|
+
try {
|
|
659
|
+
const res = await http.get("/v2/parse/formats");
|
|
660
|
+
if (res.status !== 200 || !res.data?.success) throwForBadResponse(res, "get parse formats");
|
|
661
|
+
return res.data.data?.formats ?? [];
|
|
662
|
+
} catch (err) {
|
|
663
|
+
if (err?.isAxiosError) return normalizeAxiosError(err, "get parse formats");
|
|
664
|
+
throw err;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
641
667
|
|
|
642
668
|
// src/v2/methods/search.ts
|
|
643
669
|
function prepareSearchPayload(req) {
|
|
@@ -2220,6 +2246,13 @@ var FirecrawlClient = class {
|
|
|
2220
2246
|
async parse(file, options) {
|
|
2221
2247
|
return parse(this.http, file, options);
|
|
2222
2248
|
}
|
|
2249
|
+
/**
|
|
2250
|
+
* List the file formats the parse endpoint accepts on this deployment.
|
|
2251
|
+
* @returns Formats with their kind, extensions, MIME types, and availability.
|
|
2252
|
+
*/
|
|
2253
|
+
async getParseFormats() {
|
|
2254
|
+
return getParseFormats(this.http);
|
|
2255
|
+
}
|
|
2223
2256
|
// Search
|
|
2224
2257
|
/**
|
|
2225
2258
|
* Search the web and optionally scrape each result.
|
|
@@ -2673,7 +2706,7 @@ var FirecrawlApp = class {
|
|
|
2673
2706
|
if (typeof process !== "undefined" && process.env && process.env.npm_package_version) {
|
|
2674
2707
|
return process.env.npm_package_version;
|
|
2675
2708
|
}
|
|
2676
|
-
const packageJson = await import("./package-
|
|
2709
|
+
const packageJson = await import("./package-JVVNUZPT.js");
|
|
2677
2710
|
return packageJson.default.version;
|
|
2678
2711
|
} catch (error) {
|
|
2679
2712
|
const isTest = typeof process !== "undefined" && (process.env.JEST_WORKER_ID != null || false);
|
|
@@ -2888,7 +2921,7 @@ var FirecrawlApp = class {
|
|
|
2888
2921
|
throw new FirecrawlError("No crawl ID provided", 400);
|
|
2889
2922
|
}
|
|
2890
2923
|
const headers = this.prepareHeaders();
|
|
2891
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}
|
|
2924
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}`, this.apiUrl);
|
|
2892
2925
|
if (skip !== void 0) {
|
|
2893
2926
|
targetURL.searchParams.set("skip", skip.toString());
|
|
2894
2927
|
}
|
|
@@ -3133,7 +3166,7 @@ var FirecrawlApp = class {
|
|
|
3133
3166
|
throw new FirecrawlError("No batch scrape ID provided", 400);
|
|
3134
3167
|
}
|
|
3135
3168
|
const headers = this.prepareHeaders();
|
|
3136
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}
|
|
3169
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}`, this.apiUrl);
|
|
3137
3170
|
if (skip !== void 0) {
|
|
3138
3171
|
targetURL.searchParams.set("skip", skip.toString());
|
|
3139
3172
|
}
|
|
@@ -3345,7 +3378,7 @@ var FirecrawlApp = class {
|
|
|
3345
3378
|
*/
|
|
3346
3379
|
async getRequest(url, headers) {
|
|
3347
3380
|
try {
|
|
3348
|
-
return await axios2.get(url, { headers });
|
|
3381
|
+
return await axios2.get(pinToApiOrigin(this.apiUrl, url), { headers });
|
|
3349
3382
|
} catch (error) {
|
|
3350
3383
|
if (error instanceof AxiosError && error.response) {
|
|
3351
3384
|
return error.response;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firecrawl",
|
|
3
|
-
"version": "4.42.
|
|
3
|
+
"version": "4.42.2",
|
|
4
4
|
"description": "JavaScript SDK for the Firecrawl API: web scraping, crawling, web search, and scientific literature search over a research paper index of PubMed, bioRxiv, medRxiv and arXiv abstracts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"author": "Mendable.ai",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"axios": "1.
|
|
22
|
+
"axios": "1.20.0",
|
|
23
23
|
"typescript-event-target": "^1.1.1",
|
|
24
24
|
"zod": "^3.23.8",
|
|
25
25
|
"zod-to-json-schema": "^3.23.0"
|
package/pnpm-workspace.yaml
CHANGED
|
@@ -7,10 +7,17 @@ overrides:
|
|
|
7
7
|
"rollup@<4.59.0": ">=4.59.0"
|
|
8
8
|
"picomatch@<4.0.4": ">=4.0.4"
|
|
9
9
|
handlebars: ">=4.7.9"
|
|
10
|
-
|
|
10
|
+
# GHSA-q2hr-2g5m-vwhr / GHSA-qhr7-859c-m2p7 / GHSA-6j4f-fj2g-mc7p:
|
|
11
|
+
# pin the 5.x line only. Exact 5.0.12 cannot resolve to 6.x.
|
|
12
|
+
"brace-expansion@>=5.0.0 <5.0.12": "5.0.12"
|
|
11
13
|
"js-yaml@>=3.0.0 <3.15.2": "3.15.2"
|
|
12
14
|
"js-yaml@>=4.0.0 <4.3.2": "4.3.2"
|
|
13
|
-
|
|
15
|
+
# GHSA-vh66-26gq-q6x8 / GHSA-9fr6-4gfg-395g / GHSA-c29m-xwm3-cm6r /
|
|
16
|
+
# GHSA-mghh-pgcx-3jjj / GHSA-x97p-jq2g-jp4f / GHSA-3pq3-5fj3-cg6v /
|
|
17
|
+
# GHSA-542g-h47m-68v8 / GHSA-j8rh-479h-cp32 / GHSA-4hqw-qxg8-jxx2 /
|
|
18
|
+
# GHSA-m8m8-qj5v-23w3 / GHSA-44g4-m2mj-wpvx / GHSA-r4gj-5m52-g5wh:
|
|
19
|
+
# pin the 1.x line only. Exact 1.20.0 cannot resolve to 2.x.
|
|
20
|
+
"axios@>=1.0.0 <1.20.0": "1.20.0"
|
|
14
21
|
"follow-redirects@<1.16.0": ">=1.16.0 <2.0.0"
|
|
15
22
|
"form-data@>=4.0.0 <4.0.6": "4.0.6"
|
|
16
23
|
"@babel/core@>=7.0.0 <7.29.6": "7.29.7"
|
|
@@ -3,6 +3,7 @@ import { config } from "dotenv";
|
|
|
3
3
|
import { getIdentity, getApiUrl } from "./utils/idmux";
|
|
4
4
|
import { testTimeoutMs, withRateLimitRetry } from "./utils/rateLimit";
|
|
5
5
|
import { describe, test, expect, beforeAll } from "@jest/globals";
|
|
6
|
+
import { SdkError } from "../../../v2/types";
|
|
6
7
|
|
|
7
8
|
config();
|
|
8
9
|
|
|
@@ -65,4 +66,29 @@ describe("v2.parse e2e", () => {
|
|
|
65
66
|
},
|
|
66
67
|
testTimeoutMs(60_000),
|
|
67
68
|
);
|
|
69
|
+
|
|
70
|
+
test(
|
|
71
|
+
"lists supported parse formats",
|
|
72
|
+
async () => {
|
|
73
|
+
if (!client) throw new Error();
|
|
74
|
+
|
|
75
|
+
let formats;
|
|
76
|
+
try {
|
|
77
|
+
formats = await client.getParseFormats();
|
|
78
|
+
} catch (err) {
|
|
79
|
+
if (err instanceof SdkError && err.status === 404) {
|
|
80
|
+
console.warn("Skipping: /v2/parse/formats is not deployed on this API");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
expect(formats.length).toBeGreaterThan(0);
|
|
87
|
+
const pdf = formats.find(f => f.format === "pdf");
|
|
88
|
+
expect(pdf?.kind).toBe("document");
|
|
89
|
+
expect(pdf?.extensions).toContain(".pdf");
|
|
90
|
+
expect(pdf?.mimeTypes).toContain("application/pdf");
|
|
91
|
+
},
|
|
92
|
+
testTimeoutMs(60_000),
|
|
93
|
+
);
|
|
68
94
|
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, test, expect, jest, afterEach } from "@jest/globals";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import FirecrawlApp from "../../../v1";
|
|
4
|
+
|
|
5
|
+
const API_URL = "https://api.firecrawl.dev";
|
|
6
|
+
const API_KEY = "fc-test";
|
|
7
|
+
|
|
8
|
+
const origins: Array<[string, string]> = [
|
|
9
|
+
["same origin", API_URL],
|
|
10
|
+
["cross host", "https://evil.example"],
|
|
11
|
+
["protocol-relative", "//evil.example"],
|
|
12
|
+
["different port", "https://api.firecrawl.dev:8443"],
|
|
13
|
+
["different scheme", "http://api.firecrawl.dev"],
|
|
14
|
+
["whitespace-prefixed", "\n https://evil.example"],
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
function mockGet(respond: (url: URL) => unknown) {
|
|
18
|
+
const sent: Array<{ url: string; authorization: unknown }> = [];
|
|
19
|
+
jest.spyOn(axios, "get").mockImplementation(async (url: string, config?: any) => {
|
|
20
|
+
sent.push({ url, authorization: config?.headers?.Authorization });
|
|
21
|
+
return { status: 200, data: respond(new URL(url)) };
|
|
22
|
+
});
|
|
23
|
+
return sent;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function expectPinned(sent: Array<{ url: string; authorization: unknown }>, expectedUrls: string[]) {
|
|
27
|
+
expect(sent.map(req => req.url)).toEqual(expectedUrls);
|
|
28
|
+
for (const req of sent) {
|
|
29
|
+
expect(new URL(req.url).origin).toBe(API_URL);
|
|
30
|
+
expect(req.url).not.toContain("evil.example");
|
|
31
|
+
expect(req.authorization).toBe(`Bearer ${API_KEY}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const completedPage = (next: string) => ({
|
|
36
|
+
success: true,
|
|
37
|
+
status: "completed",
|
|
38
|
+
total: 2,
|
|
39
|
+
completed: 2,
|
|
40
|
+
expiresAt: "2030-01-01T00:00:00Z",
|
|
41
|
+
data: [{ markdown: "a" }],
|
|
42
|
+
next,
|
|
43
|
+
});
|
|
44
|
+
const lastPage = () => ({ success: true, status: "completed", data: [{ markdown: "b" }] });
|
|
45
|
+
|
|
46
|
+
describe("v1 pins next URLs to the api_url origin", () => {
|
|
47
|
+
afterEach(() => {
|
|
48
|
+
jest.restoreAllMocks();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe.each(origins)("%s next", (_label, origin) => {
|
|
52
|
+
const app = new FirecrawlApp({ apiKey: API_KEY, apiUrl: API_URL });
|
|
53
|
+
|
|
54
|
+
test.each([
|
|
55
|
+
["checkCrawlStatus", "/v1/crawl/abc"],
|
|
56
|
+
["checkBatchScrapeStatus", "/v1/batch/scrape/abc"],
|
|
57
|
+
] as const)("%s getAllData follows server next", async (method, path) => {
|
|
58
|
+
const sent = mockGet(url => (url.searchParams.has("skip") ? lastPage() : completedPage(`${origin}${path}?skip=10`)));
|
|
59
|
+
const res: any = await app[method]("abc", true);
|
|
60
|
+
expect(res.data).toHaveLength(2);
|
|
61
|
+
expectPinned(sent, [`${API_URL}${path}`, `${API_URL}${path}?skip=10`]);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test.each([
|
|
65
|
+
["checkCrawlStatus", "/v1/crawl/abc"],
|
|
66
|
+
["checkBatchScrapeStatus", "/v1/batch/scrape/abc"],
|
|
67
|
+
] as const)("%s caller-supplied nextURL", async (method, path) => {
|
|
68
|
+
const sent = mockGet(lastPage);
|
|
69
|
+
await app[method]("abc", false, `${origin}${path}?skip=10`);
|
|
70
|
+
expectPinned(sent, [`${API_URL}${path}?skip=10`]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("monitorJobStatus follows server next", async () => {
|
|
74
|
+
const path = "/v1/crawl/abc";
|
|
75
|
+
const sent = mockGet(url => (url.searchParams.has("skip") ? lastPage() : completedPage(`${origin}${path}?skip=10`)));
|
|
76
|
+
const res: any = await app.monitorJobStatus("abc", app.prepareHeaders(), 0);
|
|
77
|
+
expect(res.data).toHaveLength(2);
|
|
78
|
+
expectPinned(sent, [`${API_URL}${path}`, `${API_URL}${path}?skip=10`]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, test, expect } from "@jest/globals";
|
|
2
|
+
import axios, { type AxiosAdapter } from "axios";
|
|
3
|
+
import { FirecrawlClient } from "../../../v2/client";
|
|
4
|
+
import { pinToApiOrigin } from "../../../utils/apiOrigin";
|
|
5
|
+
|
|
6
|
+
const API_URL = "https://api.firecrawl.dev";
|
|
7
|
+
const API_KEY = "fc-test";
|
|
8
|
+
|
|
9
|
+
const origins: Array<[string, string]> = [
|
|
10
|
+
["same origin", API_URL],
|
|
11
|
+
["cross host", "https://evil.example"],
|
|
12
|
+
["protocol-relative", "//evil.example"],
|
|
13
|
+
["different port", "https://api.firecrawl.dev:8443"],
|
|
14
|
+
["different scheme", "http://api.firecrawl.dev"],
|
|
15
|
+
["whitespace-prefixed", "\n https://evil.example"],
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function makeClient(firstPage: (next: string) => unknown, lastPage: unknown, next: string) {
|
|
19
|
+
const client = new FirecrawlClient({ apiKey: API_KEY, apiUrl: API_URL });
|
|
20
|
+
const sent: Array<{ url: string; authorization: unknown }> = [];
|
|
21
|
+
const adapter: AxiosAdapter = async config => {
|
|
22
|
+
const url = axios.getUri(config);
|
|
23
|
+
sent.push({ url, authorization: config.headers.Authorization });
|
|
24
|
+
const data = new URL(url).searchParams.has("skip") ? lastPage : firstPage(next);
|
|
25
|
+
return { data, status: 200, statusText: "OK", headers: {}, config };
|
|
26
|
+
};
|
|
27
|
+
(client as any).http.instance.defaults.adapter = adapter;
|
|
28
|
+
return { client, sent };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function expectPinned(sent: Array<{ url: string; authorization: unknown }>, path: string) {
|
|
32
|
+
expect(sent).toHaveLength(2);
|
|
33
|
+
expect(sent[1]!.url).toBe(`${API_URL}${path}?skip=10`);
|
|
34
|
+
for (const req of sent) {
|
|
35
|
+
expect(new URL(req.url).origin).toBe(API_URL);
|
|
36
|
+
expect(req.url).not.toContain("evil.example");
|
|
37
|
+
expect(req.authorization).toBe(`Bearer ${API_KEY}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe("v2 pagination pins next URLs to the api_url origin", () => {
|
|
42
|
+
describe.each(origins)("%s next", (_label, origin) => {
|
|
43
|
+
test("crawl status", async () => {
|
|
44
|
+
const path = "/v2/crawl/abc";
|
|
45
|
+
const { client, sent } = makeClient(
|
|
46
|
+
next => ({ success: true, status: "completed", completed: 2, total: 2, next, data: [{ markdown: "a" }] }),
|
|
47
|
+
{ success: true, next: null, data: [{ markdown: "b" }] },
|
|
48
|
+
`${origin}${path}?skip=10`,
|
|
49
|
+
);
|
|
50
|
+
const job = await client.getCrawlStatus("abc");
|
|
51
|
+
expect(job.data).toHaveLength(2);
|
|
52
|
+
expectPinned(sent, path);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("batch scrape status", async () => {
|
|
56
|
+
const path = "/v2/batch/scrape/abc";
|
|
57
|
+
const { client, sent } = makeClient(
|
|
58
|
+
next => ({ success: true, status: "completed", completed: 2, total: 2, next, data: [{ markdown: "a" }] }),
|
|
59
|
+
{ success: true, next: null, data: [{ markdown: "b" }] },
|
|
60
|
+
`${origin}${path}?skip=10`,
|
|
61
|
+
);
|
|
62
|
+
const job = await client.getBatchScrapeStatus("abc");
|
|
63
|
+
expect(job.data).toHaveLength(2);
|
|
64
|
+
expectPinned(sent, path);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("monitor check", async () => {
|
|
68
|
+
const path = "/v2/monitor/m1/checks/c1";
|
|
69
|
+
const { client, sent } = makeClient(
|
|
70
|
+
next => ({ success: true, data: { id: "c1", pages: [{ url: "https://a.example" }], next } }),
|
|
71
|
+
{ success: true, data: { pages: [{ url: "https://b.example" }], next: null } },
|
|
72
|
+
`${origin}${path}?skip=10`,
|
|
73
|
+
);
|
|
74
|
+
const check = await client.getMonitorCheck("m1", "c1");
|
|
75
|
+
expect(check.pages).toHaveLength(2);
|
|
76
|
+
expectPinned(sent, path);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("pinToApiOrigin", () => {
|
|
82
|
+
test("rewrites absolute URLs onto the api origin, keeping path and query and dropping the fragment", () => {
|
|
83
|
+
expect(pinToApiOrigin(API_URL, "https://evil.example/v2/crawl/abc?skip=10#frag")).toBe(
|
|
84
|
+
`${API_URL}/v2/crawl/abc?skip=10`,
|
|
85
|
+
);
|
|
86
|
+
expect(pinToApiOrigin("http://localhost:3002", "https://evil.example:444/v2/crawl/abc?skip=10")).toBe(
|
|
87
|
+
"http://localhost:3002/v2/crawl/abc?skip=10",
|
|
88
|
+
);
|
|
89
|
+
expect(pinToApiOrigin(API_URL, "\\\\evil.example/v2/crawl/abc")).toBe(`${API_URL}/v2/crawl/abc`);
|
|
90
|
+
for (const url of ["\nhttps://evil.example/v2/crawl/abc", "h\tttps://evil.example/v2/crawl/abc", "\u0000 //evil.example/v2/crawl/abc", "/\\evil.example/v2/crawl/abc"]) {
|
|
91
|
+
expect(pinToApiOrigin(API_URL, url)).toBe(`${API_URL}/v2/crawl/abc`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("leaves relative URLs unchanged", () => {
|
|
96
|
+
expect(pinToApiOrigin(API_URL, "/v2/crawl/abc?skip=10")).toBe("/v2/crawl/abc?skip=10");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("throws when apiUrl is not absolute and the URL needs pinning", () => {
|
|
100
|
+
expect(() => pinToApiOrigin("api.firecrawl.dev", "https://evil.example/v2/crawl/abc")).toThrow(
|
|
101
|
+
"apiUrl must be an absolute URL",
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { describe, test, expect } from "@jest/globals";
|
|
2
|
+
import axios, { type AxiosAdapter } from "axios";
|
|
3
|
+
import { Firecrawl } from "../../../index";
|
|
4
|
+
import { SdkError } from "../../../v2/types";
|
|
5
|
+
|
|
6
|
+
const API_URL = "https://api.firecrawl.dev";
|
|
7
|
+
const API_KEY = "fc-test";
|
|
8
|
+
|
|
9
|
+
function makeClient(status: number, data: unknown) {
|
|
10
|
+
const client = new Firecrawl({ apiKey: API_KEY, apiUrl: API_URL });
|
|
11
|
+
const sent: Array<{ url: string; method?: string; authorization: unknown }> = [];
|
|
12
|
+
const adapter: AxiosAdapter = async config => {
|
|
13
|
+
sent.push({ url: axios.getUri(config), method: config.method, authorization: config.headers.Authorization });
|
|
14
|
+
const response = { data, status, statusText: "", headers: {}, config };
|
|
15
|
+
if (status >= 400) {
|
|
16
|
+
throw new axios.AxiosError(`Request failed with status code ${status}`, "ERR_BAD_RESPONSE", config, null, response);
|
|
17
|
+
}
|
|
18
|
+
return response;
|
|
19
|
+
};
|
|
20
|
+
(client as any).http.instance.defaults.adapter = adapter;
|
|
21
|
+
return { client, sent };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe("v2.getParseFormats unit", () => {
|
|
25
|
+
test("GETs /v2/parse/formats with auth and unwraps data.formats", async () => {
|
|
26
|
+
const { client, sent } = makeClient(200, {
|
|
27
|
+
success: true,
|
|
28
|
+
data: {
|
|
29
|
+
formats: [
|
|
30
|
+
{ format: "pdf", kind: "document", extensions: [".pdf"], mimeTypes: ["application/pdf"], available: true },
|
|
31
|
+
{ format: "png", kind: "image", extensions: [".png"], mimeTypes: ["image/png"], available: false },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const formats = await client.getParseFormats();
|
|
37
|
+
|
|
38
|
+
expect(sent).toEqual([{ url: `${API_URL}/v2/parse/formats`, method: "get", authorization: `Bearer ${API_KEY}` }]);
|
|
39
|
+
expect(formats).toHaveLength(2);
|
|
40
|
+
expect(formats[0]).toEqual({ format: "pdf", kind: "document", extensions: [".pdf"], mimeTypes: ["application/pdf"], available: true });
|
|
41
|
+
expect(formats[1]!.kind).toBe("image");
|
|
42
|
+
expect(formats[1]!.mimeTypes).toEqual(["image/png"]);
|
|
43
|
+
expect(formats[1]!.available).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("tolerates unknown kinds and extra fields", async () => {
|
|
47
|
+
const { client } = makeClient(200, {
|
|
48
|
+
success: true,
|
|
49
|
+
data: {
|
|
50
|
+
formats: [
|
|
51
|
+
{ format: "mp3", kind: "audio", extensions: [".mp3"], mimeTypes: ["audio/mpeg"], available: true, maxSizeMb: 50 },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const [format] = await client.getParseFormats();
|
|
57
|
+
|
|
58
|
+
expect(format!.format).toBe("mp3");
|
|
59
|
+
expect(format!.kind).toBe("audio");
|
|
60
|
+
expect(format!.mimeTypes).toEqual(["audio/mpeg"]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("returns an empty list when formats is missing", async () => {
|
|
64
|
+
const { client } = makeClient(200, { success: true, data: {} });
|
|
65
|
+
|
|
66
|
+
await expect(client.getParseFormats()).resolves.toEqual([]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test.each([401, 500])("throws SdkError on %i", async status => {
|
|
70
|
+
const { client } = makeClient(status, { success: false, error: "Unauthorized" });
|
|
71
|
+
|
|
72
|
+
const err = await client.getParseFormats().catch(e => e);
|
|
73
|
+
|
|
74
|
+
expect(err).toBeInstanceOf(SdkError);
|
|
75
|
+
expect(err.status).toBe(status);
|
|
76
|
+
expect(err.message).toBe("Unauthorized");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("throws SdkError when success is false", async () => {
|
|
80
|
+
const { client } = makeClient(200, { success: false, error: "nope" });
|
|
81
|
+
|
|
82
|
+
await expect(client.getParseFormats()).rejects.toBeInstanceOf(SdkError);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrite an absolute or protocol-relative URL onto apiUrl's scheme, host and
|
|
3
|
+
* port (keeping path and query, dropping any fragment) so credentials never
|
|
4
|
+
* leave the configured API origin. Relative URLs are returned unchanged.
|
|
5
|
+
* Throws if apiUrl is not an absolute URL.
|
|
6
|
+
*/
|
|
7
|
+
export function pinToApiOrigin(apiUrl: string, url: string): string {
|
|
8
|
+
const normalized = url.replace(/[\t\n\r]/g, "").replace(/^[\u0000-\u0020]+/, "");
|
|
9
|
+
if (!/^([a-z][a-z\d+\-.]*:|[\\/]{2})/i.test(normalized)) return url;
|
|
10
|
+
const base = URL.canParse(apiUrl) ? new URL(apiUrl) : null;
|
|
11
|
+
if (!base?.host) {
|
|
12
|
+
throw new Error(`apiUrl must be an absolute URL, got ${JSON.stringify(apiUrl)}`);
|
|
13
|
+
}
|
|
14
|
+
const target = new URL(normalized, base);
|
|
15
|
+
const pinned = new URL(base.origin);
|
|
16
|
+
pinned.pathname = target.pathname;
|
|
17
|
+
pinned.search = target.search;
|
|
18
|
+
return pinned.href;
|
|
19
|
+
}
|
package/src/v1/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ import axios, { type AxiosResponse, type AxiosRequestHeaders, AxiosError } from
|
|
|
2
2
|
import * as zt from "zod";
|
|
3
3
|
import { zodSchemaToJsonSchema } from "../utils/zodSchemaToJson";
|
|
4
4
|
import { TypedEventTarget } from "typescript-event-target";
|
|
5
|
+
import type { RequiresAction } from "../v2/types";
|
|
6
|
+
import { pinToApiOrigin } from "../utils/apiOrigin";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Configuration interface for FirecrawlApp.
|
|
@@ -439,6 +441,8 @@ export interface CrawlErrorsResponse {
|
|
|
439
441
|
url: string,
|
|
440
442
|
code?: string,
|
|
441
443
|
error: string,
|
|
444
|
+
/** Present when the page needs provider terms accepted first. */
|
|
445
|
+
requiresAction?: RequiresAction,
|
|
442
446
|
}[];
|
|
443
447
|
|
|
444
448
|
/**
|
|
@@ -919,7 +923,7 @@ export default class FirecrawlApp {
|
|
|
919
923
|
}
|
|
920
924
|
|
|
921
925
|
const headers: AxiosRequestHeaders = this.prepareHeaders();
|
|
922
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}
|
|
926
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/crawl/${id}`, this.apiUrl);
|
|
923
927
|
if (skip !== undefined) {
|
|
924
928
|
targetURL.searchParams.set("skip", skip.toString());
|
|
925
929
|
}
|
|
@@ -1207,7 +1211,7 @@ export default class FirecrawlApp {
|
|
|
1207
1211
|
}
|
|
1208
1212
|
|
|
1209
1213
|
const headers: AxiosRequestHeaders = this.prepareHeaders();
|
|
1210
|
-
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}
|
|
1214
|
+
const targetURL = new URL(nextURL ?? `${this.apiUrl}/v1/batch/scrape/${id}`, this.apiUrl);
|
|
1211
1215
|
if (skip !== undefined) {
|
|
1212
1216
|
targetURL.searchParams.set("skip", skip.toString());
|
|
1213
1217
|
}
|
|
@@ -1448,7 +1452,7 @@ export default class FirecrawlApp {
|
|
|
1448
1452
|
headers: AxiosRequestHeaders
|
|
1449
1453
|
): Promise<AxiosResponse> {
|
|
1450
1454
|
try {
|
|
1451
|
-
return await axios.get(url, { headers });
|
|
1455
|
+
return await axios.get(pinToApiOrigin(this.apiUrl, url), { headers });
|
|
1452
1456
|
} catch (error) {
|
|
1453
1457
|
if (error instanceof AxiosError && error.response) {
|
|
1454
1458
|
return error.response as AxiosResponse;
|
package/src/v2/client.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
interact as interactMethod,
|
|
5
5
|
stopInteraction as stopInteractionMethod,
|
|
6
6
|
} from "./methods/scrape";
|
|
7
|
-
import { parse as parseMethod } from "./methods/parse";
|
|
7
|
+
import { parse as parseMethod, getParseFormats } from "./methods/parse";
|
|
8
8
|
import { search } from "./methods/search";
|
|
9
9
|
import { scrapeAlexandria, findTools } from "./methods/tools";
|
|
10
10
|
import { developerSearch as developerSearchMethod } from "./methods/developer";
|
|
@@ -53,6 +53,7 @@ import type {
|
|
|
53
53
|
FindToolsData,
|
|
54
54
|
AlexandriaScrapeData,
|
|
55
55
|
ParseFile,
|
|
56
|
+
ParseFormatInfo,
|
|
56
57
|
ParseOptions,
|
|
57
58
|
ScrapeOptions,
|
|
58
59
|
SearchData,
|
|
@@ -273,6 +274,14 @@ export class FirecrawlClient {
|
|
|
273
274
|
return parseMethod(this.http, file, options);
|
|
274
275
|
}
|
|
275
276
|
|
|
277
|
+
/**
|
|
278
|
+
* List the file formats the parse endpoint accepts on this deployment.
|
|
279
|
+
* @returns Formats with their kind, extensions, MIME types, and availability.
|
|
280
|
+
*/
|
|
281
|
+
async getParseFormats(): Promise<ParseFormatInfo[]> {
|
|
282
|
+
return getParseFormats(this.http);
|
|
283
|
+
}
|
|
284
|
+
|
|
276
285
|
// Search
|
|
277
286
|
/**
|
|
278
287
|
* Search the web and optionally scrape each result.
|
package/src/v2/methods/agent.ts
CHANGED
|
@@ -12,6 +12,7 @@ function prepareAgentPayload(args: {
|
|
|
12
12
|
origin?: string;
|
|
13
13
|
maxCredits?: number;
|
|
14
14
|
strictConstrainToURLs?: boolean;
|
|
15
|
+
/** Defaults to spark-2. "spark-1-pro" and "spark-1-mini" are deprecated and run spark-2. */
|
|
15
16
|
model?: "spark-1-pro" | "spark-1-mini" | "spark-2";
|
|
16
17
|
effort?: AgentEffort;
|
|
17
18
|
webhook?: string | AgentWebhookConfig;
|
package/src/v2/methods/batch.ts
CHANGED
|
@@ -152,7 +152,7 @@ export async function getBatchScrapeErrors(
|
|
|
152
152
|
try {
|
|
153
153
|
const res = await http.get<{
|
|
154
154
|
success?: boolean;
|
|
155
|
-
data?:
|
|
155
|
+
data?: CrawlErrorsResponse;
|
|
156
156
|
}>(`/v2/batch/scrape/${jobId}/errors`);
|
|
157
157
|
if (res.status !== 200) throwForBadResponse(res, "get batch scrape errors");
|
|
158
158
|
const payload = res.data?.data ?? (res.data as any);
|
package/src/v2/methods/crawl.ts
CHANGED
|
@@ -162,7 +162,7 @@ export async function crawl(http: HttpClient, request: CrawlRequest, pollInterva
|
|
|
162
162
|
|
|
163
163
|
export async function getCrawlErrors(http: HttpClient, crawlId: string): Promise<CrawlErrorsResponse> {
|
|
164
164
|
try {
|
|
165
|
-
const res = await http.get<{ success?: boolean; data?:
|
|
165
|
+
const res = await http.get<{ success?: boolean; data?: CrawlErrorsResponse }>(`/v2/crawl/${crawlId}/errors`);
|
|
166
166
|
if (res.status !== 200) throwForBadResponse(res, "get crawl errors");
|
|
167
167
|
const payload = res.data?.data ?? (res.data as any);
|
|
168
168
|
return { errors: payload.errors || [], robotsBlocked: payload.robotsBlocked || [] };
|
package/src/v2/methods/parse.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Document, type ParseFile, type ParseOptions } from "../types";
|
|
1
|
+
import { type Document, type ParseFile, type ParseFormatInfo, type ParseOptions } from "../types";
|
|
2
2
|
import { HttpClient } from "../utils/httpClient";
|
|
3
3
|
import { agentHintMetadata } from "../utils/agentHints";
|
|
4
4
|
import { ensureValidParseOptions } from "../utils/validation";
|
|
@@ -95,3 +95,14 @@ export async function parse(
|
|
|
95
95
|
throw err;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
+
|
|
99
|
+
export async function getParseFormats(http: HttpClient): Promise<ParseFormatInfo[]> {
|
|
100
|
+
try {
|
|
101
|
+
const res = await http.get<{ success: boolean; data?: { formats: ParseFormatInfo[] } }>("/v2/parse/formats");
|
|
102
|
+
if (res.status !== 200 || !res.data?.success) throwForBadResponse(res, "get parse formats");
|
|
103
|
+
return res.data.data?.formats ?? [];
|
|
104
|
+
} catch (err: any) {
|
|
105
|
+
if (err?.isAxiosError) return normalizeAxiosError(err, "get parse formats");
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
}
|
package/src/v2/types.ts
CHANGED
|
@@ -366,6 +366,18 @@ export type ParseOptions = Omit<
|
|
|
366
366
|
proxy?: "basic" | "auto";
|
|
367
367
|
};
|
|
368
368
|
|
|
369
|
+
/** A file format accepted by the parse endpoint. */
|
|
370
|
+
export interface ParseFormatInfo {
|
|
371
|
+
/** Format identifier, e.g. "pdf". */
|
|
372
|
+
format: string;
|
|
373
|
+
kind: "document" | "image" | (string & {});
|
|
374
|
+
/** File extensions including the leading dot, e.g. ".pdf". */
|
|
375
|
+
extensions: string[];
|
|
376
|
+
mimeTypes: string[];
|
|
377
|
+
/** False when the format is recognized but not enabled on this deployment. */
|
|
378
|
+
available: boolean;
|
|
379
|
+
}
|
|
380
|
+
|
|
369
381
|
export interface WebhookConfig {
|
|
370
382
|
url: string;
|
|
371
383
|
headers?: Record<string, string>;
|
|
@@ -1627,6 +1639,11 @@ export interface AgentStatusResponse {
|
|
|
1627
1639
|
status: "processing" | "completed" | "failed";
|
|
1628
1640
|
error?: string;
|
|
1629
1641
|
data?: unknown;
|
|
1642
|
+
/** Best-effort result on a failed run; never a completed `data` value. */
|
|
1643
|
+
partial?: unknown;
|
|
1644
|
+
/** Schema validity of `partial`, when a schema was supplied. */
|
|
1645
|
+
partialSchemaValid?: boolean;
|
|
1646
|
+
stopReason?: "credit_limit_reached";
|
|
1630
1647
|
/**
|
|
1631
1648
|
* Server-provided model name. Widened past the request-side union on
|
|
1632
1649
|
* purpose: new models ship without an SDK release, so pinning this to known
|
|
@@ -1672,6 +1689,9 @@ export interface AgentThreadRun {
|
|
|
1672
1689
|
message: string | null;
|
|
1673
1690
|
/** Only present when the request asked for includeData. */
|
|
1674
1691
|
data?: unknown;
|
|
1692
|
+
partial?: unknown;
|
|
1693
|
+
partialSchemaValid?: boolean;
|
|
1694
|
+
stopReason?: "credit_limit_reached";
|
|
1675
1695
|
suggestions?: AgentSuggestion[] | null;
|
|
1676
1696
|
pendingApproval?: PendingApproval | null;
|
|
1677
1697
|
exchange?: AgentExchangeSummary | null;
|
|
@@ -1955,6 +1975,8 @@ export interface CrawlErrorsResponse {
|
|
|
1955
1975
|
url: string;
|
|
1956
1976
|
code?: string;
|
|
1957
1977
|
error: string;
|
|
1978
|
+
/** Present when the page needs provider terms accepted first. */
|
|
1979
|
+
requiresAction?: RequiresAction;
|
|
1958
1980
|
}[];
|
|
1959
1981
|
robotsBlocked: string[];
|
|
1960
1982
|
}
|
|
@@ -4,6 +4,7 @@ import axios, {
|
|
|
4
4
|
type AxiosResponse,
|
|
5
5
|
} from "axios";
|
|
6
6
|
import { getVersion } from "./getVersion";
|
|
7
|
+
import { pinToApiOrigin } from "../../utils/apiOrigin";
|
|
7
8
|
|
|
8
9
|
export interface HttpClientOptions {
|
|
9
10
|
apiKey: string;
|
|
@@ -64,6 +65,7 @@ export class HttpClient {
|
|
|
64
65
|
config.headers = {
|
|
65
66
|
...(config.headers || {}),
|
|
66
67
|
};
|
|
68
|
+
if (config.url) config.url = pinToApiOrigin(this.apiUrl, config.url);
|
|
67
69
|
|
|
68
70
|
let lastError: any;
|
|
69
71
|
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|