oilpriceapi 0.7.0 → 0.9.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 +244 -30
- package/dist/cjs/client.js +610 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/index.js +96 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/resources/alerts.js +387 -0
- package/dist/cjs/resources/analytics.js +188 -0
- package/dist/cjs/resources/bunker-fuels.js +210 -0
- package/dist/cjs/resources/commodities.js +115 -0
- package/dist/cjs/resources/data-quality.js +144 -0
- package/dist/cjs/resources/data-sources.js +298 -0
- package/dist/cjs/resources/diesel.js +119 -0
- package/dist/cjs/resources/drilling.js +269 -0
- package/dist/cjs/resources/ei/drilling-productivity.js +108 -0
- package/dist/cjs/resources/ei/forecasts.js +106 -0
- package/dist/cjs/resources/ei/frac-focus.js +165 -0
- package/dist/cjs/resources/ei/index.js +98 -0
- package/dist/cjs/resources/ei/oil-inventories.js +97 -0
- package/dist/cjs/resources/ei/opec-production.js +97 -0
- package/dist/cjs/resources/ei/rig-counts.js +93 -0
- package/dist/cjs/resources/ei/well-permits.js +136 -0
- package/dist/cjs/resources/forecasts.js +168 -0
- package/dist/cjs/resources/futures.js +424 -0
- package/dist/cjs/resources/indicators.js +79 -0
- package/dist/cjs/resources/raw.js +128 -0
- package/dist/cjs/resources/rig-counts.js +164 -0
- package/dist/cjs/resources/spreads.js +105 -0
- package/dist/cjs/resources/storage.js +166 -0
- package/dist/cjs/resources/streaming.js +350 -0
- package/dist/cjs/resources/webhooks.js +283 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/version.js +24 -0
- package/dist/client.d.ts +130 -3
- package/dist/client.js +206 -30
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +25 -16
- package/dist/index.d.ts +28 -5
- package/dist/index.js +29 -1
- package/dist/resources/alerts.js +31 -77
- package/dist/resources/analytics.d.ts +147 -214
- package/dist/resources/analytics.js +104 -141
- package/dist/resources/bunker-fuels.d.ts +35 -12
- package/dist/resources/bunker-fuels.js +41 -26
- package/dist/resources/commodities.js +2 -1
- package/dist/resources/data-quality.js +2 -1
- package/dist/resources/data-sources.d.ts +31 -31
- package/dist/resources/data-sources.js +30 -85
- package/dist/resources/diesel.d.ts +1 -1
- package/dist/resources/diesel.js +9 -38
- package/dist/resources/drilling.js +2 -1
- package/dist/resources/ei/drilling-productivity.js +2 -1
- package/dist/resources/ei/forecasts.js +2 -1
- package/dist/resources/ei/frac-focus.d.ts +23 -9
- package/dist/resources/ei/frac-focus.js +20 -9
- package/dist/resources/ei/index.js +2 -1
- package/dist/resources/ei/oil-inventories.js +2 -1
- package/dist/resources/ei/opec-production.js +2 -1
- package/dist/resources/ei/rig-counts.js +2 -1
- package/dist/resources/ei/well-permits.d.ts +25 -9
- package/dist/resources/ei/well-permits.js +20 -7
- package/dist/resources/forecasts.d.ts +4 -1
- package/dist/resources/forecasts.js +13 -6
- package/dist/resources/futures.d.ts +178 -1
- package/dist/resources/futures.js +199 -8
- package/dist/resources/indicators.d.ts +170 -0
- package/dist/resources/indicators.js +75 -0
- package/dist/resources/raw.d.ts +94 -0
- package/dist/resources/raw.js +124 -0
- package/dist/resources/rig-counts.js +5 -2
- package/dist/resources/spreads.d.ts +121 -0
- package/dist/resources/spreads.js +101 -0
- package/dist/resources/storage.d.ts +5 -4
- package/dist/resources/storage.js +7 -6
- package/dist/resources/streaming.d.ts +272 -0
- package/dist/resources/streaming.js +342 -0
- package/dist/resources/webhooks.d.ts +73 -23
- package/dist/resources/webhooks.js +59 -77
- package/dist/types.d.ts +43 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/package.json +21 -6
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OilPriceAPIConfig, Price, LatestPricesOptions, HistoricalPricesOptions, Commodity, CommoditiesResponse, CategoriesResponse, DataConnectorPrice, DataConnectorOptions } from "./types.js";
|
|
1
|
+
import type { OilPriceAPIConfig, Price, LatestPricesOptions, HistoricalPricesOptions, Commodity, CommoditiesResponse, CategoriesResponse, DataConnectorPrice, DataConnectorOptions, DemoPricesResponse, DemoCommoditiesResponse } from "./types.js";
|
|
2
2
|
import { DieselResource } from "./resources/diesel.js";
|
|
3
3
|
import { AlertsResource } from "./resources/alerts.js";
|
|
4
4
|
import { CommoditiesResource } from "./resources/commodities.js";
|
|
@@ -13,6 +13,26 @@ import { DrillingIntelligenceResource } from "./resources/drilling.js";
|
|
|
13
13
|
import { EnergyIntelligenceResource } from "./resources/ei/index.js";
|
|
14
14
|
import { WebhooksResource } from "./resources/webhooks.js";
|
|
15
15
|
import { DataSourcesResource } from "./resources/data-sources.js";
|
|
16
|
+
import { SpreadsResource } from "./resources/spreads.js";
|
|
17
|
+
import { IndicatorsResource } from "./resources/indicators.js";
|
|
18
|
+
import { RawResource } from "./resources/raw.js";
|
|
19
|
+
import { StreamingResource } from "./resources/streaming.js";
|
|
20
|
+
/**
|
|
21
|
+
* Raw HTTP response wrapper.
|
|
22
|
+
*
|
|
23
|
+
* Returned by {@link OilPriceAPI.raw} accessors to expose the underlying
|
|
24
|
+
* HTTP status code and response headers alongside the parsed data.
|
|
25
|
+
*
|
|
26
|
+
* @typeParam T - The parsed response body type.
|
|
27
|
+
*/
|
|
28
|
+
export interface APIResponse<T> {
|
|
29
|
+
/** Parsed response data (same shape the non-raw method would return). */
|
|
30
|
+
data: T;
|
|
31
|
+
/** HTTP status code (e.g., 200, 201). */
|
|
32
|
+
status: number;
|
|
33
|
+
/** Response headers. */
|
|
34
|
+
headers: Headers;
|
|
35
|
+
}
|
|
16
36
|
/**
|
|
17
37
|
* Official Node.js client for Oil Price API
|
|
18
38
|
*
|
|
@@ -105,7 +125,29 @@ export declare class OilPriceAPI {
|
|
|
105
125
|
* Data sources resource (BYOS - Bring Your Own Source)
|
|
106
126
|
*/
|
|
107
127
|
readonly dataSources: DataSourcesResource;
|
|
108
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Spreads resource (crack, basis, curve structure, margin, physical premium)
|
|
130
|
+
*/
|
|
131
|
+
readonly spreads: SpreadsResource;
|
|
132
|
+
/**
|
|
133
|
+
* Indicators resource (fuel switching, price context, storage analytics,
|
|
134
|
+
* annotations, CFTC positioning, congressional trades)
|
|
135
|
+
*/
|
|
136
|
+
readonly indicators: IndicatorsResource;
|
|
137
|
+
/**
|
|
138
|
+
* Raw-response accessor.
|
|
139
|
+
*
|
|
140
|
+
* Mirrors the top-level price/commodity methods but returns the underlying
|
|
141
|
+
* HTTP status and headers alongside the parsed data via {@link APIResponse}.
|
|
142
|
+
*/
|
|
143
|
+
readonly raw: RawResource;
|
|
144
|
+
/**
|
|
145
|
+
* Real-time price streaming resource (WebSocket / ActionCable).
|
|
146
|
+
*
|
|
147
|
+
* Streaming requires a Reservoir Mastery (Professional+) plan.
|
|
148
|
+
*/
|
|
149
|
+
readonly stream: StreamingResource;
|
|
150
|
+
constructor(config?: OilPriceAPIConfig);
|
|
109
151
|
/**
|
|
110
152
|
* Log debug messages if debug mode is enabled
|
|
111
153
|
*/
|
|
@@ -123,9 +165,28 @@ export declare class OilPriceAPI {
|
|
|
123
165
|
*/
|
|
124
166
|
private isRetryable;
|
|
125
167
|
/**
|
|
126
|
-
*
|
|
168
|
+
* Shape a parsed JSON response body into the value returned to callers.
|
|
169
|
+
*
|
|
170
|
+
* Centralizes the response-structure handling so that both {@link request}
|
|
171
|
+
* and {@link requestRaw} return identical data. Handles the latest/historical
|
|
172
|
+
* envelope shapes as well as the generic `{ data }` fallback used by resource
|
|
173
|
+
* mutations, alerts, webhooks, etc.
|
|
174
|
+
*/
|
|
175
|
+
private shapeResponseData;
|
|
176
|
+
/**
|
|
177
|
+
* Internal method to make HTTP requests with retry and timeout.
|
|
178
|
+
* Supports all HTTP methods (GET, POST, PATCH, DELETE) with consistent
|
|
179
|
+
* retry logic, timeout handling, and typed error responses.
|
|
127
180
|
*/
|
|
128
181
|
private request;
|
|
182
|
+
/**
|
|
183
|
+
* Internal method identical to {@link request} but returns the underlying
|
|
184
|
+
* HTTP status and headers alongside the parsed data.
|
|
185
|
+
*
|
|
186
|
+
* Used by the public {@link raw} accessor to expose response metadata
|
|
187
|
+
* (issue #7) without changing the return shape of existing methods.
|
|
188
|
+
*/
|
|
189
|
+
private requestRaw;
|
|
129
190
|
/**
|
|
130
191
|
* Get the latest prices for all commodities or a specific commodity
|
|
131
192
|
*
|
|
@@ -165,6 +226,35 @@ export declare class OilPriceAPI {
|
|
|
165
226
|
* ```
|
|
166
227
|
*/
|
|
167
228
|
getHistoricalPrices(options?: HistoricalPricesOptions): Promise<Price[]>;
|
|
229
|
+
/**
|
|
230
|
+
* Paginate through historical prices automatically.
|
|
231
|
+
*
|
|
232
|
+
* Returns an async generator that yields pages of prices, fetching
|
|
233
|
+
* the next page only when needed. Avoids loading all data into memory.
|
|
234
|
+
*
|
|
235
|
+
* @param options - Same options as getHistoricalPrices, plus perPage (default: 100)
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* // Iterate through all pages
|
|
240
|
+
* for await (const page of client.paginateHistoricalPrices({
|
|
241
|
+
* commodity: 'BRENT_CRUDE_USD',
|
|
242
|
+
* startDate: '2024-01-01',
|
|
243
|
+
* endDate: '2024-12-31',
|
|
244
|
+
* perPage: 100,
|
|
245
|
+
* })) {
|
|
246
|
+
* console.log(`Got ${page.length} prices`);
|
|
247
|
+
* // Process each page...
|
|
248
|
+
* }
|
|
249
|
+
*
|
|
250
|
+
* // Or collect all prices
|
|
251
|
+
* const allPrices: Price[] = [];
|
|
252
|
+
* for await (const page of client.paginateHistoricalPrices({ commodity: 'WTI_USD' })) {
|
|
253
|
+
* allPrices.push(...page);
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
paginateHistoricalPrices(options?: HistoricalPricesOptions): AsyncGenerator<Price[]>;
|
|
168
258
|
/**
|
|
169
259
|
* Get prices from your connected data sources (BYOS)
|
|
170
260
|
*
|
|
@@ -221,4 +311,41 @@ export declare class OilPriceAPI {
|
|
|
221
311
|
* ```
|
|
222
312
|
*/
|
|
223
313
|
getCommodity(code: string): Promise<Commodity>;
|
|
314
|
+
/**
|
|
315
|
+
* Fetch live sample prices from the public, no-auth demo endpoint.
|
|
316
|
+
*
|
|
317
|
+
* Hits `GET /v1/demo/prices` (no API key required) and returns the parsed
|
|
318
|
+
* `{ prices, meta }` envelope. Useful for trying the client without
|
|
319
|
+
* credentials. Subject to the demo rate limit (~20 requests/hour).
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* const demo = await client.getDemoPrices();
|
|
324
|
+
* const brent = demo.prices.find(p => p.code === 'BRENT_CRUDE_USD');
|
|
325
|
+
* console.log(brent?.price);
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
getDemoPrices(): Promise<DemoPricesResponse>;
|
|
329
|
+
/**
|
|
330
|
+
* Fetch the catalogue of commodities from the public, no-auth demo endpoint.
|
|
331
|
+
*
|
|
332
|
+
* Hits `GET /v1/demo/commodities` (no API key required) and returns the parsed
|
|
333
|
+
* `{ commodities, meta }` envelope, where `meta.free_commodities` lists the
|
|
334
|
+
* codes available on the free demo tier.
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* const demo = await client.getDemoCommodities();
|
|
339
|
+
* console.log(demo.meta.total, demo.meta.free_commodities);
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
getDemoCommodities(): Promise<DemoCommoditiesResponse>;
|
|
343
|
+
/**
|
|
344
|
+
* Minimal fetch for the no-auth demo endpoints.
|
|
345
|
+
*
|
|
346
|
+
* Unlike {@link request}, this does NOT run the latest/historical response
|
|
347
|
+
* shaping (which would strip the `meta` block) and does NOT require an API
|
|
348
|
+
* key — it returns the raw `data` envelope from `{ status, data }`.
|
|
349
|
+
*/
|
|
350
|
+
private requestDemo;
|
|
224
351
|
}
|
package/dist/client.js
CHANGED
|
@@ -14,6 +14,10 @@ import { EnergyIntelligenceResource } from "./resources/ei/index.js";
|
|
|
14
14
|
import { WebhooksResource } from "./resources/webhooks.js";
|
|
15
15
|
import { DataSourcesResource } from "./resources/data-sources.js";
|
|
16
16
|
import { SDK_VERSION, SDK_NAME, buildUserAgent } from "./version.js";
|
|
17
|
+
import { SpreadsResource } from "./resources/spreads.js";
|
|
18
|
+
import { IndicatorsResource } from "./resources/indicators.js";
|
|
19
|
+
import { RawResource } from "./resources/raw.js";
|
|
20
|
+
import { StreamingResource } from "./resources/streaming.js";
|
|
17
21
|
/**
|
|
18
22
|
* Official Node.js client for Oil Price API
|
|
19
23
|
*
|
|
@@ -41,11 +45,11 @@ import { SDK_VERSION, SDK_NAME, buildUserAgent } from "./version.js";
|
|
|
41
45
|
* ```
|
|
42
46
|
*/
|
|
43
47
|
export class OilPriceAPI {
|
|
44
|
-
constructor(config) {
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
constructor(config = {}) {
|
|
49
|
+
this.apiKey = config.apiKey || process.env.OILPRICEAPI_KEY || "";
|
|
50
|
+
if (!this.apiKey) {
|
|
51
|
+
throw new OilPriceAPIError("API key required. Set OILPRICEAPI_KEY env var or pass apiKey in config.");
|
|
47
52
|
}
|
|
48
|
-
this.apiKey = config.apiKey;
|
|
49
53
|
this.baseUrl = config.baseUrl || "https://api.oilpriceapi.com";
|
|
50
54
|
this.retries = config.retries !== undefined ? config.retries : 3;
|
|
51
55
|
this.retryDelay = config.retryDelay || 1000;
|
|
@@ -69,6 +73,10 @@ export class OilPriceAPI {
|
|
|
69
73
|
this.ei = new EnergyIntelligenceResource(this);
|
|
70
74
|
this.webhooks = new WebhooksResource(this);
|
|
71
75
|
this.dataSources = new DataSourcesResource(this);
|
|
76
|
+
this.spreads = new SpreadsResource(this);
|
|
77
|
+
this.indicators = new IndicatorsResource(this);
|
|
78
|
+
this.raw = new RawResource(this);
|
|
79
|
+
this.stream = new StreamingResource(this);
|
|
72
80
|
}
|
|
73
81
|
/**
|
|
74
82
|
* Log debug messages if debug mode is enabled
|
|
@@ -123,9 +131,50 @@ export class OilPriceAPI {
|
|
|
123
131
|
return false;
|
|
124
132
|
}
|
|
125
133
|
/**
|
|
126
|
-
*
|
|
134
|
+
* Shape a parsed JSON response body into the value returned to callers.
|
|
135
|
+
*
|
|
136
|
+
* Centralizes the response-structure handling so that both {@link request}
|
|
137
|
+
* and {@link requestRaw} return identical data. Handles the latest/historical
|
|
138
|
+
* envelope shapes as well as the generic `{ data }` fallback used by resource
|
|
139
|
+
* mutations, alerts, webhooks, etc.
|
|
140
|
+
*/
|
|
141
|
+
shapeResponseData(responseData) {
|
|
142
|
+
// Handle different response structures
|
|
143
|
+
// Latest endpoint: { status, data: { price, ... } }
|
|
144
|
+
// Historical endpoint: { status, data: { prices: [...] } }
|
|
145
|
+
if (responseData.status === "success" && responseData.data) {
|
|
146
|
+
if (responseData.data.prices) {
|
|
147
|
+
// Historical endpoint - return prices array
|
|
148
|
+
this.log(`Returning ${responseData.data.prices.length} prices`);
|
|
149
|
+
return responseData.data.prices;
|
|
150
|
+
}
|
|
151
|
+
else if (responseData.data.price !== undefined) {
|
|
152
|
+
// Latest endpoint - wrap single price in array
|
|
153
|
+
this.log("Returning single price (wrapped in array)");
|
|
154
|
+
return [responseData.data];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Fallback - return data as-is (used by resource mutations, alerts, webhooks, etc.)
|
|
158
|
+
this.log("Returning data as-is");
|
|
159
|
+
return (responseData.data !== undefined ? responseData.data : responseData);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Internal method to make HTTP requests with retry and timeout.
|
|
163
|
+
* Supports all HTTP methods (GET, POST, PATCH, DELETE) with consistent
|
|
164
|
+
* retry logic, timeout handling, and typed error responses.
|
|
165
|
+
*/
|
|
166
|
+
async request(endpoint, params, options) {
|
|
167
|
+
const { data } = await this.requestRaw(endpoint, params, options);
|
|
168
|
+
return data;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Internal method identical to {@link request} but returns the underlying
|
|
172
|
+
* HTTP status and headers alongside the parsed data.
|
|
173
|
+
*
|
|
174
|
+
* Used by the public {@link raw} accessor to expose response metadata
|
|
175
|
+
* (issue #7) without changing the return shape of existing methods.
|
|
127
176
|
*/
|
|
128
|
-
async
|
|
177
|
+
async requestRaw(endpoint, params, options) {
|
|
129
178
|
// Build URL with query parameters
|
|
130
179
|
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
131
180
|
if (params) {
|
|
@@ -163,11 +212,15 @@ export class OilPriceAPI {
|
|
|
163
212
|
if (this.appName) {
|
|
164
213
|
headers["X-App-Name"] = this.appName;
|
|
165
214
|
}
|
|
166
|
-
const
|
|
167
|
-
method: "GET",
|
|
215
|
+
const fetchOptions = {
|
|
216
|
+
method: options?.method || "GET",
|
|
168
217
|
headers,
|
|
169
218
|
signal: controller.signal,
|
|
170
|
-
}
|
|
219
|
+
};
|
|
220
|
+
if (options?.body !== undefined) {
|
|
221
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
222
|
+
}
|
|
223
|
+
const response = await fetch(url.toString(), fetchOptions);
|
|
171
224
|
clearTimeout(timeoutId);
|
|
172
225
|
this.log(`Response: ${response.status} ${response.statusText}`);
|
|
173
226
|
// Handle error responses
|
|
@@ -177,8 +230,7 @@ export class OilPriceAPI {
|
|
|
177
230
|
// Try to parse JSON error response
|
|
178
231
|
try {
|
|
179
232
|
const errorJson = JSON.parse(errorBody);
|
|
180
|
-
errorMessage =
|
|
181
|
-
errorJson.message || errorJson.error || errorMessage;
|
|
233
|
+
errorMessage = errorJson.message || errorJson.error || errorMessage;
|
|
182
234
|
}
|
|
183
235
|
catch {
|
|
184
236
|
// Use default error message if response isn't JSON
|
|
@@ -209,30 +261,27 @@ export class OilPriceAPI {
|
|
|
209
261
|
throw new OilPriceAPIError(errorMessage, response.status, "HTTP_ERROR");
|
|
210
262
|
}
|
|
211
263
|
}
|
|
264
|
+
// Handle empty responses (e.g., 204 No Content from DELETE)
|
|
265
|
+
const responseText = await response.text();
|
|
266
|
+
if (!responseText) {
|
|
267
|
+
this.log("Empty response body");
|
|
268
|
+
return {
|
|
269
|
+
data: {},
|
|
270
|
+
status: response.status,
|
|
271
|
+
headers: response.headers,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
212
274
|
// Parse successful response
|
|
213
|
-
const responseData =
|
|
275
|
+
const responseData = JSON.parse(responseText);
|
|
214
276
|
this.log("Response data received", {
|
|
215
277
|
status: responseData.status,
|
|
216
278
|
hasData: !!responseData.data,
|
|
217
279
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
// Historical endpoint - return prices array
|
|
224
|
-
this.log(`Returning ${responseData.data.prices.length} prices`);
|
|
225
|
-
return responseData.data.prices;
|
|
226
|
-
}
|
|
227
|
-
else if (responseData.data.price !== undefined) {
|
|
228
|
-
// Latest endpoint - wrap single price in array
|
|
229
|
-
this.log("Returning single price (wrapped in array)");
|
|
230
|
-
return [responseData.data];
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// Fallback - return data as-is
|
|
234
|
-
this.log("Returning data as-is");
|
|
235
|
-
return responseData.data;
|
|
280
|
+
return {
|
|
281
|
+
data: this.shapeResponseData(responseData),
|
|
282
|
+
status: response.status,
|
|
283
|
+
headers: response.headers,
|
|
284
|
+
};
|
|
236
285
|
}
|
|
237
286
|
catch (error) {
|
|
238
287
|
// Handle abort (timeout)
|
|
@@ -353,6 +402,51 @@ export class OilPriceAPI {
|
|
|
353
402
|
// Solution: Use /v1/prices/past_year which uses direct WHERE clauses
|
|
354
403
|
return this.request("/v1/prices/past_year", params);
|
|
355
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Paginate through historical prices automatically.
|
|
407
|
+
*
|
|
408
|
+
* Returns an async generator that yields pages of prices, fetching
|
|
409
|
+
* the next page only when needed. Avoids loading all data into memory.
|
|
410
|
+
*
|
|
411
|
+
* @param options - Same options as getHistoricalPrices, plus perPage (default: 100)
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* // Iterate through all pages
|
|
416
|
+
* for await (const page of client.paginateHistoricalPrices({
|
|
417
|
+
* commodity: 'BRENT_CRUDE_USD',
|
|
418
|
+
* startDate: '2024-01-01',
|
|
419
|
+
* endDate: '2024-12-31',
|
|
420
|
+
* perPage: 100,
|
|
421
|
+
* })) {
|
|
422
|
+
* console.log(`Got ${page.length} prices`);
|
|
423
|
+
* // Process each page...
|
|
424
|
+
* }
|
|
425
|
+
*
|
|
426
|
+
* // Or collect all prices
|
|
427
|
+
* const allPrices: Price[] = [];
|
|
428
|
+
* for await (const page of client.paginateHistoricalPrices({ commodity: 'WTI_USD' })) {
|
|
429
|
+
* allPrices.push(...page);
|
|
430
|
+
* }
|
|
431
|
+
* ```
|
|
432
|
+
*/
|
|
433
|
+
async *paginateHistoricalPrices(options) {
|
|
434
|
+
const perPage = options?.perPage || 100;
|
|
435
|
+
let page = 1;
|
|
436
|
+
while (true) {
|
|
437
|
+
const results = await this.getHistoricalPrices({
|
|
438
|
+
...options,
|
|
439
|
+
page,
|
|
440
|
+
perPage,
|
|
441
|
+
});
|
|
442
|
+
if (results.length === 0)
|
|
443
|
+
break;
|
|
444
|
+
yield results;
|
|
445
|
+
if (results.length < perPage)
|
|
446
|
+
break;
|
|
447
|
+
page++;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
356
450
|
/**
|
|
357
451
|
* Get prices from your connected data sources (BYOS)
|
|
358
452
|
*
|
|
@@ -427,4 +521,86 @@ export class OilPriceAPI {
|
|
|
427
521
|
async getCommodity(code) {
|
|
428
522
|
return this.request(`/v1/commodities/${code}`, {});
|
|
429
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Fetch live sample prices from the public, no-auth demo endpoint.
|
|
526
|
+
*
|
|
527
|
+
* Hits `GET /v1/demo/prices` (no API key required) and returns the parsed
|
|
528
|
+
* `{ prices, meta }` envelope. Useful for trying the client without
|
|
529
|
+
* credentials. Subject to the demo rate limit (~20 requests/hour).
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```typescript
|
|
533
|
+
* const demo = await client.getDemoPrices();
|
|
534
|
+
* const brent = demo.prices.find(p => p.code === 'BRENT_CRUDE_USD');
|
|
535
|
+
* console.log(brent?.price);
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
538
|
+
async getDemoPrices() {
|
|
539
|
+
return this.requestDemo("/v1/demo/prices");
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Fetch the catalogue of commodities from the public, no-auth demo endpoint.
|
|
543
|
+
*
|
|
544
|
+
* Hits `GET /v1/demo/commodities` (no API key required) and returns the parsed
|
|
545
|
+
* `{ commodities, meta }` envelope, where `meta.free_commodities` lists the
|
|
546
|
+
* codes available on the free demo tier.
|
|
547
|
+
*
|
|
548
|
+
* @example
|
|
549
|
+
* ```typescript
|
|
550
|
+
* const demo = await client.getDemoCommodities();
|
|
551
|
+
* console.log(demo.meta.total, demo.meta.free_commodities);
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
554
|
+
async getDemoCommodities() {
|
|
555
|
+
return this.requestDemo("/v1/demo/commodities");
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Minimal fetch for the no-auth demo endpoints.
|
|
559
|
+
*
|
|
560
|
+
* Unlike {@link request}, this does NOT run the latest/historical response
|
|
561
|
+
* shaping (which would strip the `meta` block) and does NOT require an API
|
|
562
|
+
* key — it returns the raw `data` envelope from `{ status, data }`.
|
|
563
|
+
*/
|
|
564
|
+
async requestDemo(endpoint) {
|
|
565
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
566
|
+
this.log(`Demo request: ${url}`);
|
|
567
|
+
const controller = new AbortController();
|
|
568
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
569
|
+
try {
|
|
570
|
+
const response = await fetch(url, {
|
|
571
|
+
method: "GET",
|
|
572
|
+
headers: {
|
|
573
|
+
"Content-Type": "application/json",
|
|
574
|
+
"User-Agent": buildUserAgent(),
|
|
575
|
+
"X-SDK-Name": SDK_NAME,
|
|
576
|
+
"X-SDK-Version": SDK_VERSION,
|
|
577
|
+
},
|
|
578
|
+
signal: controller.signal,
|
|
579
|
+
});
|
|
580
|
+
if (!response.ok) {
|
|
581
|
+
const body = await response.text();
|
|
582
|
+
let message = `HTTP ${response.status}: ${response.statusText}`;
|
|
583
|
+
try {
|
|
584
|
+
const json = JSON.parse(body);
|
|
585
|
+
message = json.message || json.error || message;
|
|
586
|
+
}
|
|
587
|
+
catch {
|
|
588
|
+
// non-JSON error body
|
|
589
|
+
}
|
|
590
|
+
throw new OilPriceAPIError(message, response.status, "HTTP_ERROR");
|
|
591
|
+
}
|
|
592
|
+
const parsed = JSON.parse(await response.text());
|
|
593
|
+
// Demo envelope is { status: "success", data: { ... } }.
|
|
594
|
+
return (parsed.data !== undefined ? parsed.data : parsed);
|
|
595
|
+
}
|
|
596
|
+
catch (error) {
|
|
597
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
598
|
+
throw new TimeoutError("Request timeout", this.timeout);
|
|
599
|
+
}
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
finally {
|
|
603
|
+
clearTimeout(timeoutId);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
430
606
|
}
|
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 =
|
|
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 =
|
|
21
|
-
super(message, 401,
|
|
22
|
-
this.name =
|
|
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 =
|
|
30
|
-
super(message, 429,
|
|
31
|
-
this.name =
|
|
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 =
|
|
40
|
-
super(message, 404,
|
|
41
|
-
this.name =
|
|
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 =
|
|
49
|
-
super(message, statusCode,
|
|
50
|
-
this.name =
|
|
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 =
|
|
58
|
-
super(`${message} (${timeout}ms)`, undefined,
|
|
59
|
-
this.name =
|
|
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
|
@@ -6,22 +6,29 @@
|
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
8
|
export { OilPriceAPI } from "./client.js";
|
|
9
|
+
export type { APIResponse } from "./client.js";
|
|
9
10
|
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 { OilPriceAPIConfig, RetryStrategy, Price, LatestPricesOptions, HistoricalPricesOptions, HistoricalPeriod, AggregationInterval, Commodity, CommoditiesResponse, CommodityCategory, CategoriesResponse, DataConnectorPrice, DataConnectorOptions, DemoPrice, DemoPricesResponse, DemoCommoditiesResponse, } from "./types.js";
|
|
11
12
|
export type { DieselPrice, DieselStation, DieselStationsResponse, GetDieselStationsOptions, } from "./resources/diesel.js";
|
|
12
13
|
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 { FuturesPrice, HistoricalFuturesPrice, HistoricalFuturesOptions, FuturesOHLC, IntradayPrice, IntradayFuturesData, FuturesSpread, FuturesCurvePoint, FuturesCurveData, ContinuousContractPrice, ContinuousFuturesData, FuturesSpreadHistoryPoint, FuturesSpreadHistory, FuturesContractFamilySlug, } from "./resources/futures.js";
|
|
15
|
+
export { FUTURES_CONTRACTS, FUTURES_FAMILY_SLUGS, FuturesContractFamily, } from "./resources/futures.js";
|
|
16
|
+
export type { SpreadType, SpreadValue, HistoricalSpreadValue, HistoricalSpreadOptions, } from "./resources/spreads.js";
|
|
17
|
+
export { SpreadsResource } from "./resources/spreads.js";
|
|
18
|
+
export type { IndicatorType, FuelSwitchingIndicator, PriceContextIndicator, StorageAnalyticsIndicator, AnnotationIndicator, CFTCPositioningIndicator, CongressionalTradeIndicator, } from "./resources/indicators.js";
|
|
19
|
+
export { IndicatorsResource } from "./resources/indicators.js";
|
|
20
|
+
export { RawResource } from "./resources/raw.js";
|
|
14
21
|
export type { StorageData, HistoricalStorageData, HistoricalStorageOptions, } from "./resources/storage.js";
|
|
15
22
|
export type { RigCountData, HistoricalRigCountData, HistoricalRigCountOptions, RigCountTrend, RigCountSummary, } from "./resources/rig-counts.js";
|
|
16
23
|
export type { BunkerFuelPrice, PortBunkerPrices, PortPriceComparison, BunkerFuelSpreads, HistoricalBunkerPrice, HistoricalBunkerOptions, } from "./resources/bunker-fuels.js";
|
|
17
|
-
export type { PerformanceMetrics, PerformanceOptions, StatisticalAnalysis, CorrelationAnalysis, TrendAnalysis, SpreadAnalysis,
|
|
18
|
-
export type { MonthlyForecast, ForecastAccuracy, ArchivedForecast
|
|
24
|
+
export type { PerformanceMetrics, PerformanceOptions, StatisticalAnalysis, CorrelationAnalysis, CorrelationOptions, TrendAnalysis, TrendOptions, SpreadAnalysis, SpreadOptions, ForecastOptions, PriceForecast as AnalyticsPriceForecast, } from "./resources/analytics.js";
|
|
25
|
+
export type { MonthlyForecast, ForecastAccuracy, ArchivedForecast } from "./resources/forecasts.js";
|
|
19
26
|
export type { DataQualitySummary, DataQualityReportMeta, DataQualityReport, } from "./resources/data-quality.js";
|
|
20
27
|
export type { DrillingIntelligenceData, LatestDrillingData, DrillingSummary, DrillingTrend, FracSpreadData, WellPermitData, DUCWellData, CompletionData, WellsDrilledData, BasinDrillingData, } from "./resources/drilling.js";
|
|
21
28
|
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
29
|
export type { WebhookEndpoint, CreateWebhookParams, UpdateWebhookParams, WebhookTestResponse as WebhookTestResult, WebhookEvent, } from "./resources/webhooks.js";
|
|
23
30
|
export type { DataSourceType, DataSourceStatus, DataSource, CreateDataSourceParams, UpdateDataSourceParams, DataSourceTestResponse, DataSourceLog, DataSourceHealth, CredentialRotationResponse, } from "./resources/data-sources.js";
|
|
24
|
-
export { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, TimeoutError, } from "./errors.js";
|
|
31
|
+
export { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, ValidationError, TimeoutError, } from "./errors.js";
|
|
25
32
|
export { DieselResource } from "./resources/diesel.js";
|
|
26
33
|
export { AlertsResource } from "./resources/alerts.js";
|
|
27
34
|
export { CommoditiesResource } from "./resources/commodities.js";
|
|
@@ -36,3 +43,19 @@ export { DrillingIntelligenceResource } from "./resources/drilling.js";
|
|
|
36
43
|
export { EnergyIntelligenceResource, EIRigCountsResource, EIOilInventoriesResource, EIOPECProductionResource, EIDrillingProductivityResource, EIForecastsResource, EIWellPermitsResource, EIFracFocusResource, } from "./resources/ei/index.js";
|
|
37
44
|
export { WebhooksResource } from "./resources/webhooks.js";
|
|
38
45
|
export { DataSourcesResource } from "./resources/data-sources.js";
|
|
46
|
+
export { StreamingResource, PriceStreamSubscription, ENERGY_PRICES_CHANNEL, } from "./resources/streaming.js";
|
|
47
|
+
export type { StreamPricesOptions, PriceUpdateHandler, StreamMessage, WelcomeMessage, PriceUpdateMessage, RigCountUpdateMessage, StreamedPrice, StreamedPriceMap, } from "./resources/streaming.js";
|
|
48
|
+
/**
|
|
49
|
+
* Standalone webhook signature verification.
|
|
50
|
+
*
|
|
51
|
+
* Convenience function for verifying webhook signatures without
|
|
52
|
+
* instantiating a full client.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* import { verifyWebhookSignature } from 'oilpriceapi';
|
|
57
|
+
*
|
|
58
|
+
* const isValid = verifyWebhookSignature(rawBody, signatureHeader, secret);
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function verifyWebhookSignature(payload: string | Buffer, signature: string, secret: string): boolean;
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,14 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
8
9
|
export { OilPriceAPI } from "./client.js";
|
|
9
10
|
export { SDK_VERSION, SDK_NAME } from "./version.js";
|
|
10
|
-
export {
|
|
11
|
+
export { FUTURES_CONTRACTS, FUTURES_FAMILY_SLUGS, FuturesContractFamily, } from "./resources/futures.js";
|
|
12
|
+
export { SpreadsResource } from "./resources/spreads.js";
|
|
13
|
+
export { IndicatorsResource } from "./resources/indicators.js";
|
|
14
|
+
export { RawResource } from "./resources/raw.js";
|
|
15
|
+
export { OilPriceAPIError, AuthenticationError, RateLimitError, NotFoundError, ServerError, ValidationError, TimeoutError, } from "./errors.js";
|
|
11
16
|
export { DieselResource } from "./resources/diesel.js";
|
|
12
17
|
export { AlertsResource } from "./resources/alerts.js";
|
|
13
18
|
export { CommoditiesResource } from "./resources/commodities.js";
|
|
@@ -22,3 +27,26 @@ export { DrillingIntelligenceResource } from "./resources/drilling.js";
|
|
|
22
27
|
export { EnergyIntelligenceResource, EIRigCountsResource, EIOilInventoriesResource, EIOPECProductionResource, EIDrillingProductivityResource, EIForecastsResource, EIWellPermitsResource, EIFracFocusResource, } from "./resources/ei/index.js";
|
|
23
28
|
export { WebhooksResource } from "./resources/webhooks.js";
|
|
24
29
|
export { DataSourcesResource } from "./resources/data-sources.js";
|
|
30
|
+
export { StreamingResource, PriceStreamSubscription, ENERGY_PRICES_CHANNEL, } from "./resources/streaming.js";
|
|
31
|
+
/**
|
|
32
|
+
* Standalone webhook signature verification.
|
|
33
|
+
*
|
|
34
|
+
* Convenience function for verifying webhook signatures without
|
|
35
|
+
* instantiating a full client.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { verifyWebhookSignature } from 'oilpriceapi';
|
|
40
|
+
*
|
|
41
|
+
* const isValid = verifyWebhookSignature(rawBody, signatureHeader, secret);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function verifyWebhookSignature(payload, signature, secret) {
|
|
45
|
+
const expectedSignature = "sha256=" + createHmac("sha256", secret).update(payload).digest("hex");
|
|
46
|
+
try {
|
|
47
|
+
return timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(signature));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|