@dealcrawl/sdk 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -8,33 +8,164 @@ var DEFAULT_CONFIG = {
8
8
 
9
9
  // src/error.ts
10
10
  var ERROR_CODES = {
11
- // Authentication
12
- INVALID_API_KEY: "INVALID_API_KEY",
13
- MISSING_API_KEY: "MISSING_API_KEY",
14
- API_KEY_EXPIRED: "API_KEY_EXPIRED",
15
- ACCOUNT_SUSPENDED: "ACCOUNT_SUSPENDED",
16
- // Rate limiting
11
+ // ============================================
12
+ // Authentication & Authorization (4xx)
13
+ // ============================================
14
+ /** Missing or invalid Authorization header */
15
+ AUTH_MISSING_HEADER: "AUTH_MISSING_HEADER",
16
+ /** The provided API key is invalid or expired */
17
+ AUTH_INVALID_API_KEY: "AUTH_INVALID_API_KEY",
18
+ /** Your API key has expired */
19
+ AUTH_API_KEY_EXPIRED: "AUTH_API_KEY_EXPIRED",
20
+ /** Your API key has been revoked */
21
+ AUTH_API_KEY_REVOKED: "AUTH_API_KEY_REVOKED",
22
+ /** API key does not have required permissions */
23
+ AUTH_INSUFFICIENT_SCOPE: "AUTH_INSUFFICIENT_SCOPE",
24
+ /** Your account has been suspended */
25
+ AUTH_ACCOUNT_SUSPENDED: "AUTH_ACCOUNT_SUSPENDED",
26
+ // Legacy aliases (for backward compatibility)
27
+ /** @deprecated Use AUTH_INVALID_API_KEY instead */
28
+ INVALID_API_KEY: "AUTH_INVALID_API_KEY",
29
+ /** @deprecated Use AUTH_MISSING_HEADER instead */
30
+ MISSING_API_KEY: "AUTH_MISSING_HEADER",
31
+ /** @deprecated Use AUTH_API_KEY_EXPIRED instead */
32
+ API_KEY_EXPIRED: "AUTH_API_KEY_EXPIRED",
33
+ /** @deprecated Use AUTH_ACCOUNT_SUSPENDED instead */
34
+ ACCOUNT_SUSPENDED: "AUTH_ACCOUNT_SUSPENDED",
35
+ // ============================================
36
+ // Rate Limiting (429)
37
+ // ============================================
38
+ /** Rate limit exceeded. Please try again later */
17
39
  RATE_LIMIT_EXCEEDED: "RATE_LIMIT_EXCEEDED",
18
- QUOTA_EXCEEDED: "QUOTA_EXCEEDED",
19
- // Validation
20
- INVALID_URL: "INVALID_URL",
21
- INVALID_REQUEST: "INVALID_REQUEST",
22
- MISSING_REQUIRED_FIELD: "MISSING_REQUIRED_FIELD",
23
- // Job errors
24
- JOB_NOT_FOUND: "JOB_NOT_FOUND",
25
- JOB_FAILED: "JOB_FAILED",
40
+ /** Monthly quota exceeded. Upgrade your plan for more */
41
+ RATE_QUOTA_EXCEEDED: "RATE_QUOTA_EXCEEDED",
42
+ /** Concurrent job limit reached */
43
+ RATE_CONCURRENT_LIMIT: "RATE_CONCURRENT_LIMIT",
44
+ // Legacy aliases
45
+ /** @deprecated Use RATE_QUOTA_EXCEEDED instead */
46
+ QUOTA_EXCEEDED: "RATE_QUOTA_EXCEEDED",
47
+ // ============================================
48
+ // Validation (400, 422)
49
+ // ============================================
50
+ /** The provided input is invalid */
51
+ VALID_INVALID_INPUT: "VALID_INVALID_INPUT",
52
+ /** Required field is missing */
53
+ VALID_MISSING_FIELD: "VALID_MISSING_FIELD",
54
+ /** The provided URL is not valid */
55
+ VALID_INVALID_URL: "VALID_INVALID_URL",
56
+ /** Invalid schema format */
57
+ VALID_INVALID_SCHEMA: "VALID_INVALID_SCHEMA",
58
+ /** Invalid format */
59
+ VALID_INVALID_FORMAT: "VALID_INVALID_FORMAT",
60
+ // Legacy aliases
61
+ /** @deprecated Use VALID_INVALID_URL instead */
62
+ INVALID_URL: "VALID_INVALID_URL",
63
+ /** @deprecated Use VALID_INVALID_INPUT instead */
64
+ INVALID_REQUEST: "VALID_INVALID_INPUT",
65
+ /** @deprecated Use VALID_MISSING_FIELD instead */
66
+ MISSING_REQUIRED_FIELD: "VALID_MISSING_FIELD",
67
+ // ============================================
68
+ // Resources (404)
69
+ // ============================================
70
+ /** The requested resource was not found */
71
+ RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND",
72
+ /** Job not found */
73
+ RESOURCE_JOB_NOT_FOUND: "RESOURCE_JOB_NOT_FOUND",
74
+ /** Webhook not found */
75
+ RESOURCE_WEBHOOK_NOT_FOUND: "RESOURCE_WEBHOOK_NOT_FOUND",
76
+ /** API key not found */
77
+ RESOURCE_KEY_NOT_FOUND: "RESOURCE_KEY_NOT_FOUND",
78
+ // Legacy aliases
79
+ /** @deprecated Use RESOURCE_JOB_NOT_FOUND instead */
80
+ JOB_NOT_FOUND: "RESOURCE_JOB_NOT_FOUND",
81
+ // ============================================
82
+ // Job Processing (422, 503)
83
+ // ============================================
84
+ /** Failed to create job */
85
+ JOB_CREATION_FAILED: "JOB_CREATION_FAILED",
86
+ /** Job timed out */
26
87
  JOB_TIMEOUT: "JOB_TIMEOUT",
27
- // Scraping errors
28
- FETCH_FAILED: "FETCH_FAILED",
29
- PARSE_FAILED: "PARSE_FAILED",
30
- BLOCKED_BY_ROBOTS: "BLOCKED_BY_ROBOTS",
31
- CAPTCHA_DETECTED: "CAPTCHA_DETECTED",
32
- SITE_UNREACHABLE: "SITE_UNREACHABLE",
33
- // System errors
88
+ /** Job processing failed */
89
+ JOB_FAILED: "JOB_FAILED",
90
+ /** Job was cancelled */
91
+ JOB_CANCELLED: "JOB_CANCELLED",
92
+ // ============================================
93
+ // Scraping/Crawling (422, 503)
94
+ // ============================================
95
+ /** Failed to fetch URL */
96
+ SCRAPE_FETCH_FAILED: "SCRAPE_FETCH_FAILED",
97
+ /** Failed to parse page content */
98
+ SCRAPE_PARSE_FAILED: "SCRAPE_PARSE_FAILED",
99
+ /** URL is blocked by robots.txt */
100
+ SCRAPE_BLOCKED_BY_ROBOTS: "SCRAPE_BLOCKED_BY_ROBOTS",
101
+ /** CAPTCHA detected on page */
102
+ SCRAPE_CAPTCHA_DETECTED: "SCRAPE_CAPTCHA_DETECTED",
103
+ /** Site is unreachable */
104
+ SCRAPE_SITE_UNREACHABLE: "SCRAPE_SITE_UNREACHABLE",
105
+ /** Scraping operation timed out */
106
+ SCRAPE_TIMEOUT: "SCRAPE_TIMEOUT",
107
+ // Legacy aliases
108
+ /** @deprecated Use SCRAPE_FETCH_FAILED instead */
109
+ FETCH_FAILED: "SCRAPE_FETCH_FAILED",
110
+ /** @deprecated Use SCRAPE_PARSE_FAILED instead */
111
+ PARSE_FAILED: "SCRAPE_PARSE_FAILED",
112
+ /** @deprecated Use SCRAPE_BLOCKED_BY_ROBOTS instead */
113
+ BLOCKED_BY_ROBOTS: "SCRAPE_BLOCKED_BY_ROBOTS",
114
+ /** @deprecated Use SCRAPE_CAPTCHA_DETECTED instead */
115
+ CAPTCHA_DETECTED: "SCRAPE_CAPTCHA_DETECTED",
116
+ /** @deprecated Use SCRAPE_SITE_UNREACHABLE instead */
117
+ SITE_UNREACHABLE: "SCRAPE_SITE_UNREACHABLE",
118
+ // ============================================
119
+ // Webhooks (400, 422)
120
+ // ============================================
121
+ /** A webhook with this event and URL already exists */
122
+ WEBHOOK_ALREADY_EXISTS: "WEBHOOK_ALREADY_EXISTS",
123
+ /** Webhook URL is not valid or not publicly accessible */
124
+ WEBHOOK_INVALID_URL: "WEBHOOK_INVALID_URL",
125
+ /** Webhook replay attack detected */
126
+ WEBHOOK_REPLAY_DETECTED: "WEBHOOK_REPLAY_DETECTED",
127
+ /** Webhook request is too old */
128
+ WEBHOOK_EXPIRED: "WEBHOOK_EXPIRED",
129
+ /** Webhook signature is invalid */
130
+ WEBHOOK_INVALID_SIGNATURE: "WEBHOOK_INVALID_SIGNATURE",
131
+ // ============================================
132
+ // AI Extraction (422)
133
+ // ============================================
134
+ /** AI extraction failed to process content */
135
+ AI_EXTRACTION_FAILED: "AI_EXTRACTION_FAILED",
136
+ /** Failed to parse JSON from AI response */
137
+ AI_JSON_PARSE_FAILED: "AI_JSON_PARSE_FAILED",
138
+ /** AI response did not match expected schema */
139
+ AI_SCHEMA_VALIDATION_FAILED: "AI_SCHEMA_VALIDATION_FAILED",
140
+ /** No price information could be extracted */
141
+ AI_NO_PRICE_FOUND: "AI_NO_PRICE_FOUND",
142
+ /** Extraction confidence is below acceptable threshold */
143
+ AI_LOW_CONFIDENCE: "AI_LOW_CONFIDENCE",
144
+ /** Only partial data could be extracted */
145
+ AI_PARTIAL_RESULT: "AI_PARTIAL_RESULT",
146
+ /** Fallback extraction was used */
147
+ AI_FALLBACK_USED: "AI_FALLBACK_USED",
148
+ /** All fallback strategies failed */
149
+ AI_FALLBACK_FAILED: "AI_FALLBACK_FAILED",
150
+ /** LLM provider rate limit exceeded */
151
+ AI_PROVIDER_RATE_LIMIT: "AI_PROVIDER_RATE_LIMIT",
152
+ /** LLM provider authentication failed */
153
+ AI_PROVIDER_AUTH_FAILED: "AI_PROVIDER_AUTH_FAILED",
154
+ /** LLM provider timeout */
155
+ AI_PROVIDER_TIMEOUT: "AI_PROVIDER_TIMEOUT",
156
+ // ============================================
157
+ // System Errors (500, 503)
158
+ // ============================================
159
+ /** An internal server error occurred */
34
160
  INTERNAL_ERROR: "INTERNAL_ERROR",
35
- SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE",
161
+ /** Database operation failed */
162
+ DATABASE_ERROR: "DATABASE_ERROR",
163
+ /** Redis operation failed */
36
164
  REDIS_ERROR: "REDIS_ERROR",
37
- DATABASE_ERROR: "DATABASE_ERROR"
165
+ /** External service error */
166
+ EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR",
167
+ /** Service is temporarily unavailable */
168
+ SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE"
38
169
  };
39
170
  var DealCrawlError = class _DealCrawlError extends Error {
40
171
  /** Error code from ERROR_CODES */
@@ -58,14 +189,19 @@ var DealCrawlError = class _DealCrawlError extends Error {
58
189
  }
59
190
  /**
60
191
  * Check if the error is retryable
61
- * Rate limits and transient errors are retryable
192
+ * Rate limits, transient errors, and AI provider issues are retryable
62
193
  */
63
194
  isRetryable() {
64
195
  const retryableCodes = [
65
196
  ERROR_CODES.RATE_LIMIT_EXCEEDED,
197
+ ERROR_CODES.RATE_CONCURRENT_LIMIT,
66
198
  ERROR_CODES.SERVICE_UNAVAILABLE,
67
199
  ERROR_CODES.REDIS_ERROR,
68
- ERROR_CODES.DATABASE_ERROR
200
+ ERROR_CODES.DATABASE_ERROR,
201
+ ERROR_CODES.EXTERNAL_SERVICE_ERROR,
202
+ ERROR_CODES.AI_PROVIDER_RATE_LIMIT,
203
+ ERROR_CODES.AI_PROVIDER_TIMEOUT,
204
+ ERROR_CODES.SCRAPE_TIMEOUT
69
205
  ];
70
206
  return retryableCodes.includes(this.code);
71
207
  }
@@ -73,25 +209,92 @@ var DealCrawlError = class _DealCrawlError extends Error {
73
209
  * Check if the error is due to authentication issues
74
210
  */
75
211
  isAuthError() {
76
- const authCodes = [
77
- ERROR_CODES.INVALID_API_KEY,
78
- ERROR_CODES.MISSING_API_KEY,
79
- ERROR_CODES.API_KEY_EXPIRED,
80
- ERROR_CODES.ACCOUNT_SUSPENDED
81
- ];
82
- return authCodes.includes(this.code);
212
+ return this.code.startsWith("AUTH_");
83
213
  }
84
214
  /**
85
215
  * Check if the error is due to rate limiting
86
216
  */
87
217
  isRateLimited() {
88
- return this.code === ERROR_CODES.RATE_LIMIT_EXCEEDED;
218
+ return this.code === ERROR_CODES.RATE_LIMIT_EXCEEDED || this.code === ERROR_CODES.RATE_CONCURRENT_LIMIT;
89
219
  }
90
220
  /**
91
221
  * Check if the error is due to quota exceeded
92
222
  */
93
223
  isQuotaExceeded() {
94
- return this.code === ERROR_CODES.QUOTA_EXCEEDED;
224
+ return this.code === ERROR_CODES.RATE_QUOTA_EXCEEDED;
225
+ }
226
+ /**
227
+ * Check if the error is due to AI extraction issues
228
+ */
229
+ isExtractionError() {
230
+ return this.code.startsWith("AI_");
231
+ }
232
+ /**
233
+ * Check if result is partial (some data extracted but incomplete)
234
+ */
235
+ isPartialResult() {
236
+ return this.code === ERROR_CODES.AI_PARTIAL_RESULT || this.code === ERROR_CODES.AI_LOW_CONFIDENCE || this.code === ERROR_CODES.AI_FALLBACK_USED;
237
+ }
238
+ /**
239
+ * Check if extraction failed due to schema validation
240
+ */
241
+ isSchemaValidationError() {
242
+ return this.code === ERROR_CODES.AI_SCHEMA_VALIDATION_FAILED || this.code === ERROR_CODES.AI_JSON_PARSE_FAILED || this.code === ERROR_CODES.VALID_INVALID_SCHEMA;
243
+ }
244
+ /**
245
+ * Check if the error is due to validation issues
246
+ */
247
+ isValidationError() {
248
+ return this.code.startsWith("VALID_");
249
+ }
250
+ /**
251
+ * Check if the error is due to scraping issues
252
+ */
253
+ isScrapeError() {
254
+ return this.code.startsWith("SCRAPE_");
255
+ }
256
+ /**
257
+ * Check if the error is due to webhook issues
258
+ */
259
+ isWebhookError() {
260
+ return this.code.startsWith("WEBHOOK_");
261
+ }
262
+ /**
263
+ * Check if the error is a server error (5xx)
264
+ */
265
+ isServerError() {
266
+ return this.code === ERROR_CODES.INTERNAL_ERROR || this.code === ERROR_CODES.DATABASE_ERROR || this.code === ERROR_CODES.REDIS_ERROR || this.code === ERROR_CODES.EXTERNAL_SERVICE_ERROR || this.code === ERROR_CODES.SERVICE_UNAVAILABLE;
267
+ }
268
+ /**
269
+ * Check if the error is a client error (4xx)
270
+ */
271
+ isClientError() {
272
+ return this.isAuthError() || this.isValidationError() || this.code.startsWith("RESOURCE_") || this.isWebhookError();
273
+ }
274
+ /**
275
+ * Check if fallback was used during extraction
276
+ */
277
+ isFallbackUsed() {
278
+ return this.code === ERROR_CODES.AI_FALLBACK_USED;
279
+ }
280
+ /**
281
+ * Check if all fallback strategies failed
282
+ */
283
+ isFallbackFailed() {
284
+ return this.code === ERROR_CODES.AI_FALLBACK_FAILED;
285
+ }
286
+ /**
287
+ * Check if error is due to AI provider issues
288
+ */
289
+ isAIProviderError() {
290
+ return this.code === ERROR_CODES.AI_PROVIDER_RATE_LIMIT || this.code === ERROR_CODES.AI_PROVIDER_AUTH_FAILED || this.code === ERROR_CODES.AI_PROVIDER_TIMEOUT;
291
+ }
292
+ /**
293
+ * Get extraction-specific error details
294
+ */
295
+ getExtractionDetails() {
296
+ if (!this.isExtractionError()) return void 0;
297
+ return this.details;
95
298
  }
96
299
  /**
97
300
  * Convert error to JSON-serializable object
@@ -133,23 +336,92 @@ var DealCrawlError = class _DealCrawlError extends Error {
133
336
  function mapStatusCodeToErrorCode(statusCode) {
134
337
  switch (statusCode) {
135
338
  case 400:
136
- return ERROR_CODES.INVALID_REQUEST;
339
+ return ERROR_CODES.VALID_INVALID_INPUT;
137
340
  case 401:
138
- return ERROR_CODES.INVALID_API_KEY;
341
+ return ERROR_CODES.AUTH_INVALID_API_KEY;
139
342
  case 403:
140
- return ERROR_CODES.ACCOUNT_SUSPENDED;
343
+ return ERROR_CODES.AUTH_ACCOUNT_SUSPENDED;
141
344
  case 404:
142
- return ERROR_CODES.JOB_NOT_FOUND;
345
+ return ERROR_CODES.RESOURCE_NOT_FOUND;
346
+ case 408:
347
+ return ERROR_CODES.JOB_TIMEOUT;
348
+ case 422:
349
+ return ERROR_CODES.VALID_INVALID_INPUT;
143
350
  case 429:
144
351
  return ERROR_CODES.RATE_LIMIT_EXCEEDED;
145
352
  case 500:
146
353
  return ERROR_CODES.INTERNAL_ERROR;
354
+ case 502:
355
+ return ERROR_CODES.EXTERNAL_SERVICE_ERROR;
147
356
  case 503:
148
357
  return ERROR_CODES.SERVICE_UNAVAILABLE;
149
358
  default:
150
359
  return ERROR_CODES.INTERNAL_ERROR;
151
360
  }
152
361
  }
362
+ var ERROR_MESSAGES = {
363
+ // Authentication
364
+ AUTH_MISSING_HEADER: "Missing or invalid Authorization header",
365
+ AUTH_INVALID_API_KEY: "The provided API key is invalid or expired",
366
+ AUTH_API_KEY_EXPIRED: "Your API key has expired",
367
+ AUTH_API_KEY_REVOKED: "Your API key has been revoked",
368
+ AUTH_INSUFFICIENT_SCOPE: "API key does not have required permissions",
369
+ AUTH_ACCOUNT_SUSPENDED: "Your account has been suspended",
370
+ // Rate Limiting
371
+ RATE_LIMIT_EXCEEDED: "Rate limit exceeded. Please try again later",
372
+ RATE_QUOTA_EXCEEDED: "Monthly quota exceeded. Upgrade your plan for more",
373
+ RATE_CONCURRENT_LIMIT: "Concurrent job limit reached. Wait for existing jobs to complete",
374
+ // Validation
375
+ VALID_INVALID_INPUT: "The provided input is invalid",
376
+ VALID_MISSING_FIELD: "Required field is missing",
377
+ VALID_INVALID_URL: "The provided URL is not valid",
378
+ VALID_INVALID_SCHEMA: "Invalid schema format",
379
+ VALID_INVALID_FORMAT: "Invalid format",
380
+ // Resources
381
+ RESOURCE_NOT_FOUND: "The requested resource was not found",
382
+ RESOURCE_JOB_NOT_FOUND: "Job not found",
383
+ RESOURCE_WEBHOOK_NOT_FOUND: "Webhook not found",
384
+ RESOURCE_KEY_NOT_FOUND: "API key not found",
385
+ // Job Processing
386
+ JOB_CREATION_FAILED: "Failed to create job",
387
+ JOB_TIMEOUT: "Job timed out",
388
+ JOB_FAILED: "Job processing failed",
389
+ JOB_CANCELLED: "Job was cancelled",
390
+ // Scraping
391
+ SCRAPE_FETCH_FAILED: "Failed to fetch URL",
392
+ SCRAPE_PARSE_FAILED: "Failed to parse page content",
393
+ SCRAPE_BLOCKED_BY_ROBOTS: "URL is blocked by robots.txt",
394
+ SCRAPE_CAPTCHA_DETECTED: "CAPTCHA detected on page",
395
+ SCRAPE_SITE_UNREACHABLE: "Site is unreachable",
396
+ SCRAPE_TIMEOUT: "Scraping operation timed out",
397
+ // Webhooks
398
+ WEBHOOK_ALREADY_EXISTS: "A webhook with this event and URL already exists",
399
+ WEBHOOK_INVALID_URL: "Webhook URL is not valid or not publicly accessible",
400
+ WEBHOOK_REPLAY_DETECTED: "Webhook replay attack detected",
401
+ WEBHOOK_EXPIRED: "Webhook request is too old",
402
+ WEBHOOK_INVALID_SIGNATURE: "Webhook signature is invalid",
403
+ // AI Extraction
404
+ AI_EXTRACTION_FAILED: "AI extraction failed to process content",
405
+ AI_JSON_PARSE_FAILED: "Failed to parse JSON from AI response",
406
+ AI_SCHEMA_VALIDATION_FAILED: "AI response did not match expected schema",
407
+ AI_NO_PRICE_FOUND: "No price information could be extracted",
408
+ AI_LOW_CONFIDENCE: "Extraction confidence is below acceptable threshold",
409
+ AI_PARTIAL_RESULT: "Only partial data could be extracted",
410
+ AI_FALLBACK_USED: "Fallback extraction was used",
411
+ AI_FALLBACK_FAILED: "All fallback strategies failed",
412
+ AI_PROVIDER_RATE_LIMIT: "LLM provider rate limit exceeded",
413
+ AI_PROVIDER_AUTH_FAILED: "LLM provider authentication failed",
414
+ AI_PROVIDER_TIMEOUT: "LLM provider timeout",
415
+ // System
416
+ INTERNAL_ERROR: "An internal server error occurred",
417
+ DATABASE_ERROR: "Database operation failed",
418
+ REDIS_ERROR: "Redis operation failed",
419
+ EXTERNAL_SERVICE_ERROR: "External service error",
420
+ SERVICE_UNAVAILABLE: "Service is temporarily unavailable"
421
+ };
422
+ function getErrorMessage(code) {
423
+ return ERROR_MESSAGES[code] || "An unknown error occurred";
424
+ }
153
425
 
154
426
  // src/utils/request.ts
155
427
  function buildQueryString(params) {
@@ -2801,6 +3073,6 @@ var DealCrawl = class {
2801
3073
  }
2802
3074
  };
2803
3075
 
2804
- export { AccountResource, AgentResource, CrawlResource, DEFAULT_CONFIG, DataResource, DealCrawl, DealCrawlError, DorkResource, ERROR_CODES, ExtractResource, KeysResource, ScrapeResource, SearchResource, StatusResource, WebhooksResource, DealCrawl as default, pollUntil, waitForAll, waitForAny, waitForResult };
3076
+ export { AccountResource, AgentResource, CrawlResource, DEFAULT_CONFIG, DataResource, DealCrawl, DealCrawlError, DorkResource, ERROR_CODES, ERROR_MESSAGES, ExtractResource, KeysResource, ScrapeResource, SearchResource, StatusResource, WebhooksResource, DealCrawl as default, getErrorMessage, pollUntil, waitForAll, waitForAny, waitForResult };
2805
3077
  //# sourceMappingURL=index.mjs.map
2806
3078
  //# sourceMappingURL=index.mjs.map