@spider-cloud/spider-client 0.1.84 → 0.1.87

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 CHANGED
@@ -93,8 +93,68 @@ app.crawlUrl(url, crawlParams, stream, streamCallback);
93
93
  - **`links(url, params)`**: Retrieve all links from the specified URL with optional parameters.
94
94
  - **`screenshot(url, params)`**: Take a screenshot of the specified URL.
95
95
  - **`transform(data, params)`**: Perform a fast HTML transformation to markdown or text.
96
+ - **`unblocker(url, params)`**: Unblock challenging websites with anti-bot bypass. Supports AI extraction with `custom_prompt`.
96
97
  - **`getCredits()`**: Retrieve account's remaining credits.
97
98
 
99
+ ### AI Studio Methods
100
+
101
+ AI Studio methods require an active AI Studio subscription.
102
+
103
+ - **`aiCrawl(url, prompt, params)`**: AI-guided crawling using natural language prompts.
104
+ - **`aiScrape(url, prompt, params)`**: AI-guided scraping using natural language prompts.
105
+ - **`aiSearch(prompt, params)`**: AI-enhanced web search using natural language queries.
106
+ - **`aiBrowser(url, prompt, params)`**: AI-guided browser automation using natural language commands.
107
+ - **`aiLinks(url, prompt, params)`**: AI-guided link extraction and filtering.
108
+
109
+ ```javascript
110
+ // AI Scrape example
111
+ const result = await app.aiScrape(
112
+ "https://example.com/products",
113
+ "Extract all product names, prices, and descriptions"
114
+ );
115
+ ```
116
+
117
+ ### Unblocker with AI Extraction
118
+
119
+ ```javascript
120
+ // Unblock and extract data using AI
121
+ const result = await app.unblocker("https://protected-site.com/products", {
122
+ custom_prompt: "Extract all product names and prices as JSON"
123
+ });
124
+ // Extracted data is available in result[0].metadata.extracted_data
125
+ ```
126
+
127
+ ### Unblocker with JSON Schema Extraction
128
+
129
+ Use JSON Schema for structured, validated extraction output:
130
+
131
+ ```javascript
132
+ const result = await app.unblocker("https://protected-site.com/products", {
133
+ extraction_schema: {
134
+ name: "products",
135
+ description: "Product listing extraction",
136
+ schema: JSON.stringify({
137
+ type: "object",
138
+ properties: {
139
+ products: {
140
+ type: "array",
141
+ items: {
142
+ type: "object",
143
+ properties: {
144
+ name: { type: "string" },
145
+ price: { type: "number" }
146
+ },
147
+ required: ["name", "price"]
148
+ }
149
+ }
150
+ }
151
+ }),
152
+ strict: true
153
+ }
154
+ });
155
+ // Extracted data conforms to the schema in result[0].metadata.extracted_data
156
+ ```
157
+
98
158
  ## Error Handling
99
159
 
100
160
  The SDK provides robust error handling and will throw exceptions when it encounters critical issues. Always use `.catch()` on promises to handle these errors gracefully.
package/dist/client.d.ts CHANGED
@@ -1,4 +1,15 @@
1
- import { ChunkCallbackFunction, Collection, SpiderCoreResponse, SpiderParams, SearchRequestParams, RequestParamsTransform } from "./config";
1
+ import { ChunkCallbackFunction, Collection, SpiderCoreResponse, SpiderParams, SearchRequestParams, RequestParamsTransform, AIRequestParams, AIStudioTier } from "./config";
2
+ /**
3
+ * Rate limit state from API response headers.
4
+ */
5
+ export interface RateLimitInfo {
6
+ /** Maximum requests allowed per minute. */
7
+ limit: number;
8
+ /** Requests remaining in the current window. */
9
+ remaining: number;
10
+ /** Seconds until the rate limit window resets. */
11
+ resetSeconds: number;
12
+ }
2
13
  /**
3
14
  * Generic params for core request.
4
15
  */
