oilpriceapi 0.6.0 → 0.8.2

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.
Files changed (80) hide show
  1. package/README.md +418 -123
  2. package/dist/cjs/client.js +490 -0
  3. package/dist/cjs/errors.js +80 -0
  4. package/dist/cjs/index.js +82 -0
  5. package/dist/cjs/package.json +1 -0
  6. package/dist/cjs/resources/alerts.js +387 -0
  7. package/dist/cjs/resources/analytics.js +226 -0
  8. package/dist/cjs/resources/bunker-fuels.js +196 -0
  9. package/dist/cjs/resources/commodities.js +115 -0
  10. package/dist/cjs/resources/data-quality.js +144 -0
  11. package/dist/cjs/resources/data-sources.js +297 -0
  12. package/dist/cjs/resources/diesel.js +119 -0
  13. package/dist/cjs/resources/drilling.js +269 -0
  14. package/dist/cjs/resources/ei/drilling-productivity.js +108 -0
  15. package/dist/cjs/resources/ei/forecasts.js +106 -0
  16. package/dist/cjs/resources/ei/frac-focus.js +155 -0
  17. package/dist/cjs/resources/ei/index.js +98 -0
  18. package/dist/cjs/resources/ei/oil-inventories.js +97 -0
  19. package/dist/cjs/resources/ei/opec-production.js +97 -0
  20. package/dist/cjs/resources/ei/rig-counts.js +93 -0
  21. package/dist/cjs/resources/ei/well-permits.js +124 -0
  22. package/dist/cjs/resources/forecasts.js +162 -0
  23. package/dist/cjs/resources/futures.js +233 -0
  24. package/dist/cjs/resources/rig-counts.js +161 -0
  25. package/dist/cjs/resources/storage.js +166 -0
  26. package/dist/cjs/resources/webhooks.js +294 -0
  27. package/dist/cjs/types.js +2 -0
  28. package/dist/cjs/version.js +24 -0
  29. package/dist/client.d.ts +116 -5
  30. package/dist/client.js +169 -47
  31. package/dist/errors.d.ts +6 -0
  32. package/dist/errors.js +25 -16
  33. package/dist/index.d.ts +45 -6
  34. package/dist/index.js +40 -3
  35. package/dist/resources/alerts.d.ts +52 -15
  36. package/dist/resources/alerts.js +121 -109
  37. package/dist/resources/analytics.d.ts +325 -0
  38. package/dist/resources/analytics.js +222 -0
  39. package/dist/resources/bunker-fuels.d.ts +270 -0
  40. package/dist/resources/bunker-fuels.js +192 -0
  41. package/dist/resources/commodities.d.ts +148 -0
  42. package/dist/resources/commodities.js +111 -0
  43. package/dist/resources/data-quality.d.ts +229 -0
  44. package/dist/resources/data-quality.js +140 -0
  45. package/dist/resources/data-sources.d.ts +365 -0
  46. package/dist/resources/data-sources.js +293 -0
  47. package/dist/resources/diesel.d.ts +1 -1
  48. package/dist/resources/diesel.js +9 -38
  49. package/dist/resources/drilling.d.ts +403 -0
  50. package/dist/resources/drilling.js +265 -0
  51. package/dist/resources/ei/drilling-productivity.d.ts +173 -0
  52. package/dist/resources/ei/drilling-productivity.js +104 -0
  53. package/dist/resources/ei/forecasts.d.ts +177 -0
  54. package/dist/resources/ei/forecasts.js +102 -0
  55. package/dist/resources/ei/frac-focus.d.ts +212 -0
  56. package/dist/resources/ei/frac-focus.js +151 -0
  57. package/dist/resources/ei/index.d.ts +140 -0
  58. package/dist/resources/ei/index.js +88 -0
  59. package/dist/resources/ei/oil-inventories.d.ts +155 -0
  60. package/dist/resources/ei/oil-inventories.js +93 -0
  61. package/dist/resources/ei/opec-production.d.ts +146 -0
  62. package/dist/resources/ei/opec-production.js +93 -0
  63. package/dist/resources/ei/rig-counts.d.ts +131 -0
  64. package/dist/resources/ei/rig-counts.js +89 -0
  65. package/dist/resources/ei/well-permits.d.ts +178 -0
  66. package/dist/resources/ei/well-permits.js +120 -0
  67. package/dist/resources/forecasts.d.ts +200 -0
  68. package/dist/resources/forecasts.js +158 -0
  69. package/dist/resources/futures.d.ts +322 -0
  70. package/dist/resources/futures.js +229 -0
  71. package/dist/resources/rig-counts.d.ts +221 -0
  72. package/dist/resources/rig-counts.js +157 -0
  73. package/dist/resources/storage.d.ts +182 -0
  74. package/dist/resources/storage.js +162 -0
  75. package/dist/resources/webhooks.d.ts +326 -0
  76. package/dist/resources/webhooks.js +290 -0
  77. package/dist/types.d.ts +79 -8
  78. package/dist/version.d.ts +1 -1
  79. package/dist/version.js +2 -2
  80. package/package.json +17 -8
