@chainlink/external-adapter-framework 0.0.6 → 0.0.7

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 (161) hide show
  1. package/dist/adapter.js +60 -0
  2. package/dist/background-executor.js +45 -0
  3. package/dist/cache/factory.js +57 -0
  4. package/dist/cache/index.js +163 -0
  5. package/dist/cache/local.js +83 -0
  6. package/dist/cache/metrics.js +114 -0
  7. package/dist/cache/redis.js +100 -0
  8. package/dist/config/index.js +364 -0
  9. package/dist/config/provider-limits.js +75 -0
  10. package/dist/examples/coingecko/batch-warming.js +52 -0
  11. package/dist/examples/coingecko/index.js +10 -0
  12. package/dist/examples/coingecko/rest.js +50 -0
  13. package/dist/examples/ncfx/config/index.js +15 -0
  14. package/dist/examples/ncfx/index.js +10 -0
  15. package/dist/examples/ncfx/websocket.js +72 -0
  16. package/dist/index.js +89 -0
  17. package/dist/metrics/constants.js +25 -0
  18. package/dist/metrics/index.js +76 -0
  19. package/dist/metrics/util.js +9 -0
  20. package/dist/rate-limiting/factory.js +33 -0
  21. package/dist/rate-limiting/index.js +36 -0
  22. package/dist/rate-limiting/metrics.js +32 -0
  23. package/dist/rate-limiting/nop-limiter.js +15 -0
  24. package/dist/rate-limiting/simple-counting.js +61 -0
  25. package/dist/src/adapter.js +112 -0
  26. package/dist/src/background-executor.js +45 -0
  27. package/dist/src/cache/factory.js +57 -0
  28. package/dist/src/cache/index.js +165 -0
  29. package/dist/src/cache/local.js +83 -0
  30. package/dist/src/cache/metrics.js +114 -0
  31. package/dist/src/cache/redis.js +100 -0
  32. package/dist/src/config/index.js +366 -0
  33. package/dist/src/config/provider-limits.js +75 -0
  34. package/dist/src/examples/bank-frick/accounts.js +191 -0
  35. package/dist/src/examples/bank-frick/config/index.js +45 -0
  36. package/dist/src/examples/bank-frick/index.js +14 -0
  37. package/dist/src/examples/bank-frick/util.js +39 -0
  38. package/dist/src/examples/coingecko/batch-warming.js +52 -0
  39. package/dist/src/examples/coingecko/index.js +10 -0
  40. package/dist/src/examples/coingecko/rest.js +50 -0
  41. package/dist/src/examples/ncfx/config/index.js +15 -0
  42. package/dist/src/examples/ncfx/index.js +10 -0
  43. package/dist/src/examples/ncfx/websocket.js +72 -0
  44. package/dist/src/index.js +89 -0
  45. package/dist/src/metrics/constants.js +25 -0
  46. package/dist/src/metrics/index.js +76 -0
  47. package/dist/src/metrics/util.js +9 -0
  48. package/dist/src/rate-limiting/background/fixed-frequency.js +37 -0
  49. package/dist/src/rate-limiting/index.js +63 -0
  50. package/dist/src/rate-limiting/metrics.js +32 -0
  51. package/dist/src/rate-limiting/request/simple-counting.js +62 -0
  52. package/dist/src/test.js +6 -0
  53. package/dist/src/transports/batch-warming.js +55 -0
  54. package/dist/src/transports/index.js +85 -0
  55. package/dist/src/transports/metrics.js +119 -0
  56. package/dist/src/transports/rest.js +93 -0
  57. package/dist/src/transports/util.js +85 -0
  58. package/dist/src/transports/websocket.js +175 -0
  59. package/dist/src/util/expiring-sorted-set.js +47 -0
  60. package/dist/src/util/index.js +35 -0
  61. package/dist/src/util/logger.js +62 -0
  62. package/dist/src/util/request.js +2 -0
  63. package/dist/src/validation/error.js +41 -0
  64. package/dist/src/validation/index.js +84 -0
  65. package/dist/src/validation/input-params.js +30 -0
  66. package/dist/src/validation/override-functions.js +40 -0
  67. package/dist/src/validation/preset-tokens.json +23 -0
  68. package/dist/src/validation/validator.js +303 -0
  69. package/dist/test.js +6 -0
  70. package/dist/transports/batch-warming.js +57 -0
  71. package/dist/transports/index.js +76 -0
  72. package/dist/transports/metrics.js +133 -0
  73. package/dist/transports/rest.js +91 -0
  74. package/dist/transports/util.js +85 -0
  75. package/dist/transports/websocket.js +171 -0
  76. package/dist/util/expiring-sorted-set.js +47 -0
  77. package/dist/util/index.js +35 -0
  78. package/dist/util/logger.js +62 -0
  79. package/dist/util/request.js +2 -0
  80. package/dist/validation/error.js +41 -0
  81. package/dist/validation/index.js +82 -0
  82. package/dist/validation/input-params.js +30 -0
  83. package/dist/validation/overrideFunctions.js +42 -0
  84. package/dist/validation/presetTokens.json +23 -0
  85. package/dist/validation/validator.js +303 -0
  86. package/package.json +6 -2
  87. package/.c8rc.json +0 -3
  88. package/.eslintignore +0 -9
  89. package/.eslintrc.js +0 -96
  90. package/.github/README.MD +0 -17
  91. package/.github/actions/setup/action.yaml +0 -13
  92. package/.github/workflows/main.yaml +0 -39
  93. package/.github/workflows/publish.yaml +0 -17
  94. package/.prettierignore +0 -13
  95. package/.yarnrc +0 -0
  96. package/docker-compose.yaml +0 -35
  97. package/src/adapter.ts +0 -236
  98. package/src/background-executor.ts +0 -53
  99. package/src/cache/factory.ts +0 -28
  100. package/src/cache/index.ts +0 -236
  101. package/src/cache/local.ts +0 -73
  102. package/src/cache/metrics.ts +0 -112
  103. package/src/cache/redis.ts +0 -93
  104. package/src/config/index.ts +0 -501
  105. package/src/config/provider-limits.ts +0 -130
  106. package/src/examples/coingecko/batch-warming.ts +0 -79
  107. package/src/examples/coingecko/index.ts +0 -9
  108. package/src/examples/coingecko/rest.ts +0 -77
  109. package/src/examples/ncfx/config/index.ts +0 -12
  110. package/src/examples/ncfx/index.ts +0 -9
  111. package/src/examples/ncfx/websocket.ts +0 -100
  112. package/src/index.ts +0 -106
  113. package/src/metrics/constants.ts +0 -23
  114. package/src/metrics/index.ts +0 -116
  115. package/src/metrics/util.ts +0 -11
  116. package/src/rate-limiting/background/fixed-frequency.ts +0 -47
  117. package/src/rate-limiting/index.ts +0 -100
  118. package/src/rate-limiting/metrics.ts +0 -18
  119. package/src/rate-limiting/request/simple-counting.ts +0 -76
  120. package/src/test.ts +0 -5
  121. package/src/transports/batch-warming.ts +0 -121
  122. package/src/transports/index.ts +0 -173
  123. package/src/transports/metrics.ts +0 -95
  124. package/src/transports/rest.ts +0 -161
  125. package/src/transports/util.ts +0 -63
  126. package/src/transports/websocket.ts +0 -238
  127. package/src/util/expiring-sorted-set.ts +0 -52
  128. package/src/util/index.ts +0 -20
  129. package/src/util/logger.ts +0 -69
  130. package/src/util/request.ts +0 -115
  131. package/src/validation/error.ts +0 -116
  132. package/src/validation/index.ts +0 -101
  133. package/src/validation/input-params.ts +0 -45
  134. package/src/validation/override-functions.ts +0 -44
  135. package/src/validation/preset-tokens.json +0 -23
  136. package/src/validation/validator.ts +0 -384
  137. package/test/adapter.test.ts +0 -27
  138. package/test/background-executor.test.ts +0 -109
  139. package/test/cache/cache-key.test.ts +0 -96
  140. package/test/cache/helper.ts +0 -101
  141. package/test/cache/local.test.ts +0 -54
  142. package/test/cache/redis.test.ts +0 -89
  143. package/test/correlation.test.ts +0 -114
  144. package/test/index.test.ts +0 -37
  145. package/test/metrics/feed-id.test.ts +0 -33
  146. package/test/metrics/helper.ts +0 -14
  147. package/test/metrics/labels.test.ts +0 -36
  148. package/test/metrics/metrics.test.ts +0 -267
  149. package/test/metrics/redis-metrics.test.ts +0 -113
  150. package/test/metrics/warmer-metrics.test.ts +0 -192
  151. package/test/metrics/ws-metrics.test.ts +0 -225
  152. package/test/rate-limit-config.test.ts +0 -243
  153. package/test/transports/batch.test.ts +0 -465
  154. package/test/transports/rest.test.ts +0 -242
  155. package/test/transports/websocket.test.ts +0 -183
  156. package/test/tsconfig.json +0 -5
  157. package/test/util.ts +0 -76
  158. package/test/validation.test.ts +0 -169
  159. package/test.sh +0 -20
  160. package/tsconfig.json +0 -24
  161. package/typedoc.json +0 -6
