Skip to content

Commit ba137ac

Browse files
karlwaldmanclaude
andcommitted
feat: Add telemetry headers for app tracking (v0.7.0)
- Add appUrl and appName config options for SDK telemetry - Send X-SDK-Name, X-SDK-Version headers on every request - Send X-App-URL, X-App-Name headers when configured (10% bonus!) - Rename headers from X-Api-Client to X-SDK-Name for consistency - Bump version to 0.7.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2370509 commit ba137ac

File tree

9 files changed

+1639
-9
lines changed

9 files changed

+1639
-9
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oilpriceapi",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Official Node.js SDK for Oil Price API - Real-time and historical oil & commodity prices",
55
"type": "module",
66
"main": "./dist/index.js",

src/client.ts

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from './errors.js';
1919
import { DieselResource } from './resources/diesel.js';
2020
import { AlertsResource } from './resources/alerts.js';
21+
import { SDK_VERSION, SDK_NAME, buildUserAgent } from './version.js';
2122

2223
/**
2324
* Official Node.js client for Oil Price API
@@ -53,6 +54,8 @@ export class OilPriceAPI {
5354
private retryStrategy: RetryStrategy;
5455
private timeout: number;
5556
private debug: boolean;
57+
private appUrl?: string;
58+
private appName?: string;
5659

5760
/**
5861
* Diesel prices resource (state averages + station-level pricing)
@@ -76,6 +79,8 @@ export class OilPriceAPI {
7679
this.retryStrategy = config.retryStrategy || 'exponential';
7780
this.timeout = config.timeout || 90000; // 90 seconds for slow historical queries
7881
this.debug = config.debug || false;
82+
this.appUrl = config.appUrl;
83+
this.appName = config.appName;
7984

8085
// Initialize resources
8186
this.diesel = new DieselResource(this);
@@ -176,15 +181,26 @@ export class OilPriceAPI {
176181
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
177182

178183
try {
184+
// Build headers with optional telemetry
185+
const headers: Record<string, string> = {
186+
'Authorization': `Bearer ${this.apiKey}`,
187+
'Content-Type': 'application/json',
188+
'User-Agent': buildUserAgent(),
189+
'X-SDK-Name': SDK_NAME,
190+
'X-SDK-Version': SDK_VERSION,
191+
};
192+
193+
// Add optional telemetry headers (10% bonus for appUrl!)
194+
if (this.appUrl) {
195+
headers['X-App-URL'] = this.appUrl;
196+
}
197+
if (this.appName) {
198+
headers['X-App-Name'] = this.appName;
199+
}
200+
179201
const response = await fetch(url.toString(), {
180202
method: 'GET',
181-
headers: {
182-
'Authorization': `Bearer ${this.apiKey}`,
183-
'Content-Type': 'application/json',
184-
'User-Agent': 'oilpriceapi-node/0.5.1 node/' + process.version,
185-
'X-Api-Client': 'oilpriceapi-node',
186-
'X-Client-Version': '0.5.1',
187-
},
203+
headers,
188204
signal: controller.signal,
189205
});
190206

@@ -386,7 +402,31 @@ export class OilPriceAPI {
386402
params.end_date = options.endDate;
387403
}
388404

389-
return this.request<Price[]>('/v1/prices', params);
405+
// PERFORMANCE FIX (December 24, 2025):
406+
// Pass interval parameter to enable aggregated queries
407+
// This reduces response times from 74s to <1s for year-long queries
408+
// by returning 365 daily points instead of 600k+ raw points
409+
if (options?.interval) {
410+
params.interval = options.interval;
411+
}
412+
413+
// Pagination parameters
414+
if (options?.perPage !== undefined) {
415+
params.per_page = options.perPage.toString();
416+
}
417+
418+
if (options?.page !== undefined) {
419+
params.page = options.page.toString();
420+
}
421+
422+
// CRITICAL FIX (December 17, 2025):
423+
// Use /v1/prices/past_year endpoint instead of /v1/prices
424+
// The /v1/prices endpoint does NOT correctly handle start_date/end_date parameters
425+
// This was the same bug that affected the Python SDK (fixed in v1.4.4)
426+
// Issue: SDK was returning wrong dates for historical queries
427+
// Root Cause: Backend has_scope :by_period not working on /v1/prices
428+
// Solution: Use /v1/prices/past_year which uses direct WHERE clauses
429+
return this.request<Price[]>('/v1/prices/past_year', params);
390430
}
391431

392432
/**

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
*/
88

