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.
package/README.md ADDED
@@ -0,0 +1,222 @@
1
+ # OpenAI and Claude Usage Report Generator
2
+
3
+ A CLI tool and library for generating billing reports from the **OpenAI** or **Claude (Anthropic)** cost APIs. Outputs Markdown (readable) and CSV (data) reports.
4
+
5
+ Can be used as:
6
+ - **CLI tool**: Run reports from the command line
7
+ - **Library**: Import functions programmatically in your Node.js/TypeScript projects
8
+
9
+ ## Features
10
+
11
+ - Fetches usage/cost data from OpenAI's organization costs API or Anthropic's [Usage and Cost API](https://platform.claude.com/docs/en/build-with-claude/usage-cost-api)
12
+ - Generates detailed Markdown reports with summaries and breakdowns
13
+ - Exports CSV data for further analysis
14
+ - Daily and line-item cost breakdowns
15
+
16
+ ## Prerequisites
17
+
18
+ - Node.js 18+ and Yarn (`.nvmrc` specifies 22)
19
+ - **OpenAI**: API admin key, Organization ID, and Project ID
20
+ - **Claude**: Anthropic **Admin API key** (`sk-ant-admin...`). Standard API keys do not work; create one in [Console → Settings → Admin keys](https://console.anthropic.com/settings/admin-keys).
21
+
22
+ ## Installation
23
+
24
+ ### As a CLI Tool (Development)
25
+
26
+ ```bash
27
+ git clone <repository-url>
28
+ cd openai-and-claude-usage-report-generator
29
+ yarn install
30
+ ```
31
+
32
+ ### As an npm Package (Library)
33
+
34
+ ```bash
35
+ yarn add openai-and-claude-usage-report-generator
36
+ # or
37
+ npm install openai-and-claude-usage-report-generator
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ Create a `.env` file in the root directory (see `.env.example` for a template).
43
+
44
+ **OpenAI** (default):
45
+
46
+ ```env
47
+ OPENAI_ADMIN_KEY=sk-...
48
+ OPENAI_ORG_ID=org-...
49
+ OPENAI_PROJECT_ID=proj_...
50
+ ```
51
+
52
+ **Claude**:
53
+
54
+ ```env
55
+ ANTHROPIC_ADMIN_API_KEY=sk-ant-admin-...
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ ### CLI Usage
61
+
62
+ Generate a report for a date range. Default provider is OpenAI.
63
+
64
+ ```bash
65
+ yarn report 2024-01-01 2024-01-31
66
+ yarn report 2024-01-01 2024-01-31 --provider openai
67
+ yarn report 2024-01-01 2024-01-31 --provider claude
68
+ ```
69
+
70
+ ### Library Usage
71
+
72
+ Import and use the functions programmatically in your code:
73
+
74
+ ```typescript
75
+ import {
76
+ fetchOpenAICosts,
77
+ fetchClaudeCosts,
78
+ aggregateCosts,
79
+ generateMarkdownReport,
80
+ generateCSVReport,
81
+ writeReports,
82
+ parseDate,
83
+ validateDateRange,
84
+ loadConfig,
85
+ } from 'openai-and-claude-usage-report-generator';
86
+ import type { OpenAIReportConfig, ClaudeReportConfig } from 'openai-and-claude-usage-report-generator';
87
+
88
+ // Example: Fetch and process OpenAI costs
89
+ async function generateOpenAIReport() {
90
+ const config: OpenAIReportConfig = {
91
+ provider: 'openai',
92
+ startDate: '2024-01-01',
93
+ endDate: '2024-01-31',
94
+ apiKey: process.env.OPENAI_ADMIN_KEY!,
95
+ orgId: process.env.OPENAI_ORG_ID!,
96
+ projectId: process.env.OPENAI_PROJECT_ID!,
97
+ };
98
+
99
+ // Fetch cost data
100
+ const buckets = await fetchOpenAICosts(config);
101
+
102
+ // Aggregate the data
103
+ const aggregated = aggregateCosts(
104
+ buckets,
105
+ config.startDate,
106
+ config.endDate,
107
+ config.projectId
108
+ );
109
+
110
+ // Generate reports
111
+ const markdown = generateMarkdownReport(aggregated, config.orgId, 'openai');
112
+ const csv = generateCSVReport(aggregated);
113
+
114
+ // Or write directly to files
115
+ const { mdPath, csvPath } = writeReports(aggregated, config.orgId, 'openai');
116
+
117
+ console.log(`Reports written to ${mdPath} and ${csvPath}`);
118
+ }
119
+
120
+ // Example: Fetch and process Claude costs
121
+ async function generateClaudeReport() {
122
+ const config: ClaudeReportConfig = {
123
+ provider: 'claude',
124
+ startDate: '2024-01-01',
125
+ endDate: '2024-01-31',
126
+ apiKey: process.env.ANTHROPIC_ADMIN_API_KEY!,
127
+ };
128
+
129
+ const buckets = await fetchClaudeCosts(config);
130
+ const aggregated = aggregateCosts(buckets, config.startDate, config.endDate, 'default');
131
+ const markdown = generateMarkdownReport(aggregated, 'default', 'claude');
132
+
133
+ console.log(markdown);
134
+ }
135
+ ```
136
+
137
+ **Note**: When using as a library, you need to handle environment variables yourself. The `loadConfig` function is available but requires environment variables to be set, or you can construct the config objects directly as shown above.
138
+
139
+ ## Output
140
+
141
+ - **OpenAI**: `reports/openai/`
142
+ - **Claude**: `reports/claude/`
143
+
144
+ Each run produces:
145
+
146
+ - `usage-YYYY-MM-DD-to-YYYY-MM-DD.md` – Human-readable Markdown report
147
+ - `usage-YYYY-MM-DD-to-YYYY-MM-DD.csv` – CSV data export
148
+
149
+ ## Report Contents
150
+
151
+ The Markdown report includes:
152
+
153
+ - **Summary**: Total cost, billing days, average daily cost
154
+ - **Cost by Model/Service**: Breakdown by line item with percentages
155
+ - **Daily Usage Breakdown**: Detailed daily costs by model/service
156
+ - **Total by Day**: Daily totals for quick overview
157
+
158
+ The CSV export contains:
159
+ - Date, line item, cost (USD), and project ID for each entry
160
+
161
+ ## API Reference
162
+
163
+ ### Core Functions
164
+
165
+ #### `fetchOpenAICosts(config: OpenAIReportConfig): Promise<CostBucket[]>`
166
+ Fetches cost data from OpenAI's organization costs API. Returns an array of cost buckets.
167
+
168
+ #### `fetchClaudeCosts(config: ClaudeReportConfig): Promise<CostBucket[]>`
169
+ Fetches cost data from Anthropic's cost report API. Returns an array of cost buckets (normalized to match OpenAI format).
170
+
171
+ #### `aggregateCosts(buckets: CostBucket[], startDate: string, endDate: string, projectId: string): AggregatedCosts`
172
+ Aggregates cost buckets into a structured format with totals, daily breakdowns, and line item summaries.
173
+
174
+ #### `generateMarkdownReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string`
175
+ Generates a human-readable Markdown report from aggregated costs.
176
+
177
+ #### `generateCSVReport(aggregated: AggregatedCosts): string`
178
+ Generates a CSV report from aggregated costs.
179
+
180
+ #### `writeReports(aggregated: AggregatedCosts, orgId: string, provider: Provider, baseDir?: string): { mdPath: string; csvPath: string }`
181
+ Writes both Markdown and CSV reports to disk. Returns paths to the generated files.
182
+
183
+ ### Utility Functions
184
+
185
+ #### `parseDate(dateStr: string): Date`
186
+ Parses a date string in YYYY-MM-DD format and returns a Date object.
187
+
188
+ #### `validateDateRange(start: Date, end: Date): void`
189
+ Validates that the end date is after the start date. Throws an error if invalid.
190
+
191
+ #### `loadConfig(startDate: string, endDate: string, provider: Provider): ReportConfig`
192
+ Loads configuration from environment variables. Requires appropriate env vars to be set based on provider.
193
+
194
+ ### Types
195
+
196
+ All TypeScript types are exported. Key types include:
197
+ - `OpenAIReportConfig` - Configuration for OpenAI API
198
+ - `ClaudeReportConfig` - Configuration for Claude API
199
+ - `AggregatedCosts` - Aggregated cost data structure
200
+ - `CostBucket` - Individual cost bucket from API
201
+ - `DailyCost` - Daily cost entry
202
+ - `Provider` - Union type: `'openai' | 'claude'`
203
+
204
+ ## Development
205
+
206
+ ### Running Tests
207
+
208
+ ```bash
209
+ yarn test # watch mode
210
+ yarn test:run # single run (used by CI)
211
+ ```
212
+
213
+ ### Building
214
+
215
+ ```bash
216
+ yarn build
217
+ ```
218
+
219
+ ### CI
220
+
221
+ GitHub Actions runs on push and pull requests to `main`: `yarn install --frozen-lockfile`, `yarn test:run`, then `yarn build`. See [.github/workflows/ci.yml](.github/workflows/ci.yml).
222
+
package/dist/cli.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * CLI Entry Point
4
+ *
5
+ * Command-line interface for generating usage reports.
6
+ * Imports functionality from the library entry point.
7
+ *
8
+ * Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]
9
+ */
10
+ import 'dotenv/config';
11
+ import { type Provider } from './index.js';
12
+ export declare function parseArguments(): {
13
+ startDate: string;
14
+ endDate: string;
15
+ provider: Provider;
16
+ };
17
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,EASL,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AAOpB,wBAAgB,cAAc,IAAI;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAyB3F"}
package/dist/cli.js ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point
4
+ *
5
+ * Command-line interface for generating usage reports.
6
+ * Imports functionality from the library entry point.
7
+ *
8
+ * Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]
9
+ */
10
+ import 'dotenv/config';
11
+ import { fetchOpenAICosts, fetchClaudeCosts, aggregateCosts, writeReports, loadConfig, parseDate, validateDateRange, } from './index.js';
12
+ const USAGE = 'Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]\n' +
13
+ 'Example: yarn report 2024-01-01 2024-01-31\n' +
14
+ 'Example: yarn report 2024-01-01 2024-01-31 --provider claude';
15
+ export function parseArguments() {
16
+ const args = process.argv.slice(2);
17
+ const providerIdx = args.indexOf('--provider');
18
+ const providerArg = providerIdx >= 0 && args[providerIdx + 1] != null ? args[providerIdx + 1] : null;
19
+ const filtered = providerIdx < 0
20
+ ? args
21
+ : args.filter((_, i) => i !== providerIdx && i !== providerIdx + 1);
22
+ if (filtered.length !== 2) {
23
+ throw new Error(`Invalid arguments\n${USAGE}`);
24
+ }
25
+ const provider = providerArg === 'claude' ? 'claude' : providerArg === 'openai' ? 'openai' : 'openai';
26
+ if (providerArg != null && providerArg !== 'openai' && providerArg !== 'claude') {
27
+ throw new Error(`Invalid --provider: ${providerArg}. Use openai or claude.\n${USAGE}`);
28
+ }
29
+ const [startDate, endDate] = filtered;
30
+ const start = parseDate(startDate);
31
+ const end = parseDate(endDate);
32
+ validateDateRange(start, end);
33
+ return { startDate, endDate, provider };
34
+ }
35
+ function displayTerminalSummary(aggregated, mdPath, csvPath, provider) {
36
+ const title = provider === 'claude' ? 'Claude API Usage Report' : 'OpenAI API Usage Report';
37
+ console.log(title);
38
+ console.log('=======================');
39
+ console.log(`Period: ${aggregated.startDate} to ${aggregated.endDate}`);
40
+ console.log(`Project: ${aggregated.projectId}\n`);
41
+ console.log(`Total Cost: $${aggregated.totalCost.toFixed(2)} USD`);
42
+ console.log(`Total Days: ${aggregated.billingDays}`);
43
+ console.log(`Average Daily Cost: $${aggregated.averageDailyCost.toFixed(2)}\n`);
44
+ if (aggregated.costsByLineItem.size > 0) {
45
+ console.log('Top Models/Services:');
46
+ const sortedLineItems = Array.from(aggregated.costsByLineItem.entries())
47
+ .sort((a, b) => b[1] - a[1])
48
+ .slice(0, 5);
49
+ for (const [lineItem, cost] of sortedLineItems) {
50
+ console.log(` ${lineItem}: $${cost.toFixed(2)}`);
51
+ }
52
+ console.log('');
53
+ }
54
+ console.log('Reports generated:');
55
+ console.log(` - ${mdPath}`);
56
+ console.log(` - ${csvPath}`);
57
+ }
58
+ async function main() {
59
+ try {
60
+ const { startDate, endDate, provider } = parseArguments();
61
+ const config = loadConfig(startDate, endDate, provider);
62
+ const title = provider === 'claude' ? 'Claude API Usage Report' : 'OpenAI API Usage Report';
63
+ console.log(title);
64
+ console.log('=======================\n');
65
+ console.log(`Fetching costs from ${startDate} to ${endDate}...`);
66
+ const buckets = config.provider === 'openai'
67
+ ? await fetchOpenAICosts(config)
68
+ : await fetchClaudeCosts(config);
69
+ console.log(`Received ${buckets.length} daily buckets\n`);
70
+ const projectId = config.provider === 'openai' ? config.projectId : 'default';
71
+ const orgId = config.provider === 'openai' ? config.orgId : 'default';
72
+ const aggregated = aggregateCosts(buckets, startDate, endDate, projectId);
73
+ const { mdPath, csvPath } = writeReports(aggregated, orgId, provider);
74
+ console.log('');
75
+ displayTerminalSummary(aggregated, mdPath, csvPath, provider);
76
+ }
77
+ catch (error) {
78
+ if (error instanceof Error) {
79
+ console.error('Error:', error.message);
80
+ if (error.message.includes('OPENAI_ADMIN_KEY')) {
81
+ console.error('\nHint: Make sure OPENAI_ADMIN_KEY is set in your environment.');
82
+ }
83
+ else if (error.message.includes('OPENAI_ORG_ID')) {
84
+ console.error('\nHint: Make sure OPENAI_ORG_ID is set in your environment.');
85
+ }
86
+ else if (error.message.includes('OPENAI_PROJECT_ID')) {
87
+ console.error('\nHint: Make sure OPENAI_PROJECT_ID is set in your environment.');
88
+ }
89
+ else if (error.message.includes('ANTHROPIC_ADMIN_API_KEY')) {
90
+ console.error('\nHint: Make sure ANTHROPIC_ADMIN_API_KEY is set in your environment.');
91
+ }
92
+ }
93
+ process.exit(1);
94
+ }
95
+ }
96
+ if (!process.env.VITEST) {
97
+ main().catch((error) => {
98
+ console.error('Unexpected error:', error);
99
+ process.exit(1);
100
+ });
101
+ }
102
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,SAAS,EACT,iBAAiB,GAGlB,MAAM,YAAY,CAAC;AAEpB,MAAM,KAAK,GACT,uEAAuE;IACvE,8CAA8C;IAC9C,8DAA8D,CAAC;AAEjE,MAAM,UAAU,cAAc;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,WAAW,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrG,MAAM,QAAQ,GACZ,WAAW,GAAG,CAAC;QACb,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC;IAExE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,QAAQ,GACZ,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvF,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,4BAA4B,KAAK,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;IACtC,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAE9B,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAC7B,UAA2B,EAC3B,MAAc,EACd,OAAe,EACf,QAAkB;IAElB,MAAM,KAAK,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,SAAS,OAAO,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,YAAY,UAAU,CAAC,SAAS,IAAI,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEhF,IAAI,UAAU,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;aACrE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEf,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,eAAe,EAAE,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAExD,MAAM,KAAK,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,yBAAyB,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,uBAAuB,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC;QAEjE,MAAM,OAAO,GACX,MAAM,CAAC,QAAQ,KAAK,QAAQ;YAC1B,CAAC,CAAC,MAAM,gBAAgB,CAAC,MAAM,CAAC;YAChC,CAAC,CAAC,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,kBAAkB,CAAC,CAAC;QAE1D,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAClF,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;YAC/E,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YACnF,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBAC7D,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Library Entry Point
3
+ *
4
+ * Exports all public API functions and types for programmatic use.
5
+ * This is the main entry point when using this package as a library.
6
+ */
7
+ export type { AggregatedCosts, ClaudeCostBucket, ClaudeCostReport, ClaudeCostResult, ClaudeReportConfig, CostBucket, CostsResponse, DailyCost, OpenAIReportConfig, Provider, ReportConfig, } from './types.js';
8
+ export { parseDate, validateDateRange, loadConfig, aggregateCosts, generateMarkdownReport, generateCSVReport, writeReports, fetchOpenAICosts, fetchClaudeCosts, } from './usage-report.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Library Entry Point
3
+ *
4
+ * Exports all public API functions and types for programmatic use.
5
+ * This is the main entry point when using this package as a library.
6
+ */
7
+ // Re-export public utility functions
8
+ export { parseDate, validateDateRange, loadConfig, aggregateCosts, generateMarkdownReport, generateCSVReport, writeReports, fetchOpenAICosts, fetchClaudeCosts, } from './usage-report.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,qCAAqC;AACrC,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ // Test that the library entry point exists and exports all expected functions
3
+ describe('Library Entry Point (index.ts)', () => {
4
+ it('should export all public API functions', async () => {
5
+ // Dynamic import to test the library entry point
6
+ const lib = await import('./index.js');
7
+ // Core functions
8
+ expect(typeof lib.parseDate).toBe('function');
9
+ expect(typeof lib.validateDateRange).toBe('function');
10
+ expect(typeof lib.loadConfig).toBe('function');
11
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
12
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
13
+ expect(typeof lib.aggregateCosts).toBe('function');
14
+ expect(typeof lib.generateMarkdownReport).toBe('function');
15
+ expect(typeof lib.generateCSVReport).toBe('function');
16
+ expect(typeof lib.writeReports).toBe('function');
17
+ });
18
+ it('should export all types', async () => {
19
+ const lib = await import('./index.js');
20
+ // Types should be available (as TypeScript types, not runtime values)
21
+ // We can't directly test types at runtime, but we can verify the module exports
22
+ expect(lib).toBeDefined();
23
+ });
24
+ it('should NOT export CLI-specific functions', async () => {
25
+ const lib = await import('./index.js');
26
+ // CLI-specific functions should not be exported
27
+ expect('parseArguments' in lib).toBe(false);
28
+ expect('main' in lib).toBe(false);
29
+ });
30
+ it('should allow importing without CLI dependencies', async () => {
31
+ // This test verifies the library can be imported without dotenv/config
32
+ // which is only needed for CLI
33
+ const lib = await import('./index.js');
34
+ expect(lib).toBeDefined();
35
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
36
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
37
+ });
38
+ it('should export fetchOpenAICosts (renamed from fetchCosts)', async () => {
39
+ const lib = await import('./index.js');
40
+ // Verify the renamed function exists
41
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
42
+ // Verify old name doesn't exist
43
+ expect('fetchCosts' in lib).toBe(false);
44
+ });
45
+ });
46
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAS9C,8EAA8E;AAC9E,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,iDAAiD;QACjD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,iBAAiB;QACjB,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,sEAAsE;QACtE,gFAAgF;QAChF,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,gDAAgD;QAChD,MAAM,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,uEAAuE;QACvE,+BAA+B;QAC/B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,qCAAqC;QACrC,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,gCAAgC;QAChC,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ /**
3
+ * Integration tests to verify both CLI and library usage patterns work
4
+ */
5
+ describe('Integration: CLI and Library Usage', () => {
6
+ it('should allow importing CLI functions', async () => {
7
+ const cli = await import('./cli.js');
8
+ // Verify CLI-specific functions are available
9
+ expect(typeof cli.parseArguments).toBe('function');
10
+ });
11
+ it('should allow importing library functions', async () => {
12
+ const lib = await import('./index.js');
13
+ // Verify core library functions are available
14
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
15
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
16
+ expect(typeof lib.aggregateCosts).toBe('function');
17
+ expect(typeof lib.generateMarkdownReport).toBe('function');
18
+ expect(typeof lib.generateCSVReport).toBe('function');
19
+ expect(typeof lib.writeReports).toBe('function');
20
+ expect(typeof lib.parseDate).toBe('function');
21
+ expect(typeof lib.validateDateRange).toBe('function');
22
+ expect(typeof lib.loadConfig).toBe('function');
23
+ });
24
+ it('should allow importing types from library', async () => {
25
+ const lib = await import('./index.js');
26
+ // Types are available at compile time, but we can verify the module exports
27
+ expect(lib).toBeDefined();
28
+ });
29
+ it('should have CLI import from library (verify separation)', async () => {
30
+ // This test verifies that cli.ts imports from index.ts (the library)
31
+ // We can't directly test imports, but we can verify both modules work
32
+ const cli = await import('./cli.js');
33
+ const lib = await import('./index.js');
34
+ // Both should be importable
35
+ expect(cli).toBeDefined();
36
+ expect(lib).toBeDefined();
37
+ // CLI should have parseArguments (CLI-specific)
38
+ expect(typeof cli.parseArguments).toBe('function');
39
+ // Library should have core functions but NOT CLI functions
40
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
41
+ expect('parseArguments' in lib).toBe(false);
42
+ });
43
+ });
44
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C;;GAEG;AAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAErC,8CAA8C;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,8CAA8C;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,4EAA4E;QAC5E,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,4BAA4B;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAE1B,gDAAgD;QAChD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEnD,2DAA2D;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * OpenAI Organization Costs API Types
3
+ * https://platform.openai.com/docs/api-reference/usage
4
+ *
5
+ * Claude (Anthropic) Cost API Types
6
+ * https://platform.claude.com/docs/en/build-with-claude/usage-cost-api
7
+ */
8
+ export type Provider = 'openai' | 'claude';
9
+ export interface CostsResponse {
10
+ object: 'page';
11
+ data: CostBucket[];
12
+ has_more: boolean;
13
+ next_page: string | null;
14
+ }
15
+ export interface CostBucket {
16
+ object: 'bucket';
17
+ start_time: number;
18
+ end_time: number;
19
+ results: CostResult[];
20
+ }
21
+ export interface CostResult {
22
+ object: 'organization.costs.result';
23
+ amount: {
24
+ value: number | string;
25
+ currency: string;
26
+ };
27
+ line_item: string | null;
28
+ project_id: string | null;
29
+ }
30
+ /** Anthropic cost_report API response (raw). */
31
+ export interface ClaudeCostReport {
32
+ data: ClaudeCostBucket[];
33
+ has_more: boolean;
34
+ next_page: string | null;
35
+ }
36
+ export interface ClaudeCostBucket {
37
+ starting_at: string;
38
+ ending_at: string;
39
+ results: ClaudeCostResult[];
40
+ }
41
+ export interface ClaudeCostResult {
42
+ amount: string;
43
+ currency: string;
44
+ description: string | null;
45
+ model: string | null;
46
+ cost_type: string | null;
47
+ context_window: string | null;
48
+ token_type: string | null;
49
+ service_tier: string | null;
50
+ workspace_id: string | null;
51
+ }
52
+ export interface AggregatedCosts {
53
+ totalCost: number;
54
+ startDate: string;
55
+ endDate: string;
56
+ projectId: string;
57
+ dailyCosts: DailyCost[];
58
+ costsByLineItem: Map<string, number>;
59
+ billingDays: number;
60
+ averageDailyCost: number;
61
+ }
62
+ export interface DailyCost {
63
+ date: string;
64
+ lineItem: string;
65
+ cost: number;
66
+ }
67
+ export interface OpenAIReportConfig {
68
+ provider: 'openai';
69
+ startDate: string;
70
+ endDate: string;
71
+ apiKey: string;
72
+ orgId: string;
73
+ projectId: string;
74
+ }
75
+ export interface ClaudeReportConfig {
76
+ provider: 'claude';
77
+ startDate: string;
78
+ endDate: string;
79
+ apiKey: string;
80
+ }
81
+ export type ReportConfig = OpenAIReportConfig | ClaudeReportConfig;
82
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * OpenAI Organization Costs API Types
3
+ * https://platform.openai.com/docs/api-reference/usage
4
+ *
5
+ * Claude (Anthropic) Cost API Types
6
+ * https://platform.claude.com/docs/en/build-with-claude/usage-cost-api
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,15 @@
1
+ import { AggregatedCosts, CostBucket, type ClaudeReportConfig, type OpenAIReportConfig, type ReportConfig, type Provider } from './types.js';
2
+ export declare function parseDate(dateStr: string): Date;
3
+ export declare function validateDateRange(start: Date, end: Date): void;
4
+ export declare function toUnixTimestamp(date: Date): number;
5
+ export declare function loadConfig(startDate: string, endDate: string, provider: Provider): ReportConfig;
6
+ export declare function fetchOpenAICosts(config: OpenAIReportConfig): Promise<CostBucket[]>;
7
+ export declare function fetchClaudeCosts(config: ClaudeReportConfig): Promise<CostBucket[]>;
8
+ export declare function aggregateCosts(buckets: CostBucket[], startDate: string, endDate: string, projectId: string): AggregatedCosts;
9
+ export declare function generateMarkdownReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string;
10
+ export declare function generateCSVReport(aggregated: AggregatedCosts): string;
11
+ export declare function writeReports(aggregated: AggregatedCosts, orgId: string, provider: Provider, baseDir?: string): {
12
+ mdPath: string;
13
+ csvPath: string;
14
+ };
15
+ //# sourceMappingURL=usage-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-report.d.ts","sourceRoot":"","sources":["../src/usage-report.ts"],"names":[],"mappings":"AASA,OAAO,EACL,eAAe,EAGf,UAAU,EAGV,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AAOpB,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAI9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,YAAY,CAyBd;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAsCxF;AA2BD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAoCxF;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,eAAe,CA2CjB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAC5B,MAAM,CAgFR;AAaD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,CAoBrE;AAmBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAcrC"}