@tramvai/module-http-client 1.94.1 → 1.95.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/lib/httpClient/httpClientFactory.d.ts +2 -2
- package/lib/httpClientModule.d.ts +3 -2
- package/lib/index.browser.js +108 -115
- package/lib/index.es.js +108 -115
- package/lib/index.js +109 -115
- package/lib/papiClientModule.browser.d.ts +3 -2
- package/lib/papiClientModule.d.ts +3 -2
- package/package.json +10 -10
|
@@ -2,14 +2,14 @@ import type { MakeRequest } from '@tinkoff/request-core';
|
|
|
2
2
|
import type { APP_INFO_TOKEN } from '@tramvai/core';
|
|
3
3
|
import type { API_CLIENT_PASS_HEADERS, HTTP_CLIENT_AGENT, HTTP_CLIENT_FACTORY, DISABLE_CIRCUIT_BREAKER } from '@tramvai/tokens-http-client';
|
|
4
4
|
import type { LOGGER_TOKEN, CREATE_CACHE_TOKEN, ENV_MANAGER_TOKEN, REQUEST_MANAGER_TOKEN } from '@tramvai/tokens-common';
|
|
5
|
-
export declare const httpClientFactory: ({ logger, envManager, appInfo, requestManager, headersList, createCache,
|
|
5
|
+
export declare const httpClientFactory: ({ logger, envManager, appInfo, requestManager, headersList, createCache, makeRequestRegistry, agent, disableCircuitBreaker, }: {
|
|
6
6
|
logger: typeof LOGGER_TOKEN;
|
|
7
7
|
envManager: typeof ENV_MANAGER_TOKEN;
|
|
8
8
|
appInfo: typeof APP_INFO_TOKEN;
|
|
9
9
|
requestManager?: typeof REQUEST_MANAGER_TOKEN;
|
|
10
10
|
headersList?: typeof API_CLIENT_PASS_HEADERS;
|
|
11
11
|
createCache?: typeof CREATE_CACHE_TOKEN;
|
|
12
|
-
|
|
12
|
+
makeRequestRegistry: Map<string, MakeRequest>;
|
|
13
13
|
agent?: typeof HTTP_CLIENT_AGENT;
|
|
14
14
|
disableCircuitBreaker: typeof DISABLE_CIRCUIT_BREAKER;
|
|
15
15
|
}) => typeof HTTP_CLIENT_FACTORY;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
}
|
|
1
|
+
export declare const HttpClientModule: import("@tramvai/core").ModuleType<{
|
|
2
|
+
new (): {};
|
|
3
|
+
}>;
|
package/lib/index.browser.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
2
1
|
import { createToken } from '@tinkoff/dippy';
|
|
3
2
|
import { Module, provide, Scope, APP_INFO_TOKEN } from '@tramvai/core';
|
|
4
3
|
import { PAPI_SERVICE, HTTP_CLIENT_FACTORY, API_CLIENT_PASS_HEADERS, HTTP_CLIENT_AGENT, DISABLE_CIRCUIT_BREAKER, HTTP_CLIENT } from '@tramvai/tokens-http-client';
|
|
@@ -56,7 +55,7 @@ const environmentDependentOptions = typeof window === 'undefined'
|
|
|
56
55
|
: {
|
|
57
56
|
defaultTimeout: 30000,
|
|
58
57
|
};
|
|
59
|
-
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache,
|
|
58
|
+
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache, makeRequestRegistry, agent, disableCircuitBreaker = false, }) => {
|
|
60
59
|
return (options) => {
|
|
61
60
|
if (!options.name) {
|
|
62
61
|
throw Error(`Необходимо передать уникальное поле "name" для экземпляра HTTP клиента!`);
|
|
@@ -99,13 +98,13 @@ const httpClientFactory = ({ logger, envManager, appInfo, requestManager, header
|
|
|
99
98
|
adapterOptions.enableCircuitBreaker = !forceDisabledCircuitBreaker;
|
|
100
99
|
}
|
|
101
100
|
// кэшируем инстанс @tinkoff/request
|
|
102
|
-
if (!
|
|
103
|
-
|
|
101
|
+
if (!makeRequestRegistry.has(adapterOptions.name)) {
|
|
102
|
+
makeRequestRegistry.set(adapterOptions.name, createTinkoffRequest(adapterOptions));
|
|
104
103
|
}
|
|
105
|
-
const
|
|
104
|
+
const makeRequest = makeRequestRegistry.get(adapterOptions.name);
|
|
106
105
|
const httpClientAdapter = new HttpClientAdapter({
|
|
107
106
|
options: adapterOptions,
|
|
108
|
-
|
|
107
|
+
makeRequest,
|
|
109
108
|
});
|
|
110
109
|
return httpClientAdapter;
|
|
111
110
|
};
|
|
@@ -133,120 +132,114 @@ class PapiService extends ApiService {
|
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
],
|
|
151
|
-
})
|
|
152
|
-
], PapiClientModule);
|
|
135
|
+
const PapiClientModule = /* @__PURE__ */ Module({
|
|
136
|
+
providers: [
|
|
137
|
+
provide({
|
|
138
|
+
provide: PAPI_SERVICE,
|
|
139
|
+
scope: Scope.SINGLETON,
|
|
140
|
+
useClass: PapiService,
|
|
141
|
+
deps: {
|
|
142
|
+
httpClientFactory: HTTP_CLIENT_FACTORY,
|
|
143
|
+
baseUrl: SERVER_MODULE_PAPI_PUBLIC_URL,
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
],
|
|
147
|
+
})(class PapiClientModule {
|
|
148
|
+
});
|
|
153
149
|
|
|
154
150
|
const createCacheToken = createToken('httpClient createCache');
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
requestManager: {
|
|
171
|
-
token: REQUEST_MANAGER_TOKEN,
|
|
172
|
-
optional: true,
|
|
173
|
-
},
|
|
174
|
-
headersList: {
|
|
175
|
-
token: API_CLIENT_PASS_HEADERS,
|
|
176
|
-
optional: true,
|
|
177
|
-
},
|
|
178
|
-
agent: {
|
|
179
|
-
token: HTTP_CLIENT_AGENT,
|
|
180
|
-
optional: true,
|
|
181
|
-
},
|
|
182
|
-
disableCircuitBreaker: {
|
|
183
|
-
token: DISABLE_CIRCUIT_BREAKER,
|
|
184
|
-
optional: true,
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
}),
|
|
188
|
-
provide({
|
|
189
|
-
provide: HTTP_CLIENT,
|
|
190
|
-
useFactory: ({ factory }) => {
|
|
191
|
-
return factory({
|
|
192
|
-
name: 'http-client',
|
|
193
|
-
disableCache: true,
|
|
194
|
-
});
|
|
151
|
+
const HttpClientModule = /* @__PURE__ */ Module({
|
|
152
|
+
imports: [PapiClientModule],
|
|
153
|
+
providers: [
|
|
154
|
+
provide({
|
|
155
|
+
provide: HTTP_CLIENT_FACTORY,
|
|
156
|
+
useFactory: httpClientFactory,
|
|
157
|
+
deps: {
|
|
158
|
+
logger: LOGGER_TOKEN,
|
|
159
|
+
envManager: ENV_MANAGER_TOKEN,
|
|
160
|
+
appInfo: APP_INFO_TOKEN,
|
|
161
|
+
createCache: createCacheToken,
|
|
162
|
+
makeRequestRegistry: 'makeRequestRegistry',
|
|
163
|
+
requestManager: {
|
|
164
|
+
token: REQUEST_MANAGER_TOKEN,
|
|
165
|
+
optional: true,
|
|
195
166
|
},
|
|
196
|
-
|
|
197
|
-
|
|
167
|
+
headersList: {
|
|
168
|
+
token: API_CLIENT_PASS_HEADERS,
|
|
169
|
+
optional: true,
|
|
198
170
|
},
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
useValue: [
|
|
203
|
-
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
204
|
-
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
205
|
-
],
|
|
206
|
-
multi: true,
|
|
207
|
-
}),
|
|
208
|
-
/**
|
|
209
|
-
* хранилище для экземпляров @tinkoff/request
|
|
210
|
-
*
|
|
211
|
-
* требуется хранить экземпляры в единственном виде,
|
|
212
|
-
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
213
|
-
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
214
|
-
* если создавать новые экземпляры на Scope.REQUEST
|
|
215
|
-
*/
|
|
216
|
-
provide({
|
|
217
|
-
provide: 'tinkoffRequestRegistry',
|
|
218
|
-
scope: Scope.SINGLETON,
|
|
219
|
-
useFactory: () => new Map(),
|
|
220
|
-
}),
|
|
221
|
-
/**
|
|
222
|
-
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
223
|
-
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
224
|
-
* и доступен для очистки через `/papi/clear-cache`.
|
|
225
|
-
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
226
|
-
* инстансов кэши было бы неограниченное количество.
|
|
227
|
-
*
|
|
228
|
-
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
229
|
-
* (и соответственно кэшей) создаются только один раз, благодаря `tinkoffRequestRegistry`.
|
|
230
|
-
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
231
|
-
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
232
|
-
*/
|
|
233
|
-
provide({
|
|
234
|
-
provide: createCacheToken,
|
|
235
|
-
scope: Scope.SINGLETON,
|
|
236
|
-
useFactory: ({ createCache }) => {
|
|
237
|
-
return createCache;
|
|
171
|
+
agent: {
|
|
172
|
+
token: HTTP_CLIENT_AGENT,
|
|
173
|
+
optional: true,
|
|
238
174
|
},
|
|
239
|
-
|
|
240
|
-
|
|
175
|
+
disableCircuitBreaker: {
|
|
176
|
+
token: DISABLE_CIRCUIT_BREAKER,
|
|
177
|
+
optional: true,
|
|
241
178
|
},
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
provide({
|
|
182
|
+
provide: HTTP_CLIENT,
|
|
183
|
+
useFactory: ({ factory }) => {
|
|
184
|
+
return factory({
|
|
185
|
+
name: 'http-client',
|
|
186
|
+
disableCache: true,
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
deps: {
|
|
190
|
+
factory: HTTP_CLIENT_FACTORY,
|
|
191
|
+
},
|
|
192
|
+
}),
|
|
193
|
+
provide({
|
|
194
|
+
provide: ENV_USED_TOKEN,
|
|
195
|
+
useValue: [
|
|
196
|
+
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
197
|
+
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
198
|
+
],
|
|
199
|
+
multi: true,
|
|
200
|
+
}),
|
|
201
|
+
/**
|
|
202
|
+
* хранилище для экземпляров @tinkoff/request
|
|
203
|
+
*
|
|
204
|
+
* требуется хранить экземпляры в единственном виде,
|
|
205
|
+
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
206
|
+
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
207
|
+
* если создавать новые экземпляры на Scope.REQUEST
|
|
208
|
+
*/
|
|
209
|
+
provide({
|
|
210
|
+
provide: 'makeRequestRegistry',
|
|
211
|
+
scope: Scope.SINGLETON,
|
|
212
|
+
useFactory: () => new Map(),
|
|
213
|
+
}),
|
|
214
|
+
/**
|
|
215
|
+
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
216
|
+
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
217
|
+
* и доступен для очистки через `/papi/clear-cache`.
|
|
218
|
+
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
219
|
+
* инстансов кэши было бы неограниченное количество.
|
|
220
|
+
*
|
|
221
|
+
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
222
|
+
* (и соответственно кэшей) создаются только один раз, благодаря `makeRequestRegistry`.
|
|
223
|
+
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
224
|
+
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
225
|
+
*/
|
|
226
|
+
provide({
|
|
227
|
+
provide: createCacheToken,
|
|
228
|
+
scope: Scope.SINGLETON,
|
|
229
|
+
useFactory: ({ createCache }) => {
|
|
230
|
+
return createCache;
|
|
231
|
+
},
|
|
232
|
+
deps: {
|
|
233
|
+
createCache: CREATE_CACHE_TOKEN,
|
|
234
|
+
},
|
|
235
|
+
}),
|
|
236
|
+
provide({
|
|
237
|
+
provide: API_CLIENT_PASS_HEADERS,
|
|
238
|
+
multi: true,
|
|
239
|
+
useValue: ['x-request-id'],
|
|
240
|
+
}),
|
|
241
|
+
],
|
|
242
|
+
})(class HttpClientModule {
|
|
243
|
+
});
|
|
251
244
|
|
|
252
245
|
export { HttpClientModule, PapiService, fillHeaderIp, fillHeaders, formatError, httpClientFactory };
|
package/lib/index.es.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
2
1
|
import { createChildContainer, createToken } from '@tinkoff/dippy';
|
|
3
2
|
import { Module, provide, Scope, DI_TOKEN, APP_INFO_TOKEN } from '@tramvai/core';
|
|
4
3
|
import { PAPI_SERVICE, HTTP_CLIENT_FACTORY, API_CLIENT_PASS_HEADERS, HTTP_CLIENT_AGENT, DISABLE_CIRCUIT_BREAKER, HTTP_CLIENT } from '@tramvai/tokens-http-client';
|
|
@@ -86,7 +85,7 @@ const environmentDependentOptions = typeof window === 'undefined'
|
|
|
86
85
|
: {
|
|
87
86
|
defaultTimeout: 30000,
|
|
88
87
|
};
|
|
89
|
-
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache,
|
|
88
|
+
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache, makeRequestRegistry, agent, disableCircuitBreaker = false, }) => {
|
|
90
89
|
return (options) => {
|
|
91
90
|
if (!options.name) {
|
|
92
91
|
throw Error(`Необходимо передать уникальное поле "name" для экземпляра HTTP клиента!`);
|
|
@@ -129,13 +128,13 @@ const httpClientFactory = ({ logger, envManager, appInfo, requestManager, header
|
|
|
129
128
|
adapterOptions.enableCircuitBreaker = !forceDisabledCircuitBreaker;
|
|
130
129
|
}
|
|
131
130
|
// кэшируем инстанс @tinkoff/request
|
|
132
|
-
if (!
|
|
133
|
-
|
|
131
|
+
if (!makeRequestRegistry.has(adapterOptions.name)) {
|
|
132
|
+
makeRequestRegistry.set(adapterOptions.name, createTinkoffRequest(adapterOptions));
|
|
134
133
|
}
|
|
135
|
-
const
|
|
134
|
+
const makeRequest = makeRequestRegistry.get(adapterOptions.name);
|
|
136
135
|
const httpClientAdapter = new HttpClientAdapter({
|
|
137
136
|
options: adapterOptions,
|
|
138
|
-
|
|
137
|
+
makeRequest,
|
|
139
138
|
});
|
|
140
139
|
return httpClientAdapter;
|
|
141
140
|
};
|
|
@@ -180,120 +179,114 @@ class PapiService extends BaseHttpClient {
|
|
|
180
179
|
}
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
],
|
|
198
|
-
})
|
|
199
|
-
], PapiClientModule);
|
|
182
|
+
const PapiClientModule = /* @__PURE__ */ Module({
|
|
183
|
+
providers: [
|
|
184
|
+
provide({
|
|
185
|
+
provide: PAPI_SERVICE,
|
|
186
|
+
scope: Scope.SINGLETON,
|
|
187
|
+
useClass: PapiService,
|
|
188
|
+
deps: {
|
|
189
|
+
di: DI_TOKEN,
|
|
190
|
+
papi: { token: SERVER_MODULE_PAPI_PUBLIC_ROUTE, optional: true, multi: true },
|
|
191
|
+
},
|
|
192
|
+
}),
|
|
193
|
+
],
|
|
194
|
+
})(class PapiClientModule {
|
|
195
|
+
});
|
|
200
196
|
|
|
201
197
|
const createCacheToken = createToken('httpClient createCache');
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
requestManager: {
|
|
218
|
-
token: REQUEST_MANAGER_TOKEN,
|
|
219
|
-
optional: true,
|
|
220
|
-
},
|
|
221
|
-
headersList: {
|
|
222
|
-
token: API_CLIENT_PASS_HEADERS,
|
|
223
|
-
optional: true,
|
|
224
|
-
},
|
|
225
|
-
agent: {
|
|
226
|
-
token: HTTP_CLIENT_AGENT,
|
|
227
|
-
optional: true,
|
|
228
|
-
},
|
|
229
|
-
disableCircuitBreaker: {
|
|
230
|
-
token: DISABLE_CIRCUIT_BREAKER,
|
|
231
|
-
optional: true,
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
}),
|
|
235
|
-
provide({
|
|
236
|
-
provide: HTTP_CLIENT,
|
|
237
|
-
useFactory: ({ factory }) => {
|
|
238
|
-
return factory({
|
|
239
|
-
name: 'http-client',
|
|
240
|
-
disableCache: true,
|
|
241
|
-
});
|
|
198
|
+
const HttpClientModule = /* @__PURE__ */ Module({
|
|
199
|
+
imports: [PapiClientModule],
|
|
200
|
+
providers: [
|
|
201
|
+
provide({
|
|
202
|
+
provide: HTTP_CLIENT_FACTORY,
|
|
203
|
+
useFactory: httpClientFactory,
|
|
204
|
+
deps: {
|
|
205
|
+
logger: LOGGER_TOKEN,
|
|
206
|
+
envManager: ENV_MANAGER_TOKEN,
|
|
207
|
+
appInfo: APP_INFO_TOKEN,
|
|
208
|
+
createCache: createCacheToken,
|
|
209
|
+
makeRequestRegistry: 'makeRequestRegistry',
|
|
210
|
+
requestManager: {
|
|
211
|
+
token: REQUEST_MANAGER_TOKEN,
|
|
212
|
+
optional: true,
|
|
242
213
|
},
|
|
243
|
-
|
|
244
|
-
|
|
214
|
+
headersList: {
|
|
215
|
+
token: API_CLIENT_PASS_HEADERS,
|
|
216
|
+
optional: true,
|
|
245
217
|
},
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
useValue: [
|
|
250
|
-
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
251
|
-
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
252
|
-
],
|
|
253
|
-
multi: true,
|
|
254
|
-
}),
|
|
255
|
-
/**
|
|
256
|
-
* хранилище для экземпляров @tinkoff/request
|
|
257
|
-
*
|
|
258
|
-
* требуется хранить экземпляры в единственном виде,
|
|
259
|
-
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
260
|
-
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
261
|
-
* если создавать новые экземпляры на Scope.REQUEST
|
|
262
|
-
*/
|
|
263
|
-
provide({
|
|
264
|
-
provide: 'tinkoffRequestRegistry',
|
|
265
|
-
scope: Scope.SINGLETON,
|
|
266
|
-
useFactory: () => new Map(),
|
|
267
|
-
}),
|
|
268
|
-
/**
|
|
269
|
-
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
270
|
-
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
271
|
-
* и доступен для очистки через `/papi/clear-cache`.
|
|
272
|
-
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
273
|
-
* инстансов кэши было бы неограниченное количество.
|
|
274
|
-
*
|
|
275
|
-
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
276
|
-
* (и соответственно кэшей) создаются только один раз, благодаря `tinkoffRequestRegistry`.
|
|
277
|
-
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
278
|
-
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
279
|
-
*/
|
|
280
|
-
provide({
|
|
281
|
-
provide: createCacheToken,
|
|
282
|
-
scope: Scope.SINGLETON,
|
|
283
|
-
useFactory: ({ createCache }) => {
|
|
284
|
-
return createCache;
|
|
218
|
+
agent: {
|
|
219
|
+
token: HTTP_CLIENT_AGENT,
|
|
220
|
+
optional: true,
|
|
285
221
|
},
|
|
286
|
-
|
|
287
|
-
|
|
222
|
+
disableCircuitBreaker: {
|
|
223
|
+
token: DISABLE_CIRCUIT_BREAKER,
|
|
224
|
+
optional: true,
|
|
288
225
|
},
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
228
|
+
provide({
|
|
229
|
+
provide: HTTP_CLIENT,
|
|
230
|
+
useFactory: ({ factory }) => {
|
|
231
|
+
return factory({
|
|
232
|
+
name: 'http-client',
|
|
233
|
+
disableCache: true,
|
|
234
|
+
});
|
|
235
|
+
},
|
|
236
|
+
deps: {
|
|
237
|
+
factory: HTTP_CLIENT_FACTORY,
|
|
238
|
+
},
|
|
239
|
+
}),
|
|
240
|
+
provide({
|
|
241
|
+
provide: ENV_USED_TOKEN,
|
|
242
|
+
useValue: [
|
|
243
|
+
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
244
|
+
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
245
|
+
],
|
|
246
|
+
multi: true,
|
|
247
|
+
}),
|
|
248
|
+
/**
|
|
249
|
+
* хранилище для экземпляров @tinkoff/request
|
|
250
|
+
*
|
|
251
|
+
* требуется хранить экземпляры в единственном виде,
|
|
252
|
+
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
253
|
+
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
254
|
+
* если создавать новые экземпляры на Scope.REQUEST
|
|
255
|
+
*/
|
|
256
|
+
provide({
|
|
257
|
+
provide: 'makeRequestRegistry',
|
|
258
|
+
scope: Scope.SINGLETON,
|
|
259
|
+
useFactory: () => new Map(),
|
|
260
|
+
}),
|
|
261
|
+
/**
|
|
262
|
+
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
263
|
+
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
264
|
+
* и доступен для очистки через `/papi/clear-cache`.
|
|
265
|
+
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
266
|
+
* инстансов кэши было бы неограниченное количество.
|
|
267
|
+
*
|
|
268
|
+
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
269
|
+
* (и соответственно кэшей) создаются только один раз, благодаря `makeRequestRegistry`.
|
|
270
|
+
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
271
|
+
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
272
|
+
*/
|
|
273
|
+
provide({
|
|
274
|
+
provide: createCacheToken,
|
|
275
|
+
scope: Scope.SINGLETON,
|
|
276
|
+
useFactory: ({ createCache }) => {
|
|
277
|
+
return createCache;
|
|
278
|
+
},
|
|
279
|
+
deps: {
|
|
280
|
+
createCache: CREATE_CACHE_TOKEN,
|
|
281
|
+
},
|
|
282
|
+
}),
|
|
283
|
+
provide({
|
|
284
|
+
provide: API_CLIENT_PASS_HEADERS,
|
|
285
|
+
multi: true,
|
|
286
|
+
useValue: ['x-request-id'],
|
|
287
|
+
}),
|
|
288
|
+
],
|
|
289
|
+
})(class HttpClientModule {
|
|
290
|
+
});
|
|
298
291
|
|
|
299
292
|
export { HttpClientModule, PapiService, fillHeaderIp, fillHeaders, formatError, httpClientFactory };
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var tslib = require('tslib');
|
|
6
5
|
var dippy = require('@tinkoff/dippy');
|
|
7
6
|
var core = require('@tramvai/core');
|
|
8
7
|
var tokensHttpClient = require('@tramvai/tokens-http-client');
|
|
@@ -97,7 +96,7 @@ const environmentDependentOptions = typeof window === 'undefined'
|
|
|
97
96
|
: {
|
|
98
97
|
defaultTimeout: 30000,
|
|
99
98
|
};
|
|
100
|
-
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache,
|
|
99
|
+
const httpClientFactory = ({ logger, envManager, appInfo, requestManager, headersList, createCache, makeRequestRegistry, agent, disableCircuitBreaker = false, }) => {
|
|
101
100
|
return (options) => {
|
|
102
101
|
if (!options.name) {
|
|
103
102
|
throw Error(`Необходимо передать уникальное поле "name" для экземпляра HTTP клиента!`);
|
|
@@ -140,13 +139,13 @@ const httpClientFactory = ({ logger, envManager, appInfo, requestManager, header
|
|
|
140
139
|
adapterOptions.enableCircuitBreaker = !forceDisabledCircuitBreaker;
|
|
141
140
|
}
|
|
142
141
|
// кэшируем инстанс @tinkoff/request
|
|
143
|
-
if (!
|
|
144
|
-
|
|
142
|
+
if (!makeRequestRegistry.has(adapterOptions.name)) {
|
|
143
|
+
makeRequestRegistry.set(adapterOptions.name, tinkoffRequestHttpClientAdapter.createTinkoffRequest(adapterOptions));
|
|
145
144
|
}
|
|
146
|
-
const
|
|
145
|
+
const makeRequest = makeRequestRegistry.get(adapterOptions.name);
|
|
147
146
|
const httpClientAdapter = new tinkoffRequestHttpClientAdapter.HttpClientAdapter({
|
|
148
147
|
options: adapterOptions,
|
|
149
|
-
|
|
148
|
+
makeRequest,
|
|
150
149
|
});
|
|
151
150
|
return httpClientAdapter;
|
|
152
151
|
};
|
|
@@ -191,122 +190,117 @@ class PapiService extends httpClient.BaseHttpClient {
|
|
|
191
190
|
}
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
],
|
|
209
|
-
})
|
|
210
|
-
], PapiClientModule);
|
|
193
|
+
const PapiClientModule = /* @__PURE__ */ core.Module({
|
|
194
|
+
providers: [
|
|
195
|
+
core.provide({
|
|
196
|
+
provide: tokensHttpClient.PAPI_SERVICE,
|
|
197
|
+
scope: core.Scope.SINGLETON,
|
|
198
|
+
useClass: PapiService,
|
|
199
|
+
deps: {
|
|
200
|
+
di: core.DI_TOKEN,
|
|
201
|
+
papi: { token: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE, optional: true, multi: true },
|
|
202
|
+
},
|
|
203
|
+
}),
|
|
204
|
+
],
|
|
205
|
+
})(class PapiClientModule {
|
|
206
|
+
});
|
|
211
207
|
|
|
212
208
|
const createCacheToken = dippy.createToken('httpClient createCache');
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
requestManager: {
|
|
229
|
-
token: tokensCommon.REQUEST_MANAGER_TOKEN,
|
|
230
|
-
optional: true,
|
|
231
|
-
},
|
|
232
|
-
headersList: {
|
|
233
|
-
token: tokensHttpClient.API_CLIENT_PASS_HEADERS,
|
|
234
|
-
optional: true,
|
|
235
|
-
},
|
|
236
|
-
agent: {
|
|
237
|
-
token: tokensHttpClient.HTTP_CLIENT_AGENT,
|
|
238
|
-
optional: true,
|
|
239
|
-
},
|
|
240
|
-
disableCircuitBreaker: {
|
|
241
|
-
token: tokensHttpClient.DISABLE_CIRCUIT_BREAKER,
|
|
242
|
-
optional: true,
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
}),
|
|
246
|
-
core.provide({
|
|
247
|
-
provide: tokensHttpClient.HTTP_CLIENT,
|
|
248
|
-
useFactory: ({ factory }) => {
|
|
249
|
-
return factory({
|
|
250
|
-
name: 'http-client',
|
|
251
|
-
disableCache: true,
|
|
252
|
-
});
|
|
209
|
+
const HttpClientModule = /* @__PURE__ */ core.Module({
|
|
210
|
+
imports: [PapiClientModule],
|
|
211
|
+
providers: [
|
|
212
|
+
core.provide({
|
|
213
|
+
provide: tokensHttpClient.HTTP_CLIENT_FACTORY,
|
|
214
|
+
useFactory: httpClientFactory,
|
|
215
|
+
deps: {
|
|
216
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
217
|
+
envManager: tokensCommon.ENV_MANAGER_TOKEN,
|
|
218
|
+
appInfo: core.APP_INFO_TOKEN,
|
|
219
|
+
createCache: createCacheToken,
|
|
220
|
+
makeRequestRegistry: 'makeRequestRegistry',
|
|
221
|
+
requestManager: {
|
|
222
|
+
token: tokensCommon.REQUEST_MANAGER_TOKEN,
|
|
223
|
+
optional: true,
|
|
253
224
|
},
|
|
254
|
-
|
|
255
|
-
|
|
225
|
+
headersList: {
|
|
226
|
+
token: tokensHttpClient.API_CLIENT_PASS_HEADERS,
|
|
227
|
+
optional: true,
|
|
256
228
|
},
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
useValue: [
|
|
261
|
-
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
262
|
-
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
263
|
-
],
|
|
264
|
-
multi: true,
|
|
265
|
-
}),
|
|
266
|
-
/**
|
|
267
|
-
* хранилище для экземпляров @tinkoff/request
|
|
268
|
-
*
|
|
269
|
-
* требуется хранить экземпляры в единственном виде,
|
|
270
|
-
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
271
|
-
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
272
|
-
* если создавать новые экземпляры на Scope.REQUEST
|
|
273
|
-
*/
|
|
274
|
-
core.provide({
|
|
275
|
-
provide: 'tinkoffRequestRegistry',
|
|
276
|
-
scope: core.Scope.SINGLETON,
|
|
277
|
-
useFactory: () => new Map(),
|
|
278
|
-
}),
|
|
279
|
-
/**
|
|
280
|
-
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
281
|
-
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
282
|
-
* и доступен для очистки через `/papi/clear-cache`.
|
|
283
|
-
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
284
|
-
* инстансов кэши было бы неограниченное количество.
|
|
285
|
-
*
|
|
286
|
-
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
287
|
-
* (и соответственно кэшей) создаются только один раз, благодаря `tinkoffRequestRegistry`.
|
|
288
|
-
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
289
|
-
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
290
|
-
*/
|
|
291
|
-
core.provide({
|
|
292
|
-
provide: createCacheToken,
|
|
293
|
-
scope: core.Scope.SINGLETON,
|
|
294
|
-
useFactory: ({ createCache }) => {
|
|
295
|
-
return createCache;
|
|
229
|
+
agent: {
|
|
230
|
+
token: tokensHttpClient.HTTP_CLIENT_AGENT,
|
|
231
|
+
optional: true,
|
|
296
232
|
},
|
|
297
|
-
|
|
298
|
-
|
|
233
|
+
disableCircuitBreaker: {
|
|
234
|
+
token: tokensHttpClient.DISABLE_CIRCUIT_BREAKER,
|
|
235
|
+
optional: true,
|
|
299
236
|
},
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
237
|
+
},
|
|
238
|
+
}),
|
|
239
|
+
core.provide({
|
|
240
|
+
provide: tokensHttpClient.HTTP_CLIENT,
|
|
241
|
+
useFactory: ({ factory }) => {
|
|
242
|
+
return factory({
|
|
243
|
+
name: 'http-client',
|
|
244
|
+
disableCache: true,
|
|
245
|
+
});
|
|
246
|
+
},
|
|
247
|
+
deps: {
|
|
248
|
+
factory: tokensHttpClient.HTTP_CLIENT_FACTORY,
|
|
249
|
+
},
|
|
250
|
+
}),
|
|
251
|
+
core.provide({
|
|
252
|
+
provide: tokensCommon.ENV_USED_TOKEN,
|
|
253
|
+
useValue: [
|
|
254
|
+
{ key: 'HTTP_CLIENT_CACHE_DISABLED', optional: true, dehydrate: false },
|
|
255
|
+
{ key: 'HTTP_CLIENT_CIRCUIT_BREAKER_DISABLED', optional: true, dehydrate: false },
|
|
256
|
+
],
|
|
257
|
+
multi: true,
|
|
258
|
+
}),
|
|
259
|
+
/**
|
|
260
|
+
* хранилище для экземпляров @tinkoff/request
|
|
261
|
+
*
|
|
262
|
+
* требуется хранить экземпляры в единственном виде,
|
|
263
|
+
* т.к. многие плагины @tinkoff/request после инициализации имеют состояние
|
|
264
|
+
* (cache, circuit breaker), и не будут корректно работать на сервере,
|
|
265
|
+
* если создавать новые экземпляры на Scope.REQUEST
|
|
266
|
+
*/
|
|
267
|
+
core.provide({
|
|
268
|
+
provide: 'makeRequestRegistry',
|
|
269
|
+
scope: core.Scope.SINGLETON,
|
|
270
|
+
useFactory: () => new Map(),
|
|
271
|
+
}),
|
|
272
|
+
/**
|
|
273
|
+
* `CREATE_CACHE_TOKEN` имеет проверку, если токен используется провайдером,
|
|
274
|
+
* который имеет Scope.SINGLETON, то инстанс кэша сохраняется в общее хранилище,
|
|
275
|
+
* и доступен для очистки через `/papi/clear-cache`.
|
|
276
|
+
* Scope.REQUEST игнорируется, т.к. это верная утечка памяти,
|
|
277
|
+
* инстансов кэши было бы неограниченное количество.
|
|
278
|
+
*
|
|
279
|
+
* HTTP клиенты создаются со Scope.REQUEST, но инстансы @tinkoff/request
|
|
280
|
+
* (и соответственно кэшей) создаются только один раз, благодаря `makeRequestRegistry`.
|
|
281
|
+
* это гарантирует отсутствие утечек памяти, поэтому мы обходим проверку
|
|
282
|
+
* на Scope.SINGLETON c помощью обертки `createCacheToken`
|
|
283
|
+
*/
|
|
284
|
+
core.provide({
|
|
285
|
+
provide: createCacheToken,
|
|
286
|
+
scope: core.Scope.SINGLETON,
|
|
287
|
+
useFactory: ({ createCache }) => {
|
|
288
|
+
return createCache;
|
|
289
|
+
},
|
|
290
|
+
deps: {
|
|
291
|
+
createCache: tokensCommon.CREATE_CACHE_TOKEN,
|
|
292
|
+
},
|
|
293
|
+
}),
|
|
294
|
+
core.provide({
|
|
295
|
+
provide: tokensHttpClient.API_CLIENT_PASS_HEADERS,
|
|
296
|
+
multi: true,
|
|
297
|
+
useValue: ['x-request-id'],
|
|
298
|
+
}),
|
|
299
|
+
],
|
|
300
|
+
})(class HttpClientModule {
|
|
301
|
+
});
|
|
309
302
|
|
|
303
|
+
exports.HttpClientModule = HttpClientModule;
|
|
310
304
|
exports.PapiService = PapiService;
|
|
311
305
|
exports.fillHeaderIp = fillHeaderIp;
|
|
312
306
|
exports.fillHeaders = fillHeaders;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-http-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.95.0",
|
|
4
4
|
"initialVersion": "0.58.99",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -25,21 +25,21 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@tramvai/http-client": "0.1.25",
|
|
28
|
-
"@tramvai/tinkoff-request-http-client-adapter": "0.8.
|
|
29
|
-
"@tramvai/tokens-http-client": "1.
|
|
30
|
-
"@tramvai/tokens-common": "1.
|
|
31
|
-
"@tramvai/tokens-server": "1.
|
|
28
|
+
"@tramvai/tinkoff-request-http-client-adapter": "0.8.332",
|
|
29
|
+
"@tramvai/tokens-http-client": "1.95.0",
|
|
30
|
+
"@tramvai/tokens-common": "1.95.0",
|
|
31
|
+
"@tramvai/tokens-server": "1.95.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@tinkoff/request-core": "^0.8.9"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@tinkoff/utils": "^2.1.2",
|
|
38
|
-
"@tramvai/core": "1.
|
|
39
|
-
"@tramvai/module-common": "1.
|
|
40
|
-
"@tramvai/papi": "1.
|
|
41
|
-
"@tramvai/test-helpers": "1.
|
|
42
|
-
"@tramvai/test-mocks": "1.
|
|
38
|
+
"@tramvai/core": "1.95.0",
|
|
39
|
+
"@tramvai/module-common": "1.95.0",
|
|
40
|
+
"@tramvai/papi": "1.95.0",
|
|
41
|
+
"@tramvai/test-helpers": "1.95.0",
|
|
42
|
+
"@tramvai/test-mocks": "1.95.0",
|
|
43
43
|
"@tinkoff/dippy": "0.7.39",
|
|
44
44
|
"node-fetch": "^2.6.1",
|
|
45
45
|
"tslib": "^2.0.3"
|