oilpriceapi 0.6.0 → 0.7.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.
Files changed (49) hide show
  1. package/README.md +376 -113
  2. package/dist/client.d.ts +83 -3
  3. package/dist/client.js +104 -38
  4. package/dist/index.d.ts +31 -6
  5. package/dist/index.js +17 -3
  6. package/dist/resources/alerts.d.ts +52 -15
  7. package/dist/resources/alerts.js +143 -85
  8. package/dist/resources/analytics.d.ts +325 -0
  9. package/dist/resources/analytics.js +221 -0
  10. package/dist/resources/bunker-fuels.d.ts +270 -0
  11. package/dist/resources/bunker-fuels.js +191 -0
  12. package/dist/resources/commodities.d.ts +148 -0
  13. package/dist/resources/commodities.js +110 -0
  14. package/dist/resources/data-quality.d.ts +229 -0
  15. package/dist/resources/data-quality.js +139 -0
  16. package/dist/resources/data-sources.d.ts +365 -0
  17. package/dist/resources/data-sources.js +349 -0
  18. package/dist/resources/drilling.d.ts +403 -0
  19. package/dist/resources/drilling.js +264 -0
  20. package/dist/resources/ei/drilling-productivity.d.ts +173 -0
  21. package/dist/resources/ei/drilling-productivity.js +103 -0
  22. package/dist/resources/ei/forecasts.d.ts +177 -0
  23. package/dist/resources/ei/forecasts.js +101 -0
  24. package/dist/resources/ei/frac-focus.d.ts +212 -0
  25. package/dist/resources/ei/frac-focus.js +150 -0
  26. package/dist/resources/ei/index.d.ts +140 -0
  27. package/dist/resources/ei/index.js +87 -0
  28. package/dist/resources/ei/oil-inventories.d.ts +155 -0
  29. package/dist/resources/ei/oil-inventories.js +92 -0
  30. package/dist/resources/ei/opec-production.d.ts +146 -0
  31. package/dist/resources/ei/opec-production.js +92 -0
  32. package/dist/resources/ei/rig-counts.d.ts +131 -0
  33. package/dist/resources/ei/rig-counts.js +88 -0
  34. package/dist/resources/ei/well-permits.d.ts +178 -0
  35. package/dist/resources/ei/well-permits.js +119 -0
  36. package/dist/resources/forecasts.d.ts +200 -0
  37. package/dist/resources/forecasts.js +157 -0
  38. package/dist/resources/futures.d.ts +322 -0
  39. package/dist/resources/futures.js +228 -0
  40. package/dist/resources/rig-counts.d.ts +221 -0
  41. package/dist/resources/rig-counts.js +157 -0
  42. package/dist/resources/storage.d.ts +182 -0
  43. package/dist/resources/storage.js +161 -0
  44. package/dist/resources/webhooks.d.ts +290 -0
  45. package/dist/resources/webhooks.js +297 -0
  46. package/dist/types.d.ts +77 -7
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +3 -3
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Data Sources Resource
3
+ *
4
+ * Manage custom data source integrations for Bring Your Own Source (BYOS) feature.
5
+ */
6
+ import type { OilPriceAPI } from "../client.js";
7
+ /**
8
+ * Data source types
9
+ */
10
+ export type DataSourceType = "api" | "database" | "file" | "sftp" | "webhook" | "custom";
11
+ /**
12
+ * Data source status
13
+ */
14
+ export type DataSourceStatus = "active" | "paused" | "error" | "pending";
15
+ /**
16
+ * Data source configuration
17
+ */
18
+ export interface DataSource {
19
+ /** Unique data source identifier */
20
+ id: string;
21
+ /** User-friendly name */
22
+ name: string;
23
+ /** Data source type */
24
+ type: DataSourceType;
25
+ /** Connection configuration (encrypted) */
26
+ config: Record<string, unknown>;
27
+ /** Whether the data source is active */
28
+ enabled: boolean;
29
+ /** Current status */
30
+ status: DataSourceStatus;
31
+ /** Last successful sync timestamp */
32
+ last_sync_at?: string;
33
+ /** Next scheduled sync timestamp */
34
+ next_sync_at?: string;
35
+ /** Sync frequency in minutes */
36
+ sync_frequency_minutes?: number;
37
+ /** Number of successful syncs */
38
+ successful_syncs: number;
39
+ /** Number of failed syncs */
40
+ failed_syncs: number;
41
+ /** Last error message */
42
+ last_error?: string;
43
+ /** Optional metadata */
44
+ metadata?: Record<string, unknown>;
45
+ /** ISO timestamp when source was created */
46
+ created_at: string;
47
+ /** ISO timestamp when source was last updated */
48
+ updated_at: string;
49
+ }
50
+ /**
51
+ * Parameters for creating a data source
52
+ */
53
+ export interface CreateDataSourceParams {
54
+ /** User-friendly name */
55
+ name: string;
56
+ /** Data source type */
57
+ type: DataSourceType;
58
+ /** Connection configuration */
59
+ config: Record<string, unknown>;
60
+ /** Whether to enable immediately (default: true) */
61
+ enabled?: boolean;
62
+ /** Sync frequency in minutes (default: 60) */
63
+ sync_frequency_minutes?: number;
64
+ /** Optional metadata */
65
+ metadata?: Record<string, unknown>;
66
+ }
67
+ /**
68
+ * Parameters for updating a data source
69
+ */
70
+ export interface UpdateDataSourceParams {
71
+ /** User-friendly name */
72
+ name?: string;
73
+ /** Connection configuration */
74
+ config?: Record<string, unknown>;
75
+ /** Whether the data source is active */
76
+ enabled?: boolean;
77
+ /** Sync frequency in minutes */
78
+ sync_frequency_minutes?: number;
79
+ /** Metadata */
80
+ metadata?: Record<string, unknown>;
81
+ }
82
+ /**
83
+ * Data source test response
84
+ */
85
+ export interface DataSourceTestResponse {
86
+ /** Test result status */
87
+ success: boolean;
88
+ /** Connection test duration in milliseconds */
89
+ duration_ms: number;
90
+ /** Number of records fetched in test */
91
+ records_count?: number;
92
+ /** Sample data */
93
+ sample_data?: Record<string, unknown>[];
94
+ /** Error message if test failed */
95
+ error?: string;
96
+ }
97
+ /**
98
+ * Data source sync log entry
99
+ */
100
+ export interface DataSourceLog {
101
+ /** Log entry ID */
102
+ id: string;
103
+ /** Data source ID */
104
+ data_source_id: string;
105
+ /** Sync status */
106
+ status: "success" | "failed";
107
+ /** Number of records synced */
108
+ records_synced?: number;
109
+ /** Sync duration in milliseconds */
110
+ duration_ms?: number;
111
+ /** Error message if sync failed */
112
+ error?: string;
113
+ /** ISO timestamp when sync started */
114
+ started_at: string;
115
+ /** ISO timestamp when sync completed */
116
+ completed_at?: string;
117
+ }
118
+ /**
119
+ * Data source health metrics
120
+ */
121
+ export interface DataSourceHealth {
122
+ /** Data source ID */
123
+ id: string;
124
+ /** Overall health status */
125
+ status: "healthy" | "degraded" | "down";
126
+ /** Success rate (0-100) */
127
+ success_rate: number;
128
+ /** Average sync duration in milliseconds */
129
+ avg_duration_ms: number;
130
+ /** Last sync status */
131
+ last_sync_status?: "success" | "failed";
132
+ /** Last sync timestamp */
133
+ last_sync_at?: string;
134
+ /** Recent errors */
135
+ recent_errors?: string[];
136
+ }
137
+ /**
138
+ * Credential rotation response
139
+ */
140
+ export interface CredentialRotationResponse {
141
+ /** Whether rotation was successful */
142
+ success: boolean;
143
+ /** New credential ID or reference */
144
+ credential_id?: string;
145
+ /** Message */
146
+ message?: string;
147
+ }
148
+ /**
149
+ * Data Sources Resource
150
+ *
151
+ * Manage custom data source integrations for importing your own price data
152
+ * into the platform (BYOS - Bring Your Own Source feature).
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * import { OilPriceAPI } from 'oilpriceapi';
157
+ *
158
+ * const client = new OilPriceAPI({ apiKey: 'your_key' });
159
+ *
160
+ * // Create a data source
161
+ * const source = await client.dataSources.create({
162
+ * name: 'Internal Price Feed',
163
+ * type: 'api',
164
+ * config: {
165
+ * url: 'https://internal.company.com/api/prices',
166
+ * auth_type: 'bearer',
167
+ * token: 'secret-token'
168
+ * },
169
+ * sync_frequency_minutes: 30
170
+ * });
171
+ *
172
+ * // Test the data source
173
+ * const test = await client.dataSources.test(source.id);
174
+ * console.log(`Test result: ${test.success}`);
175
+ *
176
+ * // Check health
177
+ * const health = await client.dataSources.health(source.id);
178
+ * console.log(`Health: ${health.status}`);
179
+ * console.log(`Success rate: ${health.success_rate}%`);
180
+ *
181
+ * // View sync logs
182
+ * const logs = await client.dataSources.logs(source.id);
183
+ * logs.forEach(log => {
184
+ * console.log(`${log.started_at}: ${log.status} - ${log.records_synced} records`);
185
+ * });
186
+ * ```
187
+ */
188
+ export declare class DataSourcesResource {
189
+ private client;
190
+ constructor(client: OilPriceAPI);
191
+ /**
192
+ * List all data sources
193
+ *
194
+ * @returns Array of data sources
195
+ *
196
+ * @throws {OilPriceAPIError} If API request fails
197
+ * @throws {AuthenticationError} If API key is invalid
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const sources = await client.dataSources.list();
202
+ * sources.forEach(source => {
203
+ * console.log(`${source.name}: ${source.status}`);
204
+ * console.log(` Success rate: ${source.successful_syncs}/${source.successful_syncs + source.failed_syncs}`);
205
+ * });
206
+ * ```
207
+ */
208
+ list(): Promise<DataSource[]>;
209
+ /**
210
+ * Get a specific data source
211
+ *
212
+ * @param id - Data source ID
213
+ * @returns Data source details
214
+ *
215
+ * @throws {NotFoundError} If data source not found
216
+ * @throws {OilPriceAPIError} If API request fails
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const source = await client.dataSources.get('source-id');
221
+ * console.log(`${source.name} (${source.type})`);
222
+ * console.log(`Last sync: ${source.last_sync_at}`);
223
+ * ```
224
+ */
225
+ get(id: string): Promise<DataSource>;
226
+ /**
227
+ * Create a new data source
228
+ *
229
+ * @param params - Data source configuration
230
+ * @returns Created data source
231
+ *
232
+ * @throws {OilPriceAPIError} If API request fails
233
+ * @throws {AuthenticationError} If API key is invalid
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * const source = await client.dataSources.create({
238
+ * name: 'SFTP Price Feed',
239
+ * type: 'sftp',
240
+ * config: {
241
+ * host: 'sftp.example.com',
242
+ * username: 'user',
243
+ * password: 'pass',
244
+ * path: '/prices/daily.csv'
245
+ * },
246
+ * sync_frequency_minutes: 1440 // Daily
247
+ * });
248
+ * ```
249
+ */
250
+ create(params: CreateDataSourceParams): Promise<DataSource>;
251
+ /**
252
+ * Update a data source
253
+ *
254
+ * @param id - Data source ID
255
+ * @param params - Fields to update
256
+ * @returns Updated data source
257
+ *
258
+ * @throws {NotFoundError} If data source not found
259
+ * @throws {OilPriceAPIError} If API request fails
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * // Pause a data source
264
+ * await client.dataSources.update(sourceId, { enabled: false });
265
+ *
266
+ * // Update sync frequency
267
+ * await client.dataSources.update(sourceId, {
268
+ * sync_frequency_minutes: 120
269
+ * });
270
+ * ```
271
+ */
272
+ update(id: string, params: UpdateDataSourceParams): Promise<DataSource>;
273
+ /**
274
+ * Delete a data source
275
+ *
276
+ * @param id - Data source ID
277
+ *
278
+ * @throws {NotFoundError} If data source not found
279
+ * @throws {OilPriceAPIError} If API request fails
280
+ *
281
+ * @example
282
+ * ```typescript
283
+ * await client.dataSources.delete(sourceId);
284
+ * console.log('Data source deleted');
285
+ * ```
286
+ */
287
+ delete(id: string): Promise<void>;
288
+ /**
289
+ * Test a data source connection
290
+ *
291
+ * @param id - Data source ID
292
+ * @returns Test results
293
+ *
294
+ * @throws {NotFoundError} If data source not found
295
+ * @throws {OilPriceAPIError} If API request fails
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * const test = await client.dataSources.test(sourceId);
300
+ * console.log(`Connection test: ${test.success ? 'passed' : 'failed'}`);
301
+ * console.log(`Duration: ${test.duration_ms}ms`);
302
+ * if (test.sample_data) {
303
+ * console.log(`Sample records: ${test.sample_data.length}`);
304
+ * }
305
+ * ```
306
+ */
307
+ test(id: string): Promise<DataSourceTestResponse>;
308
+ /**
309
+ * Get data source sync logs
310
+ *
311
+ * @param id - Data source ID
312
+ * @returns Array of sync log entries
313
+ *
314
+ * @throws {NotFoundError} If data source not found
315
+ * @throws {OilPriceAPIError} If API request fails
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * const logs = await client.dataSources.logs(sourceId);
320
+ * logs.forEach(log => {
321
+ * console.log(`${log.started_at}: ${log.status}`);
322
+ * if (log.records_synced) {
323
+ * console.log(` ${log.records_synced} records in ${log.duration_ms}ms`);
324
+ * }
325
+ * });
326
+ * ```
327
+ */
328
+ logs(id: string): Promise<DataSourceLog[]>;
329
+ /**
330
+ * Get data source health metrics
331
+ *
332
+ * @param id - Data source ID
333
+ * @returns Health metrics
334
+ *
335
+ * @throws {NotFoundError} If data source not found
336
+ * @throws {OilPriceAPIError} If API request fails
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * const health = await client.dataSources.health(sourceId);
341
+ * console.log(`Status: ${health.status}`);
342
+ * console.log(`Success rate: ${health.success_rate}%`);
343
+ * console.log(`Avg duration: ${health.avg_duration_ms}ms`);
344
+ * ```
345
+ */
346
+ health(id: string): Promise<DataSourceHealth>;
347
+ /**
348
+ * Rotate data source credentials
349
+ *
350
+ * Updates stored credentials with new values and re-encrypts them.
351
+ *
352
+ * @param id - Data source ID
353
+ * @returns Rotation result
354
+ *
355
+ * @throws {NotFoundError} If data source not found
356
+ * @throws {OilPriceAPIError} If API request fails
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * const result = await client.dataSources.rotateCredentials(sourceId);
361
+ * console.log(`Credential rotation: ${result.success ? 'success' : 'failed'}`);
362
+ * ```
363
+ */
364
+ rotateCredentials(id: string): Promise<CredentialRotationResponse>;
365
+ }
@@ -0,0 +1,349 @@
1
+ /**
2
+ * Data Sources Resource
3
+ *
4
+ * Manage custom data source integrations for Bring Your Own Source (BYOS) feature.
5
+ */
6
+ /**
7
+ * Data Sources Resource
8
+ *
9
+ * Manage custom data source integrations for importing your own price data
10
+ * into the platform (BYOS - Bring Your Own Source feature).
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { OilPriceAPI } from 'oilpriceapi';
15
+ *
16
+ * const client = new OilPriceAPI({ apiKey: 'your_key' });
17
+ *
18
+ * // Create a data source
19
+ * const source = await client.dataSources.create({
20
+ * name: 'Internal Price Feed',
21
+ * type: 'api',
22
+ * config: {
23
+ * url: 'https://internal.company.com/api/prices',
24
+ * auth_type: 'bearer',
25
+ * token: 'secret-token'
26
+ * },
27
+ * sync_frequency_minutes: 30
28
+ * });
29
+ *
30
+ * // Test the data source
31
+ * const test = await client.dataSources.test(source.id);
32
+ * console.log(`Test result: ${test.success}`);
33
+ *
34
+ * // Check health
35
+ * const health = await client.dataSources.health(source.id);
36
+ * console.log(`Health: ${health.status}`);
37
+ * console.log(`Success rate: ${health.success_rate}%`);
38
+ *
39
+ * // View sync logs
40
+ * const logs = await client.dataSources.logs(source.id);
41
+ * logs.forEach(log => {
42
+ * console.log(`${log.started_at}: ${log.status} - ${log.records_synced} records`);
43
+ * });
44
+ * ```
45
+ */
46
+ export class DataSourcesResource {
47
+ constructor(client) {
48
+ this.client = client;
49
+ }
50
+ /**
51
+ * List all data sources
52
+ *
53
+ * @returns Array of data sources
54
+ *
55
+ * @throws {OilPriceAPIError} If API request fails
56
+ * @throws {AuthenticationError} If API key is invalid
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const sources = await client.dataSources.list();
61
+ * sources.forEach(source => {
62
+ * console.log(`${source.name}: ${source.status}`);
63
+ * console.log(` Success rate: ${source.successful_syncs}/${source.successful_syncs + source.failed_syncs}`);
64
+ * });
65
+ * ```
66
+ */
67
+ async list() {
68
+ const response = await this.client["request"]("/v1/data-sources", {});
69
+ return Array.isArray(response) ? response : response.data_sources;
70
+ }
71
+ /**
72
+ * Get a specific data source
73
+ *
74
+ * @param id - Data source ID
75
+ * @returns Data source details
76
+ *
77
+ * @throws {NotFoundError} If data source not found
78
+ * @throws {OilPriceAPIError} If API request fails
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const source = await client.dataSources.get('source-id');
83
+ * console.log(`${source.name} (${source.type})`);
84
+ * console.log(`Last sync: ${source.last_sync_at}`);
85
+ * ```
86
+ */
87
+ async get(id) {
88
+ if (!id || typeof id !== "string") {
89
+ throw new Error("Data source ID must be a non-empty string");
90
+ }
91
+ const response = await this.client["request"](`/v1/data-sources/${id}`, {});
92
+ return "data_source" in response ? response.data_source : response;
93
+ }
94
+ /**
95
+ * Create a new data source
96
+ *
97
+ * @param params - Data source configuration
98
+ * @returns Created data source
99
+ *
100
+ * @throws {OilPriceAPIError} If API request fails
101
+ * @throws {AuthenticationError} If API key is invalid
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const source = await client.dataSources.create({
106
+ * name: 'SFTP Price Feed',
107
+ * type: 'sftp',
108
+ * config: {
109
+ * host: 'sftp.example.com',
110
+ * username: 'user',
111
+ * password: 'pass',
112
+ * path: '/prices/daily.csv'
113
+ * },
114
+ * sync_frequency_minutes: 1440 // Daily
115
+ * });
116
+ * ```
117
+ */
118
+ async create(params) {
119
+ if (!params.name || typeof params.name !== "string") {
120
+ throw new Error("Data source name is required");
121
+ }
122
+ if (!params.type) {
123
+ throw new Error("Data source type is required");
124
+ }
125
+ if (!params.config || typeof params.config !== "object") {
126
+ throw new Error("Data source config is required");
127
+ }
128
+ const url = `${this.client["baseUrl"]}/v1/data-sources`;
129
+ const response = await fetch(url, {
130
+ method: "POST",
131
+ headers: {
132
+ Authorization: `Bearer ${this.client["apiKey"]}`,
133
+ "Content-Type": "application/json",
134
+ },
135
+ body: JSON.stringify({
136
+ data_source: {
137
+ name: params.name,
138
+ type: params.type,
139
+ config: params.config,
140
+ enabled: params.enabled ?? true,
141
+ sync_frequency_minutes: params.sync_frequency_minutes ?? 60,
142
+ metadata: params.metadata,
143
+ },
144
+ }),
145
+ });
146
+ if (!response.ok) {
147
+ const errorText = await response.text();
148
+ throw new Error(`Failed to create data source: ${response.status} ${errorText}`);
149
+ }
150
+ const data = (await response.json());
151
+ return "data_source" in data ? data.data_source : data;
152
+ }
153
+ /**
154
+ * Update a data source
155
+ *
156
+ * @param id - Data source ID
157
+ * @param params - Fields to update
158
+ * @returns Updated data source
159
+ *
160
+ * @throws {NotFoundError} If data source not found
161
+ * @throws {OilPriceAPIError} If API request fails
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * // Pause a data source
166
+ * await client.dataSources.update(sourceId, { enabled: false });
167
+ *
168
+ * // Update sync frequency
169
+ * await client.dataSources.update(sourceId, {
170
+ * sync_frequency_minutes: 120
171
+ * });
172
+ * ```
173
+ */
174
+ async update(id, params) {
175
+ if (!id || typeof id !== "string") {
176
+ throw new Error("Data source ID must be a non-empty string");
177
+ }
178
+ const url = `${this.client["baseUrl"]}/v1/data-sources/${id}`;
179
+ const response = await fetch(url, {
180
+ method: "PATCH",
181
+ headers: {
182
+ Authorization: `Bearer ${this.client["apiKey"]}`,
183
+ "Content-Type": "application/json",
184
+ },
185
+ body: JSON.stringify({
186
+ data_source: params,
187
+ }),
188
+ });
189
+ if (!response.ok) {
190
+ const errorText = await response.text();
191
+ throw new Error(`Failed to update data source: ${response.status} ${errorText}`);
192
+ }
193
+ const data = (await response.json());
194
+ return "data_source" in data ? data.data_source : data;
195
+ }
196
+ /**
197
+ * Delete a data source
198
+ *
199
+ * @param id - Data source ID
200
+ *
201
+ * @throws {NotFoundError} If data source not found
202
+ * @throws {OilPriceAPIError} If API request fails
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * await client.dataSources.delete(sourceId);
207
+ * console.log('Data source deleted');
208
+ * ```
209
+ */
210
+ async delete(id) {
211
+ if (!id || typeof id !== "string") {
212
+ throw new Error("Data source ID must be a non-empty string");
213
+ }
214
+ const url = `${this.client["baseUrl"]}/v1/data-sources/${id}`;
215
+ const response = await fetch(url, {
216
+ method: "DELETE",
217
+ headers: {
218
+ Authorization: `Bearer ${this.client["apiKey"]}`,
219
+ "Content-Type": "application/json",
220
+ },
221
+ });
222
+ if (!response.ok) {
223
+ const errorText = await response.text();
224
+ throw new Error(`Failed to delete data source: ${response.status} ${errorText}`);
225
+ }
226
+ }
227
+ /**
228
+ * Test a data source connection
229
+ *
230
+ * @param id - Data source ID
231
+ * @returns Test results
232
+ *
233
+ * @throws {NotFoundError} If data source not found
234
+ * @throws {OilPriceAPIError} If API request fails
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * const test = await client.dataSources.test(sourceId);
239
+ * console.log(`Connection test: ${test.success ? 'passed' : 'failed'}`);
240
+ * console.log(`Duration: ${test.duration_ms}ms`);
241
+ * if (test.sample_data) {
242
+ * console.log(`Sample records: ${test.sample_data.length}`);
243
+ * }
244
+ * ```
245
+ */
246
+ async test(id) {
247
+ if (!id || typeof id !== "string") {
248
+ throw new Error("Data source ID must be a non-empty string");
249
+ }
250
+ const url = `${this.client["baseUrl"]}/v1/data-sources/${id}/test`;
251
+ const response = await fetch(url, {
252
+ method: "POST",
253
+ headers: {
254
+ Authorization: `Bearer ${this.client["apiKey"]}`,
255
+ "Content-Type": "application/json",
256
+ },
257
+ });
258
+ if (!response.ok) {
259
+ const errorText = await response.text();
260
+ throw new Error(`Failed to test data source: ${response.status} ${errorText}`);
261
+ }
262
+ return response.json();
263
+ }
264
+ /**
265
+ * Get data source sync logs
266
+ *
267
+ * @param id - Data source ID
268
+ * @returns Array of sync log entries
269
+ *
270
+ * @throws {NotFoundError} If data source not found
271
+ * @throws {OilPriceAPIError} If API request fails
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * const logs = await client.dataSources.logs(sourceId);
276
+ * logs.forEach(log => {
277
+ * console.log(`${log.started_at}: ${log.status}`);
278
+ * if (log.records_synced) {
279
+ * console.log(` ${log.records_synced} records in ${log.duration_ms}ms`);
280
+ * }
281
+ * });
282
+ * ```
283
+ */
284
+ async logs(id) {
285
+ if (!id || typeof id !== "string") {
286
+ throw new Error("Data source ID must be a non-empty string");
287
+ }
288
+ const response = await this.client["request"](`/v1/data-sources/${id}/logs`, {});
289
+ return Array.isArray(response) ? response : response.logs;
290
+ }
291
+ /**
292
+ * Get data source health metrics
293
+ *
294
+ * @param id - Data source ID
295
+ * @returns Health metrics
296
+ *
297
+ * @throws {NotFoundError} If data source not found
298
+ * @throws {OilPriceAPIError} If API request fails
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * const health = await client.dataSources.health(sourceId);
303
+ * console.log(`Status: ${health.status}`);
304
+ * console.log(`Success rate: ${health.success_rate}%`);
305
+ * console.log(`Avg duration: ${health.avg_duration_ms}ms`);
306
+ * ```
307
+ */
308
+ async health(id) {
309
+ if (!id || typeof id !== "string") {
310
+ throw new Error("Data source ID must be a non-empty string");
311
+ }
312
+ return this.client["request"](`/v1/data-sources/${id}/health`, {});
313
+ }
314
+ /**
315
+ * Rotate data source credentials
316
+ *
317
+ * Updates stored credentials with new values and re-encrypts them.
318
+ *
319
+ * @param id - Data source ID
320
+ * @returns Rotation result
321
+ *
322
+ * @throws {NotFoundError} If data source not found
323
+ * @throws {OilPriceAPIError} If API request fails
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * const result = await client.dataSources.rotateCredentials(sourceId);
328
+ * console.log(`Credential rotation: ${result.success ? 'success' : 'failed'}`);
329
+ * ```
330
+ */
331
+ async rotateCredentials(id) {
332
+ if (!id || typeof id !== "string") {
333
+ throw new Error("Data source ID must be a non-empty string");
334
+ }
335
+ const url = `${this.client["baseUrl"]}/v1/data-sources/${id}/rotate-credentials`;
336
+ const response = await fetch(url, {
337
+ method: "POST",
338
+ headers: {
339
+ Authorization: `Bearer ${this.client["apiKey"]}`,
340
+ "Content-Type": "application/json",
341
+ },
342
+ });
343
+ if (!response.ok) {
344
+ const errorText = await response.text();
345
+ throw new Error(`Failed to rotate credentials: ${response.status} ${errorText}`);
346
+ }
347
+ return response.json();
348
+ }
349
+ }