oilpriceapi 0.7.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.
- package/README.md +43 -11
- package/dist/cjs/client.js +490 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/index.js +82 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/resources/alerts.js +387 -0
- package/dist/cjs/resources/analytics.js +226 -0
- package/dist/cjs/resources/bunker-fuels.js +196 -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 +297 -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 +155 -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 +124 -0
- package/dist/cjs/resources/forecasts.js +162 -0
- package/dist/cjs/resources/futures.js +233 -0
- package/dist/cjs/resources/rig-counts.js +161 -0
- package/dist/cjs/resources/storage.js +166 -0
- package/dist/cjs/resources/webhooks.js +294 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/version.js +24 -0
- package/dist/client.d.ts +33 -2
- package/dist/client.js +70 -14
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +25 -16
- package/dist/index.d.ts +16 -2
- package/dist/index.js +24 -1
- package/dist/resources/alerts.js +31 -77
- package/dist/resources/analytics.js +8 -7
- package/dist/resources/bunker-fuels.js +5 -4
- package/dist/resources/commodities.js +2 -1
- package/dist/resources/data-quality.js +2 -1
- package/dist/resources/data-sources.js +21 -77
- 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.js +4 -3
- 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.js +2 -1
- package/dist/resources/forecasts.js +2 -1
- package/dist/resources/futures.js +9 -8
- package/dist/resources/storage.js +2 -1
- package/dist/resources/webhooks.d.ts +36 -0
- package/dist/resources/webhooks.js +60 -67
- package/dist/types.d.ts +2 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/package.json +15 -6
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Manage webhook endpoints for real-time event notifications.
|
|
5
5
|
*/
|
|
6
|
+
import { ValidationError } from "../errors.js";
|
|
7
|
+
import { verifyWebhookSignature } from "../index.js";
|
|
6
8
|
/**
|
|
7
9
|
* Webhooks Resource
|
|
8
10
|
*
|
|
@@ -85,7 +87,7 @@ export class WebhooksResource {
|
|
|
85
87
|
*/
|
|
86
88
|
async get(id) {
|
|
87
89
|
if (!id || typeof id !== "string") {
|
|
88
|
-
throw new
|
|
90
|
+
throw new ValidationError("Webhook ID must be a non-empty string");
|
|
89
91
|
}
|
|
90
92
|
const response = await this.client["request"](`/v1/webhooks/${id}`, {});
|
|
91
93
|
return "webhook" in response ? response.webhook : response;
|
|
@@ -113,24 +115,17 @@ export class WebhooksResource {
|
|
|
113
115
|
*/
|
|
114
116
|
async create(params) {
|
|
115
117
|
if (!params.name || typeof params.name !== "string") {
|
|
116
|
-
throw new
|
|
118
|
+
throw new ValidationError("Webhook name is required");
|
|
117
119
|
}
|
|
118
120
|
if (!params.url || !params.url.startsWith("https://")) {
|
|
119
|
-
throw new
|
|
121
|
+
throw new ValidationError("Webhook URL must use HTTPS protocol");
|
|
120
122
|
}
|
|
121
|
-
if (!params.events ||
|
|
122
|
-
|
|
123
|
-
params.events.length === 0) {
|
|
124
|
-
throw new Error("At least one event type is required");
|
|
123
|
+
if (!params.events || !Array.isArray(params.events) || params.events.length === 0) {
|
|
124
|
+
throw new ValidationError("At least one event type is required");
|
|
125
125
|
}
|
|
126
|
-
const
|
|
127
|
-
const response = await fetch(url, {
|
|
126
|
+
const response = await this.client["request"]("/v1/webhooks", {}, {
|
|
128
127
|
method: "POST",
|
|
129
|
-
|
|
130
|
-
Authorization: `Bearer ${this.client["apiKey"]}`,
|
|
131
|
-
"Content-Type": "application/json",
|
|
132
|
-
},
|
|
133
|
-
body: JSON.stringify({
|
|
128
|
+
body: {
|
|
134
129
|
webhook: {
|
|
135
130
|
name: params.name,
|
|
136
131
|
url: params.url,
|
|
@@ -139,14 +134,9 @@ export class WebhooksResource {
|
|
|
139
134
|
secret: params.secret,
|
|
140
135
|
metadata: params.metadata,
|
|
141
136
|
},
|
|
142
|
-
}
|
|
137
|
+
},
|
|
143
138
|
});
|
|
144
|
-
|
|
145
|
-
const errorText = await response.text();
|
|
146
|
-
throw new Error(`Failed to create webhook: ${response.status} ${errorText}`);
|
|
147
|
-
}
|
|
148
|
-
const data = (await response.json());
|
|
149
|
-
return "webhook" in data ? data.webhook : data;
|
|
139
|
+
return "webhook" in response ? response.webhook : response;
|
|
150
140
|
}
|
|
151
141
|
/**
|
|
152
142
|
* Update a webhook endpoint
|
|
@@ -171,32 +161,20 @@ export class WebhooksResource {
|
|
|
171
161
|
*/
|
|
172
162
|
async update(id, params) {
|
|
173
163
|
if (!id || typeof id !== "string") {
|
|
174
|
-
throw new
|
|
164
|
+
throw new ValidationError("Webhook ID must be a non-empty string");
|
|
175
165
|
}
|
|
176
166
|
if (params.url !== undefined && !params.url.startsWith("https://")) {
|
|
177
|
-
throw new
|
|
167
|
+
throw new ValidationError("Webhook URL must use HTTPS protocol");
|
|
178
168
|
}
|
|
179
169
|
if (params.events !== undefined &&
|
|
180
170
|
(!Array.isArray(params.events) || params.events.length === 0)) {
|
|
181
|
-
throw new
|
|
171
|
+
throw new ValidationError("Events must be a non-empty array");
|
|
182
172
|
}
|
|
183
|
-
const
|
|
184
|
-
const response = await fetch(url, {
|
|
173
|
+
const response = await this.client["request"](`/v1/webhooks/${id}`, {}, {
|
|
185
174
|
method: "PATCH",
|
|
186
|
-
|
|
187
|
-
Authorization: `Bearer ${this.client["apiKey"]}`,
|
|
188
|
-
"Content-Type": "application/json",
|
|
189
|
-
},
|
|
190
|
-
body: JSON.stringify({
|
|
191
|
-
webhook: params,
|
|
192
|
-
}),
|
|
175
|
+
body: { webhook: params },
|
|
193
176
|
});
|
|
194
|
-
|
|
195
|
-
const errorText = await response.text();
|
|
196
|
-
throw new Error(`Failed to update webhook: ${response.status} ${errorText}`);
|
|
197
|
-
}
|
|
198
|
-
const data = (await response.json());
|
|
199
|
-
return "webhook" in data ? data.webhook : data;
|
|
177
|
+
return "webhook" in response ? response.webhook : response;
|
|
200
178
|
}
|
|
201
179
|
/**
|
|
202
180
|
* Delete a webhook endpoint
|
|
@@ -214,20 +192,9 @@ export class WebhooksResource {
|
|
|
214
192
|
*/
|
|
215
193
|
async delete(id) {
|
|
216
194
|
if (!id || typeof id !== "string") {
|
|
217
|
-
throw new
|
|
218
|
-
}
|
|
219
|
-
const url = `${this.client["baseUrl"]}/v1/webhooks/${id}`;
|
|
220
|
-
const response = await fetch(url, {
|
|
221
|
-
method: "DELETE",
|
|
222
|
-
headers: {
|
|
223
|
-
Authorization: `Bearer ${this.client["apiKey"]}`,
|
|
224
|
-
"Content-Type": "application/json",
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
if (!response.ok) {
|
|
228
|
-
const errorText = await response.text();
|
|
229
|
-
throw new Error(`Failed to delete webhook: ${response.status} ${errorText}`);
|
|
195
|
+
throw new ValidationError("Webhook ID must be a non-empty string");
|
|
230
196
|
}
|
|
197
|
+
await this.client["request"](`/v1/webhooks/${id}`, {}, { method: "DELETE" });
|
|
231
198
|
}
|
|
232
199
|
/**
|
|
233
200
|
* Test a webhook endpoint
|
|
@@ -252,21 +219,9 @@ export class WebhooksResource {
|
|
|
252
219
|
*/
|
|
253
220
|
async test(id) {
|
|
254
221
|
if (!id || typeof id !== "string") {
|
|
255
|
-
throw new
|
|
256
|
-
}
|
|
257
|
-
const url = `${this.client["baseUrl"]}/v1/webhooks/${id}/test`;
|
|
258
|
-
const response = await fetch(url, {
|
|
259
|
-
method: "POST",
|
|
260
|
-
headers: {
|
|
261
|
-
Authorization: `Bearer ${this.client["apiKey"]}`,
|
|
262
|
-
"Content-Type": "application/json",
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
if (!response.ok) {
|
|
266
|
-
const errorText = await response.text();
|
|
267
|
-
throw new Error(`Failed to test webhook: ${response.status} ${errorText}`);
|
|
222
|
+
throw new ValidationError("Webhook ID must be a non-empty string");
|
|
268
223
|
}
|
|
269
|
-
return
|
|
224
|
+
return this.client["request"](`/v1/webhooks/${id}/test`, {}, { method: "POST" });
|
|
270
225
|
}
|
|
271
226
|
/**
|
|
272
227
|
* Get webhook event history
|
|
@@ -289,9 +244,47 @@ export class WebhooksResource {
|
|
|
289
244
|
*/
|
|
290
245
|
async events(id) {
|
|
291
246
|
if (!id || typeof id !== "string") {
|
|
292
|
-
throw new
|
|
247
|
+
throw new ValidationError("Webhook ID must be a non-empty string");
|
|
293
248
|
}
|
|
294
249
|
const response = await this.client["request"](`/v1/webhooks/${id}/events`, {});
|
|
295
250
|
return Array.isArray(response) ? response : response.events;
|
|
296
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Verify a webhook signature.
|
|
254
|
+
*
|
|
255
|
+
* Validates that a webhook payload was sent by OilPriceAPI by checking
|
|
256
|
+
* the HMAC-SHA256 signature. Uses constant-time comparison to prevent
|
|
257
|
+
* timing attacks.
|
|
258
|
+
*
|
|
259
|
+
* @param payload - Raw request body (string or Buffer)
|
|
260
|
+
* @param signature - Value of the X-OilPriceAPI-Signature header (e.g., "sha256=abc123...")
|
|
261
|
+
* @param secret - Your webhook signing secret
|
|
262
|
+
* @returns true if signature is valid
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```typescript
|
|
266
|
+
* import express from 'express';
|
|
267
|
+
* import { OilPriceAPI } from 'oilpriceapi';
|
|
268
|
+
*
|
|
269
|
+
* const app = express();
|
|
270
|
+
* const client = new OilPriceAPI({ apiKey: 'your_key' });
|
|
271
|
+
*
|
|
272
|
+
* // Use raw body parser for webhook routes
|
|
273
|
+
* app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
|
|
274
|
+
* const signature = req.headers['x-oilpriceapi-signature'] as string;
|
|
275
|
+
* const isValid = client.webhooks.verifySignature(req.body, signature, 'your_secret');
|
|
276
|
+
*
|
|
277
|
+
* if (!isValid) {
|
|
278
|
+
* return res.status(401).send('Invalid signature');
|
|
279
|
+
* }
|
|
280
|
+
*
|
|
281
|
+
* const event = JSON.parse(req.body.toString());
|
|
282
|
+
* console.log('Verified webhook:', event.type);
|
|
283
|
+
* res.sendStatus(200);
|
|
284
|
+
* });
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
verifySignature(payload, signature, secret) {
|
|
288
|
+
return verifyWebhookSignature(payload, signature, secret);
|
|
289
|
+
}
|
|
297
290
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ export type RetryStrategy = "exponential" | "linear" | "fixed";
|
|
|
8
8
|
export interface OilPriceAPIConfig {
|
|
9
9
|
/**
|
|
10
10
|
* Your API key from https://www.oilpriceapi.com
|
|
11
|
+
* If not provided, reads from OILPRICEAPI_KEY environment variable.
|
|
11
12
|
*/
|
|
12
|
-
apiKey
|
|
13
|
+
apiKey?: string;
|
|
13
14
|
/**
|
|
14
15
|
* Base URL for the API (optional, for testing)
|
|
15
16
|
* @default "https://api.oilpriceapi.com"
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* - X-Client-Version header
|
|
8
8
|
* - Package.json (should match)
|
|
9
9
|
*/
|
|
10
|
-
export const SDK_VERSION =
|
|
10
|
+
export const SDK_VERSION = "0.8.2";
|
|
11
11
|
/**
|
|
12
12
|
* SDK identifier used in User-Agent and X-Api-Client headers
|
|
13
13
|
*/
|
|
14
|
-
export const SDK_NAME =
|
|
14
|
+
export const SDK_NAME = "oilpriceapi-node";
|
|
15
15
|
/**
|
|
16
16
|
* Build the full User-Agent string
|
|
17
17
|
*/
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oilpriceapi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Official Node.js SDK for Oil Price API - Real-time and historical oil & commodity prices",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
6
|
+
"main": "./dist/cjs/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"import":
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/cjs/index.js"
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
},
|
|
15
20
|
"files": [
|
|
@@ -18,9 +23,11 @@
|
|
|
18
23
|
"LICENSE"
|
|
19
24
|
],
|
|
20
25
|
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
26
|
+
"build": "tsc && tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
|
|
27
|
+
"lint": "eslint src/",
|
|
22
28
|
"test": "vitest run",
|
|
23
29
|
"test:watch": "vitest",
|
|
30
|
+
"docs": "typedoc",
|
|
24
31
|
"prepublishOnly": "npm run build"
|
|
25
32
|
},
|
|
26
33
|
"keywords": [
|
|
@@ -56,7 +63,9 @@
|
|
|
56
63
|
"devDependencies": {
|
|
57
64
|
"@types/node": "^20.10.0",
|
|
58
65
|
"@vitest/coverage-v8": "^4.0.16",
|
|
66
|
+
"eslint": "^9.39.4",
|
|
59
67
|
"typescript": "^5.3.0",
|
|
68
|
+
"typescript-eslint": "^8.57.2",
|
|
60
69
|
"vitest": "^4.0.16"
|
|
61
70
|
}
|
|
62
71
|
}
|