oblien 1.0.7 → 1.1.1
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 +387 -408
- package/agents.js +14 -0
- package/credits.js +11 -0
- package/icons.js +11 -0
- package/index.d.ts +261 -0
- package/index.js +23 -0
- package/namespaces.js +12 -0
- package/package.json +13 -2
- package/sandbox.js +12 -0
- package/search.js +11 -0
- package/src/agents/agent.js +229 -0
- package/src/agents/index.js +212 -0
- package/src/agents/settings.js +100 -0
- package/src/agents/tools.js +155 -0
- package/src/client.js +18 -0
- package/src/credits/index.js +299 -0
- package/src/icons/index.js +185 -0
- package/src/namespaces/index.js +225 -0
- package/src/namespaces/namespace.js +274 -0
- package/src/sandbox/index.js +185 -0
- package/src/sandbox/sandbox.js +124 -0
- package/src/search/index.js +191 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credits Module
|
|
3
|
+
* Manages credits, quotas, usage tracking, and transactions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class OblienCredits {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import('../client.js').OblienClient} client - Oblien client instance
|
|
9
|
+
*/
|
|
10
|
+
constructor(client) {
|
|
11
|
+
if (!client) {
|
|
12
|
+
throw new Error('Oblien client is required');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
this.client = client;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Balance Management
|
|
20
|
+
// =============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get client's total credit balance
|
|
24
|
+
* @returns {Promise<number>} Current credit balance
|
|
25
|
+
*/
|
|
26
|
+
async getBalance() {
|
|
27
|
+
const response = await this.client.get('credits/balance');
|
|
28
|
+
return response.balance;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Add credits to client (internal use - requires admin permissions)
|
|
33
|
+
* @param {number} amount - Amount of credits to add
|
|
34
|
+
* @param {string} [reason] - Reason for adding credits
|
|
35
|
+
* @param {Object} [metadata] - Additional metadata
|
|
36
|
+
* @returns {Promise<Object>} Result with new balance
|
|
37
|
+
*/
|
|
38
|
+
async addCredits(amount, reason = 'manual', metadata = {}) {
|
|
39
|
+
const response = await this.client.post('credits/add', {
|
|
40
|
+
amount,
|
|
41
|
+
reason,
|
|
42
|
+
metadata
|
|
43
|
+
});
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// Quota Management
|
|
49
|
+
// =============================================================================
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get all namespace quotas with pagination and filtering
|
|
53
|
+
* @param {Object} [options] - Query options
|
|
54
|
+
* @param {number} [options.limit] - Max results (default: 100, max: 500)
|
|
55
|
+
* @param {number} [options.offset] - Offset for pagination
|
|
56
|
+
* @param {string} [options.after] - Cursor for pagination (format: "namespace:service")
|
|
57
|
+
* @param {string} [options.search] - Search query
|
|
58
|
+
* @param {string} [options.status] - Filter by status: 'active', 'warning', 'exceeded'
|
|
59
|
+
* @returns {Promise<Object>} Namespaces with quotas and pagination info
|
|
60
|
+
*/
|
|
61
|
+
async getNamespaceQuotas(options = {}) {
|
|
62
|
+
const response = await this.client.get('credits/namespaces', options);
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get detailed namespace quota information
|
|
68
|
+
* @param {string} namespace - Namespace slug or ID
|
|
69
|
+
* @param {Object} [options] - Query options
|
|
70
|
+
* @param {number} [options.days] - Number of days for stats (default: 7, max: 90)
|
|
71
|
+
* @returns {Promise<Object>} Namespace details with quotas, usage, and transactions
|
|
72
|
+
*/
|
|
73
|
+
async getNamespaceDetails(namespace, options = {}) {
|
|
74
|
+
const response = await this.client.get(`credits/namespaces/${namespace}`, options);
|
|
75
|
+
return response;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Set quota for a namespace and service
|
|
80
|
+
* @param {Object} options - Quota options
|
|
81
|
+
* @param {string} options.namespace - Namespace slug
|
|
82
|
+
* @param {string} options.service - Service name (e.g., 'ai', 'deployment', 'sandbox')
|
|
83
|
+
* @param {number} options.quotaLimit - Quota limit (null or 0 for unlimited)
|
|
84
|
+
* @param {string} [options.period] - Quota period: 'daily', 'monthly', 'unlimited'
|
|
85
|
+
* @returns {Promise<Object>} Created/updated quota
|
|
86
|
+
*/
|
|
87
|
+
async setQuota(options) {
|
|
88
|
+
if (!options.namespace || !options.service) {
|
|
89
|
+
throw new Error('namespace and service are required');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (options.quotaLimit === undefined) {
|
|
93
|
+
throw new Error('quotaLimit is required');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const response = await this.client.post('credits/namespace-quota', {
|
|
97
|
+
namespace: options.namespace,
|
|
98
|
+
service: options.service,
|
|
99
|
+
quotaLimit: options.quotaLimit,
|
|
100
|
+
period: options.period || 'unlimited'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return response;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Reset namespace quota (e.g., for monthly reset)
|
|
108
|
+
* @param {string} namespace - Namespace slug
|
|
109
|
+
* @param {string} service - Service name
|
|
110
|
+
* @returns {Promise<Object>} Reset result
|
|
111
|
+
*/
|
|
112
|
+
async resetQuota(namespace, service) {
|
|
113
|
+
if (!namespace || !service) {
|
|
114
|
+
throw new Error('namespace and service are required');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const response = await this.client.post('credits/reset-quota', {
|
|
118
|
+
namespace,
|
|
119
|
+
service
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return response;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// Usage History & Transactions
|
|
127
|
+
// =============================================================================
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get credit usage history with filtering and pagination
|
|
131
|
+
* @param {Object} [options] - Query options
|
|
132
|
+
* @param {string} [options.namespace] - Filter by namespace
|
|
133
|
+
* @param {string} [options.endUserId] - Filter by end user ID
|
|
134
|
+
* @param {string} [options.service] - Filter by service
|
|
135
|
+
* @param {string} [options.type] - Filter by type: 'deduction', 'addition', 'refund', 'adjustment'
|
|
136
|
+
* @param {string} [options.startDate] - Start date (ISO string)
|
|
137
|
+
* @param {string} [options.endDate] - End date (ISO string)
|
|
138
|
+
* @param {number} [options.limit] - Max results (default: 50)
|
|
139
|
+
* @param {number} [options.offset] - Offset for pagination
|
|
140
|
+
* @param {string} [options.after] - Cursor for pagination (timestamp)
|
|
141
|
+
* @param {number} [options.afterId] - Cursor ID for pagination
|
|
142
|
+
* @returns {Promise<Object>} History with transactions and pagination
|
|
143
|
+
*/
|
|
144
|
+
async getHistory(options = {}) {
|
|
145
|
+
const response = await this.client.get('credits/history', options);
|
|
146
|
+
return response;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get available filter options for history
|
|
151
|
+
* @returns {Promise<Object>} Available namespaces and services
|
|
152
|
+
*/
|
|
153
|
+
async getHistoryFilters() {
|
|
154
|
+
const response = await this.client.get('credits/history/filters');
|
|
155
|
+
return response;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get usage summary by namespace/service
|
|
160
|
+
* @param {Object} [options] - Query options
|
|
161
|
+
* @param {string} [options.namespace] - Filter by namespace
|
|
162
|
+
* @param {number} [options.days] - Number of days to look back (default: 30)
|
|
163
|
+
* @param {number} [options.limit] - Max results (default: 50, max: 500)
|
|
164
|
+
* @param {number} [options.offset] - Offset for pagination
|
|
165
|
+
* @param {number} [options.after] - Cursor for pagination (total_spent value)
|
|
166
|
+
* @returns {Promise<Object>} Summary with aggregated usage
|
|
167
|
+
*/
|
|
168
|
+
async getSummary(options = {}) {
|
|
169
|
+
const response = await this.client.get('credits/summary', options);
|
|
170
|
+
return response;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Get daily usage statistics (for charts)
|
|
175
|
+
* @param {Object} [options] - Query options
|
|
176
|
+
* @param {number} [options.days] - Number of days (default: 7)
|
|
177
|
+
* @returns {Promise<Object>} Daily usage statistics
|
|
178
|
+
*/
|
|
179
|
+
async getUsageStats(options = {}) {
|
|
180
|
+
const response = await this.client.get('credits/usage-stats', options);
|
|
181
|
+
return response;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// =============================================================================
|
|
185
|
+
// Pricing & Packages
|
|
186
|
+
// =============================================================================
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get available credit packages
|
|
190
|
+
* @returns {Promise<Array>} Array of credit packages
|
|
191
|
+
*/
|
|
192
|
+
async getPackages() {
|
|
193
|
+
const response = await this.client.get('credits/packages');
|
|
194
|
+
return response.packages || response.data || response;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get pricing information and limits
|
|
199
|
+
* @returns {Promise<Object>} Pricing info with rates and limits
|
|
200
|
+
*/
|
|
201
|
+
async getPricingInfo() {
|
|
202
|
+
const response = await this.client.get('credits/pricing-info');
|
|
203
|
+
return response;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Calculate credits from money or vice versa
|
|
208
|
+
* @param {Object} options - Calculation options
|
|
209
|
+
* @param {string} [options.packageId] - Package ID to calculate
|
|
210
|
+
* @param {number} [options.amount] - Money amount to convert to credits
|
|
211
|
+
* @param {number} [options.credits] - Credits to convert to money
|
|
212
|
+
* @returns {Promise<Object>} Calculation result with amount and credits
|
|
213
|
+
*/
|
|
214
|
+
async calculateCost(options) {
|
|
215
|
+
if (!options.packageId && !options.amount && !options.credits) {
|
|
216
|
+
throw new Error('Must provide either packageId, amount, or credits');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const response = await this.client.post('credits/calculate-cost', options);
|
|
220
|
+
return response;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Calculate credits for a given amount (preview)
|
|
225
|
+
* @param {number} amount - Money amount
|
|
226
|
+
* @returns {Promise<Object>} Credits calculation
|
|
227
|
+
*/
|
|
228
|
+
async calculateCredits(amount) {
|
|
229
|
+
const response = await this.client.get('credits/calculate', { amount });
|
|
230
|
+
return response;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// =============================================================================
|
|
234
|
+
// Purchase Management
|
|
235
|
+
// =============================================================================
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create Stripe checkout to purchase credits
|
|
239
|
+
* @param {Object} options - Purchase options
|
|
240
|
+
* @param {string} [options.packageId] - Package ID to purchase
|
|
241
|
+
* @param {number} [options.amount] - Custom amount to purchase
|
|
242
|
+
* @param {Object} [options.metadata] - Additional metadata
|
|
243
|
+
* @returns {Promise<Object>} Checkout session with URL
|
|
244
|
+
*/
|
|
245
|
+
async createCheckout(options) {
|
|
246
|
+
if (!options.packageId && !options.amount) {
|
|
247
|
+
throw new Error('Must provide either packageId or amount');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const response = await this.client.post('credits/purchase', options);
|
|
251
|
+
return response;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get purchase history
|
|
256
|
+
* @param {Object} [options] - Query options
|
|
257
|
+
* @param {number} [options.limit] - Max results (default: 50, max: 100)
|
|
258
|
+
* @param {number} [options.offset] - Offset for pagination
|
|
259
|
+
* @param {boolean} [options.light] - If true, returns basic data only (faster)
|
|
260
|
+
* @returns {Promise<Object>} Purchase history with pagination
|
|
261
|
+
*/
|
|
262
|
+
async getPurchaseHistory(options = {}) {
|
|
263
|
+
const response = await this.client.get('credits/purchases', options);
|
|
264
|
+
return response;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Get single purchase details
|
|
269
|
+
* @param {string} purchaseId - Purchase ID
|
|
270
|
+
* @returns {Promise<Object>} Purchase details
|
|
271
|
+
*/
|
|
272
|
+
async getPurchaseDetails(purchaseId) {
|
|
273
|
+
const response = await this.client.get(`credits/purchases/${purchaseId}`);
|
|
274
|
+
return response;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get Stripe checkout session URL for pending purchase
|
|
279
|
+
* @param {string} purchaseId - Purchase ID
|
|
280
|
+
* @returns {Promise<Object>} Session with checkout URL
|
|
281
|
+
*/
|
|
282
|
+
async getPurchaseSession(purchaseId) {
|
|
283
|
+
const response = await this.client.get(`credits/purchases/${purchaseId}/session`);
|
|
284
|
+
return response;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Cancel a pending purchase
|
|
289
|
+
* @param {string} purchaseId - Purchase ID
|
|
290
|
+
* @returns {Promise<Object>} Cancellation result
|
|
291
|
+
*/
|
|
292
|
+
async cancelPurchase(purchaseId) {
|
|
293
|
+
const response = await this.client.post(`credits/purchases/${purchaseId}/cancel`);
|
|
294
|
+
return response;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export default OblienCredits;
|
|
299
|
+
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oblien Icons Module
|
|
3
|
+
* Search and fetch icons, images, and videos
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class OblienIcons {
|
|
7
|
+
constructor(client) {
|
|
8
|
+
if (!client) throw new Error('Oblien client is required');
|
|
9
|
+
this.client = client;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Search for icons using semantic search
|
|
14
|
+
*
|
|
15
|
+
* @param {string} query - Search query
|
|
16
|
+
* @param {Object} options - Search options
|
|
17
|
+
* @param {number} options.offset - Pagination offset (default: 0)
|
|
18
|
+
* @param {number} options.limit - Number of results (default: 100)
|
|
19
|
+
* @returns {Promise<Object>} Search results with pagination info
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const results = await icons.search('home', { limit: 50 });
|
|
23
|
+
* // Returns:
|
|
24
|
+
* // {
|
|
25
|
+
* // results: [
|
|
26
|
+
* // {
|
|
27
|
+
* // url: 'https://cdn.oblien.com/static/png-icons/...',
|
|
28
|
+
* // filename: 'home-outline.png',
|
|
29
|
+
* // name: 'home',
|
|
30
|
+
* // description: 'home',
|
|
31
|
+
* // style: 'Outline',
|
|
32
|
+
* // score: 0.95,
|
|
33
|
+
* // success: true
|
|
34
|
+
* // }
|
|
35
|
+
* // ],
|
|
36
|
+
* // hasMore: true,
|
|
37
|
+
* // offset: 50,
|
|
38
|
+
* // total: 245
|
|
39
|
+
* // }
|
|
40
|
+
*/
|
|
41
|
+
async search(query, options = {}) {
|
|
42
|
+
if (!query || typeof query !== 'string') {
|
|
43
|
+
throw new Error('Query must be a non-empty string');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { offset = 0, limit = 100 } = options;
|
|
47
|
+
|
|
48
|
+
return this.client.post('icons/search-icons', {
|
|
49
|
+
query: query.trim(),
|
|
50
|
+
offset,
|
|
51
|
+
limit
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Fetch multiple items (icons, images, videos) with semantic matching
|
|
57
|
+
*
|
|
58
|
+
* @param {Array<Object>} items - Array of items to fetch
|
|
59
|
+
* @param {string} items[].type - Type: 'icon', 'image', or 'video'
|
|
60
|
+
* @param {string} items[].description - Description for semantic matching
|
|
61
|
+
* @param {boolean} items[].is_vector - Whether the item is a vector (optional)
|
|
62
|
+
* @param {string} items[].variant - Variant type (optional, for images/videos)
|
|
63
|
+
* @returns {Promise<Array>} Array of fetched items with URLs
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const items = await icons.fetch([
|
|
67
|
+
* { type: 'icon', description: 'user profile' },
|
|
68
|
+
* { type: 'icon', description: 'settings gear' },
|
|
69
|
+
* { type: 'image', description: 'mountain landscape' },
|
|
70
|
+
* { type: 'video', description: 'ocean waves' }
|
|
71
|
+
* ]);
|
|
72
|
+
*
|
|
73
|
+
* // Returns:
|
|
74
|
+
* // [
|
|
75
|
+
* // {
|
|
76
|
+
* // url: 'https://cdn.oblien.com/static/icons/...',
|
|
77
|
+
* // description: 'user profile',
|
|
78
|
+
* // style: 'Outline',
|
|
79
|
+
* // success: true
|
|
80
|
+
* // },
|
|
81
|
+
* // {
|
|
82
|
+
* // url: 'https://cdn.oblien.com/static/assets/...',
|
|
83
|
+
* // type: 'image',
|
|
84
|
+
* // description: 'mountain landscape',
|
|
85
|
+
* // variant: 'regular',
|
|
86
|
+
* // success: true
|
|
87
|
+
* // }
|
|
88
|
+
* // ]
|
|
89
|
+
*/
|
|
90
|
+
async fetch(items) {
|
|
91
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
92
|
+
throw new Error('Items must be a non-empty array');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Validate items
|
|
96
|
+
for (const item of items) {
|
|
97
|
+
if (!item.type || !['icon', 'image', 'video'].includes(item.type)) {
|
|
98
|
+
throw new Error('Each item must have a valid type: icon, image, or video');
|
|
99
|
+
}
|
|
100
|
+
if (!item.description || typeof item.description !== 'string') {
|
|
101
|
+
throw new Error('Each item must have a description string');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return this.client.post('icons/fetch', { data: items });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Fetch a single icon
|
|
110
|
+
* Convenience method for fetching one icon
|
|
111
|
+
*
|
|
112
|
+
* @param {string} description - Icon description
|
|
113
|
+
* @returns {Promise<Object>} Icon object with URL
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const icon = await icons.fetchIcon('home');
|
|
117
|
+
* // Returns: { url: '...', description: 'home', style: 'Outline', success: true }
|
|
118
|
+
*/
|
|
119
|
+
async fetchIcon(description) {
|
|
120
|
+
if (!description || typeof description !== 'string') {
|
|
121
|
+
throw new Error('Description must be a non-empty string');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const result = await this.fetch([{ type: 'icon', description }]);
|
|
125
|
+
return result[0] || null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Fetch multiple icons at once
|
|
130
|
+
* Convenience method for fetching multiple icons
|
|
131
|
+
*
|
|
132
|
+
* @param {Array<string>} descriptions - Array of icon descriptions
|
|
133
|
+
* @returns {Promise<Array>} Array of icon objects
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* const icons = await icons.fetchIcons(['home', 'settings', 'user']);
|
|
137
|
+
* // Returns: [{ url: '...', description: 'home', ... }, ...]
|
|
138
|
+
*/
|
|
139
|
+
async fetchIcons(descriptions) {
|
|
140
|
+
if (!Array.isArray(descriptions) || descriptions.length === 0) {
|
|
141
|
+
throw new Error('Descriptions must be a non-empty array');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const items = descriptions.map(desc => ({ type: 'icon', description: desc }));
|
|
145
|
+
return this.fetch(items);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Search icons with pagination helper
|
|
150
|
+
* Automatically handles pagination and returns all results
|
|
151
|
+
*
|
|
152
|
+
* @param {string} query - Search query
|
|
153
|
+
* @param {Object} options - Search options
|
|
154
|
+
* @param {number} options.maxResults - Maximum results to fetch (default: 500)
|
|
155
|
+
* @param {number} options.batchSize - Results per batch (default: 100)
|
|
156
|
+
* @returns {Promise<Array>} All matching icons
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* const allIcons = await icons.searchAll('home', { maxResults: 200 });
|
|
160
|
+
* // Returns: [{ url: '...', name: 'home', ... }, ...]
|
|
161
|
+
*/
|
|
162
|
+
async searchAll(query, options = {}) {
|
|
163
|
+
const { maxResults = 500, batchSize = 100 } = options;
|
|
164
|
+
const allResults = [];
|
|
165
|
+
let offset = 0;
|
|
166
|
+
let hasMore = true;
|
|
167
|
+
|
|
168
|
+
while (hasMore && allResults.length < maxResults) {
|
|
169
|
+
const response = await this.search(query, {
|
|
170
|
+
offset,
|
|
171
|
+
limit: Math.min(batchSize, maxResults - allResults.length)
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (response.results && response.results.length > 0) {
|
|
175
|
+
allResults.push(...response.results);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
hasMore = response.hasMore && allResults.length < maxResults;
|
|
179
|
+
offset = response.offset;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return allResults;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|