package/dist/client.d.ts CHANGED
@@ -1,6 +1,18 @@
1
- import type { OilPriceAPIConfig, Price, LatestPricesOptions, HistoricalPricesOptions, Commodity, CommoditiesResponse, CategoriesResponse } from './types.js';
2
- import { DieselResource } from './resources/diesel.js';
3
- import { AlertsResource } from './resources/alerts.js';
1
+ import type { OilPriceAPIConfig, Price, LatestPricesOptions, HistoricalPricesOptions, Commodity, CommoditiesResponse, CategoriesResponse, DataConnectorPrice, DataConnectorOptions } from "./types.js";
2
+ import { DieselResource } from "./resources/diesel.js";
3
+ import { AlertsResource } from "./resources/alerts.js";
4
+ import { CommoditiesResource } from "./resources/commodities.js";
5
+ import { FuturesResource } from "./resources/futures.js";
6
+ import { StorageResource } from "./resources/storage.js";
7
+ import { RigCountsResource } from "./resources/rig-counts.js";
8
+ import { BunkerFuelsResource } from "./resources/bunker-fuels.js";
9
+ import { AnalyticsResource } from "./resources/analytics.js";
10
+ import { ForecastsResource } from "./resources/forecasts.js";
11
+ import { DataQualityResource } from "./resources/data-quality.js";
12
+ import { DrillingIntelligenceResource } from "./resources/drilling.js";
13
+ import { EnergyIntelligenceResource } from "./resources/ei/index.js";
14
+ import { WebhooksResource } from "./resources/webhooks.js";
15
+ import { DataSourcesResource } from "./resources/data-sources.js";
4
16
  /**
5
17
  * Official Node.js client for Oil Price API
6
18
  *
@@ -35,6 +47,8 @@ export declare class OilPriceAPI {
35
47
  private retryStrategy;
36
48
  private timeout;
37
49
  private debug;
50
+ private appUrl?;
51
+ private appName?;
38
52
  /**
39
53
  * Diesel prices resource (state averages + station-level pricing)
40
54
  */