@@ -14,12 +25,28 @@ export interface SpiderConfig {
14
25
  */
15
26
  export declare class Spider {
16
27
  private apiKey?;
28
+ private aiRateLimiter;
29
+ private aiStudioTier;
30
+ /** The latest rate limit state from API response headers. */
31
+ rateLimit: RateLimitInfo;
17
32
  /**
18
33
  * Create an instance of Spider.
19
34
  * @param {string | null} apiKey - The API key used to authenticate to the Spider API. If null, attempts to source from environment variables.
35
+ * @param {AIStudioTier} aiStudioTier - The AI Studio subscription tier for rate limiting. Defaults to 'starter'.
20
36
  * @throws Will throw an error if the API key is not provided.
21
37
  */
22
- constructor(props?: SpiderConfig);
38
+ constructor(props?: SpiderConfig & {
39
+ aiStudioTier?: AIStudioTier;
40
+ });
41
+ /**
42
+ * Update the AI Studio subscription tier (adjusts rate limiting).
43
+ * @param {AIStudioTier} tier - The new subscription tier.
44
+ */
45
+ setAIStudioTier(tier: AIStudioTier): void;
46
+ /**
47
+ * Update rate limit state from response headers.
48
+ */
49
+ private _updateRateLimit;
23
50
  /**
24
51
  * Internal method to handle POST requests.
25
52
  * @param {string} endpoint - The API endpoint to which the POST request should be sent.
@@ -66,6 +93,13 @@ export declare class Spider {
66
93
  * @returns {Promise<any>} The screenshot data.
67
94
  */
68
95
  screenshot(url: string, params?: GenericParams): Promise<any>;
96
+ /**
97
+ * Unblock a challenging url to get data.
98
+ * @param {string} url - The URL to get data from.
99
+ * @param {GenericParams} [params={}] - Configuration parameters for the screenshot.
100
+ * @returns {Promise<any>} The screenshot data.
101
+ */
102
+ unblocker(url: string, params?: GenericParams): Promise<any>;
69
103
  /**
70
104
  * Perform a search and gather a list of websites to start crawling and collect resources.
71
105
  * @param {string} search - The search query.
@@ -113,6 +147,64 @@ export declare class Spider {
113
147
  Authorization: string;
114
148
  "User-Agent": string;
115
149
  };
150
+ /**
151
+ * Internal method to handle AI Studio POST requests with rate limiting.
152
+ * @param {string} endpoint - The AI Studio endpoint.
153
+ * @param {Record<string, any>} data - The request data including prompt.
154
+ * @returns {Promise<any>} The response data.
155
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
156
+ * @throws {AIStudioRateLimitExceeded} When rate limit is exceeded server-side.
157
+ */
158
+ private _aiApiPost;
159
+ /**
160
+ * AI-guided crawling using natural language prompts.
161
+ * Requires an active AI Studio subscription.
162
+ * @param {string} url - The URL to start crawling.
163
+ * @param {string} prompt - Natural language instruction for what to crawl and extract.
164
+ * @param {AIRequestParams} [params={}] - Additional parameters for the crawl.
165
+ * @returns {Promise<any>} The crawl results guided by the AI prompt.
166
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
167
+ */
168
+ aiCrawl(url: string, prompt: string, params?: Omit<AIRequestParams, "prompt">): Promise<any>;
169
+ /**
170
+ * AI-guided scraping using natural language prompts.
171
+ * Requires an active AI Studio subscription.
172
+ * @param {string} url - The URL to scrape.
173
+ * @param {string} prompt - Natural language description of data to extract.
174
+ * @param {AIRequestParams} [params={}] - Additional parameters for the scrape.
175
+ * @returns {Promise<any>} The scraped data guided by the AI prompt.
176
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
177
+ */
178
+ aiScrape(url: string, prompt: string, params?: Omit<AIRequestParams, "prompt">): Promise<any>;
179
+ /**
180
+ * AI-enhanced web search using natural language queries.
181
+ * Requires an active AI Studio subscription.
182
+ * @param {string} prompt - Natural language search query.
183
+ * @param {SearchRequestParams} [params={}] - Additional search parameters.
184
+ * @returns {Promise<any>} The search results with AI-enhanced relevance.
185
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
186
+ */
187
+ aiSearch(prompt: string, params?: SearchRequestParams): Promise<any>;
188
+ /**
189
+ * AI-guided browser automation using natural language commands.
190
+ * Requires an active AI Studio subscription.
191
+ * @param {string} url - The URL to automate.
192
+ * @param {string} prompt - Natural language description of browser actions.
193
+ * @param {AIRequestParams} [params={}] - Additional parameters for automation.
194
+ * @returns {Promise<any>} The automation results.
195
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
196
+ */
197
+ aiBrowser(url: string, prompt: string, params?: Omit<AIRequestParams, "prompt">): Promise<any>;
198
+ /**
199
+ * AI-guided link extraction and filtering.
200
+ * Requires an active AI Studio subscription.
201
+ * @param {string} url - The URL to extract links from.
202
+ * @param {string} prompt - Natural language description of what links to find.
203
+ * @param {AIRequestParams} [params={}] - Additional parameters.
204
+ * @returns {Promise<any>} The filtered links based on AI analysis.
205
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
206
+ */
207
+ aiLinks(url: string, prompt: string, params?: Omit<AIRequestParams, "prompt">): Promise<any>;
116
208
  /**
117
209
  * Handles errors from API requests.
118
210
  * @param {Response} response - The fetch response object.
package/dist/client.js CHANGED
@@ -5,6 +5,50 @@ const config_1 = require("./config");
5
5
  const package_json_1 = require("../package.json");
6
6
  const stream_reader_1 = require("./utils/stream-reader");
7
7
  const exponential_backoff_1 = require("exponential-backoff");
8
+ /**
9
+ * Simple client-side rate limiter for AI Studio endpoints.
10
+ * Uses a sliding window approach to limit requests per second.
11
+ */
12
+ class RateLimiter {
13
+ constructor(requestsPerSecond) {
14
+ this.timestamps = [];
15
+ this.maxRequests = requestsPerSecond;
16
+ this.windowMs = 1000;
17
+ }
18
+ /**
19
+ * Update the rate limit (e.g., when user tier changes).
20
+ */
21
+ setLimit(requestsPerSecond) {
22
+ this.maxRequests = requestsPerSecond;
23
+ }
24
+ /**
25
+ * Check if a request can be made. If not, returns the ms to wait.
26
+ * If yes, records the request and returns 0.
27
+ */
28
+ tryAcquire() {
29
+ const now = Date.now();
30
+ // Remove timestamps outside the window
31
+ this.timestamps = this.timestamps.filter((t) => now - t < this.windowMs);
32
+ if (this.timestamps.length >= this.maxRequests) {
33
+ // Calculate how long to wait
34
+ const oldestInWindow = this.timestamps[0];
35
+ const waitTime = this.windowMs - (now - oldestInWindow);
36
+ return Math.max(1, waitTime);
37
+ }
38
+ this.timestamps.push(now);
39
+ return 0;
40
+ }
41
+ /**
42
+ * Wait until a request can be made, then acquire the slot.
43
+ */
44
+ async acquire() {
45
+ const waitTime = this.tryAcquire();
46
+ if (waitTime > 0) {
47
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
48
+ return this.acquire();
49
+ }
50
+ }
51
+ }
8
52
  /**
9
53
  * A class to interact with the Spider API.
10
54
  */
@@ -12,15 +56,42 @@ class Spider {
12
56
  /**
13
57
  * Create an instance of Spider.
14
58
  * @param {string | null} apiKey - The API key used to authenticate to the Spider API. If null, attempts to source from environment variables.
59
+ * @param {AIStudioTier} aiStudioTier - The AI Studio subscription tier for rate limiting. Defaults to 'starter'.
15
60
  * @throws Will throw an error if the API key is not provided.
16
61
  */
17
62
  constructor(props) {
18
63
  var _a;
64
+ /** The latest rate limit state from API response headers. */
65
+ this.rateLimit = { limit: 0, remaining: 0, resetSeconds: 0 };
19
66
  this.apiKey = (props === null || props === void 0 ? void 0 : props.apiKey) || ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.SPIDER_API_KEY);
67
+ this.aiStudioTier = (props === null || props === void 0 ? void 0 : props.aiStudioTier) || "starter";
68
+ this.aiRateLimiter = new RateLimiter(config_1.AI_STUDIO_RATE_LIMITS[this.aiStudioTier]);
20
69
  if (!this.apiKey) {
21
70
  throw new Error("No API key provided");
22
71
  }
23
72
  }
73
+ /**
74
+ * Update the AI Studio subscription tier (adjusts rate limiting).
75
+ * @param {AIStudioTier} tier - The new subscription tier.
76
+ */
77
+ setAIStudioTier(tier) {
78
+ this.aiStudioTier = tier;
79
+ this.aiRateLimiter.setLimit(config_1.AI_STUDIO_RATE_LIMITS[tier]);
80
+ }
81
+ /**
82
+ * Update rate limit state from response headers.
83
+ */
84
+ _updateRateLimit(headers) {
85
+ const limit = headers.get("RateLimit-Limit");
86
+ const remaining = headers.get("RateLimit-Remaining");
87
+ const reset = headers.get("RateLimit-Reset");
88
+ if (limit)
89
+ this.rateLimit.limit = Number(limit);
90
+ if (remaining)
91
+ this.rateLimit.remaining = Number(remaining);
92
+ if (reset)
93
+ this.rateLimit.resetSeconds = Number(reset);
94
+ }
24
95
  /**
25
96
  * Internal method to handle POST requests.
26
97
  * @param {string} endpoint - The API endpoint to which the POST request should be sent.
@@ -30,11 +101,20 @@ class Spider {
30
101
  */
31
102
  async _apiPost(endpoint, data, stream, jsonl) {
32
103
  const headers = jsonl ? this.prepareHeadersJsonL : this.prepareHeaders;
33
- const response = await (0, exponential_backoff_1.backOff)(() => fetch(`${config_1.APISchema["url"]}/${config_1.ApiVersion.V1}/${endpoint}`, {
34
- method: "POST",
35
- headers: headers,
36
- body: JSON.stringify(data),
37
- }), {
104
+ const response = await (0, exponential_backoff_1.backOff)(async () => {
105
+ const res = await fetch(`${config_1.APISchema["url"]}/${config_1.ApiVersion.V1}/${endpoint}`, {
106
+ method: "POST",
107
+ headers: headers,
108
+ body: JSON.stringify(data),
109
+ });
110
+ this._updateRateLimit(res.headers);
111
+ if (res.status === 429) {
112
+ const retryAfter = Number(res.headers.get("Retry-After") || "1");
113
+ await new Promise((r) => setTimeout(r, retryAfter * 1000));
114
+ throw new Error(`Rate limited on ${endpoint}. Retrying after ${retryAfter}s.`);
115
+ }
116
+ return res;
117
+ }, {
38
118
  numOfAttempts: 5,
39
119
  });
40
120
  if (!stream) {
@@ -54,10 +134,19 @@ class Spider {
54
134
  */
55
135
  async _apiGet(endpoint) {
56
136
  const headers = this.prepareHeaders;
57
- const response = await (0, exponential_backoff_1.backOff)(() => fetch(`${config_1.APISchema["url"]}/${config_1.ApiVersion.V1}/${endpoint}`, {
58
- method: "GET",
59
- headers: headers,
60
- }), {
137
+ const response = await (0, exponential_backoff_1.backOff)(async () => {
138
+ const res = await fetch(`${config_1.APISchema["url"]}/${config_1.ApiVersion.V1}/${endpoint}`, {
139
+ method: "GET",
140
+ headers: headers,
141
+ });
142
+ this._updateRateLimit(res.headers);
143
+ if (res.status === 429) {
144
+ const retryAfter = Number(res.headers.get("Retry-After") || "1");
145
+ await new Promise((r) => setTimeout(r, retryAfter * 1000));
146
+ throw new Error(`Rate limited on ${endpoint}. Retrying after ${retryAfter}s.`);
147
+ }
148
+ return res;
149
+ }, {
61
150
  numOfAttempts: 5,
62
151
  });
63
152
  if (response.ok) {
@@ -117,6 +206,15 @@ class Spider {
117
206
  async screenshot(url, params = {}) {
118
207
  return this._apiPost(config_1.APIRoutes.Screenshot, { url: url, ...params });
119
208
  }
209
+ /**
210
+ * Unblock a challenging url to get data.
211
+ * @param {string} url - The URL to get data from.
212
+ * @param {GenericParams} [params={}] - Configuration parameters for the screenshot.
213
+ * @returns {Promise<any>} The screenshot data.
214
+ */
215
+ async unblocker(url, params = {}) {
216
+ return this._apiPost(config_1.APIRoutes.Unblocker, { url: url, ...params });
217
+ }
120
218
  /**
121
219
  * Perform a search and gather a list of websites to start crawling and collect resources.
122
220
  * @param {string} search - The search query.
@@ -178,6 +276,102 @@ class Spider {
178
276
  "Content-Type": "application/jsonl",
179
277
  };
180
278
  }
279
+ /**
280
+ * Internal method to handle AI Studio POST requests with rate limiting.
281
+ * @param {string} endpoint - The AI Studio endpoint.
282
+ * @param {Record<string, any>} data - The request data including prompt.
283
+ * @returns {Promise<any>} The response data.
284
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
285
+ * @throws {AIStudioRateLimitExceeded} When rate limit is exceeded server-side.
286
+ */
287
+ async _aiApiPost(endpoint, data) {
288
+ // Apply client-side rate limiting
289
+ await this.aiRateLimiter.acquire();
290
+ const headers = this.prepareHeaders;
291
+ const response = await (0, exponential_backoff_1.backOff)(() => fetch(`${config_1.APISchema["url"]}/${config_1.ApiVersion.V1}/${endpoint}`, {
292
+ method: "POST",
293
+ headers: headers,
294
+ body: JSON.stringify(data),
295
+ }), {
296
+ numOfAttempts: 3,
297
+ retry: (e, attemptNumber) => {
298
+ // Don't retry on subscription or rate limit errors
299
+ return attemptNumber < 3;
300
+ },
301
+ });
302
+ if (response.ok) {
303
+ return response.json();
304
+ }
305
+ // Handle AI Studio specific errors
306
+ if (response.status === 402) {
307
+ throw new config_1.AIStudioSubscriptionRequired();
308
+ }
309
+ if (response.status === 429) {
310
+ const retryAfter = response.headers.get("Retry-After");
311
+ const retryAfterMs = retryAfter ? parseInt(retryAfter) * 1000 : 1000;
312
+ throw new config_1.AIStudioRateLimitExceeded(retryAfterMs);
313
+ }
314
+ this.handleError(response, `AI request to ${endpoint}`);
315
+ }
316
+ /**
317
+ * AI-guided crawling using natural language prompts.
318
+ * Requires an active AI Studio subscription.
319
+ * @param {string} url - The URL to start crawling.
320
+ * @param {string} prompt - Natural language instruction for what to crawl and extract.
321
+ * @param {AIRequestParams} [params={}] - Additional parameters for the crawl.
322
+ * @returns {Promise<any>} The crawl results guided by the AI prompt.
323
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
324
+ */
325
+ async aiCrawl(url, prompt, params = {}) {
326
+ return this._aiApiPost(config_1.APIRoutes.AICrawl, { url, prompt, ...params });
327
+ }
328
+ /**
329
+ * AI-guided scraping using natural language prompts.
330
+ * Requires an active AI Studio subscription.
331
+ * @param {string} url - The URL to scrape.
332
+ * @param {string} prompt - Natural language description of data to extract.
333
+ * @param {AIRequestParams} [params={}] - Additional parameters for the scrape.
334
+ * @returns {Promise<any>} The scraped data guided by the AI prompt.
335
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
336
+ */
337
+ async aiScrape(url, prompt, params = {}) {
338
+ return this._aiApiPost(config_1.APIRoutes.AIScrape, { url, prompt, ...params });
339
+ }
340
+ /**
341
+ * AI-enhanced web search using natural language queries.
342
+ * Requires an active AI Studio subscription.
343
+ * @param {string} prompt - Natural language search query.
344
+ * @param {SearchRequestParams} [params={}] - Additional search parameters.
345
+ * @returns {Promise<any>} The search results with AI-enhanced relevance.
346
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
347
+ */
348
+ async aiSearch(prompt, params = {}) {
349
+ return this._aiApiPost(config_1.APIRoutes.AISearch, { prompt, ...params });
350
+ }
351
+ /**
352
+ * AI-guided browser automation using natural language commands.
353
+ * Requires an active AI Studio subscription.
354
+ * @param {string} url - The URL to automate.
355
+ * @param {string} prompt - Natural language description of browser actions.
356
+ * @param {AIRequestParams} [params={}] - Additional parameters for automation.
357
+ * @returns {Promise<any>} The automation results.
358
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
359
+ */
360
+ async aiBrowser(url, prompt, params = {}) {
361
+ return this._aiApiPost(config_1.APIRoutes.AIBrowser, { url, prompt, ...params });
362
+ }
363
+ /**
364
+ * AI-guided link extraction and filtering.
365
+ * Requires an active AI Studio subscription.
366
+ * @param {string} url - The URL to extract links from.
367
+ * @param {string} prompt - Natural language description of what links to find.
368
+ * @param {AIRequestParams} [params={}] - Additional parameters.
369
+ * @returns {Promise<any>} The filtered links based on AI analysis.
370
+ * @throws {AIStudioSubscriptionRequired} When subscription is not active.
371
+ */
372
+ async aiLinks(url, prompt, params = {}) {
373
+ return this._aiApiPost(config_1.APIRoutes.AILinks, { url, prompt, ...params });
374
+ }
181
375
  /**
182
376
  * Handles errors from API requests.
183
377
  * @param {Response} response - The fetch response object.
package/dist/config.d.ts CHANGED
@@ -591,12 +591,88 @@ export declare enum ApiVersion {
591
591
  }
592
592
  export declare enum APIRoutes {
593
593
  Crawl = "crawl",
594
+ Scrape = "scrape",
595
+ Unblocker = "unblocker",
594
596
  Links = "links",
595
597
  Screenshot = "screenshot",
596
598
  Search = "search",
597
599
  Transform = "transform",
598
600
  Data = "data",
599
- DataCredits = "data/credits"
601
+ DataCredits = "data/credits",
602
+ AICrawl = "ai/crawl",
603
+ AIScrape = "ai/scrape",
604
+ AISearch = "ai/search",
605
+ AIBrowser = "ai/browser",
606
+ AILinks = "ai/links"
607
+ }
608
+ /**
609
+ * AI Studio subscription tiers with their rate limits (requests per second).
610
+ */
611
+ export declare const AI_STUDIO_RATE_LIMITS: {
612
+ readonly starter: 1;
613
+ readonly lite: 5;
614
+ readonly standard: 10;
615
+ readonly custom: 25;
616
+ };
617
+ export type AIStudioTier = keyof typeof AI_STUDIO_RATE_LIMITS;
618
+ /**
619
+ * Parameters for AI Studio endpoints.
620
+ * All AI endpoints require a 'prompt' parameter for natural language instructions.
621
+ */
622
+ export interface AIRequestParams extends Omit<SpiderParams, "url"> {
623
+ /** Natural language instruction for AI-guided extraction */
624
+ prompt: string;
625
+ }
626
+ /**
627
+ * AI Studio subscription info and URLs.
628
+ */
629
+ export declare const AIStudioInfo: {
630
+ /** Base URL for AI Studio */
631
+ readonly baseUrl: "https://aistudio.spider.cloud";
632
+ /** URL for pricing/subscription page */
633
+ readonly pricingUrl: "https://aistudio.spider.cloud/pricing";
634
+ /** URL for AI Studio documentation */
635
+ readonly docsUrl: "https://aistudio.spider.cloud/docs";
636
+ /** Available subscription tiers */
637
+ readonly tiers: {
638
+ readonly starter: {
639
+ readonly price: 6;
640
+ readonly credits: 30000;
641
+ readonly rateLimit: 1;
642
+ };
643
+ readonly lite: {
644
+ readonly price: 30;
645
+ readonly credits: 150000;
646
+ readonly rateLimit: 5;
647
+ };
648
+ readonly standard: {
649
+ readonly price: 125;
650
+ readonly credits: 600000;
651
+ readonly rateLimit: 10;
652
+ };
653
+ readonly custom: {
654
+ readonly price: 600;
655
+ readonly credits: 3000000;
656
+ readonly rateLimit: 25;
657
+ };
658
+ };
659
+ };
660
+ /**
661
+ * Error thrown when AI Studio subscription is required but not active.
662
+ */
663
+ export declare class AIStudioSubscriptionRequired extends Error {
664
+ /** URL to subscribe to AI Studio */
665
+ subscribeUrl: string;
666
+ constructor(message?: string);
667
+ }
668
+ /**
669
+ * Error thrown when AI Studio rate limit is exceeded.
670
+ */
671
+ export declare class AIStudioRateLimitExceeded extends Error {
672
+ retryAfterMs: number;
673
+ /** URL to upgrade subscription for higher rate limits */
674
+ upgradeUrl: string;
675
+ constructor(retryAfterMs: number, currentTier?: AIStudioTier);
600
676
  }
601
677
  export declare const APISchema: {
602
678
  url: string;
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setBaseUrl = exports.APISchema = exports.APIRoutes = exports.ApiVersion = exports.Collection = exports.RedirectPolicy = void 0;
3
+ exports.setBaseUrl = exports.APISchema = exports.AIStudioRateLimitExceeded = exports.AIStudioSubscriptionRequired = exports.AIStudioInfo = exports.AI_STUDIO_RATE_LIMITS = exports.APIRoutes = exports.ApiVersion = exports.Collection = exports.RedirectPolicy = void 0;
4
4
  // The HTTP redirect policy to use. Loose allows all domains and Strict only allows relative requests to the domain.
5
5
  var RedirectPolicy;
6
6
  (function (RedirectPolicy) {
@@ -32,6 +32,10 @@ var APIRoutes;
32
32
  (function (APIRoutes) {
33
33
  // Crawl a website to collect the contents. Can be one page or many.
34
34
  APIRoutes["Crawl"] = "crawl";
35
+ // Scrape a website to collect the contents. Can be one page or many.
36
+ APIRoutes["Scrape"] = "scrape";
37
+ // Unblock a website to collect the contents. Can be one page or many.
38
+ APIRoutes["Unblocker"] = "unblocker";
35
39
  // Crawl a website to collect the links. Can be one page or many.
36
40
  APIRoutes["Links"] = "links";
37
41
  // Crawl a website to collect screenshots. Can be one page or many.
@@ -44,7 +48,66 @@ var APIRoutes;
44
48
  APIRoutes["Data"] = "data";
45
49
  // Get the credits remaining for an account.
46
50
  APIRoutes["DataCredits"] = "data/credits";
51
+ // AI Studio endpoints (requires AI Studio subscription)
52
+ APIRoutes["AICrawl"] = "ai/crawl";
53
+ APIRoutes["AIScrape"] = "ai/scrape";
54
+ APIRoutes["AISearch"] = "ai/search";
55
+ APIRoutes["AIBrowser"] = "ai/browser";
56
+ APIRoutes["AILinks"] = "ai/links";
47
57
  })(APIRoutes || (exports.APIRoutes = APIRoutes = {}));
58
+ /**
59
+ * AI Studio subscription tiers with their rate limits (requests per second).
60
+ */
61
+ exports.AI_STUDIO_RATE_LIMITS = {
62
+ starter: 1,
63
+ lite: 5,
64
+ standard: 10,
65
+ custom: 25,
66
+ };
67
+ /**
68
+ * AI Studio subscription info and URLs.
69
+ */
70
+ exports.AIStudioInfo = {
71
+ /** Base URL for AI Studio */
72
+ baseUrl: "https://aistudio.spider.cloud",
73
+ /** URL for pricing/subscription page */
74
+ pricingUrl: "https://aistudio.spider.cloud/pricing",
75
+ /** URL for AI Studio documentation */
76
+ docsUrl: "https://aistudio.spider.cloud/docs",
77
+ /** Available subscription tiers */
78
+ tiers: {
79
+ starter: { price: 6, credits: 30000, rateLimit: 1 },
80
+ lite: { price: 30, credits: 150000, rateLimit: 5 },
81
+ standard: { price: 125, credits: 600000, rateLimit: 10 },
82
+ custom: { price: 600, credits: 3000000, rateLimit: 25 },
83
+ },
84
+ };
85
+ /**
86
+ * Error thrown when AI Studio subscription is required but not active.
87
+ */
88
+ class AIStudioSubscriptionRequired extends Error {
89
+ constructor(message = "AI Studio subscription required to use /ai/* endpoints.") {
90
+ super(`${message}\n\nSubscribe at: ${exports.AIStudioInfo.pricingUrl}\n\nPlans start at $${exports.AIStudioInfo.tiers.starter.price}/month with ${exports.AIStudioInfo.tiers.starter.credits.toLocaleString()} credits.`);
91
+ this.name = "AIStudioSubscriptionRequired";
92
+ this.subscribeUrl = exports.AIStudioInfo.pricingUrl;
93
+ }
94
+ }
95
+ exports.AIStudioSubscriptionRequired = AIStudioSubscriptionRequired;
96
+ /**
97
+ * Error thrown when AI Studio rate limit is exceeded.
98
+ */
99
+ class AIStudioRateLimitExceeded extends Error {
100
+ constructor(retryAfterMs, currentTier) {
101
+ const upgradeHint = currentTier && currentTier !== "custom"
102
+ ? `\n\nUpgrade your plan for higher rate limits: ${exports.AIStudioInfo.pricingUrl}`
103
+ : "";
104
+ super(`AI Studio rate limit exceeded. Retry after ${retryAfterMs}ms.${upgradeHint}`);
105
+ this.name = "AIStudioRateLimitExceeded";
106
+ this.retryAfterMs = retryAfterMs;
107
+ this.upgradeUrl = exports.AIStudioInfo.pricingUrl;
108
+ }
109
+ }
110
+ exports.AIStudioRateLimitExceeded = AIStudioRateLimitExceeded;
48
111
  // The base API target info for Spider Cloud.
49
112
  exports.APISchema = {
50
113
  url: "https://api.spider.cloud",
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { Spider } from "./client";
2
- export { Collection, setBaseUrl, APISchema } from "./config";
3
- export type { SpiderParams, Budget, Viewport, QueryRequest } from "./config";
2
+ export { Collection, setBaseUrl, APISchema, AI_STUDIO_RATE_LIMITS, AIStudioInfo, AIStudioSubscriptionRequired, AIStudioRateLimitExceeded, } from "./config";
3
+ export type { SpiderParams, Budget, Viewport, QueryRequest, AIRequestParams, AIStudioTier, } from "./config";
package/dist/index.js CHANGED
@@ -1,9 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APISchema = exports.setBaseUrl = exports.Collection = exports.Spider = void 0;
3
+ exports.AIStudioRateLimitExceeded = exports.AIStudioSubscriptionRequired = exports.AIStudioInfo = exports.AI_STUDIO_RATE_LIMITS = exports.APISchema = exports.setBaseUrl = exports.Collection = exports.Spider = void 0;
4
4
  var client_1 = require("./client");
5
5
  Object.defineProperty(exports, "Spider", { enumerable: true, get: function () { return client_1.Spider; } });
6
6
  var config_1 = require("./config");
7
7
  Object.defineProperty(exports, "Collection", { enumerable: true, get: function () { return config_1.Collection; } });
8
8
  Object.defineProperty(exports, "setBaseUrl", { enumerable: true, get: function () { return config_1.setBaseUrl; } });
9
9
  Object.defineProperty(exports, "APISchema", { enumerable: true, get: function () { return config_1.APISchema; } });
10
+ Object.defineProperty(exports, "AI_STUDIO_RATE_LIMITS", { enumerable: true, get: function () { return config_1.AI_STUDIO_RATE_LIMITS; } });
11
+ Object.defineProperty(exports, "AIStudioInfo", { enumerable: true, get: function () { return config_1.AIStudioInfo; } });
12
+ Object.defineProperty(exports, "AIStudioSubscriptionRequired", { enumerable: true, get: function () { return config_1.AIStudioSubscriptionRequired; } });
13
+ Object.defineProperty(exports, "AIStudioRateLimitExceeded", { enumerable: true, get: function () { return config_1.AIStudioRateLimitExceeded; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spider-cloud/spider-client",
3
- "version": "0.1.84",
3
+ "version": "0.1.87",
4
4
  "description": "Isomorphic Javascript SDK for Spider Cloud services",
5
5
  "scripts": {
6
6
  "test": "node --import tsx --test __tests__/*test.ts",