99
export { OilPriceAPI } from './client.js';
10+
export { SDK_VERSION, SDK_NAME } from './version.js';
1011
export type {
1112
OilPriceAPIConfig,
1213
RetryStrategy,
1314
Price,
1415
LatestPricesOptions,
1516
HistoricalPricesOptions,
1617
HistoricalPeriod,
18+
AggregationInterval,
1719
Commodity,
1820
CommoditiesResponse,
1921
CommodityCategory,

src/types.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ export interface OilPriceAPIConfig {
4747
* @default false
4848
*/
4949
debug?: boolean;
50+
51+
/**
52+
* Your application's URL (optional, for telemetry)
53+
* Helps us understand how the API is being used and may unlock
54+
* a 10% bonus to your request limit.
55+
* @example "https://myapp.com"
56+
*/
57+
appUrl?: string;
58+
59+
/**
60+
* Your application's name (optional, for telemetry)
61+
* @example "MyFuelPriceTracker"
62+
*/
63+
appName?: string;
5064
}
5165

5266
/**
@@ -139,6 +153,15 @@ export interface LatestPricesOptions {
139153
*/
140154
export type HistoricalPeriod = 'past_week' | 'past_month' | 'past_year';
141155

156+
/**
157+
* Aggregation interval for historical data
158+
*
159+
* PERFORMANCE TIP: Use 'daily' or 'weekly' for year-long queries to reduce
160+
* response times from 74s to <1s. The 'raw' option returns individual price
161+
* points which can be 600k+ records for a year of BRENT data.
162+
*/
163+
export type AggregationInterval = 'raw' | 'hourly' | 'daily' | 'weekly' | 'monthly';
164+
142165
/**
143166
* Options for fetching historical prices
144167
*/
@@ -164,6 +187,31 @@ export interface HistoricalPricesOptions {
164187
* Example: "2024-12-31"
165188
*/
166189
endDate?: string;
190+
191+
/**
192+
* Aggregation interval for the data
193+
*
194+
* PERFORMANCE: For year-long queries, use 'daily' (365 points) or 'weekly' (52 points)
195+
* instead of 'raw' (600k+ points for BRENT) to dramatically improve response times.
196+
*
197+
* @default API default (raw for short periods, may be aggregated for long periods)
198+
*/
199+
interval?: AggregationInterval;
200+
201+
/**
202+
* Number of results per page
203+
*
204+
* @default 100 (API default)
205+
* @max 1000
206+
*/
207+
perPage?: number;
208+
209+
/**
210+
* Page number for pagination (1-indexed)
211+
*
212+
* @default 1
213+
*/
214+
page?: number;
167215
}
168216

169217
/**

src/version.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* SDK Version - centralized to ensure consistency across all headers
3+
*
4+
* This version must be updated when publishing a new release.
5+
* It's used in:
6+
* - User-Agent header: oilpriceapi-node/{version}
7+
* - X-Client-Version header
8+
* - Package.json (should match)
9+
*/
10+
export const SDK_VERSION = '0.7.0';
11+
12+
/**
13+
* SDK identifier used in User-Agent and X-Api-Client headers
14+
*/
15+
export const SDK_NAME = 'oilpriceapi-node';
16+
17+
/**
18+
* Build the full User-Agent string
19+
*/
20+
export function buildUserAgent(): string {
21+
return `${SDK_NAME}/${SDK_VERSION} node/${process.version}`;
22+
}

0 commit comments

Comments
 (0)