leonelsearchapi 1.0.0-beta.1 → 1.0.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/index.js +4 -4
- package/package.json +1 -1
- package/readme.md +128 -95
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export class LeonelSearchAPI {
|
|
2
2
|
/**
|
|
3
3
|
* @param {Object} options
|
|
4
|
-
* @param {string} options.apiKey Your LeonelSearch API key
|
|
4
|
+
* @param {string} options.apiKey Your LeonelSearch API key (https://leonelsearch.qzz.io/dashboard)
|
|
5
5
|
* @param {string} [options.apiVersion='v1'] API version
|
|
6
6
|
* @param {boolean} [options.debug=false] Enable debug logs
|
|
7
7
|
*/
|
|
@@ -9,7 +9,7 @@ export class LeonelSearchAPI {
|
|
|
9
9
|
if (!apiKey) throw new Error('apiKey is required');
|
|
10
10
|
|
|
11
11
|
this.apiKey = apiKey;
|
|
12
|
-
this.baseURL = `
|
|
12
|
+
this.baseURL = `https://leonelsearch.qzz.io/api/${apiVersion}`;
|
|
13
13
|
this.debug = debug;
|
|
14
14
|
|
|
15
15
|
if (this.debug) {
|
|
@@ -106,8 +106,8 @@ export class LeonelSearchAPI {
|
|
|
106
106
|
console.log(
|
|
107
107
|
' Results:',
|
|
108
108
|
json.meta?.resultCount ??
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
json.results?.length ??
|
|
110
|
+
0
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leonelsearchapi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Official JavaScript client for LeonelSearchAPI. Perform searches easily with your API key.",
|
|
5
5
|
"homepage": "https://github.com/LeonelDevStudios/LeonelSearchAPI#readme",
|
|
6
6
|
"bugs": {
|
package/readme.md
CHANGED
|
@@ -28,27 +28,27 @@ npm install leonelsearchapi
|
|
|
28
28
|
## Quick Start
|
|
29
29
|
|
|
30
30
|
```javascript
|
|
31
|
-
import { LeonelSearchAPI } from
|
|
31
|
+
import { LeonelSearchAPI } from "leonelsearchapi";
|
|
32
32
|
|
|
33
33
|
// Initialize the client
|
|
34
34
|
const client = new LeonelSearchAPI({
|
|
35
|
-
apiKey:
|
|
36
|
-
debug: false
|
|
35
|
+
apiKey: "YOUR_API_KEY", // Get your key from leonelsearch.qzz.io
|
|
36
|
+
debug: false, // Set true to enable debug logs
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
// Perform a web search
|
|
40
40
|
async function searchExample() {
|
|
41
41
|
try {
|
|
42
42
|
const results = await client.search({
|
|
43
|
-
query:
|
|
44
|
-
type:
|
|
43
|
+
query: "latest space news",
|
|
44
|
+
type: "web", // Search type: 'web', 'image', 'video', or 'news'
|
|
45
45
|
limit: 5,
|
|
46
|
-
page: 1
|
|
46
|
+
page: 1,
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
console.log(results);
|
|
50
50
|
} catch (err) {
|
|
51
|
-
console.error(
|
|
51
|
+
console.error("Error:", err.message);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -61,18 +61,18 @@ searchExample();
|
|
|
61
61
|
|
|
62
62
|
### `new LeonelSearchAPI({ apiKey })`
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
- **apiKey** _(string, required)_: Your personal LeonelSearch API key
|
|
65
65
|
|
|
66
66
|
### `client.search({ query, type, limit, page })`
|
|
67
67
|
|
|
68
68
|
The main search method supporting all search types.
|
|
69
69
|
|
|
70
|
-
| Parameter | Type | Required | Default | Description | Valid Values
|
|
71
|
-
|
|
72
|
-
| query | string | ✅
|
|
73
|
-
| type | string | ✅
|
|
74
|
-
| limit | number | ❌
|
|
75
|
-
| page | number | ❌
|
|
70
|
+
| Parameter | Type | Required | Default | Description | Valid Values |
|
|
71
|
+
| --------- | ------ | -------- | ------- | -------------------------- | --------------------------------------- |
|
|
72
|
+
| query | string | ✅ | — | The search term | Any string |
|
|
73
|
+
| type | string | ✅ | — | Type of search to perform | `'web'`, `'image'`, `'video'`, `'news'` |
|
|
74
|
+
| limit | number | ❌ | 10 | Number of results per page | 1-50 |
|
|
75
|
+
| page | number | ❌ | 1 | Page number | ≥1 |
|
|
76
76
|
|
|
77
77
|
**Returns:** A Promise resolving to a structured response object:
|
|
78
78
|
|
|
@@ -96,15 +96,19 @@ The main search method supporting all search types.
|
|
|
96
96
|
For easier use, the client provides dedicated methods for each search type:
|
|
97
97
|
|
|
98
98
|
#### `client.searchWeb(query, limit = 10, page = 1)`
|
|
99
|
+
|
|
99
100
|
Performs a web search.
|
|
100
101
|
|
|
101
102
|
#### `client.searchImages(query, limit = 10, page = 1)`
|
|
103
|
+
|
|
102
104
|
Performs an image search.
|
|
103
105
|
|
|
104
106
|
#### `client.searchVideos(query, limit = 10, page = 1)`
|
|
107
|
+
|
|
105
108
|
Performs a video search.
|
|
106
109
|
|
|
107
110
|
#### `client.searchNews(query, limit = 10, page = 1)`
|
|
111
|
+
|
|
108
112
|
Performs a news search.
|
|
109
113
|
|
|
110
114
|
---
|
|
@@ -116,31 +120,31 @@ Performs a news search.
|
|
|
116
120
|
```javascript
|
|
117
121
|
// Web search
|
|
118
122
|
const webResults = await client.search({
|
|
119
|
-
query:
|
|
120
|
-
type:
|
|
121
|
-
limit: 5
|
|
123
|
+
query: "latest space exploration",
|
|
124
|
+
type: "web",
|
|
125
|
+
limit: 5,
|
|
122
126
|
});
|
|
123
127
|
|
|
124
128
|
// Image search
|
|
125
129
|
const imageResults = await client.search({
|
|
126
|
-
query:
|
|
127
|
-
type:
|
|
128
|
-
limit: 10
|
|
130
|
+
query: "mars rover photos",
|
|
131
|
+
type: "image",
|
|
132
|
+
limit: 10,
|
|
129
133
|
});
|
|
130
134
|
|
|
131
135
|
// Video search
|
|
132
136
|
const videoResults = await client.search({
|
|
133
|
-
query:
|
|
134
|
-
type:
|
|
135
|
-
limit: 3
|
|
137
|
+
query: "quantum computing explained",
|
|
138
|
+
type: "video",
|
|
139
|
+
limit: 3,
|
|
136
140
|
});
|
|
137
141
|
|
|
138
142
|
// News search
|
|
139
143
|
const newsResults = await client.search({
|
|
140
|
-
query:
|
|
141
|
-
type:
|
|
144
|
+
query: "artificial intelligence breakthroughs",
|
|
145
|
+
type: "news",
|
|
142
146
|
limit: 5,
|
|
143
|
-
page: 2
|
|
147
|
+
page: 2,
|
|
144
148
|
});
|
|
145
149
|
```
|
|
146
150
|
|
|
@@ -148,46 +152,49 @@ const newsResults = await client.search({
|
|
|
148
152
|
|
|
149
153
|
```javascript
|
|
150
154
|
// More concise syntax for common use cases
|
|
151
|
-
const webResults = await client.searchWeb(
|
|
152
|
-
const imageResults = await client.searchImages(
|
|
153
|
-
const videoResults = await client.searchVideos(
|
|
154
|
-
const newsResults = await client.searchNews(
|
|
155
|
+
const webResults = await client.searchWeb("space exploration", 10, 1);
|
|
156
|
+
const imageResults = await client.searchImages("natural landscapes", 15, 1);
|
|
157
|
+
const videoResults = await client.searchVideos("cooking tutorials", 5, 1);
|
|
158
|
+
const newsResults = await client.searchNews("technology trends", 8, 1);
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
### Complete Example with Error Handling
|
|
158
162
|
|
|
159
163
|
```javascript
|
|
160
|
-
import { LeonelSearchAPI } from
|
|
164
|
+
import { LeonelSearchAPI } from "leonelsearchapi";
|
|
161
165
|
|
|
162
|
-
const client = new LeonelSearchAPI({
|
|
163
|
-
apiKey:
|
|
166
|
+
const client = new LeonelSearchAPI({
|
|
167
|
+
apiKey: "your-api-key-here",
|
|
164
168
|
});
|
|
165
169
|
|
|
166
170
|
async function performComprehensiveSearch() {
|
|
167
171
|
try {
|
|
168
|
-
console.log(
|
|
169
|
-
|
|
172
|
+
console.log("=== Performing Multiple Search Types ===\n");
|
|
173
|
+
|
|
170
174
|
// Search for web results
|
|
171
|
-
const webSearch = await client.searchWeb(
|
|
172
|
-
console.log(
|
|
173
|
-
|
|
175
|
+
const webSearch = await client.searchWeb("renewable energy innovations", 3);
|
|
176
|
+
console.log("Web Results:", webSearch.results.length, "items found");
|
|
177
|
+
|
|
174
178
|
// Search for images
|
|
175
|
-
const imageSearch = await client.searchImages(
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
const imageSearch = await client.searchImages(
|
|
180
|
+
"solar panels installation",
|
|
181
|
+
4,
|
|
182
|
+
);
|
|
183
|
+
console.log("Image Results:", imageSearch.results.length, "items found");
|
|
184
|
+
|
|
178
185
|
// Search for news
|
|
179
|
-
const newsSearch = await client.searchNews(
|
|
180
|
-
console.log(
|
|
181
|
-
|
|
186
|
+
const newsSearch = await client.searchNews("climate policy updates", 5);
|
|
187
|
+
console.log("News Results:", newsSearch.results.length, "items found\n");
|
|
188
|
+
|
|
182
189
|
// Display sample results
|
|
183
|
-
console.log(
|
|
190
|
+
console.log("Sample News Headlines:");
|
|
184
191
|
newsSearch.results.slice(0, 3).forEach((result, index) => {
|
|
185
192
|
console.log(`${index + 1}. ${result.title}`);
|
|
186
193
|
});
|
|
187
|
-
|
|
194
|
+
|
|
188
195
|
return { webSearch, imageSearch, newsSearch };
|
|
189
196
|
} catch (error) {
|
|
190
|
-
console.error(
|
|
197
|
+
console.error("Search failed:", error.message);
|
|
191
198
|
throw error;
|
|
192
199
|
}
|
|
193
200
|
}
|
|
@@ -202,23 +209,31 @@ async function fetchPaginatedResults() {
|
|
|
202
209
|
const allResults = [];
|
|
203
210
|
let currentPage = 1;
|
|
204
211
|
const resultsPerPage = 10;
|
|
205
|
-
|
|
212
|
+
|
|
206
213
|
try {
|
|
207
214
|
// Fetch first page
|
|
208
|
-
let response = await client.searchNews(
|
|
215
|
+
let response = await client.searchNews(
|
|
216
|
+
"economic indicators",
|
|
217
|
+
resultsPerPage,
|
|
218
|
+
currentPage,
|
|
219
|
+
);
|
|
209
220
|
allResults.push(...response.results);
|
|
210
|
-
|
|
221
|
+
|
|
211
222
|
// Continue fetching while there are results
|
|
212
223
|
while (response.results.length === resultsPerPage) {
|
|
213
224
|
currentPage++;
|
|
214
|
-
response = await client.searchNews(
|
|
225
|
+
response = await client.searchNews(
|
|
226
|
+
"economic indicators",
|
|
227
|
+
resultsPerPage,
|
|
228
|
+
currentPage,
|
|
229
|
+
);
|
|
215
230
|
allResults.push(...response.results);
|
|
216
231
|
}
|
|
217
|
-
|
|
232
|
+
|
|
218
233
|
console.log(`Total results fetched: ${allResults.length}`);
|
|
219
234
|
return allResults;
|
|
220
235
|
} catch (error) {
|
|
221
|
-
console.error(
|
|
236
|
+
console.error("Pagination error:", error.message);
|
|
222
237
|
return allResults;
|
|
223
238
|
}
|
|
224
239
|
}
|
|
@@ -251,37 +266,50 @@ All search methods return results in a consistent format:
|
|
|
251
266
|
## Error Handling
|
|
252
267
|
|
|
253
268
|
```javascript
|
|
254
|
-
import { LeonelSearchAPI } from
|
|
269
|
+
import { LeonelSearchAPI } from "leonelsearchapi";
|
|
255
270
|
|
|
256
|
-
const client = new LeonelSearchAPI({ apiKey:
|
|
271
|
+
const client = new LeonelSearchAPI({ apiKey: "your-key" });
|
|
257
272
|
|
|
258
|
-
async function safeSearch(query, type =
|
|
273
|
+
async function safeSearch(query, type = "web") {
|
|
259
274
|
try {
|
|
260
275
|
const results = await client.search({ query, type });
|
|
261
276
|
return results;
|
|
262
277
|
} catch (error) {
|
|
263
278
|
// Handle specific error types
|
|
264
279
|
const errorMessage = error.message.toLowerCase();
|
|
265
|
-
|
|
266
|
-
if (errorMessage.includes(
|
|
267
|
-
console.error(
|
|
268
|
-
} else if (
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
280
|
+
|
|
281
|
+
if (errorMessage.includes("401") || errorMessage.includes("invalid api")) {
|
|
282
|
+
console.error("❌ Authentication failed. Please check your API key.");
|
|
283
|
+
} else if (
|
|
284
|
+
errorMessage.includes("429") ||
|
|
285
|
+
errorMessage.includes("rate limit")
|
|
286
|
+
) {
|
|
287
|
+
console.error(
|
|
288
|
+
"⏳ Rate limit exceeded. Please wait before making more requests.",
|
|
289
|
+
);
|
|
290
|
+
} else if (
|
|
291
|
+
errorMessage.includes("400") ||
|
|
292
|
+
errorMessage.includes("bad request")
|
|
293
|
+
) {
|
|
294
|
+
console.error(
|
|
295
|
+
"⚠️ Invalid request. Please check your search parameters.",
|
|
296
|
+
);
|
|
297
|
+
} else if (
|
|
298
|
+
errorMessage.includes("network") ||
|
|
299
|
+
errorMessage.includes("connection")
|
|
300
|
+
) {
|
|
301
|
+
console.error("🔌 Network error. Please check your internet connection.");
|
|
274
302
|
} else {
|
|
275
|
-
console.error(
|
|
303
|
+
console.error("💥 An unexpected error occurred:", error.message);
|
|
276
304
|
}
|
|
277
|
-
|
|
305
|
+
|
|
278
306
|
// Return empty results for graceful degradation
|
|
279
307
|
return { query, results: [] };
|
|
280
308
|
}
|
|
281
309
|
}
|
|
282
310
|
|
|
283
311
|
// Usage
|
|
284
|
-
const results = await safeSearch(
|
|
312
|
+
const results = await safeSearch("test query", "news");
|
|
285
313
|
```
|
|
286
314
|
|
|
287
315
|
---
|
|
@@ -291,9 +319,9 @@ const results = await safeSearch('test query', 'news');
|
|
|
291
319
|
The package includes full TypeScript definitions:
|
|
292
320
|
|
|
293
321
|
```typescript
|
|
294
|
-
import { LeonelSearchAPI, SearchResult, SearchParams } from
|
|
322
|
+
import { LeonelSearchAPI, SearchResult, SearchParams } from "leonelsearchapi";
|
|
295
323
|
|
|
296
|
-
const client = new LeonelSearchAPI({ apiKey:
|
|
324
|
+
const client = new LeonelSearchAPI({ apiKey: "your-key" });
|
|
297
325
|
|
|
298
326
|
// Type-safe search with main method
|
|
299
327
|
async function searchWithTypes(params: SearchParams) {
|
|
@@ -304,19 +332,19 @@ async function searchWithTypes(params: SearchParams) {
|
|
|
304
332
|
// Using convenience methods with type inference
|
|
305
333
|
async function convenienceExamples() {
|
|
306
334
|
// These methods are fully typed
|
|
307
|
-
const webResults = await client.searchWeb(
|
|
308
|
-
const imageResults = await client.searchImages(
|
|
309
|
-
const newsResults = await client.searchNews(
|
|
310
|
-
|
|
335
|
+
const webResults = await client.searchWeb("typescript tutorial", 5);
|
|
336
|
+
const imageResults = await client.searchImages("typescript logo", 10);
|
|
337
|
+
const newsResults = await client.searchNews("typescript updates", 8);
|
|
338
|
+
|
|
311
339
|
return { webResults, imageResults, newsResults };
|
|
312
340
|
}
|
|
313
341
|
|
|
314
342
|
// Type-safe parameter object
|
|
315
343
|
const searchParams: SearchParams = {
|
|
316
|
-
query:
|
|
317
|
-
type:
|
|
344
|
+
query: "typescript vs javascript",
|
|
345
|
+
type: "web", // TypeScript will validate this value
|
|
318
346
|
limit: 5,
|
|
319
|
-
page: 1
|
|
347
|
+
page: 1,
|
|
320
348
|
};
|
|
321
349
|
```
|
|
322
350
|
|
|
@@ -325,60 +353,65 @@ const searchParams: SearchParams = {
|
|
|
325
353
|
## Best Practices
|
|
326
354
|
|
|
327
355
|
### 1. **API Key Security**
|
|
356
|
+
|
|
328
357
|
```javascript
|
|
329
358
|
// Store API key in environment variables, not in code
|
|
330
|
-
const client = new LeonelSearchAPI({
|
|
331
|
-
apiKey: process.env.LEONELSEARCH_API_KEY
|
|
359
|
+
const client = new LeonelSearchAPI({
|
|
360
|
+
apiKey: process.env.LEONELSEARCH_API_KEY,
|
|
332
361
|
});
|
|
333
362
|
```
|
|
334
363
|
|
|
335
364
|
### 2. **Request Optimization**
|
|
365
|
+
|
|
336
366
|
```javascript
|
|
337
367
|
// Request only what you need
|
|
338
368
|
const optimalSearch = await client.search({
|
|
339
|
-
query:
|
|
340
|
-
type:
|
|
341
|
-
limit: 5
|
|
369
|
+
query: "specific topic",
|
|
370
|
+
type: "web",
|
|
371
|
+
limit: 5, // Smaller limits for faster responses
|
|
342
372
|
});
|
|
343
373
|
```
|
|
344
374
|
|
|
345
375
|
### 3. **Implement Caching**
|
|
376
|
+
|
|
346
377
|
```javascript
|
|
347
378
|
// Simple caching strategy
|
|
348
379
|
const searchCache = new Map();
|
|
349
380
|
|
|
350
|
-
async function cachedSearch(query, type =
|
|
381
|
+
async function cachedSearch(query, type = "web") {
|
|
351
382
|
const cacheKey = `${type}:${query}`;
|
|
352
|
-
|
|
383
|
+
|
|
353
384
|
if (searchCache.has(cacheKey)) {
|
|
354
385
|
return searchCache.get(cacheKey);
|
|
355
386
|
}
|
|
356
|
-
|
|
387
|
+
|
|
357
388
|
const results = await client.search({ query, type });
|
|
358
389
|
searchCache.set(cacheKey, results);
|
|
359
|
-
|
|
390
|
+
|
|
360
391
|
// Optional: Clear cache after some time
|
|
361
392
|
setTimeout(() => searchCache.delete(cacheKey), 300000); // 5 minutes
|
|
362
|
-
|
|
393
|
+
|
|
363
394
|
return results;
|
|
364
395
|
}
|
|
365
396
|
```
|
|
366
397
|
|
|
367
398
|
### 4. **Rate Limiting**
|
|
399
|
+
|
|
368
400
|
```javascript
|
|
369
401
|
// Implement request spacing
|
|
370
402
|
async function rateLimitedSearch(query, type) {
|
|
371
|
-
await new Promise(resolve => setTimeout(resolve, 1000)); // 1 second delay
|
|
403
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // 1 second delay
|
|
372
404
|
return client.search({ query, type });
|
|
373
405
|
}
|
|
374
406
|
```
|
|
375
407
|
|
|
376
408
|
### 5. **Batch Processing**
|
|
409
|
+
|
|
377
410
|
```javascript
|
|
378
411
|
// Process multiple searches efficiently
|
|
379
|
-
async function batchSearch(queries, type =
|
|
412
|
+
async function batchSearch(queries, type = "web") {
|
|
380
413
|
const results = [];
|
|
381
|
-
|
|
414
|
+
|
|
382
415
|
for (const query of queries) {
|
|
383
416
|
try {
|
|
384
417
|
const result = await client.search({ query, type, limit: 3 });
|
|
@@ -386,11 +419,11 @@ async function batchSearch(queries, type = 'web') {
|
|
|
386
419
|
} catch (error) {
|
|
387
420
|
results.push({ query, success: false, error: error.message });
|
|
388
421
|
}
|
|
389
|
-
|
|
422
|
+
|
|
390
423
|
// Delay between requests to respect rate limits
|
|
391
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
424
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
392
425
|
}
|
|
393
|
-
|
|
426
|
+
|
|
394
427
|
return results;
|
|
395
428
|
}
|
|
396
429
|
```
|
|
@@ -405,8 +438,8 @@ MIT © 2026 LeonelDev
|
|
|
405
438
|
|
|
406
439
|
## Support
|
|
407
440
|
|
|
408
|
-
For API key registration, documentation, and support, visit [leonelsearchapi.
|
|
441
|
+
For API key registration, documentation, and support, visit [leonelsearchapi.qzz.io](https://leonelsearchapi.qzz.io)
|
|
409
442
|
|
|
410
443
|
---
|
|
411
444
|
|
|
412
|
-
|
|
445
|
+
_Note: This is a beta release. API responses and features may change during development._
|