@@ -43,7 +57,55 @@ export declare class OilPriceAPI {
43
57
  * Price alerts resource (create, manage, and monitor alerts)
44
58
  */
45
59
  readonly alerts: AlertsResource;
46
- constructor(config: OilPriceAPIConfig);
60
+ /**
61
+ * Commodities resource (metadata and categories)
62
+ */
63
+ readonly commodities: CommoditiesResource;
64
+ /**
65
+ * Futures resource (contracts, OHLC, curves, spreads)
66
+ */
67
+ readonly futures: FuturesResource;
68
+ /**
69
+ * Storage resource (inventory levels, Cushing, SPR)
70
+ */
71
+ readonly storage: StorageResource;
72
+ /**
73
+ * Rig counts resource (Baker Hughes rig count data)
74
+ */
75
+ readonly rigCounts: RigCountsResource;
76
+ /**
77
+ * Bunker fuels resource (marine fuel prices at ports)
78
+ */
79
+ readonly bunkerFuels: BunkerFuelsResource;
80
+ /**
81
+ * Analytics resource (performance, statistics, correlations)
82
+ */
83
+ readonly analytics: AnalyticsResource;
84
+ /**
85
+ * Forecasts resource (EIA/IEA forecasts and accuracy)
86
+ */
87
+ readonly forecasts: ForecastsResource;
88
+ /**
89
+ * Data quality resource (quality metrics and reports)
90
+ */
91
+ readonly dataQuality: DataQualityResource;
92
+ /**
93
+ * Drilling intelligence resource (US onshore drilling activity)
94
+ */
95
+ readonly drilling: DrillingIntelligenceResource;
96
+ /**
97
+ * Energy intelligence resource (comprehensive market intelligence)
98
+ */
99
+ readonly ei: EnergyIntelligenceResource;
100
+ /**
101
+ * Webhooks resource (webhook endpoint management)
102
+ */
103
+ readonly webhooks: WebhooksResource;
104
+ /**
105
+ * Data sources resource (BYOS - Bring Your Own Source)
106
+ */
107
+ readonly dataSources: DataSourcesResource;
108
+ constructor(config?: OilPriceAPIConfig);
47
109
  /**
48
110
  * Log debug messages if debug mode is enabled
49
111
  */
@@ -61,7 +123,9 @@ export declare class OilPriceAPI {
61
123
  */
62
124
  private isRetryable;
63
125
  /**
64
- * Internal method to make HTTP requests with retry and timeout
126
+ * Internal method to make HTTP requests with retry and timeout.
127
+ * Supports all HTTP methods (GET, POST, PATCH, DELETE) with consistent
128
+ * retry logic, timeout handling, and typed error responses.
65
129
  */
66
130
  private request;
67
131
  /**
@@ -103,6 +167,53 @@ export declare class OilPriceAPI {
103
167
  * ```
104
168
  */
105
169
  getHistoricalPrices(options?: HistoricalPricesOptions): Promise<Price[]>;
170
+ /**
171
+ * Paginate through historical prices automatically.
172
+ *
173
+ * Returns an async generator that yields pages of prices, fetching
174
+ * the next page only when needed. Avoids loading all data into memory.
175
+ *
176
+ * @param options - Same options as getHistoricalPrices, plus perPage (default: 100)
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Iterate through all pages
181
+ * for await (const page of client.paginateHistoricalPrices({
182
+ * commodity: 'BRENT_CRUDE_USD',
183
+ * startDate: '2024-01-01',
184
+ * endDate: '2024-12-31',
185
+ * perPage: 100,
186
+ * })) {
187
+ * console.log(`Got ${page.length} prices`);
188
+ * // Process each page...
189
+ * }
190
+ *
191
+ * // Or collect all prices
192
+ * const allPrices: Price[] = [];
193
+ * for await (const page of client.paginateHistoricalPrices({ commodity: 'WTI_USD' })) {
194
+ * allPrices.push(...page);
195
+ * }
196
+ * ```
197
+ */
198
+ paginateHistoricalPrices(options?: HistoricalPricesOptions): AsyncGenerator<Price[]>;
199
+ /**
200
+ * Get prices from your connected data sources (BYOS)
201
+ *
202
+ * Requires Data Connector feature enabled on your organization.
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * // Get all connected prices
207
+ * const prices = await client.getDataConnectorPrices();
208
+ *
209
+ * // Filter by fuel type
210
+ * const vlsfo = await client.getDataConnectorPrices({ fuelType: 'VLSFO' });
211
+ *
212
+ * // Filter by port
213
+ * const singapore = await client.getDataConnectorPrices({ port: 'SINGAPORE' });
214
+ * ```
215
+ */
216
+ getDataConnectorPrices(options?: DataConnectorOptions): Promise<DataConnectorPrice[]>;
106
217
  /**
107
218
  * Get metadata for all supported commodities
108
219
  *
package/dist/client.js CHANGED
@@ -1,7 +1,19 @@
1
- import { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, TimeoutError, } from './errors.js';
2
- import { DieselResource } from './resources/diesel.js';
3
- import { AlertsResource } from './resources/alerts.js';
4
- import { SDK_VERSION, SDK_NAME, buildUserAgent } from './version.js';
1
+ import { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, TimeoutError, } from "./errors.js";
2
+ import { DieselResource } from "./resources/diesel.js";
3
+ import { AlertsResource } from "./resources/alerts.js";
4
+ import { CommoditiesResource } from "./resources/commodities.js";
5
+ import { FuturesResource } from "./resources/futures.js";
6
+ import { StorageResource } from "./resources/storage.js";
7
+ import { RigCountsResource } from "./resources/rig-counts.js";
8
+ import { BunkerFuelsResource } from "./resources/bunker-fuels.js";
9
+ import { AnalyticsResource } from "./resources/analytics.js";
10
+ import { ForecastsResource } from "./resources/forecasts.js";
11
+ import { DataQualityResource } from "./resources/data-quality.js";
12
+ import { DrillingIntelligenceResource } from "./resources/drilling.js";
13
+ import { EnergyIntelligenceResource } from "./resources/ei/index.js";
14
+ import { WebhooksResource } from "./resources/webhooks.js";
15
+ import { DataSourcesResource } from "./resources/data-sources.js";
16
+ import { SDK_VERSION, SDK_NAME, buildUserAgent } from "./version.js";
5
17
  /**
6
18
  * Official Node.js client for Oil Price API
7
19
  *
@@ -29,20 +41,34 @@ import { SDK_VERSION, SDK_NAME, buildUserAgent } from './version.js';
29
41
  * ```
30
42
  */
31
43
  export class OilPriceAPI {
32
- constructor(config) {
33
- if (!config.apiKey) {
34
- throw new OilPriceAPIError('API key is required');
44
+ constructor(config = {}) {
45
+ this.apiKey = config.apiKey || process.env.OILPRICEAPI_KEY || "";
46
+ if (!this.apiKey) {
47
+ throw new OilPriceAPIError("API key required. Set OILPRICEAPI_KEY env var or pass apiKey in config.");
35
48
  }
36
- this.apiKey = config.apiKey;
37
- this.baseUrl = config.baseUrl || 'https://api.oilpriceapi.com';
49
+ this.baseUrl = config.baseUrl || "https://api.oilpriceapi.com";
38
50
  this.retries = config.retries !== undefined ? config.retries : 3;
39
51
  this.retryDelay = config.retryDelay || 1000;
40
- this.retryStrategy = config.retryStrategy || 'exponential';
52
+ this.retryStrategy = config.retryStrategy || "exponential";
41
53
  this.timeout = config.timeout || 90000; // 90 seconds for slow historical queries
42
54
  this.debug = config.debug || false;
55
+ this.appUrl = config.appUrl;
56
+ this.appName = config.appName;
43
57
  // Initialize resources
44
58
  this.diesel = new DieselResource(this);
45
59
  this.alerts = new AlertsResource(this);
60
+ this.commodities = new CommoditiesResource(this);
61
+ this.futures = new FuturesResource(this);
62
+ this.storage = new StorageResource(this);
63
+ this.rigCounts = new RigCountsResource(this);
64
+ this.bunkerFuels = new BunkerFuelsResource(this);
65
+ this.analytics = new AnalyticsResource(this);
66
+ this.forecasts = new ForecastsResource(this);
67
+ this.dataQuality = new DataQualityResource(this);
68
+ this.drilling = new DrillingIntelligenceResource(this);
69
+ this.ei = new EnergyIntelligenceResource(this);
70
+ this.webhooks = new WebhooksResource(this);
71
+ this.dataSources = new DataSourcesResource(this);
46
72
  }
47
73
  /**
48
74
  * Log debug messages if debug mode is enabled
@@ -50,7 +76,7 @@ export class OilPriceAPI {
50
76
  log(message, data) {
51
77
  if (this.debug) {
52
78
  const timestamp = new Date().toISOString();
53
- console.log(`[OilPriceAPI ${timestamp}] ${message}`, data || '');
79
+ console.log(`[OilPriceAPI ${timestamp}] ${message}`, data || "");
54
80
  }
55
81
  }
56
82
  /**
@@ -58,11 +84,11 @@ export class OilPriceAPI {
58
84
  */
59
85
  calculateRetryDelay(attempt) {
60
86
  switch (this.retryStrategy) {
61
- case 'exponential':
87
+ case "exponential":
62
88
  return this.retryDelay * Math.pow(2, attempt);
63
- case 'linear':
89
+ case "linear":
64
90
  return this.retryDelay * (attempt + 1);
65
- case 'fixed':
91
+ case "fixed":
66
92
  default:
67
93
  return this.retryDelay;
68
94
  }
@@ -71,14 +97,14 @@ export class OilPriceAPI {
71
97
  * Sleep for specified milliseconds
72
98
  */
73
99
  sleep(ms) {
74
- return new Promise(resolve => setTimeout(resolve, ms));
100
+ return new Promise((resolve) => setTimeout(resolve, ms));
75
101
  }
76
102
  /**
77
103
  * Determine if error is retryable
78
104
  */
79
105
  isRetryable(error) {
80
106
  // Retry on network errors
81
- if (error instanceof TypeError && error.message.includes('fetch')) {
107
+ if (error instanceof TypeError && error.message.includes("fetch")) {
82
108
  return true;
83
109
  }
84
110
  // Retry on timeout errors
@@ -97,9 +123,11 @@ export class OilPriceAPI {
97
123
  return false;
98
124
  }
99
125
  /**
100
- * Internal method to make HTTP requests with retry and timeout
126
+ * Internal method to make HTTP requests with retry and timeout.
127
+ * Supports all HTTP methods (GET, POST, PATCH, DELETE) with consistent
128
+ * retry logic, timeout handling, and typed error responses.
101
129
  */
102
- async request(endpoint, params) {
130
+ async request(endpoint, params, options) {
103
131
  // Build URL with query parameters
104
132
  const url = new URL(`${this.baseUrl}${endpoint}`);
105
133
  if (params) {
@@ -122,17 +150,30 @@ export class OilPriceAPI {
122
150
  const controller = new AbortController();
123
151
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
124
152
  try {
125
- const response = await fetch(url.toString(), {
126
- method: 'GET',
127
- headers: {
128
- 'Authorization': `Bearer ${this.apiKey}`,
129
- 'Content-Type': 'application/json',
130
- 'User-Agent': buildUserAgent(),
131
- 'X-Api-Client': SDK_NAME,
132
- 'X-Client-Version': SDK_VERSION,
133
- },
153
+ // Build headers with optional telemetry
154
+ const headers = {
155
+ Authorization: `Bearer ${this.apiKey}`,
156
+ "Content-Type": "application/json",
157
+ "User-Agent": buildUserAgent(),
158
+ "X-SDK-Name": SDK_NAME,
159
+ "X-SDK-Version": SDK_VERSION,
160
+ };
161
+ // Add optional telemetry headers (10% bonus for appUrl!)
162
+ if (this.appUrl) {
163
+ headers["X-App-URL"] = this.appUrl;
164
+ }
165
+ if (this.appName) {
166
+ headers["X-App-Name"] = this.appName;
167
+ }
168
+ const fetchOptions = {
169
+ method: options?.method || "GET",
170
+ headers,
134
171
  signal: controller.signal,
135
- });
172
+ };
173
+ if (options?.body !== undefined) {
174
+ fetchOptions.body = JSON.stringify(options.body);
175
+ }
176
+ const response = await fetch(url.toString(), fetchOptions);
136
177
  clearTimeout(timeoutId);
137
178
  this.log(`Response: ${response.status} ${response.statusText}`);
138
179
  // Handle error responses
@@ -155,7 +196,7 @@ export class OilPriceAPI {
155
196
  case 404:
156
197
  throw new NotFoundError(errorMessage);
157
198
  case 429:
158
- const retryAfter = response.headers.get('Retry-After');
199
+ const retryAfter = response.headers.get("Retry-After");
159
200
  const rateLimitError = new RateLimitError(errorMessage, retryAfter ? parseInt(retryAfter, 10) : undefined);
160
201
  // If rate limited and we have retries left, wait and retry
161
202
  if (attempt < this.retries && rateLimitError.retryAfter) {
@@ -170,19 +211,25 @@ export class OilPriceAPI {
170
211
  case 504:
171
212
  throw new ServerError(errorMessage, response.status);
172
213
  default:
173
- throw new OilPriceAPIError(errorMessage, response.status, 'HTTP_ERROR');
214
+ throw new OilPriceAPIError(errorMessage, response.status, "HTTP_ERROR");
174
215
  }
175
216
  }
217
+ // Handle empty responses (e.g., 204 No Content from DELETE)
218
+ const responseText = await response.text();
219
+ if (!responseText) {
220
+ this.log("Empty response body");
221
+ return {};
222
+ }
176
223
  // Parse successful response
177
- const responseData = await response.json();
178
- this.log('Response data received', {
224
+ const responseData = JSON.parse(responseText);
225
+ this.log("Response data received", {
179
226
  status: responseData.status,
180
- hasData: !!responseData.data
227
+ hasData: !!responseData.data,
181
228
  });
182
229
  // Handle different response structures
183
230
  // Latest endpoint: { status, data: { price, ... } }
184
231
  // Historical endpoint: { status, data: { prices: [...] } }
185
- if (responseData.status === 'success' && responseData.data) {
232
+ if (responseData.status === "success" && responseData.data) {
186
233
  if (responseData.data.prices) {
187
234
  // Historical endpoint - return prices array
188
235
  this.log(`Returning ${responseData.data.prices.length} prices`);
@@ -190,18 +237,18 @@ export class OilPriceAPI {
190
237
  }
191
238
  else if (responseData.data.price !== undefined) {
192
239
  // Latest endpoint - wrap single price in array
193
- this.log('Returning single price (wrapped in array)');
240
+ this.log("Returning single price (wrapped in array)");
194
241
  return [responseData.data];
195
242
  }
196
243
  }
197
- // Fallback - return data as-is
198
- this.log('Returning data as-is');
199
- return responseData.data;
244
+ // Fallback - return data as-is (used by resource mutations, alerts, webhooks, etc.)
245
+ this.log("Returning data as-is");
246
+ return (responseData.data !== undefined ? responseData.data : responseData);
200
247
  }
201
248
  catch (error) {
202
249
  // Handle abort (timeout)
203
- if (error instanceof Error && error.name === 'AbortError') {
204
- throw new TimeoutError('Request timeout', this.timeout);
250
+ if (error instanceof Error && error.name === "AbortError") {
251
+ throw new TimeoutError("Request timeout", this.timeout);
205
252
  }
206
253
  throw error;
207
254
  }
@@ -210,7 +257,7 @@ export class OilPriceAPI {
210
257
  lastError = error;
211
258
  this.log(`Request failed: ${lastError.message}`, {
212
259
  attempt,
213
- retryable: this.isRetryable(lastError)
260
+ retryable: this.isRetryable(lastError),
214
261
  });
215
262
  // Re-throw our custom errors if not retryable
216
263
  if (error instanceof OilPriceAPIError && !this.isRetryable(error)) {
@@ -223,7 +270,7 @@ export class OilPriceAPI {
223
270
  }
224
271
  // Wrap fetch errors (network issues, etc.)
225
272
  if (error instanceof Error) {
226
- throw new OilPriceAPIError(`Request failed after ${this.retries + 1} attempts: ${error.message}`, undefined, 'NETWORK_ERROR');
273
+ throw new OilPriceAPIError(`Request failed after ${this.retries + 1} attempts: ${error.message}`, undefined, "NETWORK_ERROR");
227
274
  }
228
275
  throw error;
229
276
  }
@@ -234,7 +281,7 @@ export class OilPriceAPI {
234
281
  }
235
282
  }
236
283
  // This should never be reached, but TypeScript wants it
237
- throw lastError || new OilPriceAPIError('Unknown error occurred');
284
+ throw lastError || new OilPriceAPIError("Unknown error occurred");
238
285
  }
239
286
  /**
240
287
  * Get the latest prices for all commodities or a specific commodity
@@ -256,7 +303,7 @@ export class OilPriceAPI {
256
303
  if (options?.commodity) {
257
304
  params.by_code = options.commodity;
258
305
  }
259
- return this.request('/v1/prices/latest', params);
306
+ return this.request("/v1/prices/latest", params);
260
307
  }
261
308
  /**
262
309
  * Get historical prices for a time period
@@ -315,7 +362,82 @@ export class OilPriceAPI {
315
362
  // Issue: SDK was returning wrong dates for historical queries
316
363
  // Root Cause: Backend has_scope :by_period not working on /v1/prices
317
364
  // Solution: Use /v1/prices/past_year which uses direct WHERE clauses
318
- return this.request('/v1/prices/past_year', params);
365
+ return this.request("/v1/prices/past_year", params);
366
+ }
367
+ /**
368
+ * Paginate through historical prices automatically.
369
+ *
370
+ * Returns an async generator that yields pages of prices, fetching
371
+ * the next page only when needed. Avoids loading all data into memory.
372
+ *
373
+ * @param options - Same options as getHistoricalPrices, plus perPage (default: 100)
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * // Iterate through all pages
378
+ * for await (const page of client.paginateHistoricalPrices({
379
+ * commodity: 'BRENT_CRUDE_USD',
380
+ * startDate: '2024-01-01',
381
+ * endDate: '2024-12-31',
382
+ * perPage: 100,
383
+ * })) {
384
+ * console.log(`Got ${page.length} prices`);
385
+ * // Process each page...
386
+ * }
387
+ *
388
+ * // Or collect all prices
389
+ * const allPrices: Price[] = [];
390
+ * for await (const page of client.paginateHistoricalPrices({ commodity: 'WTI_USD' })) {
391
+ * allPrices.push(...page);
392
+ * }
393
+ * ```
394
+ */
395
+ async *paginateHistoricalPrices(options) {
396
+ const perPage = options?.perPage || 100;
397
+ let page = 1;
398
+ while (true) {
399
+ const results = await this.getHistoricalPrices({
400
+ ...options,
401
+ page,
402
+ perPage,
403
+ });
404
+ if (results.length === 0)
405
+ break;
406
+ yield results;
407
+ if (results.length < perPage)
408
+ break;
409
+ page++;
410
+ }
411
+ }
412
+ /**
413
+ * Get prices from your connected data sources (BYOS)
414
+ *
415
+ * Requires Data Connector feature enabled on your organization.
416
+ *
417
+ * @example
418
+ * ```typescript
419
+ * // Get all connected prices
420
+ * const prices = await client.getDataConnectorPrices();
421
+ *
422
+ * // Filter by fuel type
423
+ * const vlsfo = await client.getDataConnectorPrices({ fuelType: 'VLSFO' });
424
+ *
425
+ * // Filter by port
426
+ * const singapore = await client.getDataConnectorPrices({ port: 'SINGAPORE' });
427
+ * ```
428
+ */
429
+ async getDataConnectorPrices(options = {}) {
430
+ const params = {};
431
+ if (options.fuelType)
432
+ params.fuel_type = options.fuelType;
433
+ if (options.port)
434
+ params.port = options.port;
435
+ if (options.region)
436
+ params.region = options.region;
437
+ if (options.since)
438
+ params.since = options.since;
439
+ const response = await this.request("/v1/prices/data-connector", params);
440
+ return response.prices;
319
441
  }
320
442
  /**
321
443
  * Get metadata for all supported commodities
@@ -329,7 +451,7 @@ export class OilPriceAPI {
329
451
  * ```
330
452
  */
331
453
  async getCommodities() {
332
- return this.request('/v1/commodities', {});
454
+ return this.request("/v1/commodities", {});
333
455
  }
334
456
  /**
335
457
  * Get all commodity categories with their commodities
@@ -344,7 +466,7 @@ export class OilPriceAPI {
344
466
  * ```
345
467
  */
346
468
  async getCommodityCategories() {
347
- return this.request('/v1/commodities/categories', {});
469
+ return this.request("/v1/commodities/categories", {});
348
470
  }
349
471
  /**
350
472
  * Get metadata for a specific commodity by code
package/dist/errors.d.ts CHANGED
@@ -40,6 +40,12 @@ export declare class NotFoundError extends OilPriceAPIError {
40
40
  export declare class ServerError extends OilPriceAPIError {
41
41
  constructor(message?: string, statusCode?: number);
42
42
  }
43
+ /**
44
+ * Thrown when SDK-side input validation fails
45
+ */
46
+ export declare class ValidationError extends OilPriceAPIError {
47
+ constructor(message: string);
48
+ }
43
49
  /**
44
50
  * Thrown when request exceeds timeout
45
51
  */
package/dist/errors.js CHANGED
@@ -4,7 +4,7 @@
4
4
  export class OilPriceAPIError extends Error {
5
5
  constructor(message, statusCode, code) {
6
6
  super(message);
7
- this.name = 'OilPriceAPIError';
7
+ this.name = "OilPriceAPIError";
8
8
  this.statusCode = statusCode;
9
9
  this.code = code;
10
10
  // Maintains proper stack trace for where our error was thrown (only available on V8)
@@ -17,18 +17,18 @@ export class OilPriceAPIError extends Error {
17
17
  * Thrown when API authentication fails (401)
18
18
  */
19
19
  export class AuthenticationError extends OilPriceAPIError {
20
- constructor(message = 'Invalid API key') {
21
- super(message, 401, 'AUTHENTICATION_ERROR');
22
- this.name = 'AuthenticationError';
20
+ constructor(message = "Invalid API key") {
21
+ super(message, 401, "AUTHENTICATION_ERROR");
22
+ this.name = "AuthenticationError";
23
23
  }
24
24
  }
25
25
  /**
26
26
  * Thrown when rate limit is exceeded (429)
27
27
  */
28
28
  export class RateLimitError extends OilPriceAPIError {
29
- constructor(message = 'Rate limit exceeded', retryAfter) {
30
- super(message, 429, 'RATE_LIMIT_ERROR');
31
- this.name = 'RateLimitError';
29
+ constructor(message = "Rate limit exceeded", retryAfter) {
30
+ super(message, 429, "RATE_LIMIT_ERROR");
31
+ this.name = "RateLimitError";
32
32
  this.retryAfter = retryAfter;
33
33
  }
34
34
  }
@@ -36,26 +36,35 @@ export class RateLimitError extends OilPriceAPIError {
36
36
  * Thrown when requested resource is not found (404)
37
37
  */
38
38
  export class NotFoundError extends OilPriceAPIError {
39
- constructor(message = 'Resource not found') {
40
- super(message, 404, 'NOT_FOUND_ERROR');
41
- this.name = 'NotFoundError';
39
+ constructor(message = "Resource not found") {
40
+ super(message, 404, "NOT_FOUND_ERROR");
41
+ this.name = "NotFoundError";
42
42
  }
43
43
  }
44
44
  /**
45
45
  * Thrown when server returns 5xx error
46
46
  */
47
47
  export class ServerError extends OilPriceAPIError {
48
- constructor(message = 'Internal server error', statusCode = 500) {
49
- super(message, statusCode, 'SERVER_ERROR');
50
- this.name = 'ServerError';
48
+ constructor(message = "Internal server error", statusCode = 500) {
49
+ super(message, statusCode, "SERVER_ERROR");
50
+ this.name = "ServerError";
51
+ }
52
+ }
53
+ /**
54
+ * Thrown when SDK-side input validation fails
55
+ */
56
+ export class ValidationError extends OilPriceAPIError {
57
+ constructor(message) {
58
+ super(message, undefined, "VALIDATION_ERROR");
59
+ this.name = "ValidationError";
51
60
  }
52
61
  }
53
62
  /**
54
63
  * Thrown when request exceeds timeout
55
64
  */
56
65
  export class TimeoutError extends OilPriceAPIError {
57
- constructor(message = 'Request timeout', timeout) {
58
- super(`${message} (${timeout}ms)`, undefined, 'TIMEOUT_ERROR');
59
- this.name = 'TimeoutError';
66
+ constructor(message = "Request timeout", timeout) {
67
+ super(`${message} (${timeout}ms)`, undefined, "TIMEOUT_ERROR");
68
+ this.name = "TimeoutError";
60
69
  }
61
70
  }
package/dist/index.d.ts CHANGED
@@ -5,9 +5,48 @@
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
- export { OilPriceAPI } from './client.js';
9
- export { SDK_VERSION, SDK_NAME } from './version.js';
10
- export type { OilPriceAPIConfig, RetryStrategy, Price, LatestPricesOptions, HistoricalPricesOptions, HistoricalPeriod, AggregationInterval, Commodity, CommoditiesResponse, CommodityCategory, CategoriesResponse, } from './types.js';
11
- export type { DieselPrice, DieselStation, DieselStationsResponse, GetDieselStationsOptions, } from './resources/diesel.js';
12
- export type { PriceAlert, CreateAlertParams, UpdateAlertParams, AlertOperator, WebhookTestResponse, } from './resources/alerts.js';
13
- export { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, TimeoutError, } from './errors.js';
8
+ export { OilPriceAPI } from "./client.js";
9
+ export { SDK_VERSION, SDK_NAME } from "./version.js";
10
+ export type { OilPriceAPIConfig, RetryStrategy, Price, LatestPricesOptions, HistoricalPricesOptions, HistoricalPeriod, AggregationInterval, Commodity, CommoditiesResponse, CommodityCategory, CategoriesResponse, DataConnectorPrice, DataConnectorOptions, } from "./types.js";
11
+ export type { DieselPrice, DieselStation, DieselStationsResponse, GetDieselStationsOptions, } from "./resources/diesel.js";
12
+ export type { PriceAlert, CreateAlertParams, UpdateAlertParams, AlertOperator, } from "./resources/alerts.js";
13
+ export type { FuturesPrice, HistoricalFuturesPrice, HistoricalFuturesOptions, FuturesOHLC, IntradayPrice, IntradayFuturesData, FuturesSpread, FuturesCurvePoint, FuturesCurveData, ContinuousContractPrice, ContinuousFuturesData, } from "./resources/futures.js";
14
+ export type { StorageData, HistoricalStorageData, HistoricalStorageOptions, } from "./resources/storage.js";
15
+ export type { RigCountData, HistoricalRigCountData, HistoricalRigCountOptions, RigCountTrend, RigCountSummary, } from "./resources/rig-counts.js";
16
+ export type { BunkerFuelPrice, PortBunkerPrices, PortPriceComparison, BunkerFuelSpreads, HistoricalBunkerPrice, HistoricalBunkerOptions, } from "./resources/bunker-fuels.js";
17
+ export type { PerformanceMetrics, PerformanceOptions, StatisticalAnalysis, CorrelationAnalysis, TrendAnalysis, SpreadAnalysis, ForecastPoint, PriceForecast as AnalyticsPriceForecast, } from "./resources/analytics.js";
18
+ export type { MonthlyForecast, ForecastAccuracy, ArchivedForecast } from "./resources/forecasts.js";
19
+ export type { DataQualitySummary, DataQualityReportMeta, DataQualityReport, } from "./resources/data-quality.js";
20
+ export type { DrillingIntelligenceData, LatestDrillingData, DrillingSummary, DrillingTrend, FracSpreadData, WellPermitData, DUCWellData, CompletionData, WellsDrilledData, BasinDrillingData, } from "./resources/drilling.js";
21
+ export type { WellTimelineEvent, WellTimeline, RigCountRecord, RigCountByBasin, RigCountByState, HistoricalRigCount, OilInventoryRecord, OilInventorySummary, InventoryByProduct, HistoricalInventory, CushingInventory, OPECProductionRecord, TotalOPECProduction, ProductionByCountry, HistoricalProduction, TopProducer, DrillingProductivityRecord, DrillingProductivitySummary, DUCWellInventory, ProductivityByBasin, HistoricalProductivity, ProductivityTrend, ForecastRecord, ForecastSummary, PriceForecast, ProductionForecast, HistoricalForecast, ForecastComparison, WellPermitRecord, WellPermitSummary, PermitsByState, PermitsByOperator, PermitsByFormation, WellPermitSearchQuery, FracFocusRecord, FracFocusSummary, DisclosuresByState, DisclosuresByOperator, ChemicalUsage, WellChemical, FracFocusSearchQuery, } from "./resources/ei/index.js";
22
+ export type { WebhookEndpoint, CreateWebhookParams, UpdateWebhookParams, WebhookTestResponse as WebhookTestResult, WebhookEvent, } from "./resources/webhooks.js";
23
+ export type { DataSourceType, DataSourceStatus, DataSource, CreateDataSourceParams, UpdateDataSourceParams, DataSourceTestResponse, DataSourceLog, DataSourceHealth, CredentialRotationResponse, } from "./resources/data-sources.js";
24
+ export { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, ValidationError, TimeoutError, } from "./errors.js";
25
+ export { DieselResource } from "./resources/diesel.js";
26
+ export { AlertsResource } from "./resources/alerts.js";
27
+ export { CommoditiesResource } from "./resources/commodities.js";
28
+ export { FuturesResource } from "./resources/futures.js";
29
+ export { StorageResource } from "./resources/storage.js";
30
+ export { RigCountsResource } from "./resources/rig-counts.js";
31
+ export { BunkerFuelsResource } from "./resources/bunker-fuels.js";
32
+ export { AnalyticsResource } from "./resources/analytics.js";
33
+ export { ForecastsResource } from "./resources/forecasts.js";
34
+ export { DataQualityResource } from "./resources/data-quality.js";
35
+ export { DrillingIntelligenceResource } from "./resources/drilling.js";
36
+ export { EnergyIntelligenceResource, EIRigCountsResource, EIOilInventoriesResource, EIOPECProductionResource, EIDrillingProductivityResource, EIForecastsResource, EIWellPermitsResource, EIFracFocusResource, } from "./resources/ei/index.js";
37
+ export { WebhooksResource } from "./resources/webhooks.js";
38
+ export { DataSourcesResource } from "./resources/data-sources.js";
39
+ /**
40
+ * Standalone webhook signature verification.
41
+ *
42
+ * Convenience function for verifying webhook signatures without
43
+ * instantiating a full client.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * import { verifyWebhookSignature } from 'oilpriceapi';
48
+ *
49
+ * const isValid = verifyWebhookSignature(rawBody, signatureHeader, secret);
50
+ * ```
51
+ */
52
+ export declare function verifyWebhookSignature(payload: string | Buffer, signature: string, secret: string): boolean;