@ericdahl.dev/openai-and-claude-usage-report-generator 1.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.
@@ -0,0 +1,630 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import axios from 'axios';
3
+ import * as fs from 'fs';
4
+ import * as os from 'os';
5
+ import * as path from 'path';
6
+ import { aggregateCosts, fetchClaudeCosts, fetchOpenAICosts, generateCSVReport, generateJSONReport, generateMarkdownReport, loadConfig, parseDate, validateDateRange, writeReports, } from './usage-report.js';
7
+ import { parseArguments } from './cli.js';
8
+ vi.mock('axios');
9
+ describe('parseDate', () => {
10
+ it('parses valid YYYY-MM-DD', () => {
11
+ const d = parseDate('2024-01-15');
12
+ expect(d.toISOString().startsWith('2024-01-15')).toBe(true);
13
+ });
14
+ it('throws on invalid format', () => {
15
+ expect(() => parseDate('01-15-2024')).toThrow('Invalid date format');
16
+ expect(() => parseDate('2024/01/15')).toThrow('Invalid date format');
17
+ });
18
+ it('throws on invalid date', () => {
19
+ expect(() => parseDate('2024-02-30')).toThrow('Invalid date');
20
+ });
21
+ });
22
+ describe('validateDateRange', () => {
23
+ it('accepts end > start', () => {
24
+ expect(() => validateDateRange(parseDate('2024-01-01'), parseDate('2024-01-31'))).not.toThrow();
25
+ });
26
+ it('throws when end <= start', () => {
27
+ expect(() => validateDateRange(parseDate('2024-01-31'), parseDate('2024-01-01'))).toThrow('End date must be after start date');
28
+ expect(() => validateDateRange(parseDate('2024-01-15'), parseDate('2024-01-15'))).toThrow('End date must be after start date');
29
+ });
30
+ });
31
+ describe('parseArguments', () => {
32
+ const defaultArgv = ['node', 'report'];
33
+ function runWithArgv(args) {
34
+ const orig = process.argv;
35
+ process.argv = [...defaultArgv, ...args];
36
+ try {
37
+ return parseArguments();
38
+ }
39
+ finally {
40
+ process.argv = orig;
41
+ }
42
+ }
43
+ it('parses start and end only, default provider openai', () => {
44
+ expect(runWithArgv(['2024-01-01', '2024-01-31'])).toEqual({
45
+ startDate: '2024-01-01',
46
+ endDate: '2024-01-31',
47
+ provider: 'openai',
48
+ });
49
+ });
50
+ it('parses --provider claude', () => {
51
+ expect(runWithArgv(['2024-01-01', '2024-01-31', '--provider', 'claude'])).toEqual({
52
+ startDate: '2024-01-01',
53
+ endDate: '2024-01-31',
54
+ provider: 'claude',
55
+ });
56
+ });
57
+ it('parses --provider openai', () => {
58
+ expect(runWithArgv(['2024-01-01', '2024-01-31', '--provider', 'openai'])).toEqual({
59
+ startDate: '2024-01-01',
60
+ endDate: '2024-01-31',
61
+ provider: 'openai',
62
+ });
63
+ });
64
+ it('throws on invalid --provider', () => {
65
+ expect(() => runWithArgv(['2024-01-01', '2024-01-31', '--provider', 'gpt'])).toThrow('Invalid --provider');
66
+ });
67
+ it('throws when not exactly two date args', () => {
68
+ expect(() => runWithArgv(['2024-01-01'])).toThrow('Invalid arguments');
69
+ expect(() => runWithArgv(['2024-01-01', '2024-01-31', '2024-02-01'])).toThrow('Invalid arguments');
70
+ });
71
+ it('throws when dates invalid or range reversed', () => {
72
+ expect(() => runWithArgv(['2024-01-31', '2024-01-01'])).toThrow('End date must be after start date');
73
+ });
74
+ });
75
+ describe('loadConfig', () => {
76
+ const openaiVars = {
77
+ OPENAI_ADMIN_KEY: 'sk-openai',
78
+ OPENAI_ORG_ID: 'org-x',
79
+ OPENAI_PROJECT_ID: 'proj-y',
80
+ };
81
+ const claudeVar = { ANTHROPIC_ADMIN_API_KEY: 'sk-ant-admin-x' };
82
+ let savedEnv;
83
+ beforeEach(() => {
84
+ savedEnv = { ...process.env };
85
+ });
86
+ afterEach(() => {
87
+ process.env = savedEnv;
88
+ });
89
+ it('returns OpenAI config when provider openai and vars set', () => {
90
+ Object.assign(process.env, openaiVars);
91
+ const c = loadConfig('2024-01-01', '2024-01-31', 'openai');
92
+ expect(c).toMatchObject({
93
+ provider: 'openai',
94
+ startDate: '2024-01-01',
95
+ endDate: '2024-01-31',
96
+ apiKey: 'sk-openai',
97
+ orgId: 'org-x',
98
+ projectId: 'proj-y',
99
+ });
100
+ });
101
+ it('throws on missing OpenAI vars', () => {
102
+ delete process.env.OPENAI_ADMIN_KEY;
103
+ delete process.env.OPENAI_ORG_ID;
104
+ delete process.env.OPENAI_PROJECT_ID;
105
+ expect(() => loadConfig('2024-01-01', '2024-01-31', 'openai')).toThrow('Missing required environment variable');
106
+ process.env.OPENAI_ADMIN_KEY = 'sk';
107
+ expect(() => loadConfig('2024-01-01', '2024-01-31', 'openai')).toThrow('Missing required environment variable');
108
+ });
109
+ it('returns Claude config when provider claude and var set', () => {
110
+ process.env.ANTHROPIC_ADMIN_API_KEY = 'sk-ant-admin-x';
111
+ const c = loadConfig('2024-01-01', '2024-01-31', 'claude');
112
+ expect(c).toMatchObject({
113
+ provider: 'claude',
114
+ startDate: '2024-01-01',
115
+ endDate: '2024-01-31',
116
+ apiKey: 'sk-ant-admin-x',
117
+ });
118
+ expect(c).not.toHaveProperty('orgId');
119
+ expect(c).not.toHaveProperty('projectId');
120
+ });
121
+ it('throws on missing ANTHROPIC_ADMIN_API_KEY for Claude', () => {
122
+ delete process.env.ANTHROPIC_ADMIN_API_KEY;
123
+ expect(() => loadConfig('2024-01-01', '2024-01-31', 'claude')).toThrow('ANTHROPIC_ADMIN_API_KEY');
124
+ });
125
+ });
126
+ describe('aggregateCosts', () => {
127
+ it('aggregates OpenAI-style buckets', () => {
128
+ const buckets = [
129
+ {
130
+ object: 'bucket',
131
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
132
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
133
+ results: [
134
+ {
135
+ object: 'organization.costs.result',
136
+ amount: { value: 1.5, currency: 'USD' },
137
+ line_item: 'gpt-4',
138
+ project_id: 'proj_1',
139
+ },
140
+ {
141
+ object: 'organization.costs.result',
142
+ amount: { value: '0.5', currency: 'USD' },
143
+ line_item: 'gpt-3.5',
144
+ project_id: 'proj_1',
145
+ },
146
+ ],
147
+ },
148
+ ];
149
+ const a = aggregateCosts(buckets, '2024-01-01', '2024-01-31', 'proj_1');
150
+ expect(a.totalCost).toBe(2);
151
+ expect(a.billingDays).toBe(1);
152
+ expect(a.projectId).toBe('proj_1');
153
+ expect(a.costsByLineItem.get('gpt-4')).toBe(1.5);
154
+ expect(a.costsByLineItem.get('gpt-3.5')).toBe(0.5);
155
+ expect(a.dailyCosts).toHaveLength(2);
156
+ });
157
+ it('aggregates Claude-style normalized buckets (CostBucket shape)', () => {
158
+ const buckets = [
159
+ {
160
+ object: 'bucket',
161
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
162
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
163
+ results: [
164
+ {
165
+ object: 'organization.costs.result',
166
+ amount: { value: 1.2378, currency: 'USD' },
167
+ line_item: 'Claude Sonnet 4 Usage - Input Tokens',
168
+ project_id: null,
169
+ },
170
+ ],
171
+ },
172
+ ];
173
+ const a = aggregateCosts(buckets, '2024-01-01', '2024-01-31', 'default');
174
+ expect(a.totalCost).toBeCloseTo(1.2378);
175
+ expect(a.projectId).toBe('default');
176
+ expect(a.costsByLineItem.get('Claude Sonnet 4 Usage - Input Tokens')).toBeCloseTo(1.2378);
177
+ });
178
+ });
179
+ describe('generateMarkdownReport', () => {
180
+ const baseAggregated = {
181
+ totalCost: 10,
182
+ startDate: '2024-01-01',
183
+ endDate: '2024-01-31',
184
+ projectId: 'proj_1',
185
+ dailyCosts: [{ date: '2024-01-01', lineItem: 'gpt-4', cost: 10 }],
186
+ costsByLineItem: new Map([['gpt-4', 10]]),
187
+ billingDays: 1,
188
+ averageDailyCost: 10,
189
+ };
190
+ it('uses OpenAI title when provider openai', () => {
191
+ const md = generateMarkdownReport(baseAggregated, 'org-x', 'openai');
192
+ expect(md).toContain('# OpenAI API Usage Report');
193
+ expect(md).toContain('**Organization:** org-x');
194
+ });
195
+ it('uses Claude title when provider claude', () => {
196
+ const md = generateMarkdownReport(baseAggregated, 'default', 'claude');
197
+ expect(md).toContain('# Claude API Usage Report');
198
+ expect(md).toContain('**Organization:** default');
199
+ });
200
+ });
201
+ describe('generateCSVReport', () => {
202
+ it('emits date, line_item, cost_usd, project_id', () => {
203
+ const a = {
204
+ totalCost: 5,
205
+ startDate: '2024-01-01',
206
+ endDate: '2024-01-31',
207
+ projectId: 'default',
208
+ dailyCosts: [
209
+ { date: '2024-01-01', lineItem: 'gpt-4', cost: 3 },
210
+ { date: '2024-01-01', lineItem: 'gpt-3.5', cost: 2 },
211
+ ],
212
+ costsByLineItem: new Map([
213
+ ['gpt-4', 3],
214
+ ['gpt-3.5', 2],
215
+ ]),
216
+ billingDays: 1,
217
+ averageDailyCost: 5,
218
+ };
219
+ const csv = generateCSVReport(a);
220
+ expect(csv).toContain('date,line_item,cost_usd,project_id');
221
+ expect(csv).toContain('2024-01-01,gpt-3.5,2.00,default');
222
+ expect(csv).toContain('2024-01-01,gpt-4,3.00,default');
223
+ });
224
+ });
225
+ describe('generateJSONReport', () => {
226
+ it('generates valid JSON with all required fields', () => {
227
+ const a = {
228
+ totalCost: 5,
229
+ startDate: '2024-01-01',
230
+ endDate: '2024-01-31',
231
+ projectId: 'proj_1',
232
+ dailyCosts: [
233
+ { date: '2024-01-01', lineItem: 'gpt-4', cost: 3 },
234
+ { date: '2024-01-01', lineItem: 'gpt-3.5', cost: 2 },
235
+ ],
236
+ costsByLineItem: new Map([
237
+ ['gpt-4', 3],
238
+ ['gpt-3.5', 2],
239
+ ]),
240
+ billingDays: 1,
241
+ averageDailyCost: 5,
242
+ };
243
+ const json = generateJSONReport(a, 'org-x', 'openai');
244
+ const parsed = JSON.parse(json);
245
+ expect(parsed.metadata).toBeDefined();
246
+ expect(parsed.metadata.provider).toBe('openai');
247
+ expect(parsed.metadata.projectId).toBe('proj_1');
248
+ expect(parsed.metadata.organizationId).toBe('org-x');
249
+ expect(parsed.metadata.billingPeriod.startDate).toBe('2024-01-01');
250
+ expect(parsed.metadata.billingPeriod.endDate).toBe('2024-01-31');
251
+ expect(parsed.summary).toBeDefined();
252
+ expect(parsed.summary.totalCost).toBe(5);
253
+ expect(parsed.summary.billingDays).toBe(1);
254
+ expect(parsed.summary.averageDailyCost).toBe(5);
255
+ expect(parsed.costsByLineItem).toBeDefined();
256
+ expect(Array.isArray(parsed.costsByLineItem)).toBe(true);
257
+ expect(parsed.costsByLineItem.length).toBe(2);
258
+ expect(parsed.costsByLineItem[0].lineItem).toBe('gpt-4');
259
+ expect(parsed.costsByLineItem[0].cost).toBe(3);
260
+ expect(parsed.costsByLineItem[0].percentage).toBe(60);
261
+ expect(parsed.dailyBreakdown).toBeDefined();
262
+ expect(Array.isArray(parsed.dailyBreakdown)).toBe(true);
263
+ expect(parsed.dailyBreakdown.length).toBe(2);
264
+ expect(parsed.dailyTotals).toBeDefined();
265
+ expect(Array.isArray(parsed.dailyTotals)).toBe(true);
266
+ expect(parsed.dailyTotals.length).toBe(1);
267
+ expect(parsed.dailyTotals[0].date).toBe('2024-01-01');
268
+ expect(parsed.dailyTotals[0].total).toBe(5);
269
+ });
270
+ it('works with claude provider', () => {
271
+ const a = {
272
+ totalCost: 10,
273
+ startDate: '2024-01-01',
274
+ endDate: '2024-01-31',
275
+ projectId: 'default',
276
+ dailyCosts: [{ date: '2024-01-01', lineItem: 'claude-3-opus', cost: 10 }],
277
+ costsByLineItem: new Map([['claude-3-opus', 10]]),
278
+ billingDays: 1,
279
+ averageDailyCost: 10,
280
+ };
281
+ const json = generateJSONReport(a, 'default', 'claude');
282
+ const parsed = JSON.parse(json);
283
+ expect(parsed.metadata.provider).toBe('claude');
284
+ });
285
+ });
286
+ describe('fetchOpenAICosts (OpenAI)', () => {
287
+ const mockCostsResponse = {
288
+ data: {
289
+ object: 'page',
290
+ data: [
291
+ {
292
+ object: 'bucket',
293
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
294
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
295
+ results: [
296
+ {
297
+ object: 'organization.costs.result',
298
+ amount: { value: 2.5, currency: 'USD' },
299
+ line_item: 'gpt-4',
300
+ project_id: 'proj_1',
301
+ },
302
+ ],
303
+ },
304
+ ],
305
+ has_more: false,
306
+ next_page: null,
307
+ },
308
+ };
309
+ beforeEach(() => {
310
+ vi.mocked(axios.get).mockResolvedValue(mockCostsResponse);
311
+ });
312
+ afterEach(() => {
313
+ vi.clearAllMocks();
314
+ });
315
+ it('calls organization/costs with correct headers and params', async () => {
316
+ const config = {
317
+ provider: 'openai',
318
+ startDate: '2024-01-01',
319
+ endDate: '2024-01-31',
320
+ apiKey: 'sk-openai',
321
+ orgId: 'org-x',
322
+ projectId: 'proj_y',
323
+ };
324
+ await fetchOpenAICosts(config);
325
+ expect(axios.get).toHaveBeenCalledWith(expect.stringContaining('/v1/organization/costs'), expect.objectContaining({
326
+ params: expect.objectContaining({
327
+ start_time: expect.any(Number),
328
+ end_time: expect.any(Number),
329
+ project_ids: ['proj_y'],
330
+ group_by: ['line_item'],
331
+ bucket_width: '1d',
332
+ limit: 180,
333
+ }),
334
+ headers: expect.objectContaining({
335
+ 'Authorization': 'Bearer sk-openai',
336
+ 'OpenAI-Organization': 'org-x',
337
+ }),
338
+ }));
339
+ });
340
+ it('returns CostBucket[] from response', async () => {
341
+ const config = {
342
+ provider: 'openai',
343
+ startDate: '2024-01-01',
344
+ endDate: '2024-01-31',
345
+ apiKey: 'sk-openai',
346
+ orgId: 'org-x',
347
+ projectId: 'proj_y',
348
+ };
349
+ const buckets = await fetchOpenAICosts(config);
350
+ expect(buckets).toHaveLength(1);
351
+ expect(buckets[0].results).toHaveLength(1);
352
+ expect(buckets[0].results[0].amount.value).toBe(2.5);
353
+ expect(buckets[0].results[0].line_item).toBe('gpt-4');
354
+ });
355
+ it('paginates when has_more is true', async () => {
356
+ const bucket1 = {
357
+ object: 'bucket',
358
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
359
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
360
+ results: [
361
+ {
362
+ object: 'organization.costs.result',
363
+ amount: { value: 1, currency: 'USD' },
364
+ line_item: 'gpt-4',
365
+ project_id: 'proj_1',
366
+ },
367
+ ],
368
+ };
369
+ const bucket2 = {
370
+ ...bucket1,
371
+ start_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
372
+ end_time: new Date('2024-01-03T00:00:00Z').getTime() / 1000,
373
+ };
374
+ vi.mocked(axios.get)
375
+ .mockResolvedValueOnce({
376
+ data: {
377
+ object: 'page',
378
+ data: [bucket1],
379
+ has_more: true,
380
+ next_page: 'page_2',
381
+ },
382
+ })
383
+ .mockResolvedValueOnce({
384
+ data: {
385
+ object: 'page',
386
+ data: [bucket2],
387
+ has_more: false,
388
+ next_page: null,
389
+ },
390
+ });
391
+ const config = {
392
+ provider: 'openai',
393
+ startDate: '2024-01-01',
394
+ endDate: '2024-01-31',
395
+ apiKey: 'sk-openai',
396
+ orgId: 'org-x',
397
+ projectId: 'proj_y',
398
+ };
399
+ const buckets = await fetchOpenAICosts(config);
400
+ expect(buckets).toHaveLength(2);
401
+ expect(axios.get).toHaveBeenCalledTimes(2);
402
+ expect(axios.get).toHaveBeenNthCalledWith(2, expect.any(String), expect.objectContaining({ params: expect.objectContaining({ page: 'page_2' }) }));
403
+ });
404
+ });
405
+ describe('fetchClaudeCosts', () => {
406
+ const mockCostReport = {
407
+ data: {
408
+ data: [
409
+ {
410
+ starting_at: '2024-01-01T00:00:00Z',
411
+ ending_at: '2024-01-02T00:00:00Z',
412
+ results: [
413
+ {
414
+ amount: '123.45',
415
+ currency: 'USD',
416
+ description: 'Claude Sonnet 4 Usage - Input Tokens',
417
+ model: 'claude-sonnet-4',
418
+ cost_type: 'tokens',
419
+ context_window: null,
420
+ token_type: null,
421
+ service_tier: null,
422
+ workspace_id: null,
423
+ },
424
+ ],
425
+ },
426
+ ],
427
+ has_more: false,
428
+ next_page: null,
429
+ },
430
+ };
431
+ beforeEach(() => {
432
+ vi.mocked(axios.get).mockResolvedValue(mockCostReport);
433
+ });
434
+ afterEach(() => {
435
+ vi.clearAllMocks();
436
+ });
437
+ it('calls cost_report with correct headers and params', async () => {
438
+ const config = {
439
+ provider: 'claude',
440
+ startDate: '2024-01-01',
441
+ endDate: '2024-01-31',
442
+ apiKey: 'sk-ant-admin-test',
443
+ };
444
+ await fetchClaudeCosts(config);
445
+ expect(axios.get).toHaveBeenCalledWith(expect.stringContaining('/v1/organizations/cost_report'), expect.objectContaining({
446
+ params: expect.objectContaining({
447
+ starting_at: '2024-01-01T00:00:00.000Z',
448
+ ending_at: '2024-01-31T00:00:00.000Z',
449
+ bucket_width: '1d',
450
+ limit: 31,
451
+ }),
452
+ headers: expect.objectContaining({
453
+ 'x-api-key': 'sk-ant-admin-test',
454
+ 'anthropic-version': '2023-06-01',
455
+ }),
456
+ }));
457
+ });
458
+ it('normalizes response: cents to dollars, description to line_item', async () => {
459
+ const config = {
460
+ provider: 'claude',
461
+ startDate: '2024-01-01',
462
+ endDate: '2024-01-31',
463
+ apiKey: 'sk-ant-admin-test',
464
+ };
465
+ const buckets = await fetchClaudeCosts(config);
466
+ expect(buckets).toHaveLength(1);
467
+ expect(buckets[0].results).toHaveLength(1);
468
+ expect(buckets[0].results[0].amount.value).toBeCloseTo(1.2345);
469
+ expect(buckets[0].results[0].line_item).toBe('Claude Sonnet 4 Usage - Input Tokens');
470
+ });
471
+ it('paginates when has_more is true', async () => {
472
+ vi.mocked(axios.get)
473
+ .mockResolvedValueOnce({
474
+ data: {
475
+ data: [
476
+ {
477
+ starting_at: '2024-01-01T00:00:00Z',
478
+ ending_at: '2024-01-02T00:00:00Z',
479
+ results: [
480
+ {
481
+ amount: '100',
482
+ currency: 'USD',
483
+ description: 'Page 1',
484
+ model: null,
485
+ cost_type: null,
486
+ context_window: null,
487
+ token_type: null,
488
+ service_tier: null,
489
+ workspace_id: null,
490
+ },
491
+ ],
492
+ },
493
+ ],
494
+ has_more: true,
495
+ next_page: 'cursor_2',
496
+ },
497
+ })
498
+ .mockResolvedValueOnce({
499
+ data: {
500
+ data: [
501
+ {
502
+ starting_at: '2024-01-02T00:00:00Z',
503
+ ending_at: '2024-01-03T00:00:00Z',
504
+ results: [
505
+ {
506
+ amount: '200',
507
+ currency: 'USD',
508
+ description: 'Page 2',
509
+ model: null,
510
+ cost_type: null,
511
+ context_window: null,
512
+ token_type: null,
513
+ service_tier: null,
514
+ workspace_id: null,
515
+ },
516
+ ],
517
+ },
518
+ ],
519
+ has_more: false,
520
+ next_page: null,
521
+ },
522
+ });
523
+ const config = {
524
+ provider: 'claude',
525
+ startDate: '2024-01-01',
526
+ endDate: '2024-01-31',
527
+ apiKey: 'sk-ant-admin-test',
528
+ };
529
+ const buckets = await fetchClaudeCosts(config);
530
+ expect(buckets).toHaveLength(2);
531
+ expect(axios.get).toHaveBeenCalledTimes(2);
532
+ expect(axios.get).toHaveBeenNthCalledWith(2, expect.any(String), expect.objectContaining({ params: expect.objectContaining({ page: 'cursor_2' }) }));
533
+ });
534
+ it('uses model + cost_type when description is null, else unknown', async () => {
535
+ vi.mocked(axios.get).mockResolvedValueOnce({
536
+ data: {
537
+ data: [
538
+ {
539
+ starting_at: '2024-01-01T00:00:00Z',
540
+ ending_at: '2024-01-02T00:00:00Z',
541
+ results: [
542
+ {
543
+ amount: '100',
544
+ currency: 'USD',
545
+ description: null,
546
+ model: 'claude-3-opus',
547
+ cost_type: 'tokens',
548
+ context_window: null,
549
+ token_type: null,
550
+ service_tier: null,
551
+ workspace_id: null,
552
+ },
553
+ {
554
+ amount: '50',
555
+ currency: 'USD',
556
+ description: null,
557
+ model: null,
558
+ cost_type: null,
559
+ context_window: null,
560
+ token_type: null,
561
+ service_tier: null,
562
+ workspace_id: null,
563
+ },
564
+ ],
565
+ },
566
+ ],
567
+ has_more: false,
568
+ next_page: null,
569
+ },
570
+ });
571
+ const config = {
572
+ provider: 'claude',
573
+ startDate: '2024-01-01',
574
+ endDate: '2024-01-31',
575
+ apiKey: 'sk-ant-admin-test',
576
+ };
577
+ const buckets = await fetchClaudeCosts(config);
578
+ expect(buckets[0].results[0].line_item).toBe('claude-3-opus tokens');
579
+ expect(buckets[0].results[1].line_item).toBe('unknown');
580
+ });
581
+ });
582
+ describe('writeReports', () => {
583
+ const aggregated = {
584
+ totalCost: 5,
585
+ startDate: '2024-01-01',
586
+ endDate: '2024-01-31',
587
+ projectId: 'proj_1',
588
+ dailyCosts: [{ date: '2024-01-01', lineItem: 'gpt-4', cost: 5 }],
589
+ costsByLineItem: new Map([['gpt-4', 5]]),
590
+ billingDays: 1,
591
+ averageDailyCost: 5,
592
+ };
593
+ it('writes to reports/openai when provider openai', () => {
594
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'usage-report-'));
595
+ try {
596
+ const { mdPath, csvPath, jsonPath } = writeReports(aggregated, 'org-x', 'openai', tmp);
597
+ expect(mdPath).toContain(path.join('reports', 'openai'));
598
+ expect(csvPath).toContain(path.join('reports', 'openai'));
599
+ expect(jsonPath).toContain(path.join('reports', 'openai'));
600
+ expect(fs.existsSync(mdPath)).toBe(true);
601
+ expect(fs.existsSync(csvPath)).toBe(true);
602
+ expect(fs.existsSync(jsonPath)).toBe(true);
603
+ expect(fs.readFileSync(mdPath, 'utf8')).toContain('# OpenAI API Usage Report');
604
+ const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
605
+ expect(json.metadata.provider).toBe('openai');
606
+ }
607
+ finally {
608
+ fs.rmSync(tmp, { recursive: true });
609
+ }
610
+ });
611
+ it('writes to reports/claude when provider claude', () => {
612
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'usage-report-'));
613
+ try {
614
+ const { mdPath, csvPath, jsonPath } = writeReports(aggregated, 'default', 'claude', tmp);
615
+ expect(mdPath).toContain(path.join('reports', 'claude'));
616
+ expect(csvPath).toContain(path.join('reports', 'claude'));
617
+ expect(jsonPath).toContain(path.join('reports', 'claude'));
618
+ expect(fs.existsSync(mdPath)).toBe(true);
619
+ expect(fs.existsSync(csvPath)).toBe(true);
620
+ expect(fs.existsSync(jsonPath)).toBe(true);
621
+ expect(fs.readFileSync(mdPath, 'utf8')).toContain('# Claude API Usage Report');
622
+ const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
623
+ expect(json.metadata.provider).toBe('claude');
624
+ }
625
+ finally {
626
+ fs.rmSync(tmp, { recursive: true });
627
+ }
628
+ });
629
+ });
630
+ //# sourceMappingURL=usage-report.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-report.test.js","sourceRoot":"","sources":["../src/usage-report.test.ts"],"names":[],"mappings":"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"}