openai-and-claude-usage-report-generator 1.0.0

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,561 @@
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, 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('fetchOpenAICosts (OpenAI)', () => {
226
+ const mockCostsResponse = {
227
+ data: {
228
+ object: 'page',
229
+ data: [
230
+ {
231
+ object: 'bucket',
232
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
233
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
234
+ results: [
235
+ {
236
+ object: 'organization.costs.result',
237
+ amount: { value: 2.5, currency: 'USD' },
238
+ line_item: 'gpt-4',
239
+ project_id: 'proj_1',
240
+ },
241
+ ],
242
+ },
243
+ ],
244
+ has_more: false,
245
+ next_page: null,
246
+ },
247
+ };
248
+ beforeEach(() => {
249
+ vi.mocked(axios.get).mockResolvedValue(mockCostsResponse);
250
+ });
251
+ afterEach(() => {
252
+ vi.clearAllMocks();
253
+ });
254
+ it('calls organization/costs with correct headers and params', async () => {
255
+ const config = {
256
+ provider: 'openai',
257
+ startDate: '2024-01-01',
258
+ endDate: '2024-01-31',
259
+ apiKey: 'sk-openai',
260
+ orgId: 'org-x',
261
+ projectId: 'proj_y',
262
+ };
263
+ await fetchOpenAICosts(config);
264
+ expect(axios.get).toHaveBeenCalledWith(expect.stringContaining('/v1/organization/costs'), expect.objectContaining({
265
+ params: expect.objectContaining({
266
+ start_time: expect.any(Number),
267
+ end_time: expect.any(Number),
268
+ project_ids: ['proj_y'],
269
+ group_by: ['line_item'],
270
+ bucket_width: '1d',
271
+ limit: 180,
272
+ }),
273
+ headers: expect.objectContaining({
274
+ 'Authorization': 'Bearer sk-openai',
275
+ 'OpenAI-Organization': 'org-x',
276
+ }),
277
+ }));
278
+ });
279
+ it('returns CostBucket[] from response', async () => {
280
+ const config = {
281
+ provider: 'openai',
282
+ startDate: '2024-01-01',
283
+ endDate: '2024-01-31',
284
+ apiKey: 'sk-openai',
285
+ orgId: 'org-x',
286
+ projectId: 'proj_y',
287
+ };
288
+ const buckets = await fetchOpenAICosts(config);
289
+ expect(buckets).toHaveLength(1);
290
+ expect(buckets[0].results).toHaveLength(1);
291
+ expect(buckets[0].results[0].amount.value).toBe(2.5);
292
+ expect(buckets[0].results[0].line_item).toBe('gpt-4');
293
+ });
294
+ it('paginates when has_more is true', async () => {
295
+ const bucket1 = {
296
+ object: 'bucket',
297
+ start_time: new Date('2024-01-01T00:00:00Z').getTime() / 1000,
298
+ end_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
299
+ results: [
300
+ {
301
+ object: 'organization.costs.result',
302
+ amount: { value: 1, currency: 'USD' },
303
+ line_item: 'gpt-4',
304
+ project_id: 'proj_1',
305
+ },
306
+ ],
307
+ };
308
+ const bucket2 = {
309
+ ...bucket1,
310
+ start_time: new Date('2024-01-02T00:00:00Z').getTime() / 1000,
311
+ end_time: new Date('2024-01-03T00:00:00Z').getTime() / 1000,
312
+ };
313
+ vi.mocked(axios.get)
314
+ .mockResolvedValueOnce({
315
+ data: {
316
+ object: 'page',
317
+ data: [bucket1],
318
+ has_more: true,
319
+ next_page: 'page_2',
320
+ },
321
+ })
322
+ .mockResolvedValueOnce({
323
+ data: {
324
+ object: 'page',
325
+ data: [bucket2],
326
+ has_more: false,
327
+ next_page: null,
328
+ },
329
+ });
330
+ const config = {
331
+ provider: 'openai',
332
+ startDate: '2024-01-01',
333
+ endDate: '2024-01-31',
334
+ apiKey: 'sk-openai',
335
+ orgId: 'org-x',
336
+ projectId: 'proj_y',
337
+ };
338
+ const buckets = await fetchOpenAICosts(config);
339
+ expect(buckets).toHaveLength(2);
340
+ expect(axios.get).toHaveBeenCalledTimes(2);
341
+ expect(axios.get).toHaveBeenNthCalledWith(2, expect.any(String), expect.objectContaining({ params: expect.objectContaining({ page: 'page_2' }) }));
342
+ });
343
+ });
344
+ describe('fetchClaudeCosts', () => {
345
+ const mockCostReport = {
346
+ data: {
347
+ data: [
348
+ {
349
+ starting_at: '2024-01-01T00:00:00Z',
350
+ ending_at: '2024-01-02T00:00:00Z',
351
+ results: [
352
+ {
353
+ amount: '123.45',
354
+ currency: 'USD',
355
+ description: 'Claude Sonnet 4 Usage - Input Tokens',
356
+ model: 'claude-sonnet-4',
357
+ cost_type: 'tokens',
358
+ context_window: null,
359
+ token_type: null,
360
+ service_tier: null,
361
+ workspace_id: null,
362
+ },
363
+ ],
364
+ },
365
+ ],
366
+ has_more: false,
367
+ next_page: null,
368
+ },
369
+ };
370
+ beforeEach(() => {
371
+ vi.mocked(axios.get).mockResolvedValue(mockCostReport);
372
+ });
373
+ afterEach(() => {
374
+ vi.clearAllMocks();
375
+ });
376
+ it('calls cost_report with correct headers and params', async () => {
377
+ const config = {
378
+ provider: 'claude',
379
+ startDate: '2024-01-01',
380
+ endDate: '2024-01-31',
381
+ apiKey: 'sk-ant-admin-test',
382
+ };
383
+ await fetchClaudeCosts(config);
384
+ expect(axios.get).toHaveBeenCalledWith(expect.stringContaining('/v1/organizations/cost_report'), expect.objectContaining({
385
+ params: expect.objectContaining({
386
+ starting_at: '2024-01-01T00:00:00.000Z',
387
+ ending_at: '2024-01-31T00:00:00.000Z',
388
+ bucket_width: '1d',
389
+ limit: 31,
390
+ }),
391
+ headers: expect.objectContaining({
392
+ 'x-api-key': 'sk-ant-admin-test',
393
+ 'anthropic-version': '2023-06-01',
394
+ }),
395
+ }));
396
+ });
397
+ it('normalizes response: cents to dollars, description to line_item', async () => {
398
+ const config = {
399
+ provider: 'claude',
400
+ startDate: '2024-01-01',
401
+ endDate: '2024-01-31',
402
+ apiKey: 'sk-ant-admin-test',
403
+ };
404
+ const buckets = await fetchClaudeCosts(config);
405
+ expect(buckets).toHaveLength(1);
406
+ expect(buckets[0].results).toHaveLength(1);
407
+ expect(buckets[0].results[0].amount.value).toBeCloseTo(1.2345);
408
+ expect(buckets[0].results[0].line_item).toBe('Claude Sonnet 4 Usage - Input Tokens');
409
+ });
410
+ it('paginates when has_more is true', async () => {
411
+ vi.mocked(axios.get)
412
+ .mockResolvedValueOnce({
413
+ data: {
414
+ data: [
415
+ {
416
+ starting_at: '2024-01-01T00:00:00Z',
417
+ ending_at: '2024-01-02T00:00:00Z',
418
+ results: [
419
+ {
420
+ amount: '100',
421
+ currency: 'USD',
422
+ description: 'Page 1',
423
+ model: null,
424
+ cost_type: null,
425
+ context_window: null,
426
+ token_type: null,
427
+ service_tier: null,
428
+ workspace_id: null,
429
+ },
430
+ ],
431
+ },
432
+ ],
433
+ has_more: true,
434
+ next_page: 'cursor_2',
435
+ },
436
+ })
437
+ .mockResolvedValueOnce({
438
+ data: {
439
+ data: [
440
+ {
441
+ starting_at: '2024-01-02T00:00:00Z',
442
+ ending_at: '2024-01-03T00:00:00Z',
443
+ results: [
444
+ {
445
+ amount: '200',
446
+ currency: 'USD',
447
+ description: 'Page 2',
448
+ model: null,
449
+ cost_type: null,
450
+ context_window: null,
451
+ token_type: null,
452
+ service_tier: null,
453
+ workspace_id: null,
454
+ },
455
+ ],
456
+ },
457
+ ],
458
+ has_more: false,
459
+ next_page: null,
460
+ },
461
+ });
462
+ const config = {
463
+ provider: 'claude',
464
+ startDate: '2024-01-01',
465
+ endDate: '2024-01-31',
466
+ apiKey: 'sk-ant-admin-test',
467
+ };
468
+ const buckets = await fetchClaudeCosts(config);
469
+ expect(buckets).toHaveLength(2);
470
+ expect(axios.get).toHaveBeenCalledTimes(2);
471
+ expect(axios.get).toHaveBeenNthCalledWith(2, expect.any(String), expect.objectContaining({ params: expect.objectContaining({ page: 'cursor_2' }) }));
472
+ });
473
+ it('uses model + cost_type when description is null, else unknown', async () => {
474
+ vi.mocked(axios.get).mockResolvedValueOnce({
475
+ data: {
476
+ data: [
477
+ {
478
+ starting_at: '2024-01-01T00:00:00Z',
479
+ ending_at: '2024-01-02T00:00:00Z',
480
+ results: [
481
+ {
482
+ amount: '100',
483
+ currency: 'USD',
484
+ description: null,
485
+ model: 'claude-3-opus',
486
+ cost_type: 'tokens',
487
+ context_window: null,
488
+ token_type: null,
489
+ service_tier: null,
490
+ workspace_id: null,
491
+ },
492
+ {
493
+ amount: '50',
494
+ currency: 'USD',
495
+ description: null,
496
+ model: null,
497
+ cost_type: null,
498
+ context_window: null,
499
+ token_type: null,
500
+ service_tier: null,
501
+ workspace_id: null,
502
+ },
503
+ ],
504
+ },
505
+ ],
506
+ has_more: false,
507
+ next_page: null,
508
+ },
509
+ });
510
+ const config = {
511
+ provider: 'claude',
512
+ startDate: '2024-01-01',
513
+ endDate: '2024-01-31',
514
+ apiKey: 'sk-ant-admin-test',
515
+ };
516
+ const buckets = await fetchClaudeCosts(config);
517
+ expect(buckets[0].results[0].line_item).toBe('claude-3-opus tokens');
518
+ expect(buckets[0].results[1].line_item).toBe('unknown');
519
+ });
520
+ });
521
+ describe('writeReports', () => {
522
+ const aggregated = {
523
+ totalCost: 5,
524
+ startDate: '2024-01-01',
525
+ endDate: '2024-01-31',
526
+ projectId: 'proj_1',
527
+ dailyCosts: [{ date: '2024-01-01', lineItem: 'gpt-4', cost: 5 }],
528
+ costsByLineItem: new Map([['gpt-4', 5]]),
529
+ billingDays: 1,
530
+ averageDailyCost: 5,
531
+ };
532
+ it('writes to reports/openai when provider openai', () => {
533
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'usage-report-'));
534
+ try {
535
+ const { mdPath, csvPath } = writeReports(aggregated, 'org-x', 'openai', tmp);
536
+ expect(mdPath).toContain(path.join('reports', 'openai'));
537
+ expect(csvPath).toContain(path.join('reports', 'openai'));
538
+ expect(fs.existsSync(mdPath)).toBe(true);
539
+ expect(fs.existsSync(csvPath)).toBe(true);
540
+ expect(fs.readFileSync(mdPath, 'utf8')).toContain('# OpenAI API Usage Report');
541
+ }
542
+ finally {
543
+ fs.rmSync(tmp, { recursive: true });
544
+ }
545
+ });
546
+ it('writes to reports/claude when provider claude', () => {
547
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'usage-report-'));
548
+ try {
549
+ const { mdPath, csvPath } = writeReports(aggregated, 'default', 'claude', tmp);
550
+ expect(mdPath).toContain(path.join('reports', 'claude'));
551
+ expect(csvPath).toContain(path.join('reports', 'claude'));
552
+ expect(fs.existsSync(mdPath)).toBe(true);
553
+ expect(fs.existsSync(csvPath)).toBe(true);
554
+ expect(fs.readFileSync(mdPath, 'utf8')).toContain('# Claude API Usage Report');
555
+ }
556
+ finally {
557
+ fs.rmSync(tmp, { recursive: true });
558
+ }
559
+ });
560
+ });
561
+ //# 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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"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "openai-and-claude-usage-report-generator",
3
+ "version": "1.0.0",
4
+ "description": "OpenAI and Claude API Usage Report Generator - CLI tool and library for generating billing reports",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./cli": {
14
+ "import": "./dist/cli.js",
15
+ "types": "./dist/cli.d.ts"
16
+ }
17
+ },
18
+ "bin": {
19
+ "openai-and-claude-usage-report-generator": "./dist/cli.js",
20
+ "usage-report": "./dist/cli.js"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "scripts": {
27
+ "report": "tsx src/cli.ts",
28
+ "test": "vitest",
29
+ "test:ui": "vitest --ui",
30
+ "test:run": "vitest run",
31
+ "build": "tsc",
32
+ "postbuild": "node --input-type=module -e \"import fs from 'fs';const f='dist/cli.js';const c=fs.readFileSync(f,'utf8');fs.writeFileSync(f,'#!/usr/bin/env node\\n'+c.replace(/^#!.*\\n/,''))\"",
33
+ "prepublishOnly": "yarn test:run && yarn build"
34
+ },
35
+ "keywords": [
36
+ "openai",
37
+ "claude",
38
+ "anthropic",
39
+ "usage",
40
+ "report",
41
+ "billing",
42
+ "api",
43
+ "cost-tracking"
44
+ ],
45
+ "author": "",
46
+ "license": "ISC",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/ericdahl-dev/openai-and-claude-usage-report-generator.git"
50
+ },
51
+ "homepage": "https://github.com/ericdahl-dev/openai-and-claude-usage-report-generator#readme",
52
+ "bugs": {
53
+ "url": "https://github.com/ericdahl-dev/openai-and-claude-usage-report-generator/issues"
54
+ },
55
+ "dependencies": {
56
+ "axios": "^1.6.0",
57
+ "dotenv": "^17.2.3"
58
+ },
59
+ "devDependencies": {
60
+ "@types/node": "^20.19.28",
61
+ "@vitest/ui": "4.0.18",
62
+ "tsx": "^4.7.0",
63
+ "typescript": "^5.3.3",
64
+ "vitest": "^4.0.16"
65
+ }
66
+ }