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
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Official Node.js SDK for Oil Price API
|
|
4
|
+
*
|
|
5
|
+
* Get real-time and historical oil & commodity prices in your Node.js applications.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ENERGY_PRICES_CHANNEL = exports.PriceStreamSubscription = exports.StreamingResource = exports.DataSourcesResource = exports.WebhooksResource = exports.EIFracFocusResource = exports.EIWellPermitsResource = exports.EIForecastsResource = exports.EIDrillingProductivityResource = exports.EIOPECProductionResource = exports.EIOilInventoriesResource = exports.EIRigCountsResource = exports.EnergyIntelligenceResource = exports.DrillingIntelligenceResource = exports.DataQualityResource = exports.ForecastsResource = exports.AnalyticsResource = exports.BunkerFuelsResource = exports.RigCountsResource = exports.StorageResource = exports.FuturesResource = exports.CommoditiesResource = exports.AlertsResource = exports.DieselResource = exports.TimeoutError = exports.ValidationError = exports.ServerError = exports.NotFoundError = exports.RateLimitError = exports.AuthenticationError = exports.OilPriceAPIError = exports.RawResource = exports.IndicatorsResource = exports.SpreadsResource = exports.FuturesContractFamily = exports.FUTURES_FAMILY_SLUGS = exports.FUTURES_CONTRACTS = exports.SDK_NAME = exports.SDK_VERSION = exports.OilPriceAPI = void 0;
|
|
11
|
+
exports.verifyWebhookSignature = verifyWebhookSignature;
|
|
12
|
+
const node_crypto_1 = require("node:crypto");
|
|
13
|
+
var client_js_1 = require("./client.js");
|
|
14
|
+
Object.defineProperty(exports, "OilPriceAPI", { enumerable: true, get: function () { return client_js_1.OilPriceAPI; } });
|
|
15
|
+
var version_js_1 = require("./version.js");
|
|
16
|
+
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return version_js_1.SDK_VERSION; } });
|
|
17
|
+
Object.defineProperty(exports, "SDK_NAME", { enumerable: true, get: function () { return version_js_1.SDK_NAME; } });
|
|
18
|
+
var futures_js_1 = require("./resources/futures.js");
|
|
19
|
+
Object.defineProperty(exports, "FUTURES_CONTRACTS", { enumerable: true, get: function () { return futures_js_1.FUTURES_CONTRACTS; } });
|
|
20
|
+
Object.defineProperty(exports, "FUTURES_FAMILY_SLUGS", { enumerable: true, get: function () { return futures_js_1.FUTURES_FAMILY_SLUGS; } });
|
|
21
|
+
Object.defineProperty(exports, "FuturesContractFamily", { enumerable: true, get: function () { return futures_js_1.FuturesContractFamily; } });
|
|
22
|
+
var spreads_js_1 = require("./resources/spreads.js");
|
|
23
|
+
Object.defineProperty(exports, "SpreadsResource", { enumerable: true, get: function () { return spreads_js_1.SpreadsResource; } });
|
|
24
|
+
var indicators_js_1 = require("./resources/indicators.js");
|
|
25
|
+
Object.defineProperty(exports, "IndicatorsResource", { enumerable: true, get: function () { return indicators_js_1.IndicatorsResource; } });
|
|
26
|
+
var raw_js_1 = require("./resources/raw.js");
|
|
27
|
+
Object.defineProperty(exports, "RawResource", { enumerable: true, get: function () { return raw_js_1.RawResource; } });
|
|
28
|
+
var errors_js_1 = require("./errors.js");
|
|
29
|
+
Object.defineProperty(exports, "OilPriceAPIError", { enumerable: true, get: function () { return errors_js_1.OilPriceAPIError; } });
|
|
30
|
+
Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_js_1.AuthenticationError; } });
|
|
31
|
+
Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return errors_js_1.RateLimitError; } });
|
|
32
|
+
Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_js_1.NotFoundError; } });
|
|
33
|
+
Object.defineProperty(exports, "ServerError", { enumerable: true, get: function () { return errors_js_1.ServerError; } });
|
|
34
|
+
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_js_1.ValidationError; } });
|
|
35
|
+
Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_js_1.TimeoutError; } });
|
|
36
|
+
var diesel_js_1 = require("./resources/diesel.js");
|
|
37
|
+
Object.defineProperty(exports, "DieselResource", { enumerable: true, get: function () { return diesel_js_1.DieselResource; } });
|
|
38
|
+
var alerts_js_1 = require("./resources/alerts.js");
|
|
39
|
+
Object.defineProperty(exports, "AlertsResource", { enumerable: true, get: function () { return alerts_js_1.AlertsResource; } });
|
|
40
|
+
var commodities_js_1 = require("./resources/commodities.js");
|
|
41
|
+
Object.defineProperty(exports, "CommoditiesResource", { enumerable: true, get: function () { return commodities_js_1.CommoditiesResource; } });
|
|
42
|
+
var futures_js_2 = require("./resources/futures.js");
|
|
43
|
+
Object.defineProperty(exports, "FuturesResource", { enumerable: true, get: function () { return futures_js_2.FuturesResource; } });
|
|
44
|
+
var storage_js_1 = require("./resources/storage.js");
|
|
45
|
+
Object.defineProperty(exports, "StorageResource", { enumerable: true, get: function () { return storage_js_1.StorageResource; } });
|
|
46
|
+
var rig_counts_js_1 = require("./resources/rig-counts.js");
|
|
47
|
+
Object.defineProperty(exports, "RigCountsResource", { enumerable: true, get: function () { return rig_counts_js_1.RigCountsResource; } });
|
|
48
|
+
var bunker_fuels_js_1 = require("./resources/bunker-fuels.js");
|
|
49
|
+
Object.defineProperty(exports, "BunkerFuelsResource", { enumerable: true, get: function () { return bunker_fuels_js_1.BunkerFuelsResource; } });
|
|
50
|
+
var analytics_js_1 = require("./resources/analytics.js");
|
|
51
|
+
Object.defineProperty(exports, "AnalyticsResource", { enumerable: true, get: function () { return analytics_js_1.AnalyticsResource; } });
|
|
52
|
+
var forecasts_js_1 = require("./resources/forecasts.js");
|
|
53
|
+
Object.defineProperty(exports, "ForecastsResource", { enumerable: true, get: function () { return forecasts_js_1.ForecastsResource; } });
|
|
54
|
+
var data_quality_js_1 = require("./resources/data-quality.js");
|
|
55
|
+
Object.defineProperty(exports, "DataQualityResource", { enumerable: true, get: function () { return data_quality_js_1.DataQualityResource; } });
|
|
56
|
+
var drilling_js_1 = require("./resources/drilling.js");
|
|
57
|
+
Object.defineProperty(exports, "DrillingIntelligenceResource", { enumerable: true, get: function () { return drilling_js_1.DrillingIntelligenceResource; } });
|
|
58
|
+
var index_js_1 = require("./resources/ei/index.js");
|
|
59
|
+
Object.defineProperty(exports, "EnergyIntelligenceResource", { enumerable: true, get: function () { return index_js_1.EnergyIntelligenceResource; } });
|
|
60
|
+
Object.defineProperty(exports, "EIRigCountsResource", { enumerable: true, get: function () { return index_js_1.EIRigCountsResource; } });
|
|
61
|
+
Object.defineProperty(exports, "EIOilInventoriesResource", { enumerable: true, get: function () { return index_js_1.EIOilInventoriesResource; } });
|
|
62
|
+
Object.defineProperty(exports, "EIOPECProductionResource", { enumerable: true, get: function () { return index_js_1.EIOPECProductionResource; } });
|
|
63
|
+
Object.defineProperty(exports, "EIDrillingProductivityResource", { enumerable: true, get: function () { return index_js_1.EIDrillingProductivityResource; } });
|
|
64
|
+
Object.defineProperty(exports, "EIForecastsResource", { enumerable: true, get: function () { return index_js_1.EIForecastsResource; } });
|
|
65
|
+
Object.defineProperty(exports, "EIWellPermitsResource", { enumerable: true, get: function () { return index_js_1.EIWellPermitsResource; } });
|
|
66
|
+
Object.defineProperty(exports, "EIFracFocusResource", { enumerable: true, get: function () { return index_js_1.EIFracFocusResource; } });
|
|
67
|
+
var webhooks_js_1 = require("./resources/webhooks.js");
|
|
68
|
+
Object.defineProperty(exports, "WebhooksResource", { enumerable: true, get: function () { return webhooks_js_1.WebhooksResource; } });
|
|
69
|
+
var data_sources_js_1 = require("./resources/data-sources.js");
|
|
70
|
+
Object.defineProperty(exports, "DataSourcesResource", { enumerable: true, get: function () { return data_sources_js_1.DataSourcesResource; } });
|
|
71
|
+
var streaming_js_1 = require("./resources/streaming.js");
|
|
72
|
+
Object.defineProperty(exports, "StreamingResource", { enumerable: true, get: function () { return streaming_js_1.StreamingResource; } });
|
|
73
|
+
Object.defineProperty(exports, "PriceStreamSubscription", { enumerable: true, get: function () { return streaming_js_1.PriceStreamSubscription; } });
|
|
74
|
+
Object.defineProperty(exports, "ENERGY_PRICES_CHANNEL", { enumerable: true, get: function () { return streaming_js_1.ENERGY_PRICES_CHANNEL; } });
|
|
75
|
+
/**
|
|
76
|
+
* Standalone webhook signature verification.
|
|
77
|
+
*
|
|
78
|
+
* Convenience function for verifying webhook signatures without
|
|
79
|
+
* instantiating a full client.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { verifyWebhookSignature } from 'oilpriceapi';
|
|
84
|
+
*
|
|
85
|
+
* const isValid = verifyWebhookSignature(rawBody, signatureHeader, secret);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
function verifyWebhookSignature(payload, signature, secret) {
|
|
89
|
+
const expectedSignature = "sha256=" + (0, node_crypto_1.createHmac)("sha256", secret).update(payload).digest("hex");
|
|
90
|
+
try {
|
|
91
|
+
return (0, node_crypto_1.timingSafeEqual)(Buffer.from(expectedSignature), Buffer.from(signature));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Price Alerts Resource
|
|
4
|
+
*
|
|
5
|
+
* Manage price alert configurations for automated notifications.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.AlertsResource = void 0;
|
|
9
|
+
const errors_js_1 = require("../errors.js");
|
|
10
|
+
/**
|
|
11
|
+
* Price Alerts Resource
|
|
12
|
+
*
|
|
13
|
+
* Manage automated price alert configurations with webhook notifications.
|
|
14
|
+
*
|
|
15
|
+
* **Features:**
|
|
16
|
+
* - Create alerts with customizable conditions
|
|
17
|
+
* - Monitor commodity prices automatically
|
|
18
|
+
* - Webhook notifications when conditions are met
|
|
19
|
+
* - Cooldown periods to prevent spam
|
|
20
|
+
* - 100 alerts per user soft limit
|
|
21
|
+
*
|
|
22
|
+
* **Example:**
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { OilPriceAPI } from 'oilpriceapi';
|
|
25
|
+
*
|
|
26
|
+
* const client = new OilPriceAPI({ apiKey: 'your_key' });
|
|
27
|
+
*
|
|
28
|
+
* // Create a price alert
|
|
29
|
+
* const alert = await client.alerts.create({
|
|
30
|
+
* name: 'Brent High Price Alert',
|
|
31
|
+
* commodity_code: 'BRENT_CRUDE_USD',
|
|
32
|
+
* condition_operator: 'greater_than',
|
|
33
|
+
* condition_value: 85.00,
|
|
34
|
+
* webhook_url: 'https://your-app.com/webhooks/price-alert',
|
|
35
|
+
* enabled: true,
|
|
36
|
+
* cooldown_minutes: 60
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* console.log(`Alert created: ${alert.name} (ID: ${alert.id})`);
|
|
40
|
+
*
|
|
41
|
+
* // List all alerts
|
|
42
|
+
* const alerts = await client.alerts.list();
|
|
43
|
+
* console.log(`You have ${alerts.length} active alerts`);
|
|
44
|
+
*
|
|
45
|
+
* // Update an alert
|
|
46
|
+
* const updated = await client.alerts.update(alert.id, {
|
|
47
|
+
* condition_value: 90.00,
|
|
48
|
+
* enabled: false
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* // Delete an alert
|
|
52
|
+
* await client.alerts.delete(alert.id);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
class AlertsResource {
|
|
56
|
+
constructor(client) {
|
|
57
|
+
this.client = client;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* List all price alerts for the authenticated user
|
|
61
|
+
*
|
|
62
|
+
* Returns all configured price alerts, including disabled ones.
|
|
63
|
+
* Alerts are sorted by creation date (newest first).
|
|
64
|
+
*
|
|
65
|
+
* @returns Array of all price alerts
|
|
66
|
+
*
|
|
67
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
68
|
+
* @throws {AuthenticationError} If API key is invalid
|
|
69
|
+
* @throws {RateLimitError} If rate limit exceeded
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const alerts = await client.alerts.list();
|
|
74
|
+
*
|
|
75
|
+
* alerts.forEach(alert => {
|
|
76
|
+
* console.log(`${alert.name}: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
|
|
77
|
+
* console.log(` Status: ${alert.enabled ? 'Active' : 'Disabled'}`);
|
|
78
|
+
* console.log(` Triggers: ${alert.trigger_count}`);
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
async list() {
|
|
83
|
+
const response = await this.client["request"]("/v1/alerts", {});
|
|
84
|
+
// API returns array directly, but handle both formats for compatibility
|
|
85
|
+
return Array.isArray(response) ? response : response.alerts || [];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get a specific price alert by ID
|
|
89
|
+
*
|
|
90
|
+
* @param id - The alert ID to retrieve
|
|
91
|
+
* @returns The price alert details
|
|
92
|
+
*
|
|
93
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
94
|
+
* @throws {DataNotFoundError} If alert ID not found
|
|
95
|
+
* @throws {AuthenticationError} If API key is invalid
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const alert = await client.alerts.get('550e8400-e29b-41d4-a716-446655440000');
|
|
100
|
+
* console.log(`Alert: ${alert.name}`);
|
|
101
|
+
* console.log(`Condition: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
|
|
102
|
+
* console.log(`Last triggered: ${alert.last_triggered_at || 'Never'}`);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
async get(id) {
|
|
106
|
+
if (!id || typeof id !== "string") {
|
|
107
|
+
throw new errors_js_1.ValidationError("Alert ID must be a non-empty string");
|
|
108
|
+
}
|
|
109
|
+
const response = await this.client["request"](`/v1/alerts/${id}`, {});
|
|
110
|
+
// API returns object directly, but handle both formats for compatibility
|
|
111
|
+
return "alert" in response ? response.alert : response;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create a new price alert
|
|
115
|
+
*
|
|
116
|
+
* Creates a price alert that monitors a commodity and triggers when
|
|
117
|
+
* the price meets the specified condition. Optionally sends webhook
|
|
118
|
+
* notifications when triggered.
|
|
119
|
+
*
|
|
120
|
+
* **Validation:**
|
|
121
|
+
* - name: 1-100 characters
|
|
122
|
+
* - commodity_code: Must be a valid commodity code
|
|
123
|
+
* - condition_value: Must be > 0 and <= 1,000,000
|
|
124
|
+
* - cooldown_minutes: Must be 0-1440 (24 hours)
|
|
125
|
+
* - webhook_url: Must be valid HTTPS URL if provided
|
|
126
|
+
*
|
|
127
|
+
* **Soft Limit:** 100 alerts per user
|
|
128
|
+
*
|
|
129
|
+
* @param params - Alert configuration parameters
|
|
130
|
+
* @returns The created price alert
|
|
131
|
+
*
|
|
132
|
+
* @throws {ValidationError} If parameters are invalid
|
|
133
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
134
|
+
* @throws {AuthenticationError} If API key is invalid
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* // Alert when Brent crude exceeds $85
|
|
139
|
+
* const alert = await client.alerts.create({
|
|
140
|
+
* name: 'Brent $85 Alert',
|
|
141
|
+
* commodity_code: 'BRENT_CRUDE_USD',
|
|
142
|
+
* condition_operator: 'greater_than',
|
|
143
|
+
* condition_value: 85.00,
|
|
144
|
+
* webhook_url: 'https://myapp.com/webhook',
|
|
145
|
+
* enabled: true,
|
|
146
|
+
* cooldown_minutes: 120 // 2 hours between triggers
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
async create(params) {
|
|
151
|
+
// Validate required fields
|
|
152
|
+
if (!params.name || typeof params.name !== "string") {
|
|
153
|
+
throw new errors_js_1.ValidationError("Alert name is required and must be a string");
|
|
154
|
+
}
|
|
155
|
+
if (params.name.length < 1 || params.name.length > 100) {
|
|
156
|
+
throw new errors_js_1.ValidationError("Alert name must be 1-100 characters");
|
|
157
|
+
}
|
|
158
|
+
if (!params.commodity_code || typeof params.commodity_code !== "string") {
|
|
159
|
+
throw new errors_js_1.ValidationError("Commodity code is required and must be a string");
|
|
160
|
+
}
|
|
161
|
+
if (!params.condition_operator) {
|
|
162
|
+
throw new errors_js_1.ValidationError("Condition operator is required");
|
|
163
|
+
}
|
|
164
|
+
const validOperators = [
|
|
165
|
+
"greater_than",
|
|
166
|
+
"less_than",
|
|
167
|
+
"equals",
|
|
168
|
+
"greater_than_or_equal",
|
|
169
|
+
"less_than_or_equal",
|
|
170
|
+
];
|
|
171
|
+
if (!validOperators.includes(params.condition_operator)) {
|
|
172
|
+
throw new errors_js_1.ValidationError(`Invalid operator. Must be one of: ${validOperators.join(", ")}`);
|
|
173
|
+
}
|
|
174
|
+
if (typeof params.condition_value !== "number") {
|
|
175
|
+
throw new errors_js_1.ValidationError("Condition value must be a number");
|
|
176
|
+
}
|
|
177
|
+
if (params.condition_value <= 0 || params.condition_value > 1000000) {
|
|
178
|
+
throw new errors_js_1.ValidationError("Condition value must be greater than 0 and less than or equal to 1,000,000");
|
|
179
|
+
}
|
|
180
|
+
// Validate optional fields
|
|
181
|
+
if (params.webhook_url !== undefined) {
|
|
182
|
+
if (typeof params.webhook_url !== "string") {
|
|
183
|
+
throw new errors_js_1.ValidationError("Webhook URL must be a string");
|
|
184
|
+
}
|
|
185
|
+
if (params.webhook_url && !params.webhook_url.startsWith("https://")) {
|
|
186
|
+
throw new errors_js_1.ValidationError("Webhook URL must use HTTPS protocol");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (params.cooldown_minutes !== undefined) {
|
|
190
|
+
if (typeof params.cooldown_minutes !== "number") {
|
|
191
|
+
throw new errors_js_1.ValidationError("Cooldown minutes must be a number");
|
|
192
|
+
}
|
|
193
|
+
if (params.cooldown_minutes < 0 || params.cooldown_minutes > 1440) {
|
|
194
|
+
throw new errors_js_1.ValidationError("Cooldown minutes must be between 0 and 1440 (24 hours)");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const response = await this.client["request"]("/v1/alerts", {}, {
|
|
198
|
+
method: "POST",
|
|
199
|
+
body: {
|
|
200
|
+
price_alert: {
|
|
201
|
+
name: params.name,
|
|
202
|
+
commodity_code: params.commodity_code,
|
|
203
|
+
condition_operator: params.condition_operator,
|
|
204
|
+
condition_value: params.condition_value,
|
|
205
|
+
webhook_url: params.webhook_url,
|
|
206
|
+
enabled: params.enabled ?? true,
|
|
207
|
+
cooldown_minutes: params.cooldown_minutes ?? 60,
|
|
208
|
+
metadata: params.metadata,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
return "alert" in response ? response.alert : response;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Update an existing price alert
|
|
216
|
+
*
|
|
217
|
+
* Updates one or more fields of an existing alert. Only provided
|
|
218
|
+
* fields will be updated; others remain unchanged.
|
|
219
|
+
*
|
|
220
|
+
* @param id - The alert ID to update
|
|
221
|
+
* @param params - Fields to update (partial update supported)
|
|
222
|
+
* @returns The updated price alert
|
|
223
|
+
*
|
|
224
|
+
* @throws {ValidationError} If parameters are invalid
|
|
225
|
+
* @throws {DataNotFoundError} If alert ID not found
|
|
226
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```typescript
|
|
230
|
+
* // Disable an alert
|
|
231
|
+
* await client.alerts.update(alertId, { enabled: false });
|
|
232
|
+
*
|
|
233
|
+
* // Change threshold and cooldown
|
|
234
|
+
* await client.alerts.update(alertId, {
|
|
235
|
+
* condition_value: 90.00,
|
|
236
|
+
* cooldown_minutes: 180
|
|
237
|
+
* });
|
|
238
|
+
*
|
|
239
|
+
* // Update webhook URL
|
|
240
|
+
* await client.alerts.update(alertId, {
|
|
241
|
+
* webhook_url: 'https://newapp.com/webhook'
|
|
242
|
+
* });
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
async update(id, params) {
|
|
246
|
+
if (!id || typeof id !== "string") {
|
|
247
|
+
throw new errors_js_1.ValidationError("Alert ID must be a non-empty string");
|
|
248
|
+
}
|
|
249
|
+
// Validate fields if provided
|
|
250
|
+
if (params.name !== undefined) {
|
|
251
|
+
if (typeof params.name !== "string" ||
|
|
252
|
+
params.name.length < 1 ||
|
|
253
|
+
params.name.length > 100) {
|
|
254
|
+
throw new errors_js_1.ValidationError("Alert name must be 1-100 characters");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (params.condition_operator !== undefined) {
|
|
258
|
+
const validOperators = [
|
|
259
|
+
"greater_than",
|
|
260
|
+
"less_than",
|
|
261
|
+
"equals",
|
|
262
|
+
"greater_than_or_equal",
|
|
263
|
+
"less_than_or_equal",
|
|
264
|
+
];
|
|
265
|
+
if (!validOperators.includes(params.condition_operator)) {
|
|
266
|
+
throw new errors_js_1.ValidationError(`Invalid operator. Must be one of: ${validOperators.join(", ")}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (params.condition_value !== undefined) {
|
|
270
|
+
if (typeof params.condition_value !== "number") {
|
|
271
|
+
throw new errors_js_1.ValidationError("Condition value must be a number");
|
|
272
|
+
}
|
|
273
|
+
if (params.condition_value <= 0 || params.condition_value > 1000000) {
|
|
274
|
+
throw new errors_js_1.ValidationError("Condition value must be greater than 0 and less than or equal to 1,000,000");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (params.webhook_url !== undefined && params.webhook_url !== null) {
|
|
278
|
+
if (typeof params.webhook_url !== "string" ||
|
|
279
|
+
!params.webhook_url.startsWith("https://")) {
|
|
280
|
+
throw new errors_js_1.ValidationError("Webhook URL must be a valid HTTPS URL");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (params.cooldown_minutes !== undefined) {
|
|
284
|
+
if (typeof params.cooldown_minutes !== "number" ||
|
|
285
|
+
params.cooldown_minutes < 0 ||
|
|
286
|
+
params.cooldown_minutes > 1440) {
|
|
287
|
+
throw new errors_js_1.ValidationError("Cooldown minutes must be between 0 and 1440 (24 hours)");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const response = await this.client["request"](`/v1/alerts/${id}`, {}, {
|
|
291
|
+
method: "PATCH",
|
|
292
|
+
body: { price_alert: params },
|
|
293
|
+
});
|
|
294
|
+
return "alert" in response ? response.alert : response;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Delete a price alert
|
|
298
|
+
*
|
|
299
|
+
* Permanently deletes a price alert. This action cannot be undone.
|
|
300
|
+
*
|
|
301
|
+
* @param id - The alert ID to delete
|
|
302
|
+
*
|
|
303
|
+
* @throws {DataNotFoundError} If alert ID not found
|
|
304
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* await client.alerts.delete(alertId);
|
|
309
|
+
* console.log('Alert deleted successfully');
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
async delete(id) {
|
|
313
|
+
if (!id || typeof id !== "string") {
|
|
314
|
+
throw new errors_js_1.ValidationError("Alert ID must be a non-empty string");
|
|
315
|
+
}
|
|
316
|
+
await this.client["request"](`/v1/alerts/${id}`, {}, { method: "DELETE" });
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Test an alert
|
|
320
|
+
*
|
|
321
|
+
* Triggers a test run of the alert to verify it's working correctly.
|
|
322
|
+
* Does not affect the alert's cooldown or trigger count.
|
|
323
|
+
*
|
|
324
|
+
* @param alertId - The alert ID to test
|
|
325
|
+
* @returns Test results
|
|
326
|
+
*
|
|
327
|
+
* @throws {NotFoundError} If alert not found
|
|
328
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* const result = await client.alerts.test(alertId);
|
|
333
|
+
* console.log(`Test ${result.success ? 'passed' : 'failed'}`);
|
|
334
|
+
* if (result.response_time_ms) {
|
|
335
|
+
* console.log(`Webhook response time: ${result.response_time_ms}ms`);
|
|
336
|
+
* }
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
async test(alertId) {
|
|
340
|
+
if (!alertId || typeof alertId !== "string") {
|
|
341
|
+
throw new errors_js_1.ValidationError("Alert ID must be a non-empty string");
|
|
342
|
+
}
|
|
343
|
+
return this.client["request"](`/v1/alerts/${alertId}/test`, {}, { method: "POST" });
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Get available alert triggers
|
|
347
|
+
*
|
|
348
|
+
* Returns list of supported trigger conditions and event types.
|
|
349
|
+
*
|
|
350
|
+
* @returns Array of available triggers
|
|
351
|
+
*
|
|
352
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```typescript
|
|
356
|
+
* const triggers = await client.alerts.triggers();
|
|
357
|
+
* triggers.forEach(trigger => {
|
|
358
|
+
* console.log(`${trigger.name}: ${trigger.description}`);
|
|
359
|
+
* });
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
async triggers() {
|
|
363
|
+
const response = await this.client["request"]("/v1/alerts/triggers", {});
|
|
364
|
+
return Array.isArray(response) ? response : response.triggers;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Get alert analytics history
|
|
368
|
+
*
|
|
369
|
+
* Returns historical analytics data for alerts including trigger frequency,
|
|
370
|
+
* success rates, and response times.
|
|
371
|
+
*
|
|
372
|
+
* @returns Analytics history data
|
|
373
|
+
*
|
|
374
|
+
* @throws {OilPriceAPIError} If API request fails
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* ```typescript
|
|
378
|
+
* const analytics = await client.alerts.analyticsHistory();
|
|
379
|
+
* console.log(`Total triggers: ${analytics.total_triggers}`);
|
|
380
|
+
* console.log(`Success rate: ${analytics.success_rate}%`);
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
async analyticsHistory() {
|
|
384
|
+
return this.client["request"]("/v1/alerts/analytics_history", {});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
exports.AlertsResource = AlertsResource;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Analytics Resource
|
|
4
|
+
*
|
|
5
|
+
* Access advanced analytics including performance metrics, statistical analysis,
|
|
6
|
+
* correlations, trend detection, spreads, and forecasts.
|
|
7
|
+
*
|
|
8
|
+
* NOTE ON PARAMETERS: The OilPriceAPI analytics controller reads commodity
|
|
9
|
+
* identifiers as `code` / `code1` / `code2` and the lookback window as `period`
|
|
10
|
+
* (in days). Earlier versions of this SDK sent `commodity` / `commodity1` /
|
|
11
|
+
* `commodity2` / `days`, which the API silently ignored (and `correlation`
|
|
12
|
+
* returned "code1 and code2 parameters are required"). These methods now send
|
|
13
|
+
* the parameter names the controller actually reads.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AnalyticsResource = void 0;
|
|
17
|
+
const errors_js_1 = require("../errors.js");
|
|
18
|
+
/**
|
|
19
|
+
* Analytics Resource
|
|
20
|
+
*
|
|
21
|
+
* Access advanced analytics including performance metrics, statistical analysis,
|
|
22
|
+
* correlations, trends, spreads, and forecasts.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { OilPriceAPI } from 'oilpriceapi';
|
|
27
|
+
*
|
|
28
|
+
* const client = new OilPriceAPI({ apiKey: 'your_key' });
|
|
29
|
+
*
|
|
30
|
+
* // Analyze correlation between two commodities (90-day window)
|
|
31
|
+
* const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', { period: 90 });
|
|
32
|
+
* console.log(`Correlation: ${corr.correlation}`);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
class AnalyticsResource {
|
|
36
|
+
constructor(client) {
|
|
37
|
+
this.client = client;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the authenticated user's API usage analytics for the dashboard.
|
|
41
|
+
*
|
|
42
|
+
* Maps to `GET /v1/analytics/performance`, which reads a `range`
|
|
43
|
+
* parameter (`7d` | `30d` | `90d`).
|
|
44
|
+
*
|
|
45
|
+
* @param options - `{ range }` (default range '30d')
|
|
46
|
+
* @returns Usage analytics (overview, daily usage, endpoint breakdown, ...)
|
|
47
|
+
*/
|
|
48
|
+
async performance(options) {
|
|
49
|
+
const params = {};
|
|
50
|
+
if (options?.range)
|
|
51
|
+
params.range = options.range;
|
|
52
|
+
return this.client["request"]("/v1/analytics/performance", params);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get statistical analysis for a commodity.
|
|
56
|
+
*
|
|
57
|
+
* Maps to `GET /v1/analytics/statistics`, which reads `code` and `period`.
|
|
58
|
+
*
|
|
59
|
+
* @param code - Commodity code to analyze (e.g. 'WTI_USD')
|
|
60
|
+
* @param period - Lookback window in days (default: 30)
|
|
61
|
+
* @returns Statistical analysis
|
|
62
|
+
*
|
|
63
|
+
* @throws {ValidationError} If code is empty
|
|
64
|
+
*/
|
|
65
|
+
async statistics(code, period) {
|
|
66
|
+
if (!code || typeof code !== "string") {
|
|
67
|
+
throw new errors_js_1.ValidationError("Commodity code must be a non-empty string");
|
|
68
|
+
}
|
|
69
|
+
const params = { code };
|
|
70
|
+
if (period !== undefined)
|
|
71
|
+
params.period = period.toString();
|
|
72
|
+
return this.client["request"]("/v1/analytics/statistics", params);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Analyze correlation between two commodities.
|
|
76
|
+
*
|
|
77
|
+
* Maps to `GET /v1/analytics/correlation`, which reads `code1`, `code2`,
|
|
78
|
+
* `period` and optional `type`, `window`, `codes`.
|
|
79
|
+
*
|
|
80
|
+
* @param code1 - First commodity code
|
|
81
|
+
* @param code2 - Second commodity code
|
|
82
|
+
* @param options - Lookback window in days, or `{ period, type, window, codes }`
|
|
83
|
+
* @returns Correlation analysis
|
|
84
|
+
*
|
|
85
|
+
* @throws {ValidationError} If either code is empty
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', { period: 90 });
|
|
90
|
+
* console.log(corr.correlation);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
async correlation(code1, code2, options) {
|
|
94
|
+
if (!code1 || typeof code1 !== "string") {
|
|
95
|
+
throw new errors_js_1.ValidationError("First commodity code must be a non-empty string");
|
|
96
|
+
}
|
|
97
|
+
if (!code2 || typeof code2 !== "string") {
|
|
98
|
+
throw new errors_js_1.ValidationError("Second commodity code must be a non-empty string");
|
|
99
|
+
}
|
|
100
|
+
const opts = typeof options === "number" ? { period: options } : options || {};
|
|
101
|
+
const params = { code1, code2 };
|
|
102
|
+
if (opts.period !== undefined)
|
|
103
|
+
params.period = opts.period.toString();
|
|
104
|
+
if (opts.type)
|
|
105
|
+
params.type = opts.type;
|
|
106
|
+
if (opts.window !== undefined)
|
|
107
|
+
params.window = opts.window.toString();
|
|
108
|
+
if (opts.codes && opts.codes.length > 0)
|
|
109
|
+
params.codes = opts.codes.join(",");
|
|
110
|
+
return this.client["request"]("/v1/analytics/correlation", params);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Analyze price trend for a commodity.
|
|
114
|
+
*
|
|
115
|
+
* Maps to `GET /v1/analytics/trend`, which reads `code`, `period` and
|
|
116
|
+
* optional `type` ('analysis' | 'sma' | 'ema' | 'rsi' | 'levels') and `window`.
|
|
117
|
+
*
|
|
118
|
+
* @param code - Commodity code to analyze
|
|
119
|
+
* @param options - Lookback window in days, or `{ period, type, window }`
|
|
120
|
+
* @returns Trend analysis
|
|
121
|
+
*
|
|
122
|
+
* @throws {ValidationError} If code is empty
|
|
123
|
+
*/
|
|
124
|
+
async trend(code, options) {
|
|
125
|
+
if (!code || typeof code !== "string") {
|
|
126
|
+
throw new errors_js_1.ValidationError("Commodity code must be a non-empty string");
|
|
127
|
+
}
|
|
128
|
+
const opts = typeof options === "number" ? { period: options } : options || {};
|
|
129
|
+
const params = { code };
|
|
130
|
+
if (opts.period !== undefined)
|
|
131
|
+
params.period = opts.period.toString();
|
|
132
|
+
if (opts.type)
|
|
133
|
+
params.type = opts.type;
|
|
134
|
+
if (opts.window !== undefined)
|
|
135
|
+
params.window = opts.window.toString();
|
|
136
|
+
return this.client["request"]("/v1/analytics/trend", params);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Analyze a named commodity spread (basis / crack / ratio).
|
|
140
|
+
*
|
|
141
|
+
* Maps to `GET /v1/analytics/spread`, which reads `spread` (the named spread,
|
|
142
|
+
* e.g. 'wti_brent'), `period` and optional `type` ('current' | 'historical').
|
|
143
|
+
* Call with no `spread` to list the available named spreads.
|
|
144
|
+
*
|
|
145
|
+
* @param spread - Named spread (e.g. 'wti_brent'); omit to list available spreads
|
|
146
|
+
* @param options - Lookback window in days, or `{ period, type }`
|
|
147
|
+
* @returns Spread analysis (or the list of available spreads)
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const spread = await client.analytics.spread('wti_brent', { period: 30 });
|
|
152
|
+
* console.log(spread.current_spread);
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
async spread(spread, options) {
|
|
156
|
+
const opts = typeof options === "number" ? { period: options } : options || {};
|
|
157
|
+
const params = {};
|
|
158
|
+
if (spread)
|
|
159
|
+
params.spread = spread;
|
|
160
|
+
if (opts.period !== undefined)
|
|
161
|
+
params.period = opts.period.toString();
|
|
162
|
+
if (opts.type)
|
|
163
|
+
params.type = opts.type;
|
|
164
|
+
return this.client["request"]("/v1/analytics/spread", params);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get a statistical price forecast for a commodity.
|
|
168
|
+
*
|
|
169
|
+
* Maps to `GET /v1/analytics/forecast`, which reads `code`, `method`
|
|
170
|
+
* (default 'ema') and `period` (default 90). Call with no `code` to list
|
|
171
|
+
* the available forecast methods.
|
|
172
|
+
*
|
|
173
|
+
* @param code - Commodity code to forecast; omit to list available methods
|
|
174
|
+
* @param options - `{ method, period }`
|
|
175
|
+
* @returns Price forecast (or the list of available methods)
|
|
176
|
+
*/
|
|
177
|
+
async forecast(code, options) {
|
|
178
|
+
const params = {};
|
|
179
|
+
if (code)
|
|
180
|
+
params.code = code;
|
|
181
|
+
if (options?.method)
|
|
182
|
+
params.method = options.method;
|
|
183
|
+
if (options?.period !== undefined)
|
|
184
|
+
params.period = options.period.toString();
|
|
185
|
+
return this.client["request"]("/v1/analytics/forecast", params);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.AnalyticsResource = AnalyticsResource;
|