oilpriceapi 0.3.2 → 0.5.1

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.
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Price Alerts Resource
3
+ *
4
+ * Manage price alert configurations for automated notifications.
5
+ */
6
+ import type { OilPriceAPI } from '../client.js';
7
+ /**
8
+ * Valid condition operators for price alerts
9
+ */
10
+ export type AlertOperator = 'greater_than' | 'less_than' | 'equals' | 'greater_than_or_equal' | 'less_than_or_equal';
11
+ /**
12
+ * Price alert configuration
13
+ */
14
+ export interface PriceAlert {
15
+ /** Unique alert identifier */
16
+ id: string;
17
+ /** User-friendly alert name */
18
+ name: string;
19
+ /** Commodity code to monitor (e.g., "BRENT_CRUDE_USD") */
20
+ commodity_code: string;
21
+ /** Comparison operator for alert condition */
22
+ condition_operator: AlertOperator;
23
+ /** Price threshold value in USD */
24
+ condition_value: number;
25
+ /** Optional webhook URL for notifications */
26
+ webhook_url?: string | null;
27
+ /** Whether the alert is active */
28
+ enabled: boolean;
29
+ /** Minimum minutes between alert triggers (0-1440) */
30
+ cooldown_minutes: number;
31
+ /** Optional metadata for custom use */
32
+ metadata?: Record<string, unknown> | null;
33
+ /** Number of times this alert has triggered */
34
+ trigger_count: number;
35
+ /** ISO timestamp of last trigger, or null if never triggered */
36
+ last_triggered_at: string | null;
37
+ /** ISO timestamp when alert was created */
38
+ created_at: string;
39
+ /** ISO timestamp when alert was last updated */
40
+ updated_at: string;
41
+ }
42
+ /**
43
+ * Parameters for creating a new price alert
44
+ */
45
+ export interface CreateAlertParams {
46
+ /** User-friendly alert name */
47
+ name: string;
48
+ /** Commodity code to monitor (e.g., "BRENT_CRUDE_USD") */
49
+ commodity_code: string;
50
+ /** Comparison operator for alert condition */
51
+ condition_operator: AlertOperator;
52
+ /** Price threshold value in USD (must be > 0 and <= 1,000,000) */
53
+ condition_value: number;
54
+ /** Optional webhook URL for POST notifications */
55
+ webhook_url?: string;
56
+ /** Whether to enable the alert immediately (default: true) */
57
+ enabled?: boolean;
58
+ /** Minimum minutes between triggers (0-1440, default: 60) */
59
+ cooldown_minutes?: number;
60
+ /** Optional metadata for custom use */
61
+ metadata?: Record<string, unknown>;
62
+ }
63
+ /**
64
+ * Parameters for updating an existing price alert
65
+ */
66
+ export interface UpdateAlertParams {
67
+ /** User-friendly alert name */
68
+ name?: string;
69
+ /** Commodity code to monitor */
70
+ commodity_code?: string;
71
+ /** Comparison operator for alert condition */
72
+ condition_operator?: AlertOperator;
73
+ /** Price threshold value in USD */
74
+ condition_value?: number;
75
+ /** Webhook URL for notifications */
76
+ webhook_url?: string | null;
77
+ /** Whether the alert is active */
78
+ enabled?: boolean;
79
+ /** Minimum minutes between triggers (0-1440) */
80
+ cooldown_minutes?: number;
81
+ /** Metadata for custom use */
82
+ metadata?: Record<string, unknown> | null;
83
+ }
84
+ /**
85
+ * Response from webhook test endpoint
86
+ */
87
+ export interface WebhookTestResponse {
88
+ /** Test result status */
89
+ success: boolean;
90
+ /** HTTP status code from webhook endpoint */
91
+ status_code: number;
92
+ /** Response time in milliseconds */
93
+ response_time_ms: number;
94
+ /** Response body from webhook endpoint */
95
+ response_body?: string;
96
+ /** Error message if test failed */
97
+ error?: string;
98
+ }
99
+ /**
100
+ * Price Alerts Resource
101
+ *
102
+ * Manage automated price alert configurations with webhook notifications.
103
+ *
104
+ * **Features:**
105
+ * - Create alerts with customizable conditions
106
+ * - Monitor commodity prices automatically
107
+ * - Webhook notifications when conditions are met
108
+ * - Cooldown periods to prevent spam
109
+ * - 100 alerts per user soft limit
110
+ *
111
+ * **Example:**
112
+ * ```typescript
113
+ * import { OilPriceAPI } from 'oilpriceapi';
114
+ *
115
+ * const client = new OilPriceAPI({ apiKey: 'your_key' });
116
+ *
117
+ * // Create a price alert
118
+ * const alert = await client.alerts.create({
119
+ * name: 'Brent High Price Alert',
120
+ * commodity_code: 'BRENT_CRUDE_USD',
121
+ * condition_operator: 'greater_than',
122
+ * condition_value: 85.00,
123
+ * webhook_url: 'https://your-app.com/webhooks/price-alert',
124
+ * enabled: true,
125
+ * cooldown_minutes: 60
126
+ * });
127
+ *
128
+ * console.log(`Alert created: ${alert.name} (ID: ${alert.id})`);
129
+ *
130
+ * // List all alerts
131
+ * const alerts = await client.alerts.list();
132
+ * console.log(`You have ${alerts.length} active alerts`);
133
+ *
134
+ * // Update an alert
135
+ * const updated = await client.alerts.update(alert.id, {
136
+ * condition_value: 90.00,
137
+ * enabled: false
138
+ * });
139
+ *
140
+ * // Delete an alert
141
+ * await client.alerts.delete(alert.id);
142
+ * ```
143
+ */
144
+ export declare class AlertsResource {
145
+ private client;
146
+ constructor(client: OilPriceAPI);
147
+ /**
148
+ * List all price alerts for the authenticated user
149
+ *
150
+ * Returns all configured price alerts, including disabled ones.
151
+ * Alerts are sorted by creation date (newest first).
152
+ *
153
+ * @returns Array of all price alerts
154
+ *
155
+ * @throws {OilPriceAPIError} If API request fails
156
+ * @throws {AuthenticationError} If API key is invalid
157
+ * @throws {RateLimitError} If rate limit exceeded
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const alerts = await client.alerts.list();
162
+ *
163
+ * alerts.forEach(alert => {
164
+ * console.log(`${alert.name}: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
165
+ * console.log(` Status: ${alert.enabled ? 'Active' : 'Disabled'}`);
166
+ * console.log(` Triggers: ${alert.trigger_count}`);
167
+ * });
168
+ * ```
169
+ */
170
+ list(): Promise<PriceAlert[]>;
171
+ /**
172
+ * Get a specific price alert by ID
173
+ *
174
+ * @param id - The alert ID to retrieve
175
+ * @returns The price alert details
176
+ *
177
+ * @throws {OilPriceAPIError} If API request fails
178
+ * @throws {DataNotFoundError} If alert ID not found
179
+ * @throws {AuthenticationError} If API key is invalid
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * const alert = await client.alerts.get('550e8400-e29b-41d4-a716-446655440000');
184
+ * console.log(`Alert: ${alert.name}`);
185
+ * console.log(`Condition: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
186
+ * console.log(`Last triggered: ${alert.last_triggered_at || 'Never'}`);
187
+ * ```
188
+ */
189
+ get(id: string): Promise<PriceAlert>;
190
+ /**
191
+ * Create a new price alert
192
+ *
193
+ * Creates a price alert that monitors a commodity and triggers when
194
+ * the price meets the specified condition. Optionally sends webhook
195
+ * notifications when triggered.
196
+ *
197
+ * **Validation:**
198
+ * - name: 1-100 characters
199
+ * - commodity_code: Must be a valid commodity code
200
+ * - condition_value: Must be > 0 and <= 1,000,000
201
+ * - cooldown_minutes: Must be 0-1440 (24 hours)
202
+ * - webhook_url: Must be valid HTTPS URL if provided
203
+ *
204
+ * **Soft Limit:** 100 alerts per user
205
+ *
206
+ * @param params - Alert configuration parameters
207
+ * @returns The created price alert
208
+ *
209
+ * @throws {ValidationError} If parameters are invalid
210
+ * @throws {OilPriceAPIError} If API request fails
211
+ * @throws {AuthenticationError} If API key is invalid
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // Alert when Brent crude exceeds $85
216
+ * const alert = await client.alerts.create({
217
+ * name: 'Brent $85 Alert',
218
+ * commodity_code: 'BRENT_CRUDE_USD',
219
+ * condition_operator: 'greater_than',
220
+ * condition_value: 85.00,
221
+ * webhook_url: 'https://myapp.com/webhook',
222
+ * enabled: true,
223
+ * cooldown_minutes: 120 // 2 hours between triggers
224
+ * });
225
+ * ```
226
+ */
227
+ create(params: CreateAlertParams): Promise<PriceAlert>;
228
+ /**
229
+ * Update an existing price alert
230
+ *
231
+ * Updates one or more fields of an existing alert. Only provided
232
+ * fields will be updated; others remain unchanged.
233
+ *
234
+ * @param id - The alert ID to update
235
+ * @param params - Fields to update (partial update supported)
236
+ * @returns The updated price alert
237
+ *
238
+ * @throws {ValidationError} If parameters are invalid
239
+ * @throws {DataNotFoundError} If alert ID not found
240
+ * @throws {OilPriceAPIError} If API request fails
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * // Disable an alert
245
+ * await client.alerts.update(alertId, { enabled: false });
246
+ *
247
+ * // Change threshold and cooldown
248
+ * await client.alerts.update(alertId, {
249
+ * condition_value: 90.00,
250
+ * cooldown_minutes: 180
251
+ * });
252
+ *
253
+ * // Update webhook URL
254
+ * await client.alerts.update(alertId, {
255
+ * webhook_url: 'https://newapp.com/webhook'
256
+ * });
257
+ * ```
258
+ */
259
+ update(id: string, params: UpdateAlertParams): Promise<PriceAlert>;
260
+ /**
261
+ * Delete a price alert
262
+ *
263
+ * Permanently deletes a price alert. This action cannot be undone.
264
+ *
265
+ * @param id - The alert ID to delete
266
+ *
267
+ * @throws {DataNotFoundError} If alert ID not found
268
+ * @throws {OilPriceAPIError} If API request fails
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * await client.alerts.delete(alertId);
273
+ * console.log('Alert deleted successfully');
274
+ * ```
275
+ */
276
+ delete(id: string): Promise<void>;
277
+ /**
278
+ * Test a webhook endpoint
279
+ *
280
+ * **NOTE:** This feature is not yet available in the API. The `/v1/alerts/test_webhook`
281
+ * endpoint has not been implemented yet. This method will throw an error until the
282
+ * backend endpoint is added.
283
+ *
284
+ * To test if an alert would trigger, use the backend's `/v1/alerts/test` endpoint instead:
285
+ * ```bash
286
+ * curl -X POST "https://api.oilpriceapi.com/v1/alerts/:id/test" \
287
+ * -H "Authorization: Bearer YOUR_API_KEY"
288
+ * ```
289
+ *
290
+ * @param webhookUrl - The HTTPS webhook URL to test
291
+ * @returns Test results including response time and status
292
+ *
293
+ * @throws {Error} Feature not yet available
294
+ *
295
+ * @deprecated This feature is not yet available in the API
296
+ */
297
+ testWebhook(webhookUrl: string): Promise<WebhookTestResponse>;
298
+ }
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Price Alerts Resource
3
+ *
4
+ * Manage price alert configurations for automated notifications.
5
+ */
6
+ /**
7
+ * Price Alerts Resource
8
+ *
9
+ * Manage automated price alert configurations with webhook notifications.
10
+ *
11
+ * **Features:**
12
+ * - Create alerts with customizable conditions
13
+ * - Monitor commodity prices automatically
14
+ * - Webhook notifications when conditions are met
15
+ * - Cooldown periods to prevent spam
16
+ * - 100 alerts per user soft limit
17
+ *
18
+ * **Example:**
19
+ * ```typescript
20
+ * import { OilPriceAPI } from 'oilpriceapi';
21
+ *
22
+ * const client = new OilPriceAPI({ apiKey: 'your_key' });
23
+ *
24
+ * // Create a price alert
25
+ * const alert = await client.alerts.create({
26
+ * name: 'Brent High Price Alert',
27
+ * commodity_code: 'BRENT_CRUDE_USD',
28
+ * condition_operator: 'greater_than',
29
+ * condition_value: 85.00,
30
+ * webhook_url: 'https://your-app.com/webhooks/price-alert',
31
+ * enabled: true,
32
+ * cooldown_minutes: 60
33
+ * });
34
+ *
35
+ * console.log(`Alert created: ${alert.name} (ID: ${alert.id})`);
36
+ *
37
+ * // List all alerts
38
+ * const alerts = await client.alerts.list();
39
+ * console.log(`You have ${alerts.length} active alerts`);
40
+ *
41
+ * // Update an alert
42
+ * const updated = await client.alerts.update(alert.id, {
43
+ * condition_value: 90.00,
44
+ * enabled: false
45
+ * });
46
+ *
47
+ * // Delete an alert
48
+ * await client.alerts.delete(alert.id);
49
+ * ```
50
+ */
51
+ export class AlertsResource {
52
+ constructor(client) {
53
+ this.client = client;
54
+ }
55
+ /**
56
+ * List all price alerts for the authenticated user
57
+ *
58
+ * Returns all configured price alerts, including disabled ones.
59
+ * Alerts are sorted by creation date (newest first).
60
+ *
61
+ * @returns Array of all price alerts
62
+ *
63
+ * @throws {OilPriceAPIError} If API request fails
64
+ * @throws {AuthenticationError} If API key is invalid
65
+ * @throws {RateLimitError} If rate limit exceeded
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const alerts = await client.alerts.list();
70
+ *
71
+ * alerts.forEach(alert => {
72
+ * console.log(`${alert.name}: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
73
+ * console.log(` Status: ${alert.enabled ? 'Active' : 'Disabled'}`);
74
+ * console.log(` Triggers: ${alert.trigger_count}`);
75
+ * });
76
+ * ```
77
+ */
78
+ async list() {
79
+ const response = await this.client['request']('/v1/alerts', {});
80
+ // API returns array directly, but handle both formats for compatibility
81
+ return Array.isArray(response) ? response : (response.alerts || []);
82
+ }
83
+ /**
84
+ * Get a specific price alert by ID
85
+ *
86
+ * @param id - The alert ID to retrieve
87
+ * @returns The price alert details
88
+ *
89
+ * @throws {OilPriceAPIError} If API request fails
90
+ * @throws {DataNotFoundError} If alert ID not found
91
+ * @throws {AuthenticationError} If API key is invalid
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const alert = await client.alerts.get('550e8400-e29b-41d4-a716-446655440000');
96
+ * console.log(`Alert: ${alert.name}`);
97
+ * console.log(`Condition: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
98
+ * console.log(`Last triggered: ${alert.last_triggered_at || 'Never'}`);
99
+ * ```
100
+ */
101
+ async get(id) {
102
+ if (!id || typeof id !== 'string') {
103
+ throw new Error('Alert ID must be a non-empty string');
104
+ }
105
+ const response = await this.client['request'](`/v1/alerts/${id}`, {});
106
+ // API returns object directly, but handle both formats for compatibility
107
+ return 'alert' in response ? response.alert : response;
108
+ }
109
+ /**
110
+ * Create a new price alert
111
+ *
112
+ * Creates a price alert that monitors a commodity and triggers when
113
+ * the price meets the specified condition. Optionally sends webhook
114
+ * notifications when triggered.
115
+ *
116
+ * **Validation:**
117
+ * - name: 1-100 characters
118
+ * - commodity_code: Must be a valid commodity code
119
+ * - condition_value: Must be > 0 and <= 1,000,000
120
+ * - cooldown_minutes: Must be 0-1440 (24 hours)
121
+ * - webhook_url: Must be valid HTTPS URL if provided
122
+ *
123
+ * **Soft Limit:** 100 alerts per user
124
+ *
125
+ * @param params - Alert configuration parameters
126
+ * @returns The created price alert
127
+ *
128
+ * @throws {ValidationError} If parameters are invalid
129
+ * @throws {OilPriceAPIError} If API request fails
130
+ * @throws {AuthenticationError} If API key is invalid
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Alert when Brent crude exceeds $85
135
+ * const alert = await client.alerts.create({
136
+ * name: 'Brent $85 Alert',
137
+ * commodity_code: 'BRENT_CRUDE_USD',
138
+ * condition_operator: 'greater_than',
139
+ * condition_value: 85.00,
140
+ * webhook_url: 'https://myapp.com/webhook',
141
+ * enabled: true,
142
+ * cooldown_minutes: 120 // 2 hours between triggers
143
+ * });
144
+ * ```
145
+ */
146
+ async create(params) {
147
+ // Validate required fields
148
+ if (!params.name || typeof params.name !== 'string') {
149
+ throw new Error('Alert name is required and must be a string');
150
+ }
151
+ if (params.name.length < 1 || params.name.length > 100) {
152
+ throw new Error('Alert name must be 1-100 characters');
153
+ }
154
+ if (!params.commodity_code || typeof params.commodity_code !== 'string') {
155
+ throw new Error('Commodity code is required and must be a string');
156
+ }
157
+ if (!params.condition_operator) {
158
+ throw new Error('Condition operator is required');
159
+ }
160
+ const validOperators = [
161
+ 'greater_than',
162
+ 'less_than',
163
+ 'equals',
164
+ 'greater_than_or_equal',
165
+ 'less_than_or_equal'
166
+ ];
167
+ if (!validOperators.includes(params.condition_operator)) {
168
+ throw new Error(`Invalid operator. Must be one of: ${validOperators.join(', ')}`);
169
+ }
170
+ if (typeof params.condition_value !== 'number') {
171
+ throw new Error('Condition value must be a number');
172
+ }
173
+ if (params.condition_value <= 0 || params.condition_value > 1000000) {
174
+ throw new Error('Condition value must be greater than 0 and less than or equal to 1,000,000');
175
+ }
176
+ // Validate optional fields
177
+ if (params.webhook_url !== undefined) {
178
+ if (typeof params.webhook_url !== 'string') {
179
+ throw new Error('Webhook URL must be a string');
180
+ }
181
+ if (params.webhook_url && !params.webhook_url.startsWith('https://')) {
182
+ throw new Error('Webhook URL must use HTTPS protocol');
183
+ }
184
+ }
185
+ if (params.cooldown_minutes !== undefined) {
186
+ if (typeof params.cooldown_minutes !== 'number') {
187
+ throw new Error('Cooldown minutes must be a number');
188
+ }
189
+ if (params.cooldown_minutes < 0 || params.cooldown_minutes > 1440) {
190
+ throw new Error('Cooldown minutes must be between 0 and 1440 (24 hours)');
191
+ }
192
+ }
193
+ const url = `${this.client['baseUrl']}/v1/alerts`;
194
+ const response = await fetch(url, {
195
+ method: 'POST',
196
+ headers: {
197
+ 'Authorization': `Bearer ${this.client['apiKey']}`,
198
+ 'Content-Type': 'application/json',
199
+ },
200
+ body: JSON.stringify({
201
+ price_alert: {
202
+ name: params.name,
203
+ commodity_code: params.commodity_code,
204
+ condition_operator: params.condition_operator,
205
+ condition_value: params.condition_value,
206
+ webhook_url: params.webhook_url,
207
+ enabled: params.enabled ?? true,
208
+ cooldown_minutes: params.cooldown_minutes ?? 60,
209
+ metadata: params.metadata
210
+ }
211
+ })
212
+ });
213
+ if (!response.ok) {
214
+ const errorText = await response.text();
215
+ throw new Error(`Failed to create alert: ${response.status} ${errorText}`);
216
+ }
217
+ const data = await response.json();
218
+ // API returns object directly, but handle both formats for compatibility
219
+ return 'alert' in data ? data.alert : data;
220
+ }
221
+ /**
222
+ * Update an existing price alert
223
+ *
224
+ * Updates one or more fields of an existing alert. Only provided
225
+ * fields will be updated; others remain unchanged.
226
+ *
227
+ * @param id - The alert ID to update
228
+ * @param params - Fields to update (partial update supported)
229
+ * @returns The updated price alert
230
+ *
231
+ * @throws {ValidationError} If parameters are invalid
232
+ * @throws {DataNotFoundError} If alert ID not found
233
+ * @throws {OilPriceAPIError} If API request fails
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * // Disable an alert
238
+ * await client.alerts.update(alertId, { enabled: false });
239
+ *
240
+ * // Change threshold and cooldown
241
+ * await client.alerts.update(alertId, {
242
+ * condition_value: 90.00,
243
+ * cooldown_minutes: 180
244
+ * });
245
+ *
246
+ * // Update webhook URL
247
+ * await client.alerts.update(alertId, {
248
+ * webhook_url: 'https://newapp.com/webhook'
249
+ * });
250
+ * ```
251
+ */
252
+ async update(id, params) {
253
+ if (!id || typeof id !== 'string') {
254
+ throw new Error('Alert ID must be a non-empty string');
255
+ }
256
+ // Validate fields if provided
257
+ if (params.name !== undefined) {
258
+ if (typeof params.name !== 'string' || params.name.length < 1 || params.name.length > 100) {
259
+ throw new Error('Alert name must be 1-100 characters');
260
+ }
261
+ }
262
+ if (params.condition_operator !== undefined) {
263
+ const validOperators = [
264
+ 'greater_than',
265
+ 'less_than',
266
+ 'equals',
267
+ 'greater_than_or_equal',
268
+ 'less_than_or_equal'
269
+ ];
270
+ if (!validOperators.includes(params.condition_operator)) {
271
+ throw new Error(`Invalid operator. Must be one of: ${validOperators.join(', ')}`);
272
+ }
273
+ }
274
+ if (params.condition_value !== undefined) {
275
+ if (typeof params.condition_value !== 'number') {
276
+ throw new Error('Condition value must be a number');
277
+ }
278
+ if (params.condition_value <= 0 || params.condition_value > 1000000) {
279
+ throw new Error('Condition value must be greater than 0 and less than or equal to 1,000,000');
280
+ }
281
+ }
282
+ if (params.webhook_url !== undefined && params.webhook_url !== null) {
283
+ if (typeof params.webhook_url !== 'string' || !params.webhook_url.startsWith('https://')) {
284
+ throw new Error('Webhook URL must be a valid HTTPS URL');
285
+ }
286
+ }
287
+ if (params.cooldown_minutes !== undefined) {
288
+ if (typeof params.cooldown_minutes !== 'number' ||
289
+ params.cooldown_minutes < 0 ||
290
+ params.cooldown_minutes > 1440) {
291
+ throw new Error('Cooldown minutes must be between 0 and 1440 (24 hours)');
292
+ }
293
+ }
294
+ const url = `${this.client['baseUrl']}/v1/alerts/${id}`;
295
+ const response = await fetch(url, {
296
+ method: 'PATCH',
297
+ headers: {
298
+ 'Authorization': `Bearer ${this.client['apiKey']}`,
299
+ 'Content-Type': 'application/json',
300
+ },
301
+ body: JSON.stringify({
302
+ price_alert: params
303
+ })
304
+ });
305
+ if (!response.ok) {
306
+ const errorText = await response.text();
307
+ throw new Error(`Failed to update alert: ${response.status} ${errorText}`);
308
+ }
309
+ const data = await response.json();
310
+ // API returns object directly, but handle both formats for compatibility
311
+ return 'alert' in data ? data.alert : data;
312
+ }
313
+ /**
314
+ * Delete a price alert
315
+ *
316
+ * Permanently deletes a price alert. This action cannot be undone.
317
+ *
318
+ * @param id - The alert ID to delete
319
+ *
320
+ * @throws {DataNotFoundError} If alert ID not found
321
+ * @throws {OilPriceAPIError} If API request fails
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * await client.alerts.delete(alertId);
326
+ * console.log('Alert deleted successfully');
327
+ * ```
328
+ */
329
+ async delete(id) {
330
+ if (!id || typeof id !== 'string') {
331
+ throw new Error('Alert ID must be a non-empty string');
332
+ }
333
+ const url = `${this.client['baseUrl']}/v1/alerts/${id}`;
334
+ const response = await fetch(url, {
335
+ method: 'DELETE',
336
+ headers: {
337
+ 'Authorization': `Bearer ${this.client['apiKey']}`,
338
+ 'Content-Type': 'application/json',
339
+ }
340
+ });
341
+ if (!response.ok) {
342
+ const errorText = await response.text();
343
+ throw new Error(`Failed to delete alert: ${response.status} ${errorText}`);
344
+ }
345
+ }
346
+ /**
347
+ * Test a webhook endpoint
348
+ *
349
+ * **NOTE:** This feature is not yet available in the API. The `/v1/alerts/test_webhook`
350
+ * endpoint has not been implemented yet. This method will throw an error until the
351
+ * backend endpoint is added.
352
+ *
353
+ * To test if an alert would trigger, use the backend's `/v1/alerts/test` endpoint instead:
354
+ * ```bash
355
+ * curl -X POST "https://api.oilpriceapi.com/v1/alerts/:id/test" \
356
+ * -H "Authorization: Bearer YOUR_API_KEY"
357
+ * ```
358
+ *
359
+ * @param webhookUrl - The HTTPS webhook URL to test
360
+ * @returns Test results including response time and status
361
+ *
362
+ * @throws {Error} Feature not yet available
363
+ *
364
+ * @deprecated This feature is not yet available in the API
365
+ */
366
+ async testWebhook(webhookUrl) {
367
+ throw new Error('Webhook testing is not yet available. The /v1/alerts/test_webhook endpoint ' +
368
+ 'has not been implemented in the API. To test if an alert would trigger, ' +
369
+ 'use the /v1/alerts/:id/test endpoint instead.');
370
+ }
371
+ }