oilpriceapi 0.8.2 → 0.9.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.
Files changed (53) hide show
  1. package/README.md +201 -19
  2. package/dist/cjs/client.js +139 -19
  3. package/dist/cjs/index.js +17 -3
  4. package/dist/cjs/resources/analytics.js +99 -137
  5. package/dist/cjs/resources/bunker-fuels.js +37 -23
  6. package/dist/cjs/resources/data-sources.js +13 -12
  7. package/dist/cjs/resources/ei/frac-focus.js +16 -6
  8. package/dist/cjs/resources/ei/well-permits.js +18 -6
  9. package/dist/cjs/resources/forecasts.js +11 -5
  10. package/dist/cjs/resources/futures.js +244 -16
  11. package/dist/cjs/resources/indicators.js +79 -0
  12. package/dist/cjs/resources/raw.js +128 -0
  13. package/dist/cjs/resources/rig-counts.js +5 -2
  14. package/dist/cjs/resources/spreads.js +105 -0
  15. package/dist/cjs/resources/storage.js +5 -5
  16. package/dist/cjs/resources/streaming.js +350 -0
  17. package/dist/cjs/resources/webhooks.js +3 -14
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/client.d.ts +97 -1
  20. package/dist/client.js +139 -19
  21. package/dist/index.d.ts +12 -3
  22. package/dist/index.js +5 -0
  23. package/dist/resources/analytics.d.ts +147 -214
  24. package/dist/resources/analytics.js +99 -137
  25. package/dist/resources/bunker-fuels.d.ts +35 -12
  26. package/dist/resources/bunker-fuels.js +37 -23
  27. package/dist/resources/data-sources.d.ts +31 -31
  28. package/dist/resources/data-sources.js +13 -12
  29. package/dist/resources/ei/frac-focus.d.ts +23 -9
  30. package/dist/resources/ei/frac-focus.js +16 -6
  31. package/dist/resources/ei/well-permits.d.ts +25 -9
  32. package/dist/resources/ei/well-permits.js +18 -6
  33. package/dist/resources/forecasts.d.ts +4 -1
  34. package/dist/resources/forecasts.js +11 -5
  35. package/dist/resources/futures.d.ts +287 -33
  36. package/dist/resources/futures.js +241 -15
  37. package/dist/resources/indicators.d.ts +170 -0
  38. package/dist/resources/indicators.js +75 -0
  39. package/dist/resources/raw.d.ts +94 -0
  40. package/dist/resources/raw.js +124 -0
  41. package/dist/resources/rig-counts.js +5 -2
  42. package/dist/resources/spreads.d.ts +121 -0
  43. package/dist/resources/spreads.js +101 -0
  44. package/dist/resources/storage.d.ts +5 -4
  45. package/dist/resources/storage.js +5 -5
  46. package/dist/resources/streaming.d.ts +272 -0
  47. package/dist/resources/streaming.js +342 -0
  48. package/dist/resources/webhooks.d.ts +37 -23
  49. package/dist/resources/webhooks.js +3 -14
  50. package/dist/types.d.ts +41 -0
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +7 -1
@@ -3,6 +3,13 @@
3
3
  *
4
4
  * Access advanced analytics including performance metrics, statistical analysis,
5
5
  * correlations, trend detection, spreads, and forecasts.
6
+ *
7
+ * NOTE ON PARAMETERS: The OilPriceAPI analytics controller reads commodity
8
+ * identifiers as `code` / `code1` / `code2` and the lookback window as `period`
9
+ * (in days). Earlier versions of this SDK sent `commodity` / `commodity1` /
10
+ * `commodity2` / `days`, which the API silently ignored (and `correlation`
11
+ * returned "code1 and code2 parameters are required"). These methods now send
12
+ * the parameter names the controller actually reads.
6
13
  */
7
14
  import { ValidationError } from "../errors.js";
8
15
  /**
@@ -17,13 +24,8 @@ import { ValidationError } from "../errors.js";
17
24
  *
18
25
  * const client = new OilPriceAPI({ apiKey: 'your_key' });
19
26
  *
20
- * // Get performance metrics
21
- * const perf = await client.analytics.performance({ commodity: 'WTI_USD', days: 30 });
22
- * console.log(`30-day return: ${perf.return_percent}%`);
23
- * console.log(`Volatility: ${perf.volatility}`);
24
- *
25
- * // Analyze correlation
26
- * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', 90);
27
+ * // Analyze correlation between two commodities (90-day window)
28
+ * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', { period: 90 });
27
29
  * console.log(`Correlation: ${corr.correlation}`);
28
30
  * ```
29
31
  */
