@dealcrawl/sdk 2.11.0 → 2.12.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 +63 -0
- package/dist/index.d.mts +221 -27
- package/dist/index.d.ts +221 -27
- package/dist/index.js +234 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +234 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,69 @@ Official TypeScript SDK for the DealCrawl web scraping and crawling API.
|
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
8
|
|
|
9
|
+
## What's New in v2.12.0 (January 2026) ✨
|
|
10
|
+
|
|
11
|
+
### New Methods - 100% API Coverage
|
|
12
|
+
|
|
13
|
+
All missing API endpoints now have SDK methods (completes the 87% → 100% alignment):
|
|
14
|
+
|
|
15
|
+
**Status Resource (`client.status.*`)**
|
|
16
|
+
|
|
17
|
+
- `getJobErrors(jobId, options?)` - Get job errors without loading full results (useful for debugging large crawls)
|
|
18
|
+
|
|
19
|
+
**Data Resource (`client.data.*`)**
|
|
20
|
+
|
|
21
|
+
- `getJob(jobId)` - Get full job details with result
|
|
22
|
+
- `getJobResult(jobId)` - Get only the result of a completed job
|
|
23
|
+
- `exportJob(jobId, format)` - Export job in multiple formats (json, markdown, llm, csv)
|
|
24
|
+
|
|
25
|
+
**Webhooks Resource (`client.webhooks.*`)**
|
|
26
|
+
|
|
27
|
+
- `rotateSecret(webhookId, options)` - Rotate webhook secret with grace period support
|
|
28
|
+
- `getSecretStatus(webhookId)` - Check secret version and grace period status
|
|
29
|
+
- `verifySignature(options)` - Verify webhook signature and replay protection
|
|
30
|
+
|
|
31
|
+
### Examples
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// Get job errors for debugging
|
|
35
|
+
const errors = await client.status.getJobErrors("job_abc123", { limit: 50 });
|
|
36
|
+
|
|
37
|
+
// Export crawl results as Markdown
|
|
38
|
+
const markdown = await client.data.exportJob("crawl_123", "markdown");
|
|
39
|
+
|
|
40
|
+
// Rotate webhook secret with 24h grace period
|
|
41
|
+
await client.webhooks.rotateSecret("webhook_abc", {
|
|
42
|
+
newSecret: "new-secure-key",
|
|
43
|
+
gracePeriodHours: 24
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## What's New in v2.11.1 (January 2026) 🐛
|
|
50
|
+
|
|
51
|
+
### Bug Fixes
|
|
52
|
+
|
|
53
|
+
- **DataResource**: Fixed syntax error in `getDealsByCategory()` method (unclosed docstring + duplicate line)
|
|
54
|
+
- **SDK-API Alignment**: Verified 87% endpoint coverage with detailed alignment report
|
|
55
|
+
|
|
56
|
+
### Known Gaps
|
|
57
|
+
|
|
58
|
+
The following API endpoints do not have SDK methods yet (see [API-SDK Alignment Report](../../docs/API-SDK-ALIGNMENT-REPORT.md)):
|
|
59
|
+
|
|
60
|
+
- `GET /v1/status/:jobId/errors` - Get job errors
|
|
61
|
+
- `GET /v1/data/jobs/:jobId` - Get full job details
|
|
62
|
+
- `GET /v1/data/jobs/:jobId/result` - Get job result
|
|
63
|
+
- `GET /v1/data/jobs/:jobId/export` - Export job in multiple formats
|
|
64
|
+
- `POST /v1/webhooks/:id/rotate` - Rotate webhook secret
|
|
65
|
+
- `GET /v1/webhooks/:id/secret-status` - Get webhook secret status
|
|
66
|
+
- `POST /v1/webhooks/verify` - Verify webhook signature
|
|
67
|
+
|
|
68
|
+
These methods will be added in a future release.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
9
72
|
## What's New in v2.11.0 (January 2026) 🎉
|
|
10
73
|
|
|
11
74
|
### Breaking Changes ⚠️
|
package/dist/index.d.mts
CHANGED
|
@@ -690,6 +690,22 @@ interface CancelJobResponse {
|
|
|
690
690
|
jobId: string;
|
|
691
691
|
message: string;
|
|
692
692
|
}
|
|
693
|
+
/** Job error entry */
|
|
694
|
+
interface JobErrorEntry {
|
|
695
|
+
url?: string;
|
|
696
|
+
error: string;
|
|
697
|
+
timestamp?: string;
|
|
698
|
+
}
|
|
699
|
+
/** Job errors response */
|
|
700
|
+
interface JobErrorsResponse {
|
|
701
|
+
data: JobErrorEntry[];
|
|
702
|
+
pagination: PaginationInfo;
|
|
703
|
+
meta?: {
|
|
704
|
+
jobId: string;
|
|
705
|
+
status?: JobStatus$1;
|
|
706
|
+
offset?: number;
|
|
707
|
+
};
|
|
708
|
+
}
|
|
693
709
|
/** Job summary in list */
|
|
694
710
|
interface JobSummary {
|
|
695
711
|
id: string;
|
|
@@ -769,6 +785,32 @@ interface ClientStatsResponse {
|
|
|
769
785
|
}>;
|
|
770
786
|
};
|
|
771
787
|
}
|
|
788
|
+
/** Full job details response */
|
|
789
|
+
interface JobDetailsResponse {
|
|
790
|
+
id: string;
|
|
791
|
+
type: "scrape" | "crawl" | "dork" | "extract";
|
|
792
|
+
status: JobStatus$1;
|
|
793
|
+
input: Record<string, unknown>;
|
|
794
|
+
result?: unknown;
|
|
795
|
+
progress?: number;
|
|
796
|
+
error?: string;
|
|
797
|
+
dealsFound?: number;
|
|
798
|
+
avgDealScore?: number;
|
|
799
|
+
highestDealScore?: number;
|
|
800
|
+
checkpoint?: CheckpointInfo;
|
|
801
|
+
createdAt: string;
|
|
802
|
+
updatedAt: string;
|
|
803
|
+
completedAt?: string;
|
|
804
|
+
}
|
|
805
|
+
/** Job result response */
|
|
806
|
+
interface JobResultResponse {
|
|
807
|
+
jobId: string;
|
|
808
|
+
status: "completed";
|
|
809
|
+
result: unknown;
|
|
810
|
+
completedAt?: string;
|
|
811
|
+
}
|
|
812
|
+
/** Job export response (string for CSV/Markdown/LLM, object for JSON) */
|
|
813
|
+
type JobExportResponse = string | Record<string, unknown>;
|
|
772
814
|
/** Webhook in list */
|
|
773
815
|
interface WebhookItem {
|
|
774
816
|
id: string;
|
|
@@ -792,10 +834,17 @@ interface CreateWebhookResponse {
|
|
|
792
834
|
minDealScore: number;
|
|
793
835
|
active: boolean;
|
|
794
836
|
}
|
|
795
|
-
/** List webhooks response */
|
|
837
|
+
/** List webhooks response (standardized list format) */
|
|
796
838
|
interface ListWebhooksResponse {
|
|
797
|
-
|
|
798
|
-
|
|
839
|
+
data: WebhookItem[];
|
|
840
|
+
pagination: {
|
|
841
|
+
page: number;
|
|
842
|
+
limit: number;
|
|
843
|
+
total: number;
|
|
844
|
+
totalPages: number;
|
|
845
|
+
hasMore: boolean;
|
|
846
|
+
};
|
|
847
|
+
meta?: Record<string, unknown>;
|
|
799
848
|
}
|
|
800
849
|
/** Update webhook response */
|
|
801
850
|
interface UpdateWebhookResponse {
|
|
@@ -817,6 +866,35 @@ interface TestWebhookResponse {
|
|
|
817
866
|
responseTime?: number;
|
|
818
867
|
error?: string;
|
|
819
868
|
}
|
|
869
|
+
/** Rotate webhook secret response */
|
|
870
|
+
interface RotateSecretResponse {
|
|
871
|
+
success: boolean;
|
|
872
|
+
webhookId: string;
|
|
873
|
+
secretVersion: number;
|
|
874
|
+
previousSecretValidUntil: string;
|
|
875
|
+
gracePeriodHours: number;
|
|
876
|
+
message: string;
|
|
877
|
+
}
|
|
878
|
+
/** Webhook secret status response */
|
|
879
|
+
interface SecretStatusResponse {
|
|
880
|
+
webhookId: string;
|
|
881
|
+
hasSecret: boolean;
|
|
882
|
+
secretVersion: number;
|
|
883
|
+
lastRotatedAt?: string;
|
|
884
|
+
gracePeriod?: {
|
|
885
|
+
active: boolean;
|
|
886
|
+
previousVersion: number;
|
|
887
|
+
expiresAt: string;
|
|
888
|
+
} | null;
|
|
889
|
+
}
|
|
890
|
+
/** Verify webhook signature response */
|
|
891
|
+
interface VerifyWebhookResponse {
|
|
892
|
+
valid: boolean;
|
|
893
|
+
webhookId?: string;
|
|
894
|
+
message: string;
|
|
895
|
+
error?: string;
|
|
896
|
+
reason?: string;
|
|
897
|
+
}
|
|
820
898
|
/** API key info (safe, without secret) */
|
|
821
899
|
interface ApiKeyInfo {
|
|
822
900
|
id: string;
|
|
@@ -1415,7 +1493,7 @@ interface PriceRange {
|
|
|
1415
1493
|
interface CrawlOptions {
|
|
1416
1494
|
/** Starting URL for the crawl (required) */
|
|
1417
1495
|
url: string;
|
|
1418
|
-
/**
|
|
1496
|
+
/** @deprecated Use 'url' instead. Kept for backward compatibility. */
|
|
1419
1497
|
startUrl?: string;
|
|
1420
1498
|
/** Prompt to guide the crawl (optional) */
|
|
1421
1499
|
prompt?: string;
|
|
@@ -1535,8 +1613,6 @@ interface DorkOptions {
|
|
|
1535
1613
|
inTitle?: string;
|
|
1536
1614
|
/** Maximum results to return (default: 10, max: 100) */
|
|
1537
1615
|
maxResults?: number;
|
|
1538
|
-
/** Region code (2 letter ISO code) */
|
|
1539
|
-
region?: string;
|
|
1540
1616
|
}
|
|
1541
1617
|
/** Options for getting job deals */
|
|
1542
1618
|
interface GetDealsOptions {
|
|
@@ -1612,19 +1688,25 @@ interface ExportDealsOptions {
|
|
|
1612
1688
|
format?: ExportFormat;
|
|
1613
1689
|
/** Minimum deal score */
|
|
1614
1690
|
minScore?: number;
|
|
1615
|
-
/** Maximum price */
|
|
1616
|
-
maxPrice?: number;
|
|
1617
1691
|
/** Filter by category */
|
|
1618
1692
|
category?: string;
|
|
1619
|
-
/**
|
|
1620
|
-
|
|
1693
|
+
/** Filter by sync status to DealUp */
|
|
1694
|
+
synced?: boolean;
|
|
1695
|
+
/** Filter from date (ISO string) */
|
|
1696
|
+
fromDate?: string;
|
|
1697
|
+
/** Filter to date (ISO string) */
|
|
1698
|
+
toDate?: string;
|
|
1699
|
+
/** Maximum number of deals to export (default: 500, max: 1000) */
|
|
1700
|
+
limit?: number;
|
|
1621
1701
|
}
|
|
1622
1702
|
/** Webhook event types */
|
|
1623
1703
|
type WebhookEvent = "deal.found" | "deal.synced" | "crawl.completed" | "crawl.failed";
|
|
1624
1704
|
/** Options for creating a webhook */
|
|
1625
1705
|
interface CreateWebhookOptions {
|
|
1626
|
-
/** Event
|
|
1627
|
-
|
|
1706
|
+
/** Event types to subscribe to (array) */
|
|
1707
|
+
events?: WebhookEvent[];
|
|
1708
|
+
/** @deprecated Use 'events' array instead */
|
|
1709
|
+
event?: WebhookEvent;
|
|
1628
1710
|
/** URL to receive webhook notifications */
|
|
1629
1711
|
url: string;
|
|
1630
1712
|
/** Secret for signature verification */
|
|
@@ -2315,9 +2397,9 @@ declare class AuthResource {
|
|
|
2315
2397
|
* and how many are currently active.
|
|
2316
2398
|
*
|
|
2317
2399
|
* Tier limits:
|
|
2318
|
-
* - Free:
|
|
2319
|
-
* - Pro:
|
|
2320
|
-
* - Enterprise:
|
|
2400
|
+
* - Free: 10 concurrent connections
|
|
2401
|
+
* - Pro: 50 concurrent connections
|
|
2402
|
+
* - Enterprise: 200 concurrent connections
|
|
2321
2403
|
*
|
|
2322
2404
|
* @example
|
|
2323
2405
|
* ```ts
|
|
@@ -2634,6 +2716,47 @@ declare class DataResource {
|
|
|
2634
2716
|
* ```
|
|
2635
2717
|
*/
|
|
2636
2718
|
getRecentJobs(limit?: number): Promise<ListJobsResponse>;
|
|
2719
|
+
/**
|
|
2720
|
+
* Get full job details with result
|
|
2721
|
+
*
|
|
2722
|
+
* @example
|
|
2723
|
+
* ```ts
|
|
2724
|
+
* const job = await client.data.getJob("job_abc123");
|
|
2725
|
+
* console.log(job.result);
|
|
2726
|
+
* console.log(job.dealsFound);
|
|
2727
|
+
* ```
|
|
2728
|
+
*/
|
|
2729
|
+
getJob(jobId: string): Promise<JobDetailsResponse>;
|
|
2730
|
+
/**
|
|
2731
|
+
* Get only the result of a completed job
|
|
2732
|
+
*
|
|
2733
|
+
* @example
|
|
2734
|
+
* ```ts
|
|
2735
|
+
* const result = await client.data.getJobResult("job_abc123");
|
|
2736
|
+
* console.log(result.result);
|
|
2737
|
+
* ```
|
|
2738
|
+
*/
|
|
2739
|
+
getJobResult(jobId: string): Promise<JobResultResponse>;
|
|
2740
|
+
/**
|
|
2741
|
+
* Export job results in various formats
|
|
2742
|
+
* Supports: json, markdown, llm, csv
|
|
2743
|
+
*
|
|
2744
|
+
* @example
|
|
2745
|
+
* ```ts
|
|
2746
|
+
* // Export as JSON
|
|
2747
|
+
* const jsonData = await client.data.exportJob("job_abc123", "json");
|
|
2748
|
+
*
|
|
2749
|
+
* // Export as Markdown
|
|
2750
|
+
* const markdown = await client.data.exportJob("job_abc123", "markdown");
|
|
2751
|
+
*
|
|
2752
|
+
* // Export as LLM-optimized format
|
|
2753
|
+
* const llmText = await client.data.exportJob("job_abc123", "llm");
|
|
2754
|
+
*
|
|
2755
|
+
* // Export as CSV
|
|
2756
|
+
* const csv = await client.data.exportJob("job_abc123", "csv");
|
|
2757
|
+
* ```
|
|
2758
|
+
*/
|
|
2759
|
+
exportJob(jobId: string, format?: "json" | "markdown" | "llm" | "csv"): Promise<JobExportResponse>;
|
|
2637
2760
|
/**
|
|
2638
2761
|
* List all deals
|
|
2639
2762
|
*
|
|
@@ -2676,17 +2799,9 @@ declare class DataResource {
|
|
|
2676
2799
|
* @example
|
|
2677
2800
|
* ```ts
|
|
2678
2801
|
* const electronicsDeals = await client.data.getDealsByCategory("electronics");
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
): Promise<ListDealsResponse> {
|
|
2683
|
-
if (!category || !category.trim()) {
|
|
2684
|
-
throw new Error("category is required and cannot be empty");
|
|
2685
|
-
}
|
|
2686
|
-
return this.listDeals({ category, ...options });
|
|
2687
|
-
} return this.listDeals({ category, ...options });
|
|
2688
|
-
}
|
|
2689
|
-
|
|
2802
|
+
* ```
|
|
2803
|
+
*/
|
|
2804
|
+
getDealsByCategory(category: string, options?: Omit<ListDealsOptions, "category">): Promise<ListDealsResponse>;
|
|
2690
2805
|
/**
|
|
2691
2806
|
* Get unsynced deals (not yet sent to DealUp)
|
|
2692
2807
|
*
|
|
@@ -3221,7 +3336,9 @@ declare class KeysResource {
|
|
|
3221
3336
|
*/
|
|
3222
3337
|
revokeAll(): Promise<{
|
|
3223
3338
|
success: boolean;
|
|
3224
|
-
|
|
3339
|
+
revokedCount: number;
|
|
3340
|
+
message: string;
|
|
3341
|
+
warning: string;
|
|
3225
3342
|
}>;
|
|
3226
3343
|
/**
|
|
3227
3344
|
* Get active keys only
|
|
@@ -3532,6 +3649,24 @@ declare class StatusResource {
|
|
|
3532
3649
|
* ```
|
|
3533
3650
|
*/
|
|
3534
3651
|
getMetrics(jobId: string): Promise<JobMetricsResponse>;
|
|
3652
|
+
/**
|
|
3653
|
+
* Get errors from a job
|
|
3654
|
+
* Useful for debugging large crawls without loading full results
|
|
3655
|
+
*
|
|
3656
|
+
* @example
|
|
3657
|
+
* ```ts
|
|
3658
|
+
* const errors = await client.status.getJobErrors("job_abc123", {
|
|
3659
|
+
* limit: 50,
|
|
3660
|
+
* offset: 0
|
|
3661
|
+
* });
|
|
3662
|
+
* console.log(errors.data);
|
|
3663
|
+
* console.log(errors.pagination.total);
|
|
3664
|
+
* ```
|
|
3665
|
+
*/
|
|
3666
|
+
getJobErrors(jobId: string, options?: {
|
|
3667
|
+
limit?: number;
|
|
3668
|
+
offset?: number;
|
|
3669
|
+
}): Promise<JobErrorsResponse>;
|
|
3535
3670
|
/**
|
|
3536
3671
|
* Cancel a pending or active job
|
|
3537
3672
|
*
|
|
@@ -3696,6 +3831,65 @@ declare class WebhooksResource {
|
|
|
3696
3831
|
* ```
|
|
3697
3832
|
*/
|
|
3698
3833
|
getByEvent(event: CreateWebhookOptions["event"]): Promise<WebhookItem[]>;
|
|
3834
|
+
/**
|
|
3835
|
+
* Rotate webhook secret
|
|
3836
|
+
* Rotates the secret while keeping the old one valid during grace period
|
|
3837
|
+
*
|
|
3838
|
+
* @example
|
|
3839
|
+
* ```ts
|
|
3840
|
+
* const result = await client.webhooks.rotateSecret("webhook_abc123", {
|
|
3841
|
+
* newSecret: "new-secure-secret-key",
|
|
3842
|
+
* gracePeriodHours: 24
|
|
3843
|
+
* });
|
|
3844
|
+
* console.log(result.secretVersion);
|
|
3845
|
+
* console.log(result.previousSecretValidUntil);
|
|
3846
|
+
* ```
|
|
3847
|
+
*/
|
|
3848
|
+
rotateSecret(webhookId: string, options: {
|
|
3849
|
+
newSecret: string;
|
|
3850
|
+
gracePeriodHours?: number;
|
|
3851
|
+
}): Promise<RotateSecretResponse>;
|
|
3852
|
+
/**
|
|
3853
|
+
* Get webhook secret rotation status
|
|
3854
|
+
* Check current secret version and grace period status
|
|
3855
|
+
*
|
|
3856
|
+
* @example
|
|
3857
|
+
* ```ts
|
|
3858
|
+
* const status = await client.webhooks.getSecretStatus("webhook_abc123");
|
|
3859
|
+
* console.log(status.secretVersion);
|
|
3860
|
+
* if (status.gracePeriod?.active) {
|
|
3861
|
+
* console.log(`Grace period expires: ${status.gracePeriod.expiresAt}`);
|
|
3862
|
+
* }
|
|
3863
|
+
* ```
|
|
3864
|
+
*/
|
|
3865
|
+
getSecretStatus(webhookId: string): Promise<SecretStatusResponse>;
|
|
3866
|
+
/**
|
|
3867
|
+
* Verify webhook signature and replay protection
|
|
3868
|
+
* Validates signature, timestamp, and nonce from received webhook
|
|
3869
|
+
*
|
|
3870
|
+
* @example
|
|
3871
|
+
* ```ts
|
|
3872
|
+
* const isValid = await client.webhooks.verifySignature({
|
|
3873
|
+
* webhookId: "webhook_abc123",
|
|
3874
|
+
* payload: receivedPayload,
|
|
3875
|
+
* signature: headers["x-dealcrawl-signature"],
|
|
3876
|
+
* timestamp: parseInt(headers["x-dealcrawl-timestamp"]),
|
|
3877
|
+
* nonce: headers["x-dealcrawl-nonce"]
|
|
3878
|
+
* });
|
|
3879
|
+
* if (isValid.valid) {
|
|
3880
|
+
* console.log("Webhook is valid");
|
|
3881
|
+
* } else {
|
|
3882
|
+
* console.log(`Invalid: ${isValid.error}`);
|
|
3883
|
+
* }
|
|
3884
|
+
* ```
|
|
3885
|
+
*/
|
|
3886
|
+
verifySignature(options: {
|
|
3887
|
+
webhookId: string;
|
|
3888
|
+
payload: Record<string, unknown>;
|
|
3889
|
+
signature: string;
|
|
3890
|
+
timestamp: number;
|
|
3891
|
+
nonce: string;
|
|
3892
|
+
}): Promise<VerifyWebhookResponse>;
|
|
3699
3893
|
}
|
|
3700
3894
|
|
|
3701
3895
|
/**
|