firecrawl 4.21.1 → 4.22.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/{chunk-EH7NHUN5.js → chunk-XWPH5FOQ.js} +3 -3
- package/dist/index.cjs +184 -5
- package/dist/index.d.cts +154 -1
- package/dist/index.d.ts +154 -1
- package/dist/index.js +183 -4
- package/dist/{package-7423KYJY.js → package-VALCXP74.js} +1 -1
- package/package.json +2 -2
- package/src/__tests__/unit/v2/pagination.test.ts +21 -0
- package/src/v2/client.ts +85 -0
- package/src/v2/methods/monitor.ts +181 -0
- package/src/v2/types.ts +148 -0
- package/src/v2/utils/httpClient.ts +14 -0
- package/src/v2/utils/pagination.ts +12 -9
package/src/v2/types.ts
CHANGED
|
@@ -606,6 +606,154 @@ export interface MapOptions {
|
|
|
606
606
|
location?: LocationConfig;
|
|
607
607
|
}
|
|
608
608
|
|
|
609
|
+
export interface MonitorSchedule {
|
|
610
|
+
cron: string;
|
|
611
|
+
timezone?: string;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export interface MonitorEmailNotification {
|
|
615
|
+
enabled?: boolean;
|
|
616
|
+
recipients?: string[];
|
|
617
|
+
includeDiffs?: boolean;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
export interface MonitorNotification {
|
|
621
|
+
email?: MonitorEmailNotification;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export interface MonitorWebhookConfig {
|
|
625
|
+
url: string;
|
|
626
|
+
headers?: Record<string, string>;
|
|
627
|
+
metadata?: Record<string, string>;
|
|
628
|
+
events?: string[];
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export interface MonitorScrapeTarget {
|
|
632
|
+
id?: string;
|
|
633
|
+
type: 'scrape';
|
|
634
|
+
urls: string[];
|
|
635
|
+
scrapeOptions?: ScrapeOptions;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export interface MonitorCrawlTarget {
|
|
639
|
+
id?: string;
|
|
640
|
+
type: 'crawl';
|
|
641
|
+
url: string;
|
|
642
|
+
crawlOptions?: CrawlOptions;
|
|
643
|
+
scrapeOptions?: ScrapeOptions;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export type MonitorTarget = MonitorScrapeTarget | MonitorCrawlTarget;
|
|
647
|
+
|
|
648
|
+
export interface CreateMonitorRequest {
|
|
649
|
+
name: string;
|
|
650
|
+
schedule: MonitorSchedule;
|
|
651
|
+
webhook?: MonitorWebhookConfig;
|
|
652
|
+
notification?: MonitorNotification;
|
|
653
|
+
targets: MonitorTarget[];
|
|
654
|
+
retentionDays?: number;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export interface UpdateMonitorRequest {
|
|
658
|
+
name?: string;
|
|
659
|
+
status?: 'active' | 'paused';
|
|
660
|
+
schedule?: MonitorSchedule;
|
|
661
|
+
webhook?: MonitorWebhookConfig | null;
|
|
662
|
+
notification?: MonitorNotification | null;
|
|
663
|
+
targets?: MonitorTarget[];
|
|
664
|
+
retentionDays?: number;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
export interface MonitorSummary {
|
|
668
|
+
totalPages: number;
|
|
669
|
+
same: number;
|
|
670
|
+
changed: number;
|
|
671
|
+
new: number;
|
|
672
|
+
removed: number;
|
|
673
|
+
error: number;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
export interface Monitor {
|
|
677
|
+
id: string;
|
|
678
|
+
name: string;
|
|
679
|
+
status: 'active' | 'paused' | 'deleted';
|
|
680
|
+
schedule: MonitorSchedule;
|
|
681
|
+
nextRunAt?: string | null;
|
|
682
|
+
lastRunAt?: string | null;
|
|
683
|
+
currentCheckId?: string | null;
|
|
684
|
+
targets: MonitorTarget[];
|
|
685
|
+
webhook?: MonitorWebhookConfig | null;
|
|
686
|
+
notification?: MonitorNotification | null;
|
|
687
|
+
retentionDays: number;
|
|
688
|
+
estimatedCreditsPerMonth?: number | null;
|
|
689
|
+
lastCheckSummary?: MonitorSummary | null;
|
|
690
|
+
createdAt: string;
|
|
691
|
+
updatedAt: string;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
export interface MonitorCheck {
|
|
695
|
+
id: string;
|
|
696
|
+
monitorId: string;
|
|
697
|
+
status:
|
|
698
|
+
| 'queued'
|
|
699
|
+
| 'running'
|
|
700
|
+
| 'completed'
|
|
701
|
+
| 'failed'
|
|
702
|
+
| 'partial'
|
|
703
|
+
| 'skipped_overlap';
|
|
704
|
+
trigger: 'scheduled' | 'manual';
|
|
705
|
+
scheduledFor?: string | null;
|
|
706
|
+
startedAt?: string | null;
|
|
707
|
+
finishedAt?: string | null;
|
|
708
|
+
estimatedCredits?: number | null;
|
|
709
|
+
reservedCredits?: number | null;
|
|
710
|
+
actualCredits?: number | null;
|
|
711
|
+
billingStatus:
|
|
712
|
+
| 'not_applicable'
|
|
713
|
+
| 'reserved'
|
|
714
|
+
| 'confirmed'
|
|
715
|
+
| 'released'
|
|
716
|
+
| 'failed';
|
|
717
|
+
summary: MonitorSummary;
|
|
718
|
+
targetResults?: unknown;
|
|
719
|
+
notificationStatus?: unknown;
|
|
720
|
+
error?: string | null;
|
|
721
|
+
createdAt: string;
|
|
722
|
+
updatedAt: string;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
export interface MonitorCheckPage {
|
|
726
|
+
id: string;
|
|
727
|
+
targetId: string;
|
|
728
|
+
url: string;
|
|
729
|
+
status: 'same' | 'new' | 'changed' | 'removed' | 'error';
|
|
730
|
+
previousScrapeId?: string | null;
|
|
731
|
+
currentScrapeId?: string | null;
|
|
732
|
+
statusCode?: number | null;
|
|
733
|
+
error?: string | null;
|
|
734
|
+
metadata?: unknown;
|
|
735
|
+
diff?: unknown;
|
|
736
|
+
createdAt: string;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
export interface MonitorCheckDetail extends MonitorCheck {
|
|
740
|
+
pages: MonitorCheckPage[];
|
|
741
|
+
next?: string | null;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
export interface ListMonitorsOptions {
|
|
745
|
+
limit?: number;
|
|
746
|
+
offset?: number;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
export type ListMonitorChecksOptions = ListMonitorsOptions;
|
|
750
|
+
|
|
751
|
+
export type GetMonitorCheckOptions = PaginationConfig & {
|
|
752
|
+
limit?: number;
|
|
753
|
+
skip?: number;
|
|
754
|
+
status?: MonitorCheckPage["status"];
|
|
755
|
+
};
|
|
756
|
+
|
|
609
757
|
export interface ExtractResponse {
|
|
610
758
|
success?: boolean;
|
|
611
759
|
id?: string;
|
|
@@ -149,6 +149,20 @@ export class HttpClient {
|
|
|
149
149
|
return this.request<T>({ method: "delete", url: endpoint, headers });
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
patch<T = any>(
|
|
153
|
+
endpoint: string,
|
|
154
|
+
body: Record<string, unknown>,
|
|
155
|
+
options?: RequestOptions,
|
|
156
|
+
) {
|
|
157
|
+
return this.request<T>({
|
|
158
|
+
method: "patch",
|
|
159
|
+
url: endpoint,
|
|
160
|
+
data: body,
|
|
161
|
+
headers: options?.headers,
|
|
162
|
+
timeout: options?.timeoutMs,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
152
166
|
prepareHeaders(idempotencyKey?: string): Record<string, string> {
|
|
153
167
|
const headers: Record<string, string> = {};
|
|
154
168
|
if (idempotencyKey) headers["x-idempotency-key"] = idempotencyKey;
|
|
@@ -2,14 +2,14 @@ import type { HttpClient } from "../utils/httpClient";
|
|
|
2
2
|
import type { Document, PaginationConfig } from "../types";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Shared helper to follow `next`
|
|
5
|
+
* Shared helper to follow `next` URLs and aggregate paginated result arrays.
|
|
6
6
|
*/
|
|
7
|
-
export async function fetchAllPages(
|
|
7
|
+
export async function fetchAllPages<T = Document>(
|
|
8
8
|
http: HttpClient,
|
|
9
9
|
nextUrl: string,
|
|
10
|
-
initial:
|
|
10
|
+
initial: T[],
|
|
11
11
|
pagination?: PaginationConfig
|
|
12
|
-
): Promise<
|
|
12
|
+
): Promise<T[]> {
|
|
13
13
|
const docs = initial.slice();
|
|
14
14
|
let current: string | null = nextUrl;
|
|
15
15
|
let pageCount = 0;
|
|
@@ -22,21 +22,24 @@ export async function fetchAllPages(
|
|
|
22
22
|
if (maxPages != null && pageCount >= maxPages) break;
|
|
23
23
|
if (maxWaitTime != null && (Date.now() - started) / 1000 > maxWaitTime) break;
|
|
24
24
|
|
|
25
|
-
let payload: { success: boolean; next?: string | null; data?:
|
|
25
|
+
let payload: { success: boolean; next?: string | null; data?: T[] | { pages?: T[]; next?: string | null } } | null = null;
|
|
26
26
|
try {
|
|
27
|
-
const res = await http.get<{ success: boolean; next?: string | null; data?:
|
|
27
|
+
const res = await http.get<{ success: boolean; next?: string | null; data?: T[] | { pages?: T[]; next?: string | null } }>(current);
|
|
28
28
|
payload = res.data;
|
|
29
29
|
} catch {
|
|
30
30
|
break; // axios rejects on non-2xx; stop pagination gracefully
|
|
31
31
|
}
|
|
32
32
|
if (!payload?.success) break;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
const pageData = Array.isArray(payload.data)
|
|
35
|
+
? payload.data
|
|
36
|
+
: payload.data?.pages || [];
|
|
37
|
+
for (const d of pageData) {
|
|
35
38
|
if (maxResults != null && docs.length >= maxResults) break;
|
|
36
|
-
docs.push(d as
|
|
39
|
+
docs.push(d as T);
|
|
37
40
|
}
|
|
38
41
|
if (maxResults != null && docs.length >= maxResults) break;
|
|
39
|
-
current = (payload.next ?? null) as string | null;
|
|
42
|
+
current = (payload.next ?? (Array.isArray(payload.data) ? null : payload.data?.next) ?? null) as string | null;
|
|
40
43
|
pageCount += 1;
|
|
41
44
|
}
|
|
42
45
|
return docs;
|