@@ -32,191 +34,151 @@ export class AnalyticsResource {
32
34
  this.client = client;
33
35
  }
34
36
  /**
35
- * Get performance metrics for a commodity
36
- *
37
- * Returns key performance indicators including returns, volatility,
38
- * and price range over a specified period.
39
- *
40
- * @param options - Analysis parameters
41
- * @returns Performance metrics
37
+ * Get the authenticated user's API usage analytics for the dashboard.
42
38
  *
43
- * @throws {OilPriceAPIError} If API request fails
39
+ * Maps to `GET /v1/analytics/performance`, which reads a `range`
40
+ * parameter (`7d` | `30d` | `90d`).
44
41
  *
45
- * @example
46
- * ```typescript
47
- * const metrics = await client.analytics.performance({
48
- * commodity: 'WTI_USD',
49
- * days: 30
50
- * });
51
- * console.log(`Return: ${metrics.return_percent}%`);
52
- * console.log(`Volatility: ${metrics.volatility}`);
53
- * console.log(`High: $${metrics.high}, Low: $${metrics.low}`);
54
- * ```
42
+ * @param options - `{ range }` (default range '30d')
43
+ * @returns Usage analytics (overview, daily usage, endpoint breakdown, ...)
55
44
  */
56
45
  async performance(options) {
57
46
  const params = {};
58
- if (options?.commodity)
59
- params.commodity = options.commodity;
60
- if (options?.days)
61
- params.days = options.days.toString();
47
+ if (options?.range)
48
+ params.range = options.range;
62
49
  return this.client["request"]("/v1/analytics/performance", params);
63
50
  }
64
51
  /**
65
- * Get statistical analysis for a commodity
52
+ * Get statistical analysis for a commodity.
66
53
  *
67
- * Returns comprehensive statistical metrics including mean, median,
68
- * standard deviation, and distribution characteristics.
54
+ * Maps to `GET /v1/analytics/statistics`, which reads `code` and `period`.
69
55
  *
70
- * @param commodity - Commodity code to analyze
71
- * @param days - Number of days to analyze (default: 30)
56
+ * @param code - Commodity code to analyze (e.g. 'WTI_USD')
57
+ * @param period - Lookback window in days (default: 30)
72
58
  * @returns Statistical analysis
73
59
  *
74
- * @throws {NotFoundError} If commodity not found
75
- * @throws {OilPriceAPIError} If API request fails
76
- *
77
- * @example
78
- * ```typescript
79
- * const stats = await client.analytics.statistics('BRENT_CRUDE_USD', 90);
80
- * console.log(`Mean: $${stats.mean}`);
81
- * console.log(`Std Dev: ${stats.std_dev}`);
82
- * console.log(`Range: $${stats.min} - $${stats.max}`);
83
- * ```
60
+ * @throws {ValidationError} If code is empty
84
61
  */