@@ -1,225 +0,0 @@
1
- import FakeTimers from '@sinonjs/fake-timers'
2
- import untypedTest, { TestFn } from 'ava'
3
- import axios, { AxiosError } from 'axios'
4
- import { Server, WebSocket } from 'mock-socket'
5
- import { AddressInfo } from 'net'
6
- import { expose } from '../../src'
7
- import { Adapter, AdapterEndpoint } from '../../src/adapter'
8
- import { DEFAULT_SHARED_MS_BETWEEN_REQUESTS } from '../../src/rate-limiting'
9
- import { DEFAULT_WS_TTL, WebSocketClassProvider, WebSocketTransport } from '../../src/transports'
10
- import { ProviderResult } from '../../src/util'
11
- import { InputParameters } from '../../src/validation'
12
- import { MockCache } from '../util'
13
- import { parsePromMetrics } from './helper'
14
-
15
- export const test = untypedTest as TestFn<{
16
- serverAddress: string
17
- cache: MockCache
18
- adapterEndpoint: AdapterEndpoint
19
- server: Server
20
- }>
21
-
22
- interface AdapterRequestParams {
23
- base: string
24
- quote: string
25
- }
26
-
27
- export const inputParameters: InputParameters = {
28
- base: {
29
- type: 'string',
30
- required: true,
31
- },
32
- quote: {
33
- type: 'string',
34
- required: true,
35
- },
36
- }
37
-
38
- interface ProviderMessage {
39
- pair: string
40
- value: number
41
- }
42
-
43
- const URL = 'wss://test-ws.com/asd'
44
-
45
- /**
46
- * Sets the mocked websocket instance in the provided provider class.
47
- * We need this here, because the tests will connect using their instance of WebSocketClassProvider;
48
- * fetching from this library to the \@chainlink/ea-bootstrap package would access _another_ instance
49
- * of the same constructor. Although it should be a singleton, dependencies are different so that
50
- * means that the static classes themselves are also different.
51
- *
52
- * @param provider - singleton WebSocketClassProvider
53
- */
54
- export const mockWebSocketProvider = (provider: typeof WebSocketClassProvider): void => {
55
- // Extend mock WebSocket class to bypass protocol headers error
56
- class MockWebSocket extends WebSocket {
57
- constructor(url: string, protocol: string | string[] | Record<string, string> | undefined) {
58
- super(url, protocol instanceof Object ? undefined : protocol)
59
- }
60
- }
61
-
62
- // Need to disable typing, the mock-socket impl does not implement the ws interface fully
63
- provider.set(MockWebSocket as any) // eslint-disable-line @typescript-eslint/no-explicit-any
64
- }
65
-
66
- export const websocketTransport = new WebSocketTransport({
67
- url: URL,
68
- handlers: {
69
- async open() {
70
- return
71
- },
72
-
73
- message(message: ProviderMessage): ProviderResult<AdapterRequestParams>[] {
74
- const [base, quote] = message.pair.split('/')
75
- return [
76
- {
77
- params: { base, quote },
78
- value: message.value,
79
- },
80
- ]
81
- },
82
- },
83
- builders: {
84
- subscribeMessage: (params: AdapterRequestParams) => ({
85
- request: 'subscribe',
86
- pair: `${params.base}/${params.quote}`,
87
- }),
88
- unsubscribeMessage: (params: AdapterRequestParams) => ({
89
- request: 'unsubscribe',
90
- pair: `${params.base}/${params.quote}`,
91
- }),
92
- },
93
- })
94
-
95
- const base = 'ETH'
96
- const quote = 'USD'
97
- const price = 1234
98
-
99
- export const webSocketEndpoint: AdapterEndpoint = {
100
- name: 'test',
101
- transport: websocketTransport,
102
- inputParameters,
103
- }
104
-
105
- const CACHE_MAX_AGE = 1000
106
-
107
- const adapter: Adapter = {
108
- name: 'test',
109
- defaultEndpoint: 'test',
110
- endpoints: [webSocketEndpoint],
111
- envDefaultOverrides: {
112
- CACHE_MAX_AGE,
113
- },
114
- }
115
-
116
- const clock = FakeTimers.install()
117
-
118
- test.before(async (t) => {
119
- process.env['METRICS_ENABLED'] = 'true'
120
- process.env['METRICS_PORT'] = '9093'
121
- // Disable retries to make the testing flow easier
122
- process.env['CACHE_POLLING_MAX_RETRIES'] = '0'
123
-
124
- // Mock WS
125
- mockWebSocketProvider(WebSocketClassProvider)
126
- const mockWsServer = new Server(URL, { mock: false })
127
- mockWsServer.on('connection', (socket) => {
128
- let counter = 0
129
- const parseMessage = () => {
130
- if (counter++ === 0) {
131
- socket.send(
132
- JSON.stringify({
133
- pair: `${base}/${quote}`,
134
- value: price,
135
- }),
136
- )
137
- }
138
- }
139
- socket.on('message', parseMessage)
140
- })
141
-
142
- // Create mocked cache so we can listen when values are set
143
- // This is a more reliable method than expecting precise clock timings
144
- const mockCache = new MockCache()
145
-
146
- // Start up adapter
147
- const server = await expose(adapter, {
148
- cache: mockCache,
149
- })
150
- t.context.serverAddress = `http://localhost:${(server?.address() as AddressInfo)?.port}`
151
- t.context.cache = mockCache
152
- t.context.server = mockWsServer
153
- })
154
-
155
- test.after(async () => {
156
- clock.uninstall()
157
- })
158
-
159
- test.serial('Test WS connection, subscription, and message metrics', async (t) => {
160
- const makeRequest = () =>
161
- axios.post(t.context.serverAddress, {
162
- data: {
163
- base,
164
- quote,
165
- },
166
- })
167
-
168
- // Expect the first response to time out
169
- // The polling behavior is tested in the cache tests, so this is easier here.
170
- // Start the request:
171
- const errorPromise: Promise<AxiosError | undefined> = t.throwsAsync(makeRequest)
172
- // Advance enough time for the initial request async flow
173
- clock.tickAsync(10)
174
- // Wait for the failed cache get -> instant 504
175
- const error = await errorPromise
176
- t.is(error?.response?.status, 504)
177
-
178
- // Advance clock so that the batch warmer executes once again and wait for the cache to be set
179
- const cacheValueSetPromise = t.context.cache.waitForNextSet()
180
- await clock.tickAsync(DEFAULT_SHARED_MS_BETWEEN_REQUESTS + 10)
181
- await cacheValueSetPromise
182
-
183
- // Second request should find the response in the cache
184
- let response = await makeRequest()
185
-
186
- t.is(response.status, 200)
187
-
188
- // Check connection, subscription active, subscription total, and message total metrics when subscribed to feed
189
- const metricsAddress = `http://localhost:${process.env['METRICS_PORT']}/metrics`
190
- response = await axios.get(metricsAddress)
191
- let metricsMap = parsePromMetrics(response.data)
192
- let expectedLabel = '{app_name="test",app_version="undefined"}'
193
- t.is(metricsMap.get(`ws_connection_active${expectedLabel}`), 1)
194
- expectedLabel =
195
- '{feed_id="|base:eth|quote:usd",subscription_key="test-|base:eth|quote:usd",app_name="test",app_version="undefined"}'
196
- t.is(metricsMap.get(`ws_subscription_active${expectedLabel}`), 1)
197
- t.is(metricsMap.get(`ws_subscription_total${expectedLabel}`), 1)
198
- t.is(metricsMap.get(`ws_message_total${expectedLabel}`), 1)
199
-
200
- // Wait until the cache expires, and the subscription is out
201
- await clock.tickAsync(Math.ceil(CACHE_MAX_AGE / DEFAULT_WS_TTL) * DEFAULT_WS_TTL + 1)
202
-
203
- // Now that the cache is out and the subscription no longer there, this should time out
204
- const error2: AxiosError | undefined = await t.throwsAsync(makeRequest)
205
- t.is(error2?.response?.status, 504)
206
-
207
- // Check connection, subscription active, subscription total, and message total metrics when unsubscribed from feed
208
- response = await axios.get(metricsAddress)
209
- metricsMap = parsePromMetrics(response.data)
210
- expectedLabel = '{app_name="test",app_version="undefined"}'
211
- t.is(metricsMap.get(`ws_connection_active${expectedLabel}`), 1)
212
- expectedLabel =
213
- '{feed_id="|base:eth|quote:usd",subscription_key="test-|base:eth|quote:usd",app_name="test",app_version="undefined"}'
214
- t.is(metricsMap.get(`ws_subscription_active${expectedLabel}`), 0)
215
- t.is(metricsMap.get(`ws_subscription_total${expectedLabel}`), 1)
216
- t.is(metricsMap.get(`ws_message_total${expectedLabel}`), 2)
217
-
218
- t.context.server.close()
219
-
220
- // Check connection metric after connection closed
221
- response = await axios.get(metricsAddress)
222
- metricsMap = parsePromMetrics(response.data)
223
- expectedLabel = '{app_name="test",app_version="undefined"}'
224
- t.is(metricsMap.get(`ws_connection_active${expectedLabel}`), 0)
225
- })
@@ -1,243 +0,0 @@
1
- import test from 'ava'
2
- import { expose } from '../src'
3
- import { Adapter } from '../src/adapter'
4
- import { SimpleCountingRateLimiter } from '../src/rate-limiting'
5
- import { AdapterDependencies } from '../src/transports'
6
- import { NopTransport } from './util'
7
-
8
- test('empty tiers in rate limiting fails on startup', async (t) => {
9
- const adapter: Adapter = {
10
- name: 'test',
11
- endpoints: [
12
- {
13
- name: 'test',
14
- inputParameters: {},
15
- transport: new NopTransport(),
16
- },
17
- ],
18
- rateLimiting: {
19
- tiers: {},
20
- },
21
- }
22
-
23
- await t.throwsAsync(async () => expose(adapter), {
24
- message: 'The tiers object is defined, but has no entries',
25
- })
26
- })
27
-
28
- test('selected tier is not a valid option', async (t) => {
29
- const adapter: Adapter = {
30
- name: 'test',
31
- endpoints: [
32
- {
33
- name: 'test',
34
- inputParameters: {},
35
- transport: new NopTransport(),
36
- },
37
- ],
38
- rateLimiting: {
39
- tiers: {
40
- free: {
41
- rateLimit1s: 123,
42
- },
43
- pro: {
44
- rateLimit1s: 1234,
45
- },
46
- },
47
- },
48
- envDefaultOverrides: {
49
- RATE_LIMIT_API_TIER: 'asdasdasd',
50
- },
51
- }
52
-
53
- await t.throwsAsync(async () => expose(adapter), {
54
- message: 'The selected rate limit tier "asdasdasd" is not valid (can be one of "free", "pro")',
55
- })
56
- })
57
-
58
- test('throws error if explicit allocation leaves no room for implicitly allocated endpoints', async (t) => {
59
- const adapter: Adapter = {
60
- name: 'test',
61
- endpoints: [
62
- {
63
- name: 'test',
64
- inputParameters: {},
65
- transport: new NopTransport(),
66
- rateLimiting: {
67
- allocationPercentage: 100,
68
- },
69
- },
70
- {
71
- name: 'test2',
72
- inputParameters: {},
73
- transport: new NopTransport(),
74
- },
75
- ],
76
- rateLimiting: {
77
- tiers: {
78
- free: {
79
- rateLimit1s: 123,
80
- },
81
- pro: {
82
- rateLimit1s: 1234,
83
- },
84
- },
85
- },
86
- envDefaultOverrides: {
87
- RATE_LIMIT_API_TIER: 'asdasdasd',
88
- },
89
- }
90
-
91
- await t.throwsAsync(async () => expose(adapter), {
92
- message: 'The explicit allocation is at 100% but there are endpoints with implicit allocation',
93
- })
94
- })
95
-
96
- test('throws error if explicit allocation exceeds 100%', async (t) => {
97
- const adapter: Adapter = {
98
- name: 'test',
99
- endpoints: [
100
- {
101
- name: 'test',
102
- inputParameters: {},
103
- transport: new NopTransport(),
104
- rateLimiting: {
105
- allocationPercentage: 80,
106
- },
107
- },
108
- {
109
- name: 'test2',
110
- inputParameters: {},
111
- transport: new NopTransport(),
112
- rateLimiting: {
113
- allocationPercentage: 30,
114
- },
115
- },
116
- ],
117
- rateLimiting: {
118
- tiers: {
119
- free: {
120
- rateLimit1s: 123,
121
- },
122
- pro: {
123
- rateLimit1s: 1234,
124
- },
125
- },
126
- },
127
- envDefaultOverrides: {
128
- RATE_LIMIT_API_TIER: 'asdasdasd',
129
- },
130
- }
131
-
132
- await t.throwsAsync(async () => expose(adapter), {
133
- message: 'The total allocation set for all endpoints summed cannot exceed 100%',
134
- })
135
- })
136
-
137
- test('uses most restrictive tier if none is specified in settings', async (t) => {
138
- const adapter: Adapter = {
139
- name: 'test',
140
- endpoints: [
141
- {
142
- name: 'test',
143
- inputParameters: {},
144
- transport: new (class extends NopTransport {
145
- override async initialize(dependencies: AdapterDependencies): Promise<void> {
146
- t.true(dependencies.requestRateLimiter instanceof SimpleCountingRateLimiter)
147
- t.is(
148
- (dependencies.requestRateLimiter as unknown as Record<string, number>)[
149
- 'perSecondLimit'
150
- ],
151
- 123,
152
- )
153
- }
154
- })(),
155
- },
156
- ],
157
- rateLimiting: {
158
- tiers: {
159
- asd: {
160
- rateLimit1s: 5234,
161
- rateLimit1m: 3000 * 60,
162
- },
163
- free: {
164
- rateLimit1s: 123,
165
- rateLimit1h: 1000 * 60,
166
- },
167
- pro: {
168
- rateLimit1m: 1234 * 60,
169
- },
170
- },
171
- },
172
- }
173
-
174
- await expose(adapter)
175
- })
176
-
177
- test('uses unlimited tier if none is specified in settings', async (t) => {
178
- const adapter: Adapter = {
179
- name: 'test',
180
- endpoints: [
181
- {
182
- name: 'test',
183
- inputParameters: {},
184
- transport: new (class extends NopTransport {
185
- override async initialize(dependencies: AdapterDependencies): Promise<void> {
186
- t.true(dependencies.requestRateLimiter instanceof SimpleCountingRateLimiter)
187
- t.is(
188
- (dependencies.requestRateLimiter as unknown as Record<string, number>)[
189
- 'perSecondLimit'
190
- ],
191
- Infinity,
192
- )
193
- }
194
- })(),
195
- },
196
- ],
197
- }
198
-
199
- await expose(adapter)
200
- })
201
-
202
- test('uses specified tier if present in settings', async (t) => {
203
- const adapter: Adapter = {
204
- name: 'test',
205
- endpoints: [
206
- {
207
- name: 'test',
208
- inputParameters: {},
209
- transport: new (class extends NopTransport {
210
- override async initialize(dependencies: AdapterDependencies): Promise<void> {
211
- t.true(dependencies.requestRateLimiter instanceof SimpleCountingRateLimiter)
212
- t.is(
213
- (dependencies.requestRateLimiter as unknown as Record<string, number>)[
214
- 'perSecondLimit'
215
- ],
216
- 1234,
217
- )
218
- }
219
- })(),
220
- },
221
- ],
222
- rateLimiting: {
223
- tiers: {
224
- asd: {
225
- rateLimit1s: 5234,
226
- rateLimit1m: 3000 * 60,
227
- },
228
- free: {
229
- rateLimit1s: 123,
230
- rateLimit1h: 1000 * 60,
231
- },
232
- pro: {
233
- rateLimit1s: 1234,
234
- },
235
- },
236
- },
237
- envDefaultOverrides: {
238
- RATE_LIMIT_API_TIER: 'pro',
239
- },
240
- }
241
-
242
- await expose(adapter)
243
- })