@@ -18,6 +18,7 @@ import {
1818} from './errors.js' ;
1919import { DieselResource } from './resources/diesel.js' ;
2020import { 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 /**
0 commit comments