firecrawl-cli 0.0.1 → 0.0.3

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.
Files changed (71) hide show
  1. package/dist/__tests__/commands/crawl.test.d.ts +5 -0
  2. package/dist/__tests__/commands/crawl.test.d.ts.map +1 -0
  3. package/dist/__tests__/commands/crawl.test.js +415 -0
  4. package/dist/__tests__/commands/crawl.test.js.map +1 -0
  5. package/dist/__tests__/commands/credit-usage.test.d.ts +5 -0
  6. package/dist/__tests__/commands/credit-usage.test.d.ts.map +1 -0
  7. package/dist/__tests__/commands/credit-usage.test.js +200 -0
  8. package/dist/__tests__/commands/credit-usage.test.js.map +1 -0
  9. package/dist/__tests__/commands/map.test.d.ts +5 -0
  10. package/dist/__tests__/commands/map.test.d.ts.map +1 -0
  11. package/dist/__tests__/commands/map.test.js +287 -0
  12. package/dist/__tests__/commands/map.test.js.map +1 -0
  13. package/dist/__tests__/commands/scrape.test.d.ts +5 -0
  14. package/dist/__tests__/commands/scrape.test.d.ts.map +1 -0
  15. package/dist/__tests__/commands/scrape.test.js +231 -0
  16. package/dist/__tests__/commands/scrape.test.js.map +1 -0
  17. package/dist/__tests__/utils/job.test.d.ts +5 -0
  18. package/dist/__tests__/utils/job.test.d.ts.map +1 -0
  19. package/dist/__tests__/utils/job.test.js +53 -0
  20. package/dist/__tests__/utils/job.test.js.map +1 -0
  21. package/dist/__tests__/utils/mock-client.d.ts +23 -0
  22. package/dist/__tests__/utils/mock-client.d.ts.map +1 -0
  23. package/dist/__tests__/utils/mock-client.js +24 -0
  24. package/dist/__tests__/utils/mock-client.js.map +1 -0
  25. package/dist/commands/config.d.ts.map +1 -1
  26. package/dist/commands/config.js +5 -3
  27. package/dist/commands/config.js.map +1 -1
  28. package/dist/commands/crawl.d.ts +13 -0
  29. package/dist/commands/crawl.d.ts.map +1 -0
  30. package/dist/commands/crawl.js +242 -0
  31. package/dist/commands/crawl.js.map +1 -0
  32. package/dist/commands/credit-usage.d.ts +32 -0
  33. package/dist/commands/credit-usage.d.ts.map +1 -0
  34. package/dist/commands/credit-usage.js +175 -0
  35. package/dist/commands/credit-usage.js.map +1 -0
  36. package/dist/commands/map.d.ts +13 -0
  37. package/dist/commands/map.d.ts.map +1 -0
  38. package/dist/commands/map.js +96 -0
  39. package/dist/commands/map.js.map +1 -0
  40. package/dist/commands/scrape.d.ts.map +1 -1
  41. package/dist/commands/scrape.js.map +1 -1
  42. package/dist/index.js +134 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/types/crawl.d.ts +63 -0
  45. package/dist/types/crawl.d.ts.map +1 -0
  46. package/dist/types/crawl.js +6 -0
  47. package/dist/types/crawl.js.map +1 -0
  48. package/dist/types/map.d.ts +43 -0
  49. package/dist/types/map.d.ts.map +1 -0
  50. package/dist/types/map.js +6 -0
  51. package/dist/types/map.js.map +1 -0
  52. package/dist/utils/client.d.ts.map +1 -1
  53. package/dist/utils/client.js.map +1 -1
  54. package/dist/utils/config.d.ts.map +1 -1
  55. package/dist/utils/config.js +7 -3
  56. package/dist/utils/config.js.map +1 -1
  57. package/dist/utils/credentials.d.ts.map +1 -1
  58. package/dist/utils/credentials.js.map +1 -1
  59. package/dist/utils/job.d.ts +13 -0
  60. package/dist/utils/job.d.ts.map +1 -0
  61. package/dist/utils/job.js +29 -0
  62. package/dist/utils/job.js.map +1 -0
  63. package/dist/utils/options.d.ts.map +1 -1
  64. package/dist/utils/options.js +6 -2
  65. package/dist/utils/options.js.map +1 -1
  66. package/dist/utils/output.d.ts.map +1 -1
  67. package/dist/utils/output.js +9 -2
  68. package/dist/utils/output.js.map +1 -1
  69. package/dist/utils/url.d.ts.map +1 -1
  70. package/dist/utils/url.js.map +1 -1
  71. package/package.json +19 -3
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for crawl command
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=crawl.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crawl.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/commands/crawl.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,415 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for crawl command
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const crawl_1 = require("../../commands/crawl");
8
+ const client_1 = require("../../utils/client");
9
+ const config_1 = require("../../utils/config");
10
+ const mock_client_1 = require("../utils/mock-client");
11
+ // Mock the Firecrawl client module
12
+ vitest_1.vi.mock('../../utils/client', async () => {
13
+ const actual = await vitest_1.vi.importActual('../../utils/client');
14
+ return {
15
+ ...actual,
16
+ getClient: vitest_1.vi.fn(),
17
+ };
18
+ });
19
+ (0, vitest_1.describe)('executeCrawl', () => {
20
+ let mockClient;
21
+ (0, vitest_1.beforeEach)(() => {
22
+ (0, mock_client_1.setupTest)();
23
+ // Initialize config with test API key
24
+ (0, config_1.initializeConfig)({
25
+ apiKey: 'test-api-key',
26
+ apiUrl: 'https://api.firecrawl.dev',
27
+ });
28
+ // Create mock client
29
+ mockClient = {
30
+ startCrawl: vitest_1.vi.fn(),
31
+ getCrawlStatus: vitest_1.vi.fn(),
32
+ crawl: vitest_1.vi.fn(),
33
+ };
34
+ // Mock getClient to return our mock
35
+ vitest_1.vi.mocked(client_1.getClient).mockReturnValue(mockClient);
36
+ });
37
+ (0, vitest_1.afterEach)(() => {
38
+ (0, mock_client_1.teardownTest)();
39
+ vitest_1.vi.clearAllMocks();
40
+ });
41
+ (0, vitest_1.describe)('Start crawl (async)', () => {
42
+ (0, vitest_1.it)('should call startCrawl with correct URL and return job ID', async () => {
43
+ const mockResponse = {
44
+ id: '550e8400-e29b-41d4-a716-446655440000',
45
+ url: 'https://example.com',
46
+ };
47
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
48
+ const result = await (0, crawl_1.executeCrawl)({
49
+ urlOrJobId: 'https://example.com',
50
+ });
51
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledTimes(1);
52
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', {});
53
+ (0, vitest_1.expect)(result).toEqual({
54
+ success: true,
55
+ data: {
56
+ jobId: mockResponse.id,
57
+ url: mockResponse.url,
58
+ status: 'processing',
59
+ },
60
+ });
61
+ });
62
+ (0, vitest_1.it)('should include limit option when provided', async () => {
63
+ const mockResponse = {
64
+ id: '550e8400-e29b-41d4-a716-446655440000',
65
+ url: 'https://example.com',
66
+ };
67
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
68
+ await (0, crawl_1.executeCrawl)({
69
+ urlOrJobId: 'https://example.com',
70
+ limit: 100,
71
+ });
72
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
73
+ limit: 100,
74
+ }));
75
+ });
76
+ (0, vitest_1.it)('should include maxDepth option when provided', async () => {
77
+ const mockResponse = {
78
+ id: '550e8400-e29b-41d4-a716-446655440000',
79
+ url: 'https://example.com',
80
+ };
81
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
82
+ await (0, crawl_1.executeCrawl)({
83
+ urlOrJobId: 'https://example.com',
84
+ maxDepth: 3,
85
+ });
86
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
87
+ maxDiscoveryDepth: 3,
88
+ }));
89
+ });
90
+ (0, vitest_1.it)('should include excludePaths option when provided', async () => {
91
+ const mockResponse = {
92
+ id: '550e8400-e29b-41d4-a716-446655440000',
93
+ url: 'https://example.com',
94
+ };
95
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
96
+ await (0, crawl_1.executeCrawl)({
97
+ urlOrJobId: 'https://example.com',
98
+ excludePaths: ['/admin', '/private'],
99
+ });
100
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
101
+ excludePaths: ['/admin', '/private'],
102
+ }));
103
+ });
104
+ (0, vitest_1.it)('should include includePaths option when provided', async () => {
105
+ const mockResponse = {
106
+ id: '550e8400-e29b-41d4-a716-446655440000',
107
+ url: 'https://example.com',
108
+ };
109
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
110
+ await (0, crawl_1.executeCrawl)({
111
+ urlOrJobId: 'https://example.com',
112
+ includePaths: ['/blog', '/docs'],
113
+ });
114
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
115
+ includePaths: ['/blog', '/docs'],
116
+ }));
117
+ });
118
+ (0, vitest_1.it)('should include sitemap option when provided', async () => {
119
+ const mockResponse = {
120
+ id: '550e8400-e29b-41d4-a716-446655440000',
121
+ url: 'https://example.com',
122
+ };
123
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
124
+ await (0, crawl_1.executeCrawl)({
125
+ urlOrJobId: 'https://example.com',
126
+ sitemap: 'skip',
127
+ });
128
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
129
+ sitemap: 'skip',
130
+ }));
131
+ });
132
+ (0, vitest_1.it)('should combine all options correctly', async () => {
133
+ const mockResponse = {
134
+ id: '550e8400-e29b-41d4-a716-446655440000',
135
+ url: 'https://example.com',
136
+ };
137
+ mockClient.startCrawl.mockResolvedValue(mockResponse);
138
+ await (0, crawl_1.executeCrawl)({
139
+ urlOrJobId: 'https://example.com',
140
+ limit: 50,
141
+ maxDepth: 2,
142
+ excludePaths: ['/admin'],
143
+ includePaths: ['/blog'],
144
+ sitemap: 'include',
145
+ ignoreQueryParameters: true,
146
+ crawlEntireDomain: false,
147
+ allowExternalLinks: false,
148
+ allowSubdomains: true,
149
+ delay: 1000,
150
+ maxConcurrency: 5,
151
+ });
152
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledWith('https://example.com', {
153
+ limit: 50,
154
+ maxDiscoveryDepth: 2,
155
+ excludePaths: ['/admin'],
156
+ includePaths: ['/blog'],
157
+ sitemap: 'include',
158
+ ignoreQueryParameters: true,
159
+ crawlEntireDomain: false,
160
+ allowExternalLinks: false,
161
+ allowSubdomains: true,
162
+ delay: 1000,
163
+ maxConcurrency: 5,
164
+ });
165
+ });
166
+ });
167
+ (0, vitest_1.describe)('Check crawl status', () => {
168
+ (0, vitest_1.it)('should check status when status flag is set', async () => {
169
+ const mockStatus = {
170
+ id: '550e8400-e29b-41d4-a716-446655440000',
171
+ status: 'completed',
172
+ total: 100,
173
+ completed: 100,
174
+ creditsUsed: 50,
175
+ expiresAt: '2024-12-31T23:59:59Z',
176
+ };
177
+ mockClient.getCrawlStatus.mockResolvedValue(mockStatus);
178
+ const result = await (0, crawl_1.executeCrawl)({
179
+ urlOrJobId: '550e8400-e29b-41d4-a716-446655440000',
180
+ status: true,
181
+ });
182
+ (0, vitest_1.expect)(mockClient.getCrawlStatus).toHaveBeenCalledTimes(1);
183
+ (0, vitest_1.expect)(mockClient.getCrawlStatus).toHaveBeenCalledWith('550e8400-e29b-41d4-a716-446655440000');
184
+ (0, vitest_1.expect)(result).toEqual({
185
+ success: true,
186
+ data: {
187
+ id: mockStatus.id,
188
+ status: mockStatus.status,
189
+ total: mockStatus.total,
190
+ completed: mockStatus.completed,
191
+ creditsUsed: mockStatus.creditsUsed,
192
+ expiresAt: mockStatus.expiresAt,
193
+ },
194
+ });
195
+ });
196
+ (0, vitest_1.it)('should auto-detect job ID from UUID format', async () => {
197
+ const mockStatus = {
198
+ id: '550e8400-e29b-41d4-a716-446655440000',
199
+ status: 'scraping',
200
+ total: 100,
201
+ completed: 45,
202
+ };
203
+ mockClient.getCrawlStatus.mockResolvedValue(mockStatus);
204
+ const result = await (0, crawl_1.executeCrawl)({
205
+ urlOrJobId: '550e8400-e29b-41d4-a716-446655440000',
206
+ });
207
+ (0, vitest_1.expect)(mockClient.getCrawlStatus).toHaveBeenCalledTimes(1);
208
+ (0, vitest_1.expect)(result.success).toBe(true);
209
+ });
210
+ (0, vitest_1.it)('should handle status check with missing optional fields', async () => {
211
+ const mockStatus = {
212
+ id: '550e8400-e29b-41d4-a716-446655440000',
213
+ status: 'scraping',
214
+ total: 100,
215
+ completed: 45,
216
+ };
217
+ mockClient.getCrawlStatus.mockResolvedValue(mockStatus);
218
+ const result = await (0, crawl_1.executeCrawl)({
219
+ urlOrJobId: '550e8400-e29b-41d4-a716-446655440000',
220
+ status: true,
221
+ });
222
+ (0, vitest_1.expect)(result.success).toBe(true);
223
+ if (result.success && 'data' in result) {
224
+ (0, vitest_1.expect)(result.data?.creditsUsed).toBeUndefined();
225
+ (0, vitest_1.expect)(result.data?.expiresAt).toBeUndefined();
226
+ }
227
+ });
228
+ });
229
+ (0, vitest_1.describe)('Wait mode (synchronous crawl)', () => {
230
+ (0, vitest_1.it)('should use crawl method with wait when wait flag is set', async () => {
231
+ const mockCrawlJob = {
232
+ id: '550e8400-e29b-41d4-a716-446655440000',
233
+ status: 'completed',
234
+ total: 100,
235
+ completed: 100,
236
+ data: [{ markdown: '# Page 1' }],
237
+ };
238
+ mockClient.crawl.mockResolvedValue(mockCrawlJob);
239
+ const result = await (0, crawl_1.executeCrawl)({
240
+ urlOrJobId: 'https://example.com',
241
+ wait: true,
242
+ });
243
+ (0, vitest_1.expect)(mockClient.crawl).toHaveBeenCalledTimes(1);
244
+ (0, vitest_1.expect)(mockClient.crawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
245
+ pollInterval: 5000, // Default poll interval
246
+ }));
247
+ (0, vitest_1.expect)(result).toEqual({
248
+ success: true,
249
+ data: mockCrawlJob,
250
+ });
251
+ });
252
+ (0, vitest_1.it)('should include custom pollInterval when provided', async () => {
253
+ const mockCrawlJob = {
254
+ id: '550e8400-e29b-41d4-a716-446655440000',
255
+ status: 'completed',
256
+ total: 100,
257
+ completed: 100,
258
+ data: [],
259
+ };
260
+ mockClient.crawl.mockResolvedValue(mockCrawlJob);
261
+ await (0, crawl_1.executeCrawl)({
262
+ urlOrJobId: 'https://example.com',
263
+ wait: true,
264
+ pollInterval: 10,
265
+ });
266
+ (0, vitest_1.expect)(mockClient.crawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
267
+ pollInterval: 10000, // Converted to milliseconds
268
+ }));
269
+ });
270
+ (0, vitest_1.it)('should include timeout when provided', async () => {
271
+ const mockCrawlJob = {
272
+ id: '550e8400-e29b-41d4-a716-446655440000',
273
+ status: 'completed',
274
+ total: 100,
275
+ completed: 100,
276
+ data: [],
277
+ };
278
+ mockClient.crawl.mockResolvedValue(mockCrawlJob);
279
+ await (0, crawl_1.executeCrawl)({
280
+ urlOrJobId: 'https://example.com',
281
+ wait: true,
282
+ timeout: 300,
283
+ });
284
+ (0, vitest_1.expect)(mockClient.crawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
285
+ timeout: 300000, // Converted to milliseconds
286
+ }));
287
+ });
288
+ (0, vitest_1.it)('should combine wait options with crawl options', async () => {
289
+ const mockCrawlJob = {
290
+ id: '550e8400-e29b-41d4-a716-446655440000',
291
+ status: 'completed',
292
+ total: 50,
293
+ completed: 50,
294
+ data: [],
295
+ };
296
+ mockClient.crawl.mockResolvedValue(mockCrawlJob);
297
+ await (0, crawl_1.executeCrawl)({
298
+ urlOrJobId: 'https://example.com',
299
+ wait: true,
300
+ pollInterval: 5,
301
+ timeout: 600,
302
+ limit: 50,
303
+ maxDepth: 2,
304
+ });
305
+ (0, vitest_1.expect)(mockClient.crawl).toHaveBeenCalledWith('https://example.com', vitest_1.expect.objectContaining({
306
+ pollInterval: 5000,
307
+ timeout: 600000,
308
+ limit: 50,
309
+ maxDiscoveryDepth: 2,
310
+ }));
311
+ });
312
+ });
313
+ (0, vitest_1.describe)('Progress mode', () => {
314
+ (0, vitest_1.beforeEach)(() => {
315
+ // Mock process.stderr.write to avoid console output during tests
316
+ vitest_1.vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
317
+ // Use fake timers to avoid actual waiting
318
+ vitest_1.vi.useFakeTimers();
319
+ });
320
+ (0, vitest_1.afterEach)(() => {
321
+ vitest_1.vi.restoreAllMocks();
322
+ vitest_1.vi.useRealTimers();
323
+ });
324
+ (0, vitest_1.it)('should use custom polling with progress when progress flag is set', async () => {
325
+ const jobId = '550e8400-e29b-41d4-a716-446655440000';
326
+ const mockStartResponse = {
327
+ id: jobId,
328
+ url: 'https://example.com',
329
+ };
330
+ const mockScrapingStatus = {
331
+ id: jobId,
332
+ status: 'scraping',
333
+ total: 100,
334
+ completed: 50,
335
+ data: [],
336
+ };
337
+ const mockCompletedStatus = {
338
+ id: jobId,
339
+ status: 'completed',
340
+ total: 100,
341
+ completed: 100,
342
+ data: [],
343
+ };
344
+ mockClient.startCrawl.mockResolvedValue(mockStartResponse);
345
+ // First call returns scraping status, second returns completed
346
+ mockClient.getCrawlStatus
347
+ .mockResolvedValueOnce(mockScrapingStatus)
348
+ .mockResolvedValueOnce(mockCompletedStatus);
349
+ // Start the async operation
350
+ const crawlPromise = (0, crawl_1.executeCrawl)({
351
+ urlOrJobId: 'https://example.com',
352
+ wait: true,
353
+ progress: true,
354
+ pollInterval: 0.001, // Very short interval for testing (1ms)
355
+ });
356
+ // Fast-forward timers to resolve the first setTimeout
357
+ await vitest_1.vi.advanceTimersByTimeAsync(1);
358
+ // Fast-forward again to resolve the second setTimeout
359
+ await vitest_1.vi.advanceTimersByTimeAsync(1);
360
+ const result = await crawlPromise;
361
+ (0, vitest_1.expect)(mockClient.startCrawl).toHaveBeenCalledTimes(1);
362
+ (0, vitest_1.expect)(mockClient.getCrawlStatus).toHaveBeenCalledTimes(2);
363
+ (0, vitest_1.expect)(result.success).toBe(true);
364
+ if (result.success && 'data' in result) {
365
+ (0, vitest_1.expect)(result.data.status).toBe('completed');
366
+ }
367
+ });
368
+ });
369
+ (0, vitest_1.describe)('Error handling', () => {
370
+ (0, vitest_1.it)('should return error result when startCrawl fails', async () => {
371
+ const errorMessage = 'API Error: Invalid URL';
372
+ mockClient.startCrawl.mockRejectedValue(new Error(errorMessage));
373
+ const result = await (0, crawl_1.executeCrawl)({
374
+ urlOrJobId: 'https://example.com',
375
+ });
376
+ (0, vitest_1.expect)(result).toEqual({
377
+ success: false,
378
+ error: errorMessage,
379
+ });
380
+ });
381
+ (0, vitest_1.it)('should return error result when getCrawlStatus fails', async () => {
382
+ const errorMessage = 'Job not found';
383
+ mockClient.getCrawlStatus.mockRejectedValue(new Error(errorMessage));
384
+ const result = await (0, crawl_1.executeCrawl)({
385
+ urlOrJobId: '550e8400-e29b-41d4-a716-446655440000',
386
+ status: true,
387
+ });
388
+ (0, vitest_1.expect)(result).toEqual({
389
+ success: false,
390
+ error: errorMessage,
391
+ });
392
+ });
393
+ (0, vitest_1.it)('should return error result when crawl fails', async () => {
394
+ const errorMessage = 'Crawl timeout';
395
+ mockClient.crawl.mockRejectedValue(new Error(errorMessage));
396
+ const result = await (0, crawl_1.executeCrawl)({
397
+ urlOrJobId: 'https://example.com',
398
+ wait: true,
399
+ });
400
+ (0, vitest_1.expect)(result).toEqual({
401
+ success: false,
402
+ error: errorMessage,
403
+ });
404
+ });
405
+ (0, vitest_1.it)('should handle non-Error exceptions', async () => {
406
+ mockClient.startCrawl.mockRejectedValue('String error');
407
+ const result = await (0, crawl_1.executeCrawl)({
408
+ urlOrJobId: 'https://example.com',
409
+ });
410
+ (0, vitest_1.expect)(result.success).toBe(false);
411
+ (0, vitest_1.expect)(result.error).toBe('Unknown error occurred');
412
+ });
413
+ });
414
+ });
415
+ //# sourceMappingURL=crawl.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crawl.test.js","sourceRoot":"","sources":["../../../src/__tests__/commands/crawl.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for credit-usage command
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=credit-usage.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-usage.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/commands/credit-usage.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for credit-usage command
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const credit_usage_1 = require("../../commands/credit-usage");
8
+ const config_1 = require("../../utils/config");
9
+ const mock_client_1 = require("../utils/mock-client");
10
+ // Mock global fetch
11
+ const mockFetch = vitest_1.vi.fn();
12
+ global.fetch = mockFetch;
13
+ (0, vitest_1.describe)('executeCreditUsage', () => {
14
+ (0, vitest_1.beforeEach)(() => {
15
+ (0, mock_client_1.setupTest)();
16
+ (0, config_1.initializeConfig)({
17
+ apiKey: 'test-api-key',
18
+ apiUrl: 'https://api.firecrawl.dev',
19
+ });
20
+ });
21
+ (0, vitest_1.afterEach)(() => {
22
+ (0, mock_client_1.teardownTest)();
23
+ vitest_1.vi.clearAllMocks();
24
+ });
25
+ (0, vitest_1.describe)('API call generation', () => {
26
+ (0, vitest_1.it)('should make GET request to correct endpoint', async () => {
27
+ const mockResponse = {
28
+ remainingCredits: 1000,
29
+ planCredits: 5000,
30
+ billingPeriodStart: '2024-01-01',
31
+ billingPeriodEnd: '2024-01-31',
32
+ };
33
+ mockFetch.mockResolvedValue({
34
+ ok: true,
35
+ json: async () => ({ data: mockResponse }),
36
+ });
37
+ await (0, credit_usage_1.executeCreditUsage)();
38
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledTimes(1);
39
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://api.firecrawl.dev/v2/team/credit-usage', {
40
+ method: 'GET',
41
+ headers: {
42
+ Authorization: 'Bearer test-api-key',
43
+ 'Content-Type': 'application/json',
44
+ },
45
+ });
46
+ });
47
+ (0, vitest_1.it)('should use custom API URL when provided', async () => {
48
+ (0, config_1.initializeConfig)({
49
+ apiKey: 'test-api-key',
50
+ apiUrl: 'https://custom-api.example.com',
51
+ });
52
+ mockFetch.mockResolvedValue({
53
+ ok: true,
54
+ json: async () => ({ data: { remainingCredits: 1000 } }),
55
+ });
56
+ await (0, credit_usage_1.executeCreditUsage)();
57
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://custom-api.example.com/v2/team/credit-usage', vitest_1.expect.any(Object));
58
+ });
59
+ (0, vitest_1.it)('should handle API URL with trailing slash', async () => {
60
+ (0, config_1.initializeConfig)({
61
+ apiKey: 'test-api-key',
62
+ apiUrl: 'https://api.firecrawl.dev/',
63
+ });
64
+ mockFetch.mockResolvedValue({
65
+ ok: true,
66
+ json: async () => ({ data: { remainingCredits: 1000 } }),
67
+ });
68
+ await (0, credit_usage_1.executeCreditUsage)();
69
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://api.firecrawl.dev/v2/team/credit-usage', vitest_1.expect.any(Object));
70
+ });
71
+ (0, vitest_1.it)('should include API key from options when provided', async () => {
72
+ (0, config_1.initializeConfig)({
73
+ apiKey: 'config-api-key',
74
+ apiUrl: 'https://api.firecrawl.dev',
75
+ });
76
+ mockFetch.mockResolvedValue({
77
+ ok: true,
78
+ json: async () => ({ data: { remainingCredits: 1000 } }),
79
+ });
80
+ await (0, credit_usage_1.executeCreditUsage)({ apiKey: 'option-api-key' });
81
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith(vitest_1.expect.any(String), vitest_1.expect.objectContaining({
82
+ headers: vitest_1.expect.objectContaining({
83
+ Authorization: 'Bearer option-api-key',
84
+ }),
85
+ }));
86
+ });
87
+ });
88
+ (0, vitest_1.describe)('Response handling', () => {
89
+ (0, vitest_1.it)('should return success result with credit data', async () => {
90
+ const mockData = {
91
+ remainingCredits: 1000,
92
+ planCredits: 5000,
93
+ billingPeriodStart: '2024-01-01T00:00:00Z',
94
+ billingPeriodEnd: '2024-01-31T23:59:59Z',
95
+ };
96
+ mockFetch.mockResolvedValue({
97
+ ok: true,
98
+ json: async () => ({ data: mockData }),
99
+ });
100
+ const result = await (0, credit_usage_1.executeCreditUsage)();
101
+ (0, vitest_1.expect)(result).toEqual({
102
+ success: true,
103
+ data: mockData,
104
+ });
105
+ });
106
+ (0, vitest_1.it)('should handle response with direct data (not nested)', async () => {
107
+ const mockData = {
108
+ remainingCredits: 500,
109
+ planCredits: 2000,
110
+ billingPeriodStart: null,
111
+ billingPeriodEnd: null,
112
+ };
113
+ mockFetch.mockResolvedValue({
114
+ ok: true,
115
+ json: async () => mockData,
116
+ });
117
+ const result = await (0, credit_usage_1.executeCreditUsage)();
118
+ (0, vitest_1.expect)(result).toEqual({
119
+ success: true,
120
+ data: mockData,
121
+ });
122
+ });
123
+ (0, vitest_1.it)('should handle HTTP error responses', async () => {
124
+ mockFetch.mockResolvedValue({
125
+ ok: false,
126
+ status: 401,
127
+ statusText: 'Unauthorized',
128
+ json: async () => ({ error: 'Invalid API key' }),
129
+ });
130
+ const result = await (0, credit_usage_1.executeCreditUsage)();
131
+ (0, vitest_1.expect)(result.success).toBe(false);
132
+ (0, vitest_1.expect)(result.error).toBe('Invalid API key');
133
+ });
134
+ (0, vitest_1.it)('should handle HTTP error without error message', async () => {
135
+ mockFetch.mockResolvedValue({
136
+ ok: false,
137
+ status: 500,
138
+ statusText: 'Internal Server Error',
139
+ json: async () => ({}),
140
+ });
141
+ const result = await (0, credit_usage_1.executeCreditUsage)();
142
+ (0, vitest_1.expect)(result.success).toBe(false);
143
+ (0, vitest_1.expect)(result.error).toBe('HTTP 500: Internal Server Error');
144
+ });
145
+ (0, vitest_1.it)('should handle network errors', async () => {
146
+ mockFetch.mockRejectedValue(new Error('Network error'));
147
+ const result = await (0, credit_usage_1.executeCreditUsage)();
148
+ (0, vitest_1.expect)(result.success).toBe(false);
149
+ (0, vitest_1.expect)(result.error).toBe('Network error');
150
+ });
151
+ (0, vitest_1.it)('should handle invalid JSON responses', async () => {
152
+ mockFetch.mockResolvedValue({
153
+ ok: false,
154
+ status: 500,
155
+ statusText: 'Internal Server Error',
156
+ json: async () => {
157
+ throw new Error('Invalid JSON');
158
+ },
159
+ });
160
+ const result = await (0, credit_usage_1.executeCreditUsage)();
161
+ (0, vitest_1.expect)(result.success).toBe(false);
162
+ (0, vitest_1.expect)(result.error).toBe('HTTP 500: Internal Server Error');
163
+ });
164
+ });
165
+ (0, vitest_1.describe)('Data extraction', () => {
166
+ (0, vitest_1.it)('should extract all required fields from response', async () => {
167
+ const mockData = {
168
+ remainingCredits: 1000,
169
+ planCredits: 5000,
170
+ billingPeriodStart: '2024-01-01',
171
+ billingPeriodEnd: '2024-01-31',
172
+ };
173
+ mockFetch.mockResolvedValue({
174
+ ok: true,
175
+ json: async () => ({ data: mockData }),
176
+ });
177
+ const result = await (0, credit_usage_1.executeCreditUsage)();
178
+ (0, vitest_1.expect)(result.data).toHaveProperty('remainingCredits', 1000);
179
+ (0, vitest_1.expect)(result.data).toHaveProperty('planCredits', 5000);
180
+ (0, vitest_1.expect)(result.data).toHaveProperty('billingPeriodStart', '2024-01-01');
181
+ (0, vitest_1.expect)(result.data).toHaveProperty('billingPeriodEnd', '2024-01-31');
182
+ });
183
+ (0, vitest_1.it)('should handle null billing period dates', async () => {
184
+ const mockData = {
185
+ remainingCredits: 1000,
186
+ planCredits: 5000,
187
+ billingPeriodStart: null,
188
+ billingPeriodEnd: null,
189
+ };
190
+ mockFetch.mockResolvedValue({
191
+ ok: true,
192
+ json: async () => ({ data: mockData }),
193
+ });
194
+ const result = await (0, credit_usage_1.executeCreditUsage)();
195
+ (0, vitest_1.expect)(result.data?.billingPeriodStart).toBeNull();
196
+ (0, vitest_1.expect)(result.data?.billingPeriodEnd).toBeNull();
197
+ });
198
+ });
199
+ });
200
+ //# sourceMappingURL=credit-usage.test.js.map