@chainlink/external-adapter-framework 0.0.69 → 0.1.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/adapter/basic.d.ts +34 -2
- package/adapter/basic.js +113 -1
- package/adapter/basic.js.map +1 -1
- package/adapter/price.d.ts +33 -5
- package/adapter/price.js +41 -2
- package/adapter/price.js.map +1 -1
- package/adapter/types.d.ts +15 -1
- package/cache/index.d.ts +3 -10
- package/cache/index.js +4 -46
- package/cache/index.js.map +1 -1
- package/cache/redis.d.ts +1 -8
- package/cache/redis.js +22 -39
- package/cache/redis.js.map +1 -1
- package/config/index.d.ts +1 -1
- package/config/index.js +0 -1
- package/config/index.js.map +1 -1
- package/examples/bank-frick/accounts.d.ts +1 -1
- package/examples/bank-frick/accounts.js.map +1 -1
- package/examples/bank-frick/config/index.d.ts +1 -1
- package/examples/coingecko/src/crypto-utils.d.ts +5 -5
- package/examples/coingecko/src/crypto-utils.js +1 -2
- package/examples/coingecko/src/crypto-utils.js.map +1 -1
- package/examples/coingecko/src/endpoint/coins.js.map +1 -1
- package/examples/coingecko/src/endpoint/crypto-marketcap.d.ts +1 -1
- package/examples/coingecko/src/endpoint/crypto-marketcap.js.map +1 -1
- package/examples/coingecko/src/endpoint/crypto-volume.d.ts +1 -1
- package/examples/coingecko/src/endpoint/crypto-volume.js.map +1 -1
- package/examples/coingecko/src/endpoint/crypto.d.ts +1 -4
- package/examples/coingecko/src/endpoint/crypto.js.map +1 -1
- package/examples/coingecko/src/endpoint/dominance.d.ts +1 -1
- package/examples/coingecko/src/endpoint/dominance.js.map +1 -1
- package/examples/coingecko/src/endpoint/global-marketcap.d.ts +1 -1
- package/examples/coingecko/src/endpoint/global-marketcap.js.map +1 -1
- package/examples/coingecko/src/global-utils.d.ts +3 -3
- package/examples/coingecko/src/global-utils.js.map +1 -1
- package/examples/coingecko/src/index.d.ts +1 -1
- package/examples/coingecko-old/batch-warming.d.ts +1 -1
- package/examples/coingecko-old/rest.js.map +1 -1
- package/examples/cryptocompare/src/endpoints/crypto.d.ts +1 -1
- package/examples/cryptocompare/src/index.d.ts +1 -1
- package/examples/genesis/sseStream.d.ts +2 -2
- package/examples/genesis/sseStream.js +15 -8
- package/examples/genesis/sseStream.js.map +1 -1
- package/examples/ncfx/websocket.d.ts +1 -1
- package/index.d.ts +3 -1
- package/index.js +4 -6
- package/index.js.map +1 -1
- package/metrics/index.js +1 -1
- package/metrics/index.js.map +1 -1
- package/package.json +3 -2
- package/rate-limiting/index.d.ts +2 -2
- package/transports/batch-warming.d.ts +5 -5
- package/transports/batch-warming.js +3 -3
- package/transports/batch-warming.js.map +1 -1
- package/transports/index.d.ts +9 -16
- package/transports/index.js +2 -59
- package/transports/index.js.map +1 -1
- package/transports/metrics.d.ts +1 -1
- package/transports/rest.d.ts +4 -2
- package/transports/rest.js +2 -1
- package/transports/rest.js.map +1 -1
- package/transports/sse.d.ts +5 -5
- package/transports/sse.js +1 -2
- package/transports/sse.js.map +1 -1
- package/transports/websocket.d.ts +5 -5
- package/transports/websocket.js +2 -2
- package/transports/websocket.js.map +1 -1
- package/util/logger.d.ts +2 -0
- package/util/logger.js +44 -4
- package/util/logger.js.map +1 -1
- package/validation/index.js +6 -13
- package/validation/index.js.map +1 -1
- package/validation/input-params.d.ts +0 -1
- package/validation/input-params.js +0 -28
- package/validation/input-params.js.map +1 -1
- package/validation/input-validator.js +1 -2
- package/validation/input-validator.js.map +1 -1
- package/adapter.d.ts +0 -156
- package/adapter.js +0 -200
- package/adapter.js.map +0 -1
- package/examples/coingecko/batch-warming.d.ts +0 -7
- package/examples/coingecko/batch-warming.js +0 -54
- package/examples/coingecko/batch-warming.js.map +0 -1
- package/examples/coingecko/index.d.ts +0 -2
- package/examples/coingecko/index.js +0 -12
- package/examples/coingecko/index.js.map +0 -1
- package/examples/coingecko/rest.d.ts +0 -12
- package/examples/coingecko/rest.js +0 -55
- package/examples/coingecko/rest.js.map +0 -1
- package/examples/coingecko/src/cryptoUtils.d.ts +0 -31
- package/examples/coingecko/src/cryptoUtils.js +0 -60
- package/examples/coingecko/src/globalUtils.d.ts +0 -27
- package/examples/coingecko/src/globalUtils.js +0 -46
- package/validation/override-functions.d.ts +0 -3
- package/validation/override-functions.js +0 -41
- package/validation/override-functions.js.map +0 -1
- package/validation/preset-tokens.json +0 -23
- package/validation/validator.d.ts +0 -47
- package/validation/validator.js +0 -303
package/adapter/basic.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SettingsMap, BaseAdapterConfig, AdapterConfig } from '../config';
|
|
2
|
+
import { AdapterRequest, AdapterResponse } from '../util';
|
|
2
3
|
import { AdapterEndpoint } from './endpoint';
|
|
3
|
-
import { AdapterDependencies, AdapterParams, AdapterRateLimitingConfig, CustomAdapterSettings } from './types';
|
|
4
|
+
import { AdapterDependencies, AdapterParams, AdapterRateLimitingConfig, CustomAdapterSettings, RequestTransform } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* Main class to represent an External Adapter
|
|
6
7
|
*/
|
|
@@ -12,13 +13,14 @@ export declare class Adapter<CustomSettings extends CustomAdapterSettings = Sett
|
|
|
12
13
|
customSettings?: SettingsMap | undefined;
|
|
13
14
|
rateLimiting?: AdapterRateLimitingConfig | undefined;
|
|
14
15
|
overrides?: Record<string, string> | undefined;
|
|
16
|
+
requestTransforms?: RequestTransform[];
|
|
15
17
|
initialized: boolean;
|
|
16
18
|
/** Object containing alias translations for all endpoints */
|
|
17
19
|
endpointsMap: Record<string, AdapterEndpoint<unknown, unknown, CustomSettings>>;
|
|
18
20
|
/** Initialized dependencies that the adapter will use */
|
|
19
21
|
dependencies: AdapterDependencies;
|
|
20
22
|
/** Configuration params for various adapter properties */
|
|
21
|
-
config: AdapterConfig
|
|
23
|
+
config: AdapterConfig<CustomSettings>;
|
|
22
24
|
constructor(params: AdapterParams<CustomSettings>);
|
|
23
25
|
/**
|
|
24
26
|
* Initializes all of the [[Transport]]s in the adapter, passing along any [[AdapterDependencies]] and [[AdapterConfig]].
|
|
@@ -49,4 +51,34 @@ export declare class Adapter<CustomSettings extends CustomAdapterSettings = Sett
|
|
|
49
51
|
* @returns a set of AdapterDependencies all initialized
|
|
50
52
|
*/
|
|
51
53
|
initializeDependencies(inputDependencies?: Partial<AdapterDependencies>): AdapterDependencies;
|
|
54
|
+
/**
|
|
55
|
+
* Attempts to find a value from the Cache and return that if found.
|
|
56
|
+
*
|
|
57
|
+
* @param req - the incoming request to this adapter
|
|
58
|
+
* @returns the cached value if exists
|
|
59
|
+
*/
|
|
60
|
+
findResponseInCache(req: AdapterRequest): Promise<AdapterResponse | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Default request transform that takes requests and manipulates
|
|
63
|
+
*
|
|
64
|
+
* @param adapter - the current adapter
|
|
65
|
+
* @param req - the current adapter request
|
|
66
|
+
* @returns the modified (or new) request
|
|
67
|
+
*/
|
|
68
|
+
symbolOverrider(req: AdapterRequest): AdapterRequest<import("../util").AdapterRequestData>;
|
|
69
|
+
/**
|
|
70
|
+
* Takes the incoming request and applies all request transforms in the adapter
|
|
71
|
+
*
|
|
72
|
+
* @param req - the current adapter request
|
|
73
|
+
* @returns the request after passing through all request transforms
|
|
74
|
+
*/
|
|
75
|
+
runRequestTransforms(req: AdapterRequest): void;
|
|
76
|
+
/**
|
|
77
|
+
* Function to serve as middleware to pass along the AdapterRequest to the appropriate Transport (acc. to the endpoint in the req.)
|
|
78
|
+
*
|
|
79
|
+
* @param req - the incoming request to this adapter
|
|
80
|
+
* @param reply - the fastify reply that will be sent back
|
|
81
|
+
* @returns a simple Promise when it's done
|
|
82
|
+
*/
|
|
83
|
+
handleRequest(req: AdapterRequest): Promise<AdapterResponse>;
|
|
52
84
|
}
|
package/adapter/basic.js
CHANGED
|
@@ -31,9 +31,11 @@ const ioredis_1 = __importDefault(require("ioredis"));
|
|
|
31
31
|
const cache_1 = require("../cache");
|
|
32
32
|
const cacheMetrics = __importStar(require("../cache/metrics"));
|
|
33
33
|
const config_1 = require("../config");
|
|
34
|
+
const transportMetrics = __importStar(require("../transports/metrics"));
|
|
34
35
|
const rate_limiting_1 = require("../rate-limiting");
|
|
35
36
|
const util_1 = require("../util");
|
|
36
37
|
const censor_list_1 = __importDefault(require("../util/censor/censor-list"));
|
|
38
|
+
const error_1 = require("../validation/error");
|
|
37
39
|
const logger = (0, util_1.makeLogger)('Adapter');
|
|
38
40
|
/**
|
|
39
41
|
* Main class to represent an External Adapter
|
|
@@ -52,6 +54,7 @@ class Adapter {
|
|
|
52
54
|
this.customSettings = params.customSettings;
|
|
53
55
|
this.rateLimiting = params.rateLimiting;
|
|
54
56
|
this.overrides = params.overrides;
|
|
57
|
+
this.requestTransforms = [this.symbolOverrider.bind(this), ...(params.requestTransforms || [])];
|
|
55
58
|
this.config = (0, config_1.buildAdapterConfig)({
|
|
56
59
|
overrides: this.envDefaultOverrides,
|
|
57
60
|
customSettings: this.customSettings,
|
|
@@ -132,7 +135,10 @@ class Adapter {
|
|
|
132
135
|
buildCensorList() {
|
|
133
136
|
const censorList = Object.entries(config_1.BaseSettings)
|
|
134
137
|
.concat(Object.entries(this.customSettings || {}))
|
|
135
|
-
.filter(([name, setting]) => setting &&
|
|
138
|
+
.filter(([name, setting]) => setting &&
|
|
139
|
+
setting.type === 'string' &&
|
|
140
|
+
setting.sensitive &&
|
|
141
|
+
this.config[name])
|
|
136
142
|
.map(([name]) => ({
|
|
137
143
|
key: name,
|
|
138
144
|
// Escaping potential special characters in values before creating regex
|
|
@@ -181,6 +187,112 @@ class Adapter {
|
|
|
181
187
|
}
|
|
182
188
|
return dependencies;
|
|
183
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Attempts to find a value from the Cache and return that if found.
|
|
192
|
+
*
|
|
193
|
+
* @param req - the incoming request to this adapter
|
|
194
|
+
* @returns the cached value if exists
|
|
195
|
+
*/
|
|
196
|
+
async findResponseInCache(req) {
|
|
197
|
+
const response = await this.dependencies.cache.get(req.requestContext.cacheKey);
|
|
198
|
+
if (response) {
|
|
199
|
+
logger.debug('Found response from cache, sending that');
|
|
200
|
+
if (this.config.METRICS_ENABLED && this.config.EXPERIMENTAL_METRICS_ENABLED) {
|
|
201
|
+
const label = cacheMetrics.cacheMetricsLabel(req.requestContext.cacheKey, req.requestContext.meta?.metrics?.feedId || 'N/A', this.config.CACHE_TYPE);
|
|
202
|
+
// Record cache staleness and cache get count and value
|
|
203
|
+
const staleness = (0, cache_1.calculateStaleness)(response.maxAge, this.config.CACHE_MAX_AGE);
|
|
204
|
+
cacheMetrics.cacheGet(label, response.result, staleness);
|
|
205
|
+
req.requestContext.meta = {
|
|
206
|
+
...req.requestContext.meta,
|
|
207
|
+
metrics: { ...req.requestContext.meta?.metrics, cacheHit: true },
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return response;
|
|
211
|
+
}
|
|
212
|
+
logger.debug('Did not find response in cache, moving to next middleware');
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Default request transform that takes requests and manipulates
|
|
216
|
+
*
|
|
217
|
+
* @param adapter - the current adapter
|
|
218
|
+
* @param req - the current adapter request
|
|
219
|
+
* @returns the modified (or new) request
|
|
220
|
+
*/
|
|
221
|
+
symbolOverrider(req) {
|
|
222
|
+
const requestOverrides = req.requestContext.data?.['overrides']?.[this.name];
|
|
223
|
+
const base = req.requestContext.data['base'];
|
|
224
|
+
// Perform overrides specified in the request payload
|
|
225
|
+
if (requestOverrides) {
|
|
226
|
+
req.requestContext.data['base'] = requestOverrides[base] ?? base;
|
|
227
|
+
}
|
|
228
|
+
// Perform hardcoded adapter overrides
|
|
229
|
+
if (this.overrides) {
|
|
230
|
+
req.requestContext.data['base'] = this.overrides[base] ?? base;
|
|
231
|
+
}
|
|
232
|
+
return req;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Takes the incoming request and applies all request transforms in the adapter
|
|
236
|
+
*
|
|
237
|
+
* @param req - the current adapter request
|
|
238
|
+
* @returns the request after passing through all request transforms
|
|
239
|
+
*/
|
|
240
|
+
runRequestTransforms(req) {
|
|
241
|
+
if (!this.requestTransforms) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
for (const transform of this.requestTransforms) {
|
|
245
|
+
transform(req);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Function to serve as middleware to pass along the AdapterRequest to the appropriate Transport (acc. to the endpoint in the req.)
|
|
250
|
+
*
|
|
251
|
+
* @param req - the incoming request to this adapter
|
|
252
|
+
* @param reply - the fastify reply that will be sent back
|
|
253
|
+
* @returns a simple Promise when it's done
|
|
254
|
+
*/
|
|
255
|
+
async handleRequest(req) {
|
|
256
|
+
// First try to find the response in our cache
|
|
257
|
+
const cachedResponse = await this.findResponseInCache(req);
|
|
258
|
+
if (cachedResponse) {
|
|
259
|
+
return cachedResponse;
|
|
260
|
+
}
|
|
261
|
+
// Get transport, must be here because it's already checked in the validator
|
|
262
|
+
const transport = this.endpointsMap[req.requestContext.endpointName].transport;
|
|
263
|
+
// Set up transport if it hasn't been done already
|
|
264
|
+
if (!(await transport.hasBeenSetUp(req))) {
|
|
265
|
+
logger.debug('Transport not set up yet, doing so...');
|
|
266
|
+
const immediateResponse = await transport.setup(req, this.config);
|
|
267
|
+
if (immediateResponse) {
|
|
268
|
+
logger.debug('Got immediate response from transport, sending as response');
|
|
269
|
+
return immediateResponse;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Observe the idle time taken for polling response
|
|
273
|
+
const metricsTimer = transportMetrics.transportPollingDurationSeconds
|
|
274
|
+
.labels({ endpoint: req.requestContext.endpointName })
|
|
275
|
+
.startTimer();
|
|
276
|
+
logger.debug('Transport is set up, polling cache for response...');
|
|
277
|
+
const response = await (0, cache_1.pollResponseFromCache)(this.dependencies.cache, req.requestContext.cacheKey, {
|
|
278
|
+
maxRetries: this.config.CACHE_POLLING_MAX_RETRIES,
|
|
279
|
+
sleep: this.config.CACHE_POLLING_SLEEP_MS,
|
|
280
|
+
});
|
|
281
|
+
metricsTimer({ succeeded: String(!!response) });
|
|
282
|
+
if (response) {
|
|
283
|
+
logger.debug('Got a response from the cache, sending that back');
|
|
284
|
+
return response;
|
|
285
|
+
}
|
|
286
|
+
// Record polling mechanism failure to return response
|
|
287
|
+
transportMetrics.transportPollingFailureCount
|
|
288
|
+
.labels({ endpoint: req.requestContext.endpointName })
|
|
289
|
+
.inc();
|
|
290
|
+
logger.debug('Ran out of polling attempts, returning timeout');
|
|
291
|
+
throw new error_1.AdapterTimeoutError({
|
|
292
|
+
message: 'Timed out waiting for provider result.',
|
|
293
|
+
statusCode: 504,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
184
296
|
}
|
|
185
297
|
exports.Adapter = Adapter;
|
|
186
298
|
//# sourceMappingURL=basic.js.map
|
package/adapter/basic.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic.js","sourceRoot":"","sources":["../../../src/adapter/basic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA2B;AAC3B,
|
|
1
|
+
{"version":3,"file":"basic.js","sourceRoot":"","sources":["../../../src/adapter/basic.ts"],"names":[],"mappings":"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"}
|
package/adapter/price.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Adapter, AdapterEndpointParams, AdapterParams } from './index';
|
|
2
|
-
import { AdapterEndpoint } from './endpoint';
|
|
3
1
|
import { SettingsMap } from '../config';
|
|
2
|
+
import { AdapterRequest, AdapterRequestContext, AdapterResponse } from '../util';
|
|
3
|
+
import { AdapterEndpoint } from './endpoint';
|
|
4
|
+
import { Adapter, AdapterEndpointParams, AdapterParams } from './index';
|
|
4
5
|
/**
|
|
5
6
|
* Type for the base input parameter config that any [[PriceEndpoint]] must extend
|
|
6
7
|
*/
|
|
@@ -9,7 +10,7 @@ export declare type PriceEndpointInputParameters = {
|
|
|
9
10
|
aliases: readonly ['from', 'coin', ...string[]];
|
|
10
11
|
type: 'string';
|
|
11
12
|
description: 'The symbol of symbols of the currency to query';
|
|
12
|
-
required:
|
|
13
|
+
required: false;
|
|
13
14
|
};
|
|
14
15
|
quote: {
|
|
15
16
|
aliases: readonly ['to', 'market', ...string[]];
|
|
@@ -25,10 +26,26 @@ export declare const priceEndpointInputParameters: PriceEndpointInputParameters;
|
|
|
25
26
|
/**
|
|
26
27
|
* Type for base input params for a PriceEndpoint
|
|
27
28
|
*/
|
|
28
|
-
declare type PriceEndpointParams = {
|
|
29
|
+
export declare type PriceEndpointParams = {
|
|
29
30
|
base: string;
|
|
30
31
|
quote: string;
|
|
31
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Structure of an "includes" file.
|
|
35
|
+
* Include pairs describe an incoming price feed request, and the details specify
|
|
36
|
+
*/
|
|
37
|
+
export declare type IncludesFile = IncludePair[];
|
|
38
|
+
declare type IncludeDetails = {
|
|
39
|
+
from: string;
|
|
40
|
+
to: string;
|
|
41
|
+
inverse: boolean;
|
|
42
|
+
};
|
|
43
|
+
declare type IncludePair = {
|
|
44
|
+
from: string;
|
|
45
|
+
to: string;
|
|
46
|
+
includes: IncludeDetails[];
|
|
47
|
+
};
|
|
48
|
+
declare type IncludesMap = Record<string, Record<string, IncludeDetails>>;
|
|
32
49
|
/**
|
|
33
50
|
* A PriceEndpoint is a specific type of AdapterEndpoint. Meant to comply with standard practices for
|
|
34
51
|
* Data Feeds, its InputParameters must extend the basic ones (base/quote).
|
|
@@ -38,10 +55,21 @@ export declare class PriceEndpoint<Params extends PriceEndpointParams, ProviderR
|
|
|
38
55
|
inputParameters: PriceEndpointInputParameters;
|
|
39
56
|
});
|
|
40
57
|
}
|
|
58
|
+
declare type PriceAdapterRequest<T> = AdapterRequest<T> & {
|
|
59
|
+
requestContext: AdapterRequestContext<T> & {
|
|
60
|
+
priceMeta: {
|
|
61
|
+
inverse: boolean;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
41
65
|
/**
|
|
42
66
|
* A PriceAdapter is a specific kind of Adapter that includes at least one PriceEnpoint.
|
|
43
67
|
*/
|
|
44
68
|
export declare class PriceAdapter<CustomSettings extends SettingsMap> extends Adapter<CustomSettings> {
|
|
45
|
-
|
|
69
|
+
includesMap?: IncludesMap;
|
|
70
|
+
constructor(params: AdapterParams<CustomSettings> & {
|
|
71
|
+
includes?: IncludesFile;
|
|
72
|
+
});
|
|
73
|
+
handleRequest(req: PriceAdapterRequest<PriceEndpointParams>): Promise<AdapterResponse>;
|
|
46
74
|
}
|
|
47
75
|
export {};
|
package/adapter/price.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PriceAdapter = exports.PriceEndpoint = exports.priceEndpointInputParameters = void 0;
|
|
4
|
-
const index_1 = require("./index");
|
|
5
4
|
const endpoint_1 = require("./endpoint");
|
|
5
|
+
const index_1 = require("./index");
|
|
6
6
|
/**
|
|
7
7
|
* Base input parameter config that any [[PriceEndpoint]] must extend
|
|
8
8
|
*/
|
|
@@ -11,7 +11,7 @@ exports.priceEndpointInputParameters = {
|
|
|
11
11
|
aliases: ['from', 'coin'],
|
|
12
12
|
type: 'string',
|
|
13
13
|
description: 'The symbol of symbols of the currency to query',
|
|
14
|
-
required:
|
|
14
|
+
required: false,
|
|
15
15
|
},
|
|
16
16
|
quote: {
|
|
17
17
|
aliases: ['to', 'market'],
|
|
@@ -30,6 +30,16 @@ class PriceEndpoint extends endpoint_1.AdapterEndpoint {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
exports.PriceEndpoint = PriceEndpoint;
|
|
33
|
+
const buildIncludesMap = (includesFile) => {
|
|
34
|
+
const includesMap = {};
|
|
35
|
+
for (const { from, to, includes } of includesFile) {
|
|
36
|
+
if (!includesMap[from]) {
|
|
37
|
+
includesMap[from] = {};
|
|
38
|
+
}
|
|
39
|
+
includesMap[from][to] = includes[0];
|
|
40
|
+
}
|
|
41
|
+
return includesMap;
|
|
42
|
+
};
|
|
33
43
|
/**
|
|
34
44
|
* A PriceAdapter is a specific kind of Adapter that includes at least one PriceEnpoint.
|
|
35
45
|
*/
|
|
@@ -40,6 +50,35 @@ class PriceAdapter extends index_1.Adapter {
|
|
|
40
50
|
throw new Error(`This PriceAdapter's list of endpoints does not contain a valid PriceEndpoint`);
|
|
41
51
|
}
|
|
42
52
|
super(params);
|
|
53
|
+
if (params.includes) {
|
|
54
|
+
// Build includes map for constant lookups
|
|
55
|
+
this.includesMap = buildIncludesMap(params.includes);
|
|
56
|
+
const requestTransform = (req) => {
|
|
57
|
+
const priceRequest = req;
|
|
58
|
+
const requestData = priceRequest.requestContext.data;
|
|
59
|
+
const includesDetails = this.includesMap?.[requestData.base]?.[requestData.quote];
|
|
60
|
+
if (includesDetails) {
|
|
61
|
+
requestData.base = includesDetails.from || requestData.base;
|
|
62
|
+
requestData.quote = includesDetails.to || requestData.quote;
|
|
63
|
+
}
|
|
64
|
+
const inverse = includesDetails?.inverse || false;
|
|
65
|
+
priceRequest.requestContext.priceMeta = {
|
|
66
|
+
inverse,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
this.requestTransforms?.push(requestTransform);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async handleRequest(req) {
|
|
73
|
+
const response = await super.handleRequest(req);
|
|
74
|
+
if (this.includesMap) {
|
|
75
|
+
// We need to search in the reverse order (quote -> base) because the request transform will have inverted the pair
|
|
76
|
+
const includes = this.includesMap[req.requestContext.data.quote]?.[req.requestContext.data.base];
|
|
77
|
+
if (includes && includes.inverse) {
|
|
78
|
+
response.result = 1 / response.result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return response;
|
|
43
82
|
}
|
|
44
83
|
}
|
|
45
84
|
exports.PriceAdapter = PriceAdapter;
|
package/adapter/price.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"price.js","sourceRoot":"","sources":["../../../src/adapter/price.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"price.js","sourceRoot":"","sources":["../../../src/adapter/price.ts"],"names":[],"mappings":"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"}
|
package/adapter/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { AdapterEndpoint } from './endpoint';
|
|
|
3
3
|
import { CustomSettingsType, SettingsMap, AdapterConfig, BaseAdapterConfig } from '../config';
|
|
4
4
|
import { RequestRateLimiter, BackgroundExecuteRateLimiter, AdapterRateLimitTier } from '../rate-limiting';
|
|
5
5
|
import { Transport } from '../transports';
|
|
6
|
-
import { SubscriptionSetFactory } from '../util';
|
|
6
|
+
import { AdapterRequest, SubscriptionSetFactory } from '../util';
|
|
7
7
|
import { InputParameters } from '../validation';
|
|
8
8
|
import { Cache } from '../cache';
|
|
9
9
|
import type EventSource from 'eventsource';
|
|
@@ -45,6 +45,18 @@ export interface AdapterRateLimitingConfig {
|
|
|
45
45
|
/** Adapter rate limits, gotten from the specific tier requested */
|
|
46
46
|
tiers: Record<string, AdapterRateLimitTier>;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Type to perform arbitrary modifications on an adapter request
|
|
50
|
+
*/
|
|
51
|
+
export declare type RequestTransform = (req: AdapterRequest) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Map of overrides objects (symbol -\> symbol) per adapter name
|
|
54
|
+
*/
|
|
55
|
+
export declare type Overrides = {
|
|
56
|
+
[adapterName: string]: {
|
|
57
|
+
[symbol: string]: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
48
60
|
/**
|
|
49
61
|
* Main structure of an External Adapter
|
|
50
62
|
*/
|
|
@@ -71,6 +83,8 @@ export interface AdapterParams<CustomSettings extends SettingsMap> {
|
|
|
71
83
|
rateLimiting?: AdapterRateLimitingConfig;
|
|
72
84
|
/** Overrides for converting the 'base' parameter that are hardcoded into the adapter. */
|
|
73
85
|
overrides?: Record<string, string>;
|
|
86
|
+
/** Transforms that will apply to the request before submitting it through the adapter request flow */
|
|
87
|
+
requestTransforms?: RequestTransform[];
|
|
74
88
|
}
|
|
75
89
|
/**
|
|
76
90
|
* Structure to describe rate limits specs for a specific adapter endpoint
|
package/cache/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AdapterEndpoint } from '../adapter';
|
|
2
2
|
import { AdapterConfig, SettingsMap } from '../config';
|
|
3
|
-
import {
|
|
3
|
+
import { AdapterResponse, sleep } from '../util';
|
|
4
|
+
export * from './factory';
|
|
4
5
|
export * from './local';
|
|
5
6
|
export * from './redis';
|
|
6
|
-
export * from './factory';
|
|
7
7
|
/**
|
|
8
8
|
* An object describing an entry in the cache.
|
|
9
9
|
* @typeParam T - the type of the entry's value
|
|
@@ -71,6 +71,7 @@ export declare const calculateFeedId: <Params, Result, CustomSettings extends Se
|
|
|
71
71
|
* ```
|
|
72
72
|
*/
|
|
73
73
|
export declare const calculateKey: <CustomSettings extends SettingsMap>(data: unknown, paramNames: string[], adapterConfig: AdapterConfig<CustomSettings>) => string;
|
|
74
|
+
export declare const calculateStaleness: (expirationTimestamp: number | undefined, ttl: number) => number;
|
|
74
75
|
/**
|
|
75
76
|
* Polls the provided Cache for an AdapterResponse set in the provided key. If the maximum
|
|
76
77
|
* amount of retries is exceeded, it returns undefined instead.
|
|
@@ -84,11 +85,3 @@ export declare const pollResponseFromCache: (cache: Cache<AdapterResponse>, key:
|
|
|
84
85
|
maxRetries: number;
|
|
85
86
|
sleep: number;
|
|
86
87
|
}, retry?: number) => Promise<AdapterResponse | undefined>;
|
|
87
|
-
/**
|
|
88
|
-
* Given a Cache instance in the adapter dependencies, builds a middleware function that will perform
|
|
89
|
-
* a get from said Cache and return that if found; otherwise it'll continue the middleware chain.
|
|
90
|
-
*
|
|
91
|
-
* @param adapter - an initialized adapter
|
|
92
|
-
* @returns the cache middleware function
|
|
93
|
-
*/
|
|
94
|
-
export declare const buildCacheMiddleware: AdapterMiddlewareBuilder;
|
package/cache/index.js
CHANGED
|
@@ -10,28 +10,15 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
15
|
};
|
|
28
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
17
|
+
exports.pollResponseFromCache = exports.calculateStaleness = exports.calculateKey = exports.calculateFeedId = exports.calculateCacheKey = void 0;
|
|
30
18
|
const util_1 = require("../util");
|
|
31
|
-
|
|
19
|
+
__exportStar(require("./factory"), exports);
|
|
32
20
|
__exportStar(require("./local"), exports);
|
|
33
21
|
__exportStar(require("./redis"), exports);
|
|
34
|
-
__exportStar(require("./factory"), exports);
|
|
35
22
|
const logger = (0, util_1.makeLogger)('Cache');
|
|
36
23
|
// Uses calculateKey to generate a unique key from the endpoint name, data, and input parameters
|
|
37
24
|
const calculateCacheKey = ({ adapterEndpoint, adapterConfig, }, data) => {
|
|
@@ -74,10 +61,6 @@ const calculateKey = (data, paramNames, adapterConfig) => {
|
|
|
74
61
|
const params = data;
|
|
75
62
|
let cacheKey = '';
|
|
76
63
|
for (const paramName of paramNames) {
|
|
77
|
-
// Ignore overrides param when generating cache keys
|
|
78
|
-
if (paramName === 'overrides') {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
64
|
const param = params[paramName];
|
|
82
65
|
if (param === undefined) {
|
|
83
66
|
continue;
|
|
@@ -104,7 +87,7 @@ const calculateKey = (data, paramNames, adapterConfig) => {
|
|
|
104
87
|
return cacheKey;
|
|
105
88
|
};
|
|
106
89
|
exports.calculateKey = calculateKey;
|
|
107
|
-
// Calculate the amount of time
|
|
90
|
+
// Calculate the amount of time a non-expired entry has been in the cache
|
|
108
91
|
const calculateStaleness = (expirationTimestamp, ttl) => {
|
|
109
92
|
if (expirationTimestamp) {
|
|
110
93
|
const createTimestamp = expirationTimestamp - ttl;
|
|
@@ -116,6 +99,7 @@ const calculateStaleness = (expirationTimestamp, ttl) => {
|
|
|
116
99
|
return ttl;
|
|
117
100
|
}
|
|
118
101
|
};
|
|
102
|
+
exports.calculateStaleness = calculateStaleness;
|
|
119
103
|
/**
|
|
120
104
|
* Polls the provided Cache for an AdapterResponse set in the provided key. If the maximum
|
|
121
105
|
* amount of retries is exceeded, it returns undefined instead.
|
|
@@ -146,30 +130,4 @@ const pollResponseFromCache = async (cache, key, options, retry = 0) => {
|
|
|
146
130
|
return (0, exports.pollResponseFromCache)(cache, key, options, retry + 1);
|
|
147
131
|
};
|
|
148
132
|
exports.pollResponseFromCache = pollResponseFromCache;
|
|
149
|
-
/**
|
|
150
|
-
* Given a Cache instance in the adapter dependencies, builds a middleware function that will perform
|
|
151
|
-
* a get from said Cache and return that if found; otherwise it'll continue the middleware chain.
|
|
152
|
-
*
|
|
153
|
-
* @param adapter - an initialized adapter
|
|
154
|
-
* @returns the cache middleware function
|
|
155
|
-
*/
|
|
156
|
-
const buildCacheMiddleware = (adapter) => async (req, res) => {
|
|
157
|
-
const response = await adapter.dependencies.cache.get(req.requestContext.cacheKey);
|
|
158
|
-
if (response) {
|
|
159
|
-
logger.debug('Found response from cache, sending that');
|
|
160
|
-
if (adapter.config.METRICS_ENABLED && adapter.config.EXPERIMENTAL_METRICS_ENABLED) {
|
|
161
|
-
const label = cacheMetrics.cacheMetricsLabel(req.requestContext.cacheKey, req.requestContext.meta?.metrics?.feedId || 'N/A', adapter.config.CACHE_TYPE);
|
|
162
|
-
// Record cache staleness and cache get count and value
|
|
163
|
-
const staleness = calculateStaleness(response.maxAge, adapter.config.CACHE_MAX_AGE);
|
|
164
|
-
cacheMetrics.cacheGet(label, response.result, staleness);
|
|
165
|
-
req.requestContext.meta = {
|
|
166
|
-
...req.requestContext.meta,
|
|
167
|
-
metrics: { ...req.requestContext.meta?.metrics, cacheHit: true },
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
return res.send(response);
|
|
171
|
-
}
|
|
172
|
-
logger.debug('Did not find response in cache, moving to next middleware');
|
|
173
|
-
};
|
|
174
|
-
exports.buildCacheMiddleware = buildCacheMiddleware;
|
|
175
133
|
//# sourceMappingURL=index.js.map
|
package/cache/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"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"}
|
package/cache/redis.d.ts
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
import Redis
|
|
1
|
+
import Redis from 'ioredis';
|
|
2
2
|
import { Cache, CacheEntry } from './index';
|
|
3
|
-
/**
|
|
4
|
-
* Common callback for redis commands that logs success/fail and throws on fail
|
|
5
|
-
* @param {string} message - message to log on error
|
|
6
|
-
* @param {string} functionName - name of the redis function where this callback was used, used for metrics
|
|
7
|
-
*/
|
|
8
3
|
/**
|
|
9
4
|
* Redis implementation of a Cache. It uses a simple js Object, storing entries with both
|
|
10
5
|
* a value and an expiration timestamp. Expired entries are deleted on reads (i.e. no background gc/upkeep).
|
|
11
6
|
*
|
|
12
7
|
* @typeParam T - the type for the entries' values
|
|
13
|
-
* @param {boolean} alwaysFail - if true, error callback will always throw an error (used for testing)
|
|
14
8
|
*/
|
|
15
9
|
export declare class RedisCache<T = unknown> implements Cache<T> {
|
|
16
10
|
private client;
|
|
17
11
|
constructor(client: Redis);
|
|
18
|
-
commandCallback(message: string, functionName: string): Callback;
|
|
19
12
|
get(key: string): Promise<T | undefined>;
|
|
20
13
|
delete(key: string): Promise<void>;
|
|
21
14
|
set(key: string, value: T, ttl: number): Promise<void>;
|