85
- async statistics(commodity, days) {
86
- if (!commodity || typeof commodity !== "string") {
62
+ async statistics(code, period) {
63
+ if (!code || typeof code !== "string") {
87
64
  throw new ValidationError("Commodity code must be a non-empty string");
88
65
  }
89
- const params = { commodity };
90
- if (days)
91
- params.days = days.toString();
66
+ const params = { code };
67
+ if (period !== undefined)
68
+ params.period = period.toString();
92
69
  return this.client["request"]("/v1/analytics/statistics", params);
93
70
  }
94
71
  /**
95
- * Analyze correlation between two commodities
72
+ * Analyze correlation between two commodities.
96
73
  *
97
- * Calculates the Pearson correlation coefficient to measure how closely
98
- * two commodities move together.
74
+ * Maps to `GET /v1/analytics/correlation`, which reads `code1`, `code2`,
75
+ * `period` and optional `type`, `window`, `codes`.
99
76
  *
100
- * @param commodity1 - First commodity code
101
- * @param commodity2 - Second commodity code
102
- * @param days - Number of days to analyze (default: 30)
77
+ * @param code1 - First commodity code
78
+ * @param code2 - Second commodity code
79
+ * @param options - Lookback window in days, or `{ period, type, window, codes }`
103
80
  * @returns Correlation analysis
104
81
  *
105
- * @throws {NotFoundError} If either commodity not found
106
- * @throws {OilPriceAPIError} If API request fails
82
+ * @throws {ValidationError} If either code is empty
107
83
  *
108
84
  * @example
109
85
  * ```typescript
110
- * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', 90);
111
- * console.log(`Correlation: ${corr.correlation}`);
112
- * console.log(`Strength: ${corr.strength}`);
113
- * console.log(`R-squared: ${corr.r_squared}`);
86
+ * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', { period: 90 });
87
+ * console.log(corr.correlation);
114
88
  * ```
115
89
  */
116
- async correlation(commodity1, commodity2, days) {
117
- if (!commodity1 || typeof commodity1 !== "string") {
90
+ async correlation(code1, code2, options) {
91
+ if (!code1 || typeof code1 !== "string") {
118
92
  throw new ValidationError("First commodity code must be a non-empty string");
119
93
  }
120
- if (!commodity2 || typeof commodity2 !== "string") {
94
+ if (!code2 || typeof code2 !== "string") {
121
95
  throw new ValidationError("Second commodity code must be a non-empty string");
122
96
  }
123
- const params = {
124
- commodity1,
125
- commodity2,
126
- };
127
- if (days)
128
- params.days = days.toString();
97
+ const opts = typeof options === "number" ? { period: options } : options || {};
98
+ const params = { code1, code2 };
99
+ if (opts.period !== undefined)
100
+ params.period = opts.period.toString();
101
+ if (opts.type)
102
+ params.type = opts.type;
103
+ if (opts.window !== undefined)
104
+ params.window = opts.window.toString();
105
+ if (opts.codes && opts.codes.length > 0)
106
+ params.codes = opts.codes.join(",");
129
107
  return this.client["request"]("/v1/analytics/correlation", params);
130
108
  }
131
109
  /**
132
- * Analyze price trend for a commodity
110
+ * Analyze price trend for a commodity.
133
111
  *
134
- * Detects trend direction, strength, and key levels (support/resistance).
112
+ * Maps to `GET /v1/analytics/trend`, which reads `code`, `period` and
113
+ * optional `type` ('analysis' | 'sma' | 'ema' | 'rsi' | 'levels') and `window`.
135
114
  *
136
- * @param commodity - Commodity code to analyze
137
- * @param days - Number of days to analyze (default: 30)
115
+ * @param code - Commodity code to analyze
116
+ * @param options - Lookback window in days, or `{ period, type, window }`
138
117
  * @returns Trend analysis
139
118
  *
140
- * @throws {NotFoundError} If commodity not found
141
- * @throws {OilPriceAPIError} If API request fails
142
- *
143
- * @example
144
- * ```typescript
145
- * const trend = await client.analytics.trend('WTI_USD', 60);
146
- * console.log(`Trend: ${trend.trend} (strength: ${trend.strength})`);
147
- * console.log(`Support: $${trend.support}`);
148
- * console.log(`Resistance: $${trend.resistance}`);
149
- * ```
119
+ * @throws {ValidationError} If code is empty
150
120
  */
151
- async trend(commodity, days) {
152
- if (!commodity || typeof commodity !== "string") {
121
+ async trend(code, options) {
122
+ if (!code || typeof code !== "string") {
153
123
  throw new ValidationError("Commodity code must be a non-empty string");
154
124
  }
155
- const params = { commodity };
156
- if (days)
157
- params.days = days.toString();
125
+ const opts = typeof options === "number" ? { period: options } : options || {};
126
+ const params = { code };
127
+ if (opts.period !== undefined)
128
+ params.period = opts.period.toString();
129
+ if (opts.type)
130
+ params.type = opts.type;
131
+ if (opts.window !== undefined)
132
+ params.window = opts.window.toString();
158
133
  return this.client["request"]("/v1/analytics/trend", params);
159
134
  }
160
135
  /**
161
- * Analyze spread between two commodities
136
+ * Analyze a named commodity spread (basis / crack / ratio).
162
137
  *
163
- * Calculates current spread and compares to historical patterns.
138
+ * Maps to `GET /v1/analytics/spread`, which reads `spread` (the named spread,
139
+ * e.g. 'wti_brent'), `period` and optional `type` ('current' | 'historical').
140
+ * Call with no `spread` to list the available named spreads.
164
141
  *
165
- * @param commodity1 - First commodity code
166
- * @param commodity2 - Second commodity code
167
- * @returns Spread analysis
168
- *
169
- * @throws {NotFoundError} If either commodity not found
170
- * @throws {OilPriceAPIError} If API request fails
142
+ * @param spread - Named spread (e.g. 'wti_brent'); omit to list available spreads
143
+ * @param options - Lookback window in days, or `{ period, type }`
144
+ * @returns Spread analysis (or the list of available spreads)
171
145
  *
172
146
  * @example
173
147
  * ```typescript
174
- * const spread = await client.analytics.spread('BRENT_CRUDE_USD', 'WTI_USD');
175
- * console.log(`Current spread: $${spread.spread}`);
176
- * console.log(`Average spread: $${spread.average_spread}`);
177
- * console.log(`Z-score: ${spread.z_score}`);
148
+ * const spread = await client.analytics.spread('wti_brent', { period: 30 });
149
+ * console.log(spread.current_spread);
178
150
  * ```
179
151
  */
180
- async spread(commodity1, commodity2) {
181
- if (!commodity1 || typeof commodity1 !== "string") {
182
- throw new ValidationError("First commodity code must be a non-empty string");
183
- }
184
- if (!commodity2 || typeof commodity2 !== "string") {
185
- throw new ValidationError("Second commodity code must be a non-empty string");
186
- }
187
- return this.client["request"]("/v1/analytics/spread", {
188
- commodity1,
189
- commodity2,
190
- });
152
+ async spread(spread, options) {
153
+ const opts = typeof options === "number" ? { period: options } : options || {};
154
+ const params = {};
155
+ if (spread)
156
+ params.spread = spread;
157
+ if (opts.period !== undefined)
158
+ params.period = opts.period.toString();
159
+ if (opts.type)
160
+ params.type = opts.type;
161
+ return this.client["request"]("/v1/analytics/spread", params);
191
162
  }
192
163
  /**
193
- * Get price forecast for a commodity
194
- *
195
- * Returns forecasted prices with confidence intervals.
196
- *
197
- * @param commodity - Commodity code to forecast
198
- * @returns Price forecast
164
+ * Get a statistical price forecast for a commodity.
199
165
  *
200
- * @throws {NotFoundError} If commodity not found
201
- * @throws {OilPriceAPIError} If API request fails
166
+ * Maps to `GET /v1/analytics/forecast`, which reads `code`, `method`
167
+ * (default 'ema') and `period` (default 90). Call with no `code` to list
168
+ * the available forecast methods.
202
169
  *
203
- * @example
204
- * ```typescript
205
- * const forecast = await client.analytics.forecast('WTI_USD');
206
- * console.log(`Forecast model: ${forecast.model}`);
207
- * console.log(`Horizon: ${forecast.horizon_days} days`);
208
- *
209
- * forecast.forecast.forEach(point => {
210
- * console.log(`${point.date}: $${point.price} (${point.lower_bound}-${point.upper_bound})`);
211
- * });
212
- * ```
170
+ * @param code - Commodity code to forecast; omit to list available methods
171
+ * @param options - `{ method, period }`
172
+ * @returns Price forecast (or the list of available methods)
213
173
  */
214
- async forecast(commodity) {
215
- if (!commodity || typeof commodity !== "string") {
216
- throw new ValidationError("Commodity code must be a non-empty string");
217
- }
218
- return this.client["request"]("/v1/analytics/forecast", {
219
- commodity,
220
- });
174
+ async forecast(code, options) {
175
+ const params = {};
176
+ if (code)
177
+ params.code = code;
178
+ if (options?.method)
179
+ params.method = options.method;
180
+ if (options?.period !== undefined)
181
+ params.period = options.period.toString();
182
+ return this.client["request"]("/v1/analytics/forecast", params);
221
183
  }
222
184
  }
@@ -115,13 +115,29 @@ export interface HistoricalBunkerPrice {
115
115
  unit: string;
116
116
  }
117
117
  /**
118
- * Options for historical bunker fuel query
118
+ * Options for historical bunker fuel query.
119
+ *
120
+ * The controller reads `from` / `to` (dates) and `interval` — not `start_date` /
121
+ * `end_date` / `fuel_type`. History is returned per port (all grades).
119
122
  */
120
123
  export interface HistoricalBunkerOptions {
121
124
  /** Start date in ISO 8601 format (YYYY-MM-DD) */
122
125
  startDate?: string;
123
126
  /** End date in ISO 8601 format (YYYY-MM-DD) */
124
127
  endDate?: string;
128
+ /** Aggregation interval (e.g. 'daily') */
129
+ interval?: string;
130
+ }
131
+ /**
132
+ * Options for port-to-port bunker spread query.
133
+ */
134
+ export interface BunkerSpreadOptions {
135
+ /** Origin port code */
136
+ from: string;
137
+ /** Destination port code */
138
+ to: string;
139
+ /** Fuel grade (e.g. 'VLSFO') */
140
+ grade?: string;
125
141
  }
126
142
  /**
127
143
  * Bunker Fuels Resource
@@ -206,23 +222,23 @@ export declare class BunkerFuelsResource {
206
222
  */
207
223
  compare(ports: string[]): Promise<PortPriceComparison>;
208
224
  /**
209
- * Get bunker fuel price spreads
225
+ * Get the bunker fuel price spread between two ports.
210
226
  *
211
- * Returns spreads between different fuel grades (e.g., VLSFO-IFO380).
227
+ * Maps to `GET /v1/bunker-fuels/spreads/ports`, which reads `from`, `to`
228
+ * and `grade`. (Earlier SDKs called `/v1/bunker-fuels/spreads` with no params,
229
+ * which 404'd.)
212
230
  *
213
- * @returns Fuel price spreads
231
+ * @param options - `{ from, to, grade? }`
232
+ * @returns Port-to-port fuel price spread
214
233
  *
215
- * @throws {OilPriceAPIError} If API request fails
234
+ * @throws {ValidationError} If from/to are missing
216
235
  *
217
236
  * @example
218
237
  * ```typescript
219
- * const spreads = await client.bunkerFuels.spreads();
220
- * spreads.spreads.forEach(spread => {
221
- * console.log(`${spread.fuel1}-${spread.fuel2} spread: $${spread.average_spread}`);
222
- * });
238
+ * const spread = await client.bunkerFuels.spreads({ from: 'SIN', to: 'RTM', grade: 'VLSFO' });
223
239
  * ```
224
240
  */
225
- spreads(): Promise<BunkerFuelSpreads>;
241
+ spreads(options: BunkerSpreadOptions): Promise<BunkerFuelSpreads>;
226
242
  /**
227
243
  * Get historical bunker fuel prices
228
244
  *
@@ -234,9 +250,16 @@ export declare class BunkerFuelsResource {
234
250
  * @throws {NotFoundError} If port or fuel type not found
235
251
  * @throws {OilPriceAPIError} If API request fails
236
252
  *
253
+ * The history endpoint is keyed by port in the PATH (`/historical/:port_code`)
254
+ * and returns all grades for that port; it does not filter by a single fuel
255
+ * type. It reads `from` / `to` / `interval` query params.
256
+ *
257
+ * @param port - Port code (e.g., "SIN", "RTM") — used as a path segment
258
+ * @param options - `{ startDate, endDate, interval }`
259
+ *
237
260
  * @example
238
261
  * ```typescript
239
- * const history = await client.bunkerFuels.historical('SIN', 'VLSFO', {
262
+ * const history = await client.bunkerFuels.historical('SIN', {
240
263
  * startDate: '2024-01-01',
241
264
  * endDate: '2024-12-31'
242
265
  * });
@@ -246,7 +269,7 @@ export declare class BunkerFuelsResource {
246
269
  * });
247
270
  * ```
248
271
  */
249
- historical(port: string, fuelType: string, options?: HistoricalBunkerOptions): Promise<HistoricalBunkerPrice[]>;
272
+ historical(port: string, options?: HistoricalBunkerOptions): Promise<HistoricalBunkerPrice[]>;
250
273
  /**
251
274
  * Export bunker fuel data
252
275
  *
@@ -51,7 +51,8 @@ export class BunkerFuelsResource {
51
51
  * ```
52
52
  */
53
53
  async all() {
54
- const response = await this.client["request"]("/v1/bunker-fuels", {});
54
+ // Route is GET /v1/bunker-fuels/all (the bare /v1/bunker-fuels has no route).
55
+ const response = await this.client["request"]("/v1/bunker-fuels/all", {});
55
56
  return Array.isArray(response) ? response : response.prices;
56
57
  }
57
58
  /**
@@ -104,24 +105,33 @@ export class BunkerFuelsResource {
104
105
  });
105
106
  }
106
107
  /**
107
- * Get bunker fuel price spreads
108
+ * Get the bunker fuel price spread between two ports.
108
109
  *
109
- * Returns spreads between different fuel grades (e.g., VLSFO-IFO380).
110
+ * Maps to `GET /v1/bunker-fuels/spreads/ports`, which reads `from`, `to`
111
+ * and `grade`. (Earlier SDKs called `/v1/bunker-fuels/spreads` with no params,
112
+ * which 404'd.)
110
113
  *
111
- * @returns Fuel price spreads
114
+ * @param options - `{ from, to, grade? }`
115
+ * @returns Port-to-port fuel price spread
112
116
  *
113
- * @throws {OilPriceAPIError} If API request fails
117
+ * @throws {ValidationError} If from/to are missing
114
118
  *
115
119
  * @example
116
120
  * ```typescript
117
- * const spreads = await client.bunkerFuels.spreads();
118
- * spreads.spreads.forEach(spread => {
119
- * console.log(`${spread.fuel1}-${spread.fuel2} spread: $${spread.average_spread}`);
120
- * });
121
+ * const spread = await client.bunkerFuels.spreads({ from: 'SIN', to: 'RTM', grade: 'VLSFO' });
121
122
  * ```
122
123
  */
123
- async spreads() {
124
- return this.client["request"]("/v1/bunker-fuels/spreads", {});
124
+ async spreads(options) {
125
+ if (!options?.from || !options?.to) {
126
+ throw new ValidationError("Both 'from' and 'to' port codes are required");
127
+ }
128
+ const params = {
129
+ from: options.from,
130
+ to: options.to,
131
+ };
132
+ if (options.grade)
133
+ params.grade = options.grade;
134
+ return this.client["request"]("/v1/bunker-fuels/spreads/ports", params);
125
135
  }
126
136
  /**
127
137
  * Get historical bunker fuel prices
@@ -134,9 +144,16 @@ export class BunkerFuelsResource {
134
144
  * @throws {NotFoundError} If port or fuel type not found
135
145
  * @throws {OilPriceAPIError} If API request fails
136
146
  *
147
+ * The history endpoint is keyed by port in the PATH (`/historical/:port_code`)
148
+ * and returns all grades for that port; it does not filter by a single fuel
149
+ * type. It reads `from` / `to` / `interval` query params.
150
+ *
151
+ * @param port - Port code (e.g., "SIN", "RTM") — used as a path segment
152
+ * @param options - `{ startDate, endDate, interval }`
153
+ *
137
154
  * @example
138
155
  * ```typescript
139
- * const history = await client.bunkerFuels.historical('SIN', 'VLSFO', {
156
+ * const history = await client.bunkerFuels.historical('SIN', {
140
157
  * startDate: '2024-01-01',
141
158
  * endDate: '2024-12-31'
142
159
  * });
@@ -146,22 +163,19 @@ export class BunkerFuelsResource {
146
163
  * });
147
164
  * ```
148
165
  */
149
- async historical(port, fuelType, options) {
166
+ async historical(port, options) {
150
167
  if (!port || typeof port !== "string") {
151
168
  throw new ValidationError("Port code must be a non-empty string");
152
169
  }
153
- if (!fuelType || typeof fuelType !== "string") {
154
- throw new ValidationError("Fuel type must be a non-empty string");
155
- }
156
- const params = {
157
- port,
158
- fuel_type: fuelType,
159
- };
170
+ const params = {};
160
171
  if (options?.startDate)
161
- params.start_date = options.startDate;
172
+ params.from = options.startDate;
162
173
  if (options?.endDate)
163
- params.end_date = options.endDate;
164
- const response = await this.client["request"]("/v1/bunker-fuels/historical", params);
174
+ params.to = options.endDate;
175
+ if (options?.interval)
176
+ params.interval = options.interval;
177
+ // Port code is a PATH segment: GET /v1/bunker-fuels/historical/:port_code
178
+ const response = await this.client["request"](`/v1/bunker-fuels/historical/${port}`, params);
165
179
  return Array.isArray(response) ? response : response.data;
166
180
  }
167
181
  /**
@@ -14,6 +14,10 @@ export type DataSourceType = "api" | "database" | "file" | "sftp" | "webhook" |
14
14
  export type DataSourceStatus = "active" | "paused" | "error" | "pending";
15
15
  /**
16
16
  * Data source configuration
17
+ *
18
+ * NOTE: The API reads `source_type`, `scraper_config`, `status` and `credentials`
19
+ * (nested under `data_source`). Earlier SDK versions used `type`/`config`/`enabled`,
20
+ * which the controller silently dropped.
17
21
  */
18
22
  export interface DataSource {
19
23
  /** Unique data source identifier */
@@ -21,63 +25,59 @@ export interface DataSource {
21
25
  /** User-friendly name */
22
26
  name: string;
23
27
  /** 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;
28
+ source_type: DataSourceType;
29
+ /** Scraper / connection configuration */
30
+ scraper_config?: Record<string, unknown>;
29
31
  /** Current status */
30
32
  status: DataSourceStatus;
31
33
  /** Last successful sync timestamp */
32
34
  last_sync_at?: string;
33
35
  /** Next scheduled sync timestamp */
34
36
  next_sync_at?: string;
35
- /** Sync frequency in minutes */
36
- sync_frequency_minutes?: number;
37
37
  /** Number of successful syncs */
38
- successful_syncs: number;
38
+ successful_syncs?: number;
39
39
  /** Number of failed syncs */
40
- failed_syncs: number;
40
+ failed_syncs?: number;
41
41
  /** Last error message */
42
42
  last_error?: string;
43
- /** Optional metadata */
44
- metadata?: Record<string, unknown>;
45
43
  /** ISO timestamp when source was created */
46
44
  created_at: string;
47
45
  /** ISO timestamp when source was last updated */
48
46
  updated_at: string;
49
47
  }
50
48
  /**
51
- * Parameters for creating a data source
49
+ * Parameters for creating a data source.
50
+ *
51
+ * Maps to the controller's `data_source_params` strong params:
52
+ * `source_type`, `name`, `status`, `credentials`, `scraper_config`.
52
53
  */
53
54
  export interface CreateDataSourceParams {
54
55
  /** User-friendly name */
55
56
  name: string;
56
57
  /** 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>;
58
+ source_type: DataSourceType;
59
+ /** Scraper / connection configuration */
60
+ scraper_config?: Record<string, unknown>;
61
+ /** Credentials (encrypted server-side) */
62
+ credentials?: Record<string, unknown>;
63
+ /** Lifecycle status */
64
+ status?: DataSourceStatus;
66
65
  }
67
66
  /**
68
- * Parameters for updating a data source
67
+ * Parameters for updating a data source.
68
+ *
69
+ * Maps to `data_source_update_params`: `name`, `status`, `credentials`,
70
+ * `scraper_config` (source_type cannot be changed).
69
71
  */
70
72
  export interface UpdateDataSourceParams {
71
73
  /** User-friendly name */
72
74
  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>;
75
+ /** Scraper / connection configuration */
76
+ scraper_config?: Record<string, unknown>;
77
+ /** Credentials (encrypted server-side) */
78
+ credentials?: Record<string, unknown>;
79
+ /** Lifecycle status */
80
+ status?: DataSourceStatus;
81
81
  }
82
82
  /**
83
83
  * Data source test response
@@ -361,5 +361,5 @@ export declare class DataSourcesResource {
361
361
  * console.log(`Credential rotation: ${result.success ? 'success' : 'failed'}`);
362
362
  * ```
363
363
  */
364
- rotateCredentials(id: string): Promise<CredentialRotationResponse>;
364
+ rotateCredentials(id: string, credentials: Record<string, unknown>): Promise<CredentialRotationResponse>;
365
365
  }