@chainlink/external-adapter-framework 0.0.10 → 0.0.12
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/.c8rc.json +3 -0
- package/.eslintignore +9 -0
- package/.eslintrc.js +96 -0
- package/.github/README.MD +17 -0
- package/.github/actions/setup/action.yaml +13 -0
- package/.github/workflows/main.yaml +39 -0
- package/.github/workflows/publish.yaml +20 -0
- package/.prettierignore +13 -0
- package/.yarnrc +0 -0
- package/README.md +103 -0
- package/dist/src/adapter.d.ts +135 -0
- package/dist/src/adapter.js +145 -0
- package/dist/src/background-executor.d.ts +11 -0
- package/{background-executor.js → dist/src/background-executor.js} +0 -0
- package/{cache → dist/src/cache}/factory.d.ts +0 -0
- package/dist/src/cache/factory.js +55 -0
- package/dist/src/cache/index.d.ts +94 -0
- package/dist/src/cache/index.js +173 -0
- package/{cache → dist/src/cache}/local.d.ts +0 -0
- package/{cache → dist/src/cache}/local.js +0 -0
- package/{cache → dist/src/cache}/metrics.d.ts +0 -0
- package/{cache → dist/src/cache}/metrics.js +0 -0
- package/{cache → dist/src/cache}/redis.d.ts +0 -0
- package/dist/src/cache/redis.js +100 -0
- package/dist/src/chainlink-external-adapter-framework-0.0.6.tgz +0 -0
- package/dist/src/config/index.d.ts +214 -0
- package/dist/src/config/index.js +380 -0
- package/{config → dist/src/config}/provider-limits.d.ts +0 -0
- package/{config → dist/src/config}/provider-limits.js +1 -1
- package/dist/src/examples/bank-frick/accounts.d.ts +39 -0
- package/dist/src/examples/bank-frick/accounts.js +192 -0
- package/dist/src/examples/bank-frick/config/index.d.ts +4 -0
- package/dist/src/examples/bank-frick/config/index.js +54 -0
- package/dist/src/examples/bank-frick/index.d.ts +2 -0
- package/dist/src/examples/bank-frick/index.js +15 -0
- package/dist/src/examples/bank-frick/util.d.ts +4 -0
- package/dist/src/examples/bank-frick/util.js +39 -0
- package/dist/src/examples/coingecko/batch-warming.d.ts +7 -0
- package/dist/src/examples/coingecko/batch-warming.js +53 -0
- package/dist/src/examples/coingecko/index.d.ts +2 -0
- package/dist/src/examples/coingecko/index.js +11 -0
- package/dist/src/examples/coingecko/rest.d.ts +12 -0
- package/dist/src/examples/coingecko/rest.js +51 -0
- package/{examples → dist/src/examples}/ncfx/config/index.d.ts +0 -0
- package/{examples → dist/src/examples}/ncfx/config/index.js +0 -0
- package/dist/src/examples/ncfx/index.d.ts +13 -0
- package/dist/src/examples/ncfx/index.js +11 -0
- package/dist/src/examples/ncfx/websocket.d.ts +47 -0
- package/dist/src/examples/ncfx/websocket.js +73 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +128 -0
- package/{metrics → dist/src/metrics}/constants.d.ts +0 -0
- package/{metrics → dist/src/metrics}/constants.js +0 -0
- package/{metrics → dist/src/metrics}/index.d.ts +0 -0
- package/dist/src/metrics/index.js +122 -0
- package/dist/src/metrics/util.d.ts +7 -0
- package/dist/src/metrics/util.js +9 -0
- package/{adapter.d.ts → dist/src/package/adapter.d.ts} +0 -0
- package/{adapter.js → dist/src/package/adapter.js} +0 -0
- package/{background-executor.d.ts → dist/src/package/background-executor.d.ts} +0 -0
- package/dist/src/package/background-executor.js +45 -0
- package/dist/src/package/cache/factory.d.ts +6 -0
- package/{cache → dist/src/package/cache}/factory.js +0 -0
- package/{cache → dist/src/package/cache}/index.d.ts +0 -0
- package/{cache → dist/src/package/cache}/index.js +0 -0
- package/dist/src/package/cache/local.d.ts +23 -0
- package/dist/src/package/cache/local.js +83 -0
- package/dist/src/package/cache/metrics.d.ts +27 -0
- package/dist/src/package/cache/metrics.js +120 -0
- package/dist/src/package/cache/redis.d.ts +16 -0
- package/{cache → dist/src/package/cache}/redis.js +0 -0
- package/{config → dist/src/package/config}/index.d.ts +0 -0
- package/{config → dist/src/package/config}/index.js +0 -0
- package/dist/src/package/config/provider-limits.d.ts +31 -0
- package/dist/src/package/config/provider-limits.js +76 -0
- package/{examples → dist/src/package/examples}/coingecko/batch-warming.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/batch-warming.js +0 -0
- package/{examples → dist/src/package/examples}/coingecko/index.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/index.js +0 -0
- package/{examples → dist/src/package/examples}/coingecko/rest.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/rest.js +0 -0
- package/dist/src/package/examples/ncfx/config/index.d.ts +12 -0
- package/dist/src/package/examples/ncfx/config/index.js +15 -0
- package/{examples → dist/src/package/examples}/ncfx/index.d.ts +0 -0
- package/{examples → dist/src/package/examples}/ncfx/index.js +0 -0
- package/{examples → dist/src/package/examples}/ncfx/websocket.d.ts +0 -0
- package/{examples → dist/src/package/examples}/ncfx/websocket.js +0 -0
- package/{index.d.ts → dist/src/package/index.d.ts} +0 -0
- package/{index.js → dist/src/package/index.js} +0 -0
- package/dist/src/package/metrics/constants.d.ts +16 -0
- package/dist/src/package/metrics/constants.js +25 -0
- package/dist/src/package/metrics/index.d.ts +15 -0
- package/{metrics → dist/src/package/metrics}/index.js +0 -0
- package/{metrics → dist/src/package/metrics}/util.d.ts +0 -0
- package/{metrics → dist/src/package/metrics}/util.js +0 -0
- package/dist/src/package/package.json +72 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/background/fixed-frequency.d.ts +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/background/fixed-frequency.js +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/index.d.ts +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/index.js +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/metrics.d.ts +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/metrics.js +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/request/simple-counting.d.ts +0 -0
- package/{rate-limiting → dist/src/package/rate-limiting}/request/simple-counting.js +0 -0
- package/{test.d.ts → dist/src/package/test.d.ts} +0 -0
- package/{test.js → dist/src/package/test.js} +0 -0
- package/{transports → dist/src/package/transports}/batch-warming.d.ts +0 -0
- package/{transports → dist/src/package/transports}/batch-warming.js +0 -0
- package/{transports → dist/src/package/transports}/index.d.ts +0 -0
- package/{transports → dist/src/package/transports}/index.js +0 -0
- package/{transports → dist/src/package/transports}/metrics.d.ts +0 -0
- package/{transports → dist/src/package/transports}/metrics.js +0 -0
- package/{transports → dist/src/package/transports}/rest.d.ts +0 -0
- package/{transports → dist/src/package/transports}/rest.js +0 -0
- package/{transports → dist/src/package/transports}/util.d.ts +0 -0
- package/{transports → dist/src/package/transports}/util.js +0 -0
- package/{transports → dist/src/package/transports}/websocket.d.ts +0 -0
- package/{transports → dist/src/package/transports}/websocket.js +0 -0
- package/{util → dist/src/package/util}/expiring-sorted-set.d.ts +0 -0
- package/{util → dist/src/package/util}/expiring-sorted-set.js +0 -0
- package/{util → dist/src/package/util}/index.d.ts +0 -0
- package/{util → dist/src/package/util}/index.js +0 -0
- package/{util → dist/src/package/util}/logger.d.ts +0 -0
- package/{util → dist/src/package/util}/logger.js +0 -0
- package/{util → dist/src/package/util}/request.d.ts +0 -0
- package/{util → dist/src/package/util}/request.js +0 -0
- package/{validation → dist/src/package/validation}/error.d.ts +0 -0
- package/{validation → dist/src/package/validation}/error.js +0 -0
- package/{validation → dist/src/package/validation}/index.d.ts +0 -0
- package/{validation → dist/src/package/validation}/index.js +0 -0
- package/{validation → dist/src/package/validation}/input-params.d.ts +0 -0
- package/{validation → dist/src/package/validation}/input-params.js +0 -0
- package/{validation → dist/src/package/validation}/override-functions.d.ts +0 -0
- package/{validation → dist/src/package/validation}/override-functions.js +0 -0
- package/{validation → dist/src/package/validation}/preset-tokens.json +0 -0
- package/{validation → dist/src/package/validation}/validator.d.ts +0 -0
- package/{validation → dist/src/package/validation}/validator.js +0 -0
- package/dist/src/package.json +72 -0
- package/dist/src/rate-limiting/background/fixed-frequency.d.ts +11 -0
- package/dist/src/rate-limiting/background/fixed-frequency.js +35 -0
- package/dist/src/rate-limiting/index.d.ts +55 -0
- package/dist/src/rate-limiting/index.js +63 -0
- package/dist/src/rate-limiting/metrics.d.ts +3 -0
- package/dist/src/rate-limiting/metrics.js +44 -0
- package/dist/src/rate-limiting/request/simple-counting.d.ts +21 -0
- package/dist/src/rate-limiting/request/simple-counting.js +62 -0
- package/dist/src/test.d.ts +1 -0
- package/dist/src/test.js +6 -0
- package/dist/src/transports/batch-warming.d.ts +35 -0
- package/dist/src/transports/batch-warming.js +101 -0
- package/dist/src/transports/index.d.ts +70 -0
- package/dist/src/transports/index.js +87 -0
- package/dist/src/transports/metrics.d.ts +22 -0
- package/dist/src/transports/metrics.js +105 -0
- package/dist/src/transports/rest.d.ts +44 -0
- package/dist/src/transports/rest.js +131 -0
- package/dist/src/transports/util.d.ts +8 -0
- package/dist/src/transports/util.js +85 -0
- package/dist/src/transports/websocket.d.ts +80 -0
- package/dist/src/transports/websocket.js +166 -0
- package/dist/src/util/expiring-sorted-set.d.ts +21 -0
- package/dist/src/util/expiring-sorted-set.js +47 -0
- package/dist/src/util/index.d.ts +12 -0
- package/dist/src/util/index.js +35 -0
- package/dist/src/util/logger.d.ts +42 -0
- package/dist/src/util/logger.js +62 -0
- package/dist/src/util/request.d.ts +57 -0
- package/dist/src/util/request.js +2 -0
- package/dist/src/util/subscription-set/expiring-sorted-set.d.ts +22 -0
- package/dist/src/util/subscription-set/expiring-sorted-set.js +47 -0
- package/dist/src/util/subscription-set/subscription-set.d.ts +18 -0
- package/dist/src/util/subscription-set/subscription-set.js +19 -0
- package/dist/src/util/test-payload-loader.d.ts +25 -0
- package/dist/src/util/test-payload-loader.js +83 -0
- package/dist/src/validation/error.d.ts +50 -0
- package/dist/src/validation/error.js +79 -0
- package/dist/src/validation/index.d.ts +5 -0
- package/dist/src/validation/index.js +91 -0
- package/dist/src/validation/input-params.d.ts +15 -0
- package/dist/src/validation/input-params.js +30 -0
- package/dist/src/validation/override-functions.d.ts +3 -0
- package/dist/src/validation/override-functions.js +40 -0
- package/dist/src/validation/preset-tokens.json +23 -0
- package/dist/src/validation/validator.d.ts +47 -0
- package/dist/src/validation/validator.js +303 -0
- package/docker-compose.yaml +35 -0
- package/env.sh +54 -0
- package/env2.sh +55 -0
- package/package.json +5 -3
- package/publish.sh +0 -0
- package/src/adapter.ts +263 -0
- package/src/background-executor.ts +52 -0
- package/src/cache/factory.ts +26 -0
- package/src/cache/index.ts +258 -0
- package/src/cache/local.ts +73 -0
- package/src/cache/metrics.ts +112 -0
- package/src/cache/redis.ts +93 -0
- package/src/config/index.ts +517 -0
- package/src/config/provider-limits.ts +130 -0
- package/src/examples/bank-frick/README.MD +10 -0
- package/src/examples/bank-frick/accounts.ts +246 -0
- package/src/examples/bank-frick/config/index.ts +53 -0
- package/src/examples/bank-frick/index.ts +13 -0
- package/src/examples/bank-frick/types.d.ts +38 -0
- package/src/examples/bank-frick/util.ts +55 -0
- package/src/examples/coingecko/batch-warming.ts +78 -0
- package/src/examples/coingecko/index.ts +9 -0
- package/src/examples/coingecko/rest.ts +77 -0
- package/src/examples/ncfx/config/index.ts +12 -0
- package/src/examples/ncfx/index.ts +9 -0
- package/src/examples/ncfx/websocket.ts +99 -0
- package/src/index.ts +149 -0
- package/src/metrics/constants.ts +23 -0
- package/src/metrics/index.ts +115 -0
- package/src/metrics/util.ts +18 -0
- package/src/rate-limiting/background/fixed-frequency.ts +45 -0
- package/src/rate-limiting/index.ts +100 -0
- package/src/rate-limiting/metrics.ts +18 -0
- package/src/rate-limiting/request/simple-counting.ts +76 -0
- package/src/test.ts +5 -0
- package/src/transports/batch-warming.ts +122 -0
- package/src/transports/index.ts +152 -0
- package/src/transports/metrics.ts +95 -0
- package/src/transports/rest.ts +164 -0
- package/src/transports/util.ts +63 -0
- package/src/transports/websocket.ts +245 -0
- package/src/util/index.ts +22 -0
- package/src/util/logger.ts +69 -0
- package/src/util/request.ts +117 -0
- package/src/util/subscription-set/expiring-sorted-set.ts +54 -0
- package/src/util/subscription-set/subscription-set.ts +35 -0
- package/src/util/test-payload-loader.ts +87 -0
- package/src/validation/error.ts +116 -0
- package/src/validation/index.ts +110 -0
- package/src/validation/input-params.ts +45 -0
- package/src/validation/override-functions.ts +44 -0
- package/src/validation/preset-tokens.json +23 -0
- package/src/validation/validator.ts +384 -0
- package/test/adapter.test.ts +27 -0
- package/test/background-executor.test.ts +108 -0
- package/test/cache/cache-key.test.ts +114 -0
- package/test/cache/helper.ts +100 -0
- package/test/cache/local.test.ts +54 -0
- package/test/cache/redis.test.ts +89 -0
- package/test/correlation.test.ts +114 -0
- package/test/index.test.ts +37 -0
- package/test/metrics/feed-id.test.ts +38 -0
- package/test/metrics/helper.ts +14 -0
- package/test/metrics/labels.test.ts +36 -0
- package/test/metrics/metrics.test.ts +267 -0
- package/test/metrics/redis-metrics.test.ts +113 -0
- package/test/metrics/warmer-metrics.test.ts +192 -0
- package/test/metrics/ws-metrics.test.ts +225 -0
- package/test/rate-limit-config.test.ts +242 -0
- package/test/smoke.test.ts +166 -0
- package/test/transports/batch.test.ts +465 -0
- package/test/transports/rest.test.ts +242 -0
- package/test/transports/websocket.test.ts +183 -0
- package/test/tsconfig.json +5 -0
- package/test/util.ts +77 -0
- package/test/validation.test.ts +178 -0
- package/test-payload-fail.json +3 -0
- package/test-payload.js +22 -0
- package/test-payload.json +7 -0
- package/test.sh +20 -0
- package/test2.sh +2 -0
- package/tsconfig.json +25 -0
- package/typedoc.json +6 -0
- package/webpack.config.js +23 -0
package/.c8rc.json
ADDED
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md
|
|
2
|
+
module.exports = {
|
|
3
|
+
root: true,
|
|
4
|
+
parser: '@typescript-eslint/parser',
|
|
5
|
+
plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc'],
|
|
6
|
+
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
|
7
|
+
rules: {
|
|
8
|
+
'tsdoc/syntax': 'warn',
|
|
9
|
+
|
|
10
|
+
// Problems
|
|
11
|
+
'array-callback-return': [
|
|
12
|
+
'error',
|
|
13
|
+
{
|
|
14
|
+
allowImplicit: false,
|
|
15
|
+
checkForEach: true,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
'no-constant-binary-expression': 'error',
|
|
19
|
+
'no-constructor-return': 'error',
|
|
20
|
+
'no-duplicate-imports': 'error',
|
|
21
|
+
'no-promise-executor-return': 'error',
|
|
22
|
+
'no-self-compare': 'error',
|
|
23
|
+
'no-template-curly-in-string': 'error',
|
|
24
|
+
'no-unmodified-loop-condition': 'error',
|
|
25
|
+
'no-unreachable-loop': 'error',
|
|
26
|
+
'no-unused-private-class-members': 'error',
|
|
27
|
+
'require-atomic-updates': 'error',
|
|
28
|
+
|
|
29
|
+
// Suggestions
|
|
30
|
+
'capitalized-comments': ['error', 'always', { ignoreConsecutiveComments: true }],
|
|
31
|
+
complexity: ['error', 25], // TODO: Should be lower (15?), but validator has complex methods
|
|
32
|
+
curly: 'error',
|
|
33
|
+
'default-case-last': 'error',
|
|
34
|
+
'default-param-last': 'error',
|
|
35
|
+
eqeqeq: ['error', 'smart'],
|
|
36
|
+
'func-names': 'error',
|
|
37
|
+
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
|
38
|
+
'grouped-accessor-pairs': ['error', 'getBeforeSet'],
|
|
39
|
+
'max-depth': ['error', 4], // TODO: Should be lower (3), but validator has complex methods
|
|
40
|
+
'max-nested-callbacks': ['error', 2],
|
|
41
|
+
'max-params': ['error', 4], // TODO: Should be lower (3), but validator has complex methods,
|
|
42
|
+
'new-cap': ['error', { newIsCapExceptions: ['ctor'] }],
|
|
43
|
+
'no-caller': 'error',
|
|
44
|
+
'no-confusing-arrow': [
|
|
45
|
+
'error',
|
|
46
|
+
{
|
|
47
|
+
allowParens: true,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
'no-console': ['warn'], // We want this to debug, but the check workflow should accept no warns
|
|
51
|
+
'no-div-regex': 'error',
|
|
52
|
+
'no-eval': 'error',
|
|
53
|
+
'no-extend-native': 'error',
|
|
54
|
+
'no-extra-bind': 'error',
|
|
55
|
+
'no-extra-label': 'error',
|
|
56
|
+
'no-extra-semi': 'error',
|
|
57
|
+
'no-floating-decimal': 'error',
|
|
58
|
+
'no-implied-eval': 'error',
|
|
59
|
+
'no-invalid-this': 'error',
|
|
60
|
+
'no-labels': 'error',
|
|
61
|
+
'no-lonely-if': 'error',
|
|
62
|
+
'no-multi-assign': 'error',
|
|
63
|
+
'no-multi-str': 'error',
|
|
64
|
+
'no-nested-ternary': 'error',
|
|
65
|
+
'no-new': 'error',
|
|
66
|
+
'no-new-func': 'error',
|
|
67
|
+
'no-new-object': 'error',
|
|
68
|
+
'no-new-wrappers': 'error',
|
|
69
|
+
'no-param-reassign': 'error',
|
|
70
|
+
'no-proto': 'error',
|
|
71
|
+
'no-return-assign': 'error',
|
|
72
|
+
'no-return-await': 'error',
|
|
73
|
+
'no-sequences': 'error',
|
|
74
|
+
'no-shadow': 'off',
|
|
75
|
+
'@typescript-eslint/no-shadow': 'error', // https://stackoverflow.com/questions/63961803/eslint-says-all-enums-in-typescript-app-are-already-declared-in-the-upper-scope
|
|
76
|
+
'no-unneeded-ternary': 'error',
|
|
77
|
+
'no-useless-call': 'error',
|
|
78
|
+
'no-useless-computed-key': 'error',
|
|
79
|
+
'no-useless-concat': 'error',
|
|
80
|
+
'no-useless-rename': 'error',
|
|
81
|
+
'no-var': 'error',
|
|
82
|
+
'operator-assignment': ['error', 'always'],
|
|
83
|
+
'prefer-arrow-callback': 'error',
|
|
84
|
+
'prefer-const': 'error',
|
|
85
|
+
'prefer-exponentiation-operator': 'error',
|
|
86
|
+
'prefer-object-spread': 'error',
|
|
87
|
+
'prefer-promise-reject-errors': 'error',
|
|
88
|
+
'prefer-regex-literals': 'error',
|
|
89
|
+
'prefer-rest-params': 'error',
|
|
90
|
+
'prefer-spread': 'error',
|
|
91
|
+
'prefer-template': 'error',
|
|
92
|
+
'spaced-comment': ['error', 'always'],
|
|
93
|
+
'symbol-description': 'error',
|
|
94
|
+
yoda: 'error',
|
|
95
|
+
},
|
|
96
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Github workflows for EAv3 Framework
|
|
2
|
+
|
|
3
|
+
**Please note that this work is in progress. The README may not be accurate**
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
This directory contains a basic GitHub workflow that builds, tests, and ultimately publishes the EAv3 Framework to NPM
|
|
7
|
+
1. Setup (caches dependencies to speed up other steps)
|
|
8
|
+
2. Build/Prepare/Preflight (all the following happen at the same time)
|
|
9
|
+
1. yarn build => publish artifact of build
|
|
10
|
+
2. yarn lint
|
|
11
|
+
3. yarn test
|
|
12
|
+
3. Publish (currently unimplemented)
|
|
13
|
+
|
|
14
|
+
### Some steps that still need to be added in:
|
|
15
|
+
1. Check that changelog has an entry matching the current version in package.json
|
|
16
|
+
2. Check if a package is already published to NPM, and DON'T overwrite it unless a parameter explicitly allowing an overwrite has been passed
|
|
17
|
+
3. npm-check step that produces a report as an artifact
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: 'Setup'
|
|
2
|
+
description: 'Sets up the project, installs dependencies, and builds'
|
|
3
|
+
runs:
|
|
4
|
+
using: 'composite'
|
|
5
|
+
steps:
|
|
6
|
+
- uses: actions/setup-node@v3
|
|
7
|
+
with:
|
|
8
|
+
node-version: 16.x
|
|
9
|
+
registry-url: https://registry.npmjs.org
|
|
10
|
+
always-auth: true
|
|
11
|
+
cache: yarn
|
|
12
|
+
- run: yarn install --frozen-lockfile
|
|
13
|
+
shell: bash
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# This is the entry point for CI. It will setup the application, then run lint, test, and eventually publish if not the master or main branch
|
|
2
|
+
name: 'Main'
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
pull_request: ~
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
setup: # Load the dependencies cache for all jobs
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- uses: ./.github/actions/setup
|
|
15
|
+
build:
|
|
16
|
+
needs: setup
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
concurrency: build-${{ github.ref}}
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v3
|
|
21
|
+
- uses: ./.github/actions/setup
|
|
22
|
+
- run: yarn build
|
|
23
|
+
lint:
|
|
24
|
+
needs: setup
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
concurrency: lint-${{ github.ref }}
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v3
|
|
29
|
+
- uses: ./.github/actions/setup
|
|
30
|
+
- run: yarn lint
|
|
31
|
+
- run: yarn prettier --check **/*.{ts,md}
|
|
32
|
+
test:
|
|
33
|
+
needs: setup
|
|
34
|
+
concurrency: test-${{ github.ref }}
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v3
|
|
38
|
+
- uses: ./.github/actions/setup
|
|
39
|
+
- run: yarn test
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This is the entry point for CI. It will setup the application, then run lint, test, and eventually publish if not the master or main branch
|
|
2
|
+
name: 'Publish'
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
jobs:
|
|
9
|
+
publish: # Load the dependencies cache for all jobs
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: main
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- uses: ./.github/actions/setup
|
|
15
|
+
- run: yarn build
|
|
16
|
+
- run: cp package.json dist/src/
|
|
17
|
+
- run: npm publish --access restricted #scoped packages are restricted by default, but this is set because not all branches currently have a scoped package name
|
|
18
|
+
working-directory: dist/src
|
|
19
|
+
env:
|
|
20
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.prettierignore
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# don't ever lint node_modules
|
|
2
|
+
node_modules
|
|
3
|
+
# don't lint build output (make sure it's set to your correct build folder name)
|
|
4
|
+
dist
|
|
5
|
+
# don't lint nyc coverage output
|
|
6
|
+
coverage
|
|
7
|
+
test-payload.json
|
|
8
|
+
.yarn
|
|
9
|
+
.vscode
|
|
10
|
+
.pnp.cjs
|
|
11
|
+
.pnp.loader.mjs
|
|
12
|
+
|
|
13
|
+
packages/k6/k8s/templates
|
package/.yarnrc
ADDED
|
File without changes
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# EA Framework v3
|
|
2
|
+
|
|
3
|
+
External adapters and its core framework serve as middleware to facilitate connections between Chainlink Nodes and Data Providers (DP). Their main purpose is threefold:
|
|
4
|
+
|
|
5
|
+
- Abstract provider specific details, specifically:
|
|
6
|
+
- Transport (REST, WebSockets, RPC, SSE, etc.)
|
|
7
|
+
- Authentication (login flows, keys)
|
|
8
|
+
- Accept normalized request payloads and translate into the provider's interface (this also includes things like symbols/tickers)
|
|
9
|
+
- Parse provider responses into the desired data points (e.g. price from crypto endpoint)
|
|
10
|
+
- Make the overall system more efficient by using as few resources (e.g. API credits, networking traffic, CPU usage) as possible to fetch data, achieved by features like:
|
|
11
|
+
- Caching: since DPs update data at various times and a request to their API incurs a certain latency, EAs keep a cache of values to
|
|
12
|
+
- Provide responses to the Chainlink Nodes as quickly as possible
|
|
13
|
+
- Communicate with DPs only when necessary
|
|
14
|
+
- Cache Warming: in order to make as many of the requests to EAs be fulfilled from the cache, EAs fetch values from DPs asynchronously to keep the local ones fresh.
|
|
15
|
+
- Batching: the CL Node requests feeds individually, but it's common for DPs to provide batch endpoints to get many data points at once. With Batching, EAs keep track of incoming requests and consolidate them into one batched request.
|
|
16
|
+
- Rate limiting: the EA framework additionally checks request rates (frequency) to make sure they fall within acceptable limits (like quotas for the DP's API, or adjusting based on the NOP's API tier).
|
|
17
|
+
- Perform off chain computations (think aggregations, indexing, or any sort of data processing)
|
|
18
|
+
|
|
19
|
+
By providing a framework that gives users easy access to those features, we reduce the complexity required for Nodes to communicate with DPs since by using EAs there is only one standardized way to do so, while at the same time optimizing said communication so it's as resource efficient as possible. It also makes internal and external development easier and faster, by serving as a strict guideline to implement and add new providers.
|
|
20
|
+
|
|
21
|
+
## Qs
|
|
22
|
+
|
|
23
|
+
- Store entire response in cache?
|
|
24
|
+
- Check for valid result in adapter response?
|
|
25
|
+
|
|
26
|
+
## Env vars
|
|
27
|
+
|
|
28
|
+
These are all existing env vars, marked DONE if they have been ported to this version, or N/A if the new version disregards them altogether.
|
|
29
|
+
|
|
30
|
+
| Name | State | Comments |
|
|
31
|
+
| :----------------------------------------- | :---: | :----------------------------------------------------------- |
|
|
32
|
+
| API_TIMEOUT | N/A | Only used for WS with handler.noHTtp = true |
|
|
33
|
+
| BASE_URL | √ | |
|
|
34
|
+
| CACHE_ENABLED | N/A | Cache is integral to this fw, not including this for now |
|
|
35
|
+
| CACHE_KEY_IGNORED_PROPS | ?? | Do we want this to be available in v3. Used for feed id |
|
|
36
|
+
| CACHE_KEY_GROUP | ?? | Dunno if this applies to this fw |
|
|
37
|
+
| CACHE_MAX_AGE | √ | |
|
|
38
|
+
| CACHE_MAX_ITEMS | - | Should add when replacing obj in local impl with LRU package |
|
|
39
|
+
| CACHE_MIN_AGE | - | Used for rate limiting |
|
|
40
|
+
| CACHE_REDIS_CONNECTION_TIMEOUT | - | TODO: Redis |
|
|
41
|
+
| CACHE_REDIS_HOST | - | TODO: Redis |
|
|
42
|
+
| CACHE_REDIS_MAX_QUEUED_ITEMS | - | TODO: Redis |
|
|
43
|
+
| CACHE_REDIS_MAX_RECONNECT_COOLDOWN | - | TODO: Redis |
|
|
44
|
+
| CACHE_REDIS_PASSWORD | - | TODO: Redis |
|
|
45
|
+
| CACHE_REDIS_PATH | - | TODO: Redis |
|
|
46
|
+
| CACHE_REDIS_PORT | - | TODO: Redis |
|
|
47
|
+
| CACHE_REDIS_TIMEOUT | - | TODO: Redis |
|
|
48
|
+
| CACHE_REDIS_URL | - | TODO: Redis |
|
|
49
|
+
| CACHE_TYPE | - | TODO: Cache factory |
|
|
50
|
+
| CACHE_UPDATE_AGE_ON_GET | N/A | No longer used in EA currently, apparently |
|
|
51
|
+
| DEBUG | | |
|
|
52
|
+
| DEFAULT_WS_HEARTBEAT_INTERVAL | | |
|
|
53
|
+
| EA_HOST | | |
|
|
54
|
+
| EA_PORT | √ | |
|
|
55
|
+
| ENV_ADAPTER_URL | | |
|
|
56
|
+
| ENV_API_ENDPOINT | | |
|
|
57
|
+
| ENV_API_KEY | | |
|
|
58
|
+
| ENV_API_TIMEOUT | | |
|
|
59
|
+
| ENV_API_VERBOSE | | |
|
|
60
|
+
| ENV_WS_API_ENDPOINT | | |
|
|
61
|
+
| ENV_WS_API_KEY | | |
|
|
62
|
+
| ERROR_CAPACITY | | |
|
|
63
|
+
| EXPERIMENTAL_METRICS_ENABLED | √ | Maintaining for backwards compatibility. Defaults to true |
|
|
64
|
+
| LEGACY_ENV_ADAPTER_URL | | |
|
|
65
|
+
| LOG_LEVEL | | |
|
|
66
|
+
| METRICS_ENABLED | √ | Defaults to true |
|
|
67
|
+
| METRICS_NAME | √ | |
|
|
68
|
+
| METRICS_PORT | √ | |
|
|
69
|
+
| METRICS_USE_BASE_URL | √ | |
|
|
70
|
+
| NODE_ENV | | |
|
|
71
|
+
| npm_package_version | | |
|
|
72
|
+
| RATE_LIMIT_API_TIER | | |
|
|
73
|
+
| RATE_LIMIT_CAPACITY | | |
|
|
74
|
+
| RATE_LIMIT_CAPACITY_MINUTE | | |
|
|
75
|
+
| RATE_LIMIT_CAPACITY_SECOND | | |
|
|
76
|
+
| RATE_LIMIT_ENABLED | | |
|
|
77
|
+
| RECORD | | |
|
|
78
|
+
| REQUEST_COALESCING_ENABLED | | |
|
|
79
|
+
| REQUEST_COALESCING_ENTROPY_MAX | | |
|
|
80
|
+
| REQUEST_COALESCING_INTERVAL | | |
|
|
81
|
+
| REQUEST_COALESCING_INTERVAL_COEFFICIENT | | |
|
|
82
|
+
| REQUEST_COALESCING_INTERVAL_MAX | | |
|
|
83
|
+
| REQUEST_COALESCING_MAX_RETRIES | | |
|
|
84
|
+
| RETRY | | |
|
|
85
|
+
| SERVER_RATE_LIMIT_MAX | | |
|
|
86
|
+
| SERVER_SLOW_DOWN_AFTER_FACTOR | | |
|
|
87
|
+
| SERVER_SLOW_DOWN_DELAY_MS | | |
|
|
88
|
+
| TIMEOUT | | |
|
|
89
|
+
| WARMUP_ENABLED | | |
|
|
90
|
+
| WARMUP_INTERVAL | | |
|
|
91
|
+
| WARMUP_SUBSCRIPTION_TTL | | |
|
|
92
|
+
| WARMUP_UNHEALTHY_THRESHOLD | | |
|
|
93
|
+
| WS_CONNECTION_KEY | | |
|
|
94
|
+
| WS_CONNECTION_LIMIT | | |
|
|
95
|
+
| WS_CONNECTION_RETRY_DELAY | | |
|
|
96
|
+
| WS_CONNECTION_RETRY_LIMIT | | |
|
|
97
|
+
| WS_CONNECTION_TTL | | |
|
|
98
|
+
| WS_ENABLED | N/A | Shouldn't be part of this fw |
|
|
99
|
+
| WS_SUBSCRIPTION_LIMIT | | |
|
|
100
|
+
| WS_SUBSCRIPTION_PRIORITY_LIST | | |
|
|
101
|
+
| WS_SUBSCRIPTION_TTL | | |
|
|
102
|
+
| WS_SUBSCRIPTION_UNRESPONSIVE_TTL | | |
|
|
103
|
+
| WS_TIME_UNTIL_HANDLE_NEXT_MESSAGE_OVERRIDE | | |
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Cache } from './cache';
|
|
2
|
+
import { AdapterConfig, BaseAdapterConfig, CustomSettingsType, SettingsMap } from './config';
|
|
3
|
+
import { AdapterRateLimitTier, BackgroundExecuteRateLimiter, RequestRateLimiter } from './rate-limiting';
|
|
4
|
+
import { Transport } from './transports';
|
|
5
|
+
import { SubscriptionSetFactory } from './util';
|
|
6
|
+
import { InputParameters } from './validation/input-params';
|
|
7
|
+
/**
|
|
8
|
+
* Dependencies that will be injected into the Adapter on startup
|
|
9
|
+
*/
|
|
10
|
+
export interface AdapterDependencies {
|
|
11
|
+
cache: Cache;
|
|
12
|
+
requestRateLimiter: RequestRateLimiter;
|
|
13
|
+
backgroundExecuteRateLimiter: BackgroundExecuteRateLimiter;
|
|
14
|
+
subscriptionSetFactory: SubscriptionSetFactory;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Context that will be used on background executions of a Transport.
|
|
18
|
+
* For example, the endpointName used to log statements or generate Cache keys.
|
|
19
|
+
*/
|
|
20
|
+
export interface AdapterContext<CustomSettings extends CustomSettingsType<CustomSettings> = SettingsMap> {
|
|
21
|
+
adapterEndpoint: AdapterEndpoint<unknown, unknown, CustomSettings>;
|
|
22
|
+
adapterConfig: AdapterConfig<CustomSettings>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Structure to describe rate limits specs for the Adapter
|
|
26
|
+
*/
|
|
27
|
+
interface AdapterRateLimitingConfig {
|
|
28
|
+
/** Adapter rate limits, gotten from the specific tier requested */
|
|
29
|
+
tiers: Record<string, AdapterRateLimitTier>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Main structure of an External Adapter
|
|
33
|
+
*/
|
|
34
|
+
export interface AdapterParams<CustomSettings extends SettingsMap> {
|
|
35
|
+
/** Name of the adapter */
|
|
36
|
+
name: string;
|
|
37
|
+
/** If present, the string that will be used for requests with no specified endpoint */
|
|
38
|
+
defaultEndpoint?: string;
|
|
39
|
+
/**
|
|
40
|
+
* List of [[AdapterEndpoint]]s in the adapter. This is purposefully typed any; it's the correct type in this case.
|
|
41
|
+
*
|
|
42
|
+
* When you try to create an adapter and you provide an endpoint, if these generics were set to "unknown" instead
|
|
43
|
+
* what would happen is that Typescript would check if the types match, and would fail to assign unknown to the
|
|
44
|
+
* specific Params or Result in the transport itself.
|
|
45
|
+
* We also can't use generics, because if we had more than one transport with different requests (very likely)
|
|
46
|
+
* then those new types wouldn't match with each other.
|
|
47
|
+
*/
|
|
48
|
+
endpoints: AdapterEndpoint<any, any, CustomSettings>[];
|
|
49
|
+
/** Map of overrides to the default config values for an Adapter */
|
|
50
|
+
envDefaultOverrides?: Partial<BaseAdapterConfig>;
|
|
51
|
+
/** List of custom env vars for this particular adapter (e.g. RPC_URL) */
|
|
52
|
+
customSettings?: SettingsMap;
|
|
53
|
+
/** Configuration relevant to outbound (EA --\> DP) communication rate limiting */
|
|
54
|
+
rateLimiting?: AdapterRateLimitingConfig;
|
|
55
|
+
/** Overrides for converting the 'base' parameter that are hardcoded into the adapter. */
|
|
56
|
+
overrides?: Record<string, string>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Structure to describe rate limits specs for a specific adapter endpoint
|
|
60
|
+
*/
|
|
61
|
+
export interface EndpointRateLimitingConfig {
|
|
62
|
+
/**
|
|
63
|
+
* How much of the total limit for the adapter will be assigned to this specific endpoint.
|
|
64
|
+
* Should be a non-zero positive number up to 100.
|
|
65
|
+
* Endpoints in the same adapter without a specific allocation will divide the remaining limits equally.
|
|
66
|
+
*/
|
|
67
|
+
allocationPercentage: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Structure to describe a specific endpoint in an [[Adapter]]
|
|
71
|
+
*/
|
|
72
|
+
export interface AdapterEndpointParams<Params, Result, CustomSettings extends SettingsMap> {
|
|
73
|
+
/** Name that will be used to match input params to this endpoint (case insensitive) */
|
|
74
|
+
name: string;
|
|
75
|
+
/** List of alternative endpoint names that will resolve to this same transport (case insensitive) */
|
|
76
|
+
aliases?: string[];
|
|
77
|
+
/** Transport that will be used to handle data processing and communication for this endpoint */
|
|
78
|
+
transport: Transport<Params, Result, CustomSettings>;
|
|
79
|
+
/** Specification of what the body of a request hitting this endpoint should look like (used for validation) */
|
|
80
|
+
inputParameters: InputParameters;
|
|
81
|
+
/** Specific details related to the rate limiting for this endpoint in particular */
|
|
82
|
+
rateLimiting?: EndpointRateLimitingConfig;
|
|
83
|
+
}
|
|
84
|
+
export declare class AdapterEndpoint<Params, Result, CustomSettings extends SettingsMap> implements AdapterEndpointParams<Params, Result, CustomSettings> {
|
|
85
|
+
name: string;
|
|
86
|
+
aliases?: string[] | undefined;
|
|
87
|
+
transport: Transport<Params, Result, CustomSettings>;
|
|
88
|
+
inputParameters: InputParameters;
|
|
89
|
+
rateLimiting?: EndpointRateLimitingConfig | undefined;
|
|
90
|
+
constructor(params: AdapterEndpointParams<Params, Result, CustomSettings>);
|
|
91
|
+
}
|
|
92
|
+
export declare class Adapter<CustomSettings extends SettingsMap = SettingsMap> implements AdapterParams<CustomSettings> {
|
|
93
|
+
name: string;
|
|
94
|
+
defaultEndpoint?: string | undefined;
|
|
95
|
+
endpoints: AdapterEndpoint<unknown, unknown, CustomSettings>[];
|
|
96
|
+
envDefaultOverrides?: Partial<BaseAdapterConfig> | undefined;
|
|
97
|
+
customSettings?: SettingsMap | undefined;
|
|
98
|
+
rateLimiting?: AdapterRateLimitingConfig | undefined;
|
|
99
|
+
overrides?: Record<string, string> | undefined;
|
|
100
|
+
initialized: boolean;
|
|
101
|
+
/** Object containing alias translations for all endpoints */
|
|
102
|
+
endpointsMap: Record<string, AdapterEndpoint<unknown, unknown, CustomSettings>>;
|
|
103
|
+
/** Initialized dependencies that the adapter will use */
|
|
104
|
+
dependencies: AdapterDependencies;
|
|
105
|
+
/** Configuration params for various adapter properties */
|
|
106
|
+
config: AdapterConfig;
|
|
107
|
+
constructor(params: AdapterParams<CustomSettings>);
|
|
108
|
+
/**
|
|
109
|
+
* Initializes all of the [[Transport]]s in the adapter, passing along any [[AdapterDependencies]] and [[AdapterConfig]].
|
|
110
|
+
* Additionally, it builds a map out of all the endpoint names and aliases (checking for duplicates).
|
|
111
|
+
*/
|
|
112
|
+
initialize(dependencies?: Partial<AdapterDependencies>): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Takes an adapter and normalizes all endpoint names and aliases, as well as the default endpoint.
|
|
115
|
+
* i.e. makes them lowercase for now
|
|
116
|
+
* @param adapter - an instance of an Adapter
|
|
117
|
+
*/
|
|
118
|
+
private normalizeEndpointNames;
|
|
119
|
+
/**
|
|
120
|
+
* This function will take an adapter structure and go through each endpoint, calculating
|
|
121
|
+
* each one's allocation of the total rate limits that are set for the adapter as a whole.
|
|
122
|
+
*
|
|
123
|
+
* @param adapter - the adapter to initialize rate limiting for
|
|
124
|
+
*/
|
|
125
|
+
private calculateRateLimitAllocations;
|
|
126
|
+
/**
|
|
127
|
+
* This function will process dependencies for an adapter, such as caches or rate limiters,
|
|
128
|
+
* in order to inject them into transports and other relevant places later in the lifecycle.
|
|
129
|
+
*
|
|
130
|
+
* @param inputDependencies - a partial obj of initialized dependencies to override the created ones
|
|
131
|
+
* @returns a set of AdapterDependencies all initialized
|
|
132
|
+
*/
|
|
133
|
+
initializeDependencies(inputDependencies?: Partial<AdapterDependencies>): AdapterDependencies;
|
|
134
|
+
}
|
|
135
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Adapter = exports.AdapterEndpoint = void 0;
|
|
4
|
+
const cache_1 = require("./cache");
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
const rate_limiting_1 = require("./rate-limiting");
|
|
7
|
+
const util_1 = require("./util");
|
|
8
|
+
const logger = (0, util_1.makeLogger)('Adapter');
|
|
9
|
+
class AdapterEndpoint {
|
|
10
|
+
constructor(params) {
|
|
11
|
+
this.name = params.name;
|
|
12
|
+
this.aliases = params.aliases;
|
|
13
|
+
this.transport = params.transport;
|
|
14
|
+
this.inputParameters = params.inputParameters;
|
|
15
|
+
this.rateLimiting = params.rateLimiting;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.AdapterEndpoint = AdapterEndpoint;
|
|
19
|
+
// /**
|
|
20
|
+
// * Structure to describe an adapter that has been initialized
|
|
21
|
+
// */
|
|
22
|
+
// export interface InitializedAdapter<Params, Result, CustomSettings extends SettingsMap>
|
|
23
|
+
// extends AdapterParams<Params, Result, CustomSettings> {
|
|
24
|
+
// /** Object containing alias translations for all endpoints */
|
|
25
|
+
// endpointsMap: Record<string, AdapterEndpoint<Params, Result, CustomSettings>>
|
|
26
|
+
// /** Initialized dependencies that the adapter will use */
|
|
27
|
+
// dependencies: AdapterDependencies
|
|
28
|
+
// /** Configuration params for various adapter properties */
|
|
29
|
+
// config: AdapterConfig
|
|
30
|
+
// }
|
|
31
|
+
class Adapter {
|
|
32
|
+
constructor(params) {
|
|
33
|
+
// After initialization
|
|
34
|
+
this.initialized = false;
|
|
35
|
+
/** Object containing alias translations for all endpoints */
|
|
36
|
+
this.endpointsMap = {};
|
|
37
|
+
// Copy over params
|
|
38
|
+
this.name = params.name;
|
|
39
|
+
this.defaultEndpoint = params.defaultEndpoint?.toLowerCase();
|
|
40
|
+
this.endpoints = params.endpoints;
|
|
41
|
+
this.envDefaultOverrides = params.envDefaultOverrides;
|
|
42
|
+
this.customSettings = params.customSettings;
|
|
43
|
+
this.rateLimiting = params.rateLimiting;
|
|
44
|
+
this.overrides = params.overrides;
|
|
45
|
+
this.config = (0, config_1.buildAdapterConfig)({
|
|
46
|
+
overrides: this.envDefaultOverrides,
|
|
47
|
+
customSettings: this.customSettings,
|
|
48
|
+
});
|
|
49
|
+
this.normalizeEndpointNames();
|
|
50
|
+
this.calculateRateLimitAllocations();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Initializes all of the [[Transport]]s in the adapter, passing along any [[AdapterDependencies]] and [[AdapterConfig]].
|
|
54
|
+
* Additionally, it builds a map out of all the endpoint names and aliases (checking for duplicates).
|
|
55
|
+
*/
|
|
56
|
+
async initialize(dependencies) {
|
|
57
|
+
if (this.initialized) {
|
|
58
|
+
throw new Error('This adapter has already been initialized!');
|
|
59
|
+
}
|
|
60
|
+
this.dependencies = this.initializeDependencies(dependencies);
|
|
61
|
+
for (const endpoint of this.endpoints) {
|
|
62
|
+
// Add aliases to map to use in validation
|
|
63
|
+
const aliases = [endpoint.name, ...(endpoint.aliases || [])];
|
|
64
|
+
for (const alias of aliases) {
|
|
65
|
+
if (this.endpointsMap[alias]) {
|
|
66
|
+
throw new Error(`Duplicate endpoint / alias: "${alias}"`);
|
|
67
|
+
}
|
|
68
|
+
this.endpointsMap[alias] = endpoint;
|
|
69
|
+
}
|
|
70
|
+
logger.debug(`Initializing transport for endpoint "${endpoint.name}"...`);
|
|
71
|
+
await endpoint.transport.initialize(this.dependencies);
|
|
72
|
+
}
|
|
73
|
+
logger.debug('Adapter initialization complete.');
|
|
74
|
+
this.initialized = true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Takes an adapter and normalizes all endpoint names and aliases, as well as the default endpoint.
|
|
78
|
+
* i.e. makes them lowercase for now
|
|
79
|
+
* @param adapter - an instance of an Adapter
|
|
80
|
+
*/
|
|
81
|
+
normalizeEndpointNames() {
|
|
82
|
+
for (const endpoint of this.endpoints) {
|
|
83
|
+
endpoint.name = endpoint.name.toLowerCase();
|
|
84
|
+
endpoint.aliases = endpoint.aliases?.map((a) => a.toLowerCase());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* This function will take an adapter structure and go through each endpoint, calculating
|
|
89
|
+
* each one's allocation of the total rate limits that are set for the adapter as a whole.
|
|
90
|
+
*
|
|
91
|
+
* @param adapter - the adapter to initialize rate limiting for
|
|
92
|
+
*/
|
|
93
|
+
calculateRateLimitAllocations() {
|
|
94
|
+
const numberOfEndpoints = this.endpoints.length;
|
|
95
|
+
const endpointsWithExplicitAllocations = this.endpoints.filter((e) => e.rateLimiting);
|
|
96
|
+
const totalExplicitAllocation = endpointsWithExplicitAllocations
|
|
97
|
+
.map((e) => e.rateLimiting?.allocationPercentage || 0)
|
|
98
|
+
.reduce((sum, next) => sum + next, 0);
|
|
99
|
+
if (totalExplicitAllocation > 100) {
|
|
100
|
+
throw new Error('The total allocation set for all endpoints summed cannot exceed 100%');
|
|
101
|
+
}
|
|
102
|
+
if (totalExplicitAllocation === 100 &&
|
|
103
|
+
numberOfEndpoints - endpointsWithExplicitAllocations.length > 0) {
|
|
104
|
+
throw new Error('The explicit allocation is at 100% but there are endpoints with implicit allocation');
|
|
105
|
+
}
|
|
106
|
+
const implicitAllocation = 100 - totalExplicitAllocation;
|
|
107
|
+
logger.debug('Adapter rate limit allocations:');
|
|
108
|
+
for (const endpoint of this.endpoints) {
|
|
109
|
+
if (!endpoint.rateLimiting) {
|
|
110
|
+
endpoint.rateLimiting = {
|
|
111
|
+
allocationPercentage: implicitAllocation / (numberOfEndpoints - endpointsWithExplicitAllocations.length),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
logger.debug(`Endpoint [${endpoint.name}] - ${endpoint.rateLimiting?.allocationPercentage}%`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* This function will process dependencies for an adapter, such as caches or rate limiters,
|
|
119
|
+
* in order to inject them into transports and other relevant places later in the lifecycle.
|
|
120
|
+
*
|
|
121
|
+
* @param inputDependencies - a partial obj of initialized dependencies to override the created ones
|
|
122
|
+
* @returns a set of AdapterDependencies all initialized
|
|
123
|
+
*/
|
|
124
|
+
initializeDependencies(inputDependencies) {
|
|
125
|
+
const dependencies = inputDependencies || {};
|
|
126
|
+
if (!dependencies.cache) {
|
|
127
|
+
dependencies.cache = cache_1.CacheFactory.buildCache(this.config);
|
|
128
|
+
}
|
|
129
|
+
// In the future we might want something more complex, but for now it's better to simplify
|
|
130
|
+
// and just use the same rate limiting for everything. Once we have a more complex use case we
|
|
131
|
+
// can think of ways to make this more configurable.
|
|
132
|
+
const rateLimitingTier = (0, rate_limiting_1.getRateLimitingTier)(this.rateLimiting?.tiers, this.config.RATE_LIMIT_API_TIER);
|
|
133
|
+
if (!dependencies.requestRateLimiter) {
|
|
134
|
+
dependencies.requestRateLimiter = new rate_limiting_1.SimpleCountingRateLimiter().initialize(this.endpoints, rateLimitingTier);
|
|
135
|
+
}
|
|
136
|
+
if (!dependencies.backgroundExecuteRateLimiter) {
|
|
137
|
+
dependencies.backgroundExecuteRateLimiter = new rate_limiting_1.FixedFrequencyRateLimiter().initialize(this.endpoints, rateLimitingTier);
|
|
138
|
+
}
|
|
139
|
+
if (!dependencies.subscriptionSetFactory) {
|
|
140
|
+
dependencies.subscriptionSetFactory = new util_1.SubscriptionSetFactory(this.config);
|
|
141
|
+
}
|
|
142
|
+
return dependencies;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.Adapter = Adapter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Server } from 'http';
|
|
3
|
+
import { Adapter } from './adapter';
|
|
4
|
+
/**
|
|
5
|
+
* Very simple background loop that will call the [[Transport.backgroundExecute]] functions in all Transports.
|
|
6
|
+
* It gets the time in ms to wait as the return value from those functions, and sleeps until next execution.
|
|
7
|
+
*
|
|
8
|
+
* @param adapter - an initialized External Adapter
|
|
9
|
+
* @param server - the http server to attach an on close listener to
|
|
10
|
+
*/
|
|
11
|
+
export declare function callBackgroundExecutes(adapter: Adapter, server?: Server): Promise<void>;
|
|
File without changes
|
|
File without changes
|