@tramvai/tinkoff-request-http-client-adapter 0.9.175 → 0.9.178
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/agent/createAgent.browser.browser.js +3 -0
- package/lib/agent/createAgent.es.js +14 -0
- package/lib/agent/createAgent.js +23 -0
- package/lib/createAdapter.browser.js +10 -0
- package/lib/createAdapter.es.js +10 -0
- package/lib/createAdapter.js +14 -0
- package/lib/createTinkoffRequest.browser.js +108 -0
- package/lib/createTinkoffRequest.es.js +108 -0
- package/lib/createTinkoffRequest.js +125 -0
- package/lib/httpClientAdapter.browser.js +60 -0
- package/lib/httpClientAdapter.es.js +60 -0
- package/lib/httpClientAdapter.js +64 -0
- package/lib/index.browser.js +4 -208
- package/lib/index.es.js +4 -218
- package/lib/index.js +8 -234
- package/lib/mergeOptions.browser.js +39 -0
- package/lib/mergeOptions.es.js +39 -0
- package/lib/mergeOptions.js +47 -0
- package/package.json +5 -6
package/lib/index.browser.js
CHANGED
|
@@ -1,208 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import memoryCache from '@tinkoff/request-plugin-cache-memory';
|
|
6
|
-
import validate from '@tinkoff/request-plugin-validate';
|
|
7
|
-
import http, { isServerError, isNetworkFail, getStatus, getHeaders } from '@tinkoff/request-plugin-protocol-http';
|
|
8
|
-
import transformUrl from '@tinkoff/request-plugin-transform-url';
|
|
9
|
-
import circuitBreaker from '@tinkoff/request-plugin-circuit-breaker';
|
|
10
|
-
import retry from '@tinkoff/request-plugin-retry';
|
|
11
|
-
import { BaseHttpClient } from '@tramvai/http-client';
|
|
12
|
-
import compose from '@tinkoff/utils/function/compose';
|
|
13
|
-
|
|
14
|
-
const createAgent = () => { };
|
|
15
|
-
|
|
16
|
-
const defaultAgent = createAgent();
|
|
17
|
-
function createTinkoffRequest(options) {
|
|
18
|
-
const { logger, name, disableCache, enableCircuitBreaker, createCache, cacheTime = 30000, defaultTimeout, validator, errorValidator, errorModificator, circuitBreakerOptions = {}, getCacheKey, lruOptions = { max: 1000, maxAge: cacheTime }, agent, querySerializer, retryOptions, ...defaults } = options;
|
|
19
|
-
const log = logger && logger(`${name}:initialization`);
|
|
20
|
-
const plugins = [];
|
|
21
|
-
plugins.push({
|
|
22
|
-
init: (context, next) => {
|
|
23
|
-
next({
|
|
24
|
-
request: {
|
|
25
|
-
timeout: defaultTimeout,
|
|
26
|
-
...context.getRequest(),
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
plugins.push(transformUrl({
|
|
32
|
-
baseUrl: defaults.baseUrl,
|
|
33
|
-
transform: ({ baseUrl, path, url }) => {
|
|
34
|
-
// если пользователь передал `url`, не модифицируем его, ожидается что это абсолютный URI
|
|
35
|
-
if (url) {
|
|
36
|
-
if (process.env.NODE_ENV === 'development') {
|
|
37
|
-
if (url.indexOf('http') !== 0 && url.indexOf('//') !== 0) {
|
|
38
|
-
log === null || log === void 0 ? void 0 : log.error(`url запроса должен содержать протокол и хост! текущее значение: ${url}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return url;
|
|
42
|
-
}
|
|
43
|
-
if (baseUrl && path) {
|
|
44
|
-
const baseUrlHasTrailSlash = baseUrl.slice(-1) === '/';
|
|
45
|
-
const pathHasLeadSlash = path.slice(0, 1) === '/';
|
|
46
|
-
const needSlash = !baseUrlHasTrailSlash;
|
|
47
|
-
if (pathHasLeadSlash) {
|
|
48
|
-
// eslint-disable-next-line no-param-reassign
|
|
49
|
-
path = path.substring(1);
|
|
50
|
-
}
|
|
51
|
-
return `${baseUrl}${needSlash ? '/' : ''}${path}`;
|
|
52
|
-
}
|
|
53
|
-
if (process.env.NODE_ENV === 'development') {
|
|
54
|
-
if (!baseUrl && !path) {
|
|
55
|
-
log === null || log === void 0 ? void 0 : log.error(`запрос должен содержать url, или baseUrl с полным путем запроса, или baseUrl вместе с path!`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return baseUrl || path || '';
|
|
59
|
-
},
|
|
60
|
-
}));
|
|
61
|
-
plugins.push(logPlugin({
|
|
62
|
-
logger,
|
|
63
|
-
name,
|
|
64
|
-
showQueryFields: true,
|
|
65
|
-
showPayloadFields: true,
|
|
66
|
-
}));
|
|
67
|
-
plugins.push(memoryCache({
|
|
68
|
-
shouldExecute: !disableCache,
|
|
69
|
-
lruOptions,
|
|
70
|
-
allowStale: true,
|
|
71
|
-
getCacheKey,
|
|
72
|
-
memoryConstructor: createCache,
|
|
73
|
-
}));
|
|
74
|
-
plugins.push(deduplicateCache(getCacheKey ? { getCacheKey } : undefined));
|
|
75
|
-
if (enableCircuitBreaker) {
|
|
76
|
-
plugins.push(circuitBreaker({
|
|
77
|
-
isSystemError: either(isServerError, isNetworkFail),
|
|
78
|
-
...circuitBreakerOptions,
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
plugins.push({
|
|
82
|
-
error: (context, next) => {
|
|
83
|
-
const state = context.getState();
|
|
84
|
-
const error = errorModificator === null || errorModificator === void 0 ? void 0 : errorModificator(state);
|
|
85
|
-
if (error) {
|
|
86
|
-
return next({
|
|
87
|
-
error,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
return next();
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
if (validator || errorValidator) {
|
|
94
|
-
plugins.push(validate({
|
|
95
|
-
validator,
|
|
96
|
-
errorValidator,
|
|
97
|
-
allowFallback: true,
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
plugins.push(http({
|
|
101
|
-
agent: agent || defaultAgent,
|
|
102
|
-
querySerializer: querySerializer || undefined,
|
|
103
|
-
}));
|
|
104
|
-
if (retryOptions) {
|
|
105
|
-
plugins.push(retry(retryOptions));
|
|
106
|
-
}
|
|
107
|
-
const makeRequest = request(plugins);
|
|
108
|
-
return makeRequest;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Опции `modifyRequest`, `modifyResponse` и `modifyError`, при наличии в обоих аргументах,
|
|
113
|
-
* объединяются через метод `compose`, сначала выполняется метод из первого аргумента, затем из второго.
|
|
114
|
-
*/
|
|
115
|
-
// eslint-disable-next-line complexity
|
|
116
|
-
function mergeOptions(options, nextOptions, config) {
|
|
117
|
-
if (config === null || config === void 0 ? void 0 : config.replace) {
|
|
118
|
-
return {
|
|
119
|
-
...options,
|
|
120
|
-
...nextOptions,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
const result = {
|
|
124
|
-
...options,
|
|
125
|
-
...nextOptions,
|
|
126
|
-
query: {
|
|
127
|
-
...options.query,
|
|
128
|
-
...nextOptions.query,
|
|
129
|
-
},
|
|
130
|
-
headers: {
|
|
131
|
-
...options.headers,
|
|
132
|
-
...nextOptions.headers,
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
const composeModifier = (modifier) => {
|
|
136
|
-
if (options[modifier] && nextOptions[modifier]) {
|
|
137
|
-
// eslint-disable-next-line no-param-reassign
|
|
138
|
-
result[modifier] = compose(nextOptions[modifier], options[modifier]);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
composeModifier('modifyRequest');
|
|
142
|
-
composeModifier('modifyResponse');
|
|
143
|
-
composeModifier('modifyError');
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
class HttpClientAdapter extends BaseHttpClient {
|
|
148
|
-
constructor({ options, makeRequest, }) {
|
|
149
|
-
super();
|
|
150
|
-
this.options = options;
|
|
151
|
-
this.makeRequest = makeRequest;
|
|
152
|
-
}
|
|
153
|
-
async request(req) {
|
|
154
|
-
// применяем дефолтные опции до вызова modifyRequest на объекте запроса
|
|
155
|
-
const optionsWithDefaults = mergeOptions(this.options, req);
|
|
156
|
-
const { modifyRequest, modifyResponse, modifyError, ...reqWithDefaults } = optionsWithDefaults;
|
|
157
|
-
const { method, body, requestType, ...adaptedReq } = modifyRequest
|
|
158
|
-
? modifyRequest(reqWithDefaults)
|
|
159
|
-
: reqWithDefaults;
|
|
160
|
-
if (method) {
|
|
161
|
-
adaptedReq.httpMethod = method;
|
|
162
|
-
}
|
|
163
|
-
if (body) {
|
|
164
|
-
adaptedReq.payload = body;
|
|
165
|
-
}
|
|
166
|
-
if (requestType) {
|
|
167
|
-
adaptedReq.type = requestType;
|
|
168
|
-
}
|
|
169
|
-
const res = this.makeRequest(adaptedReq);
|
|
170
|
-
try {
|
|
171
|
-
const payload = await res;
|
|
172
|
-
const status = getStatus(res);
|
|
173
|
-
const headers = getHeaders(res);
|
|
174
|
-
const resToModify = {
|
|
175
|
-
payload,
|
|
176
|
-
status,
|
|
177
|
-
headers,
|
|
178
|
-
};
|
|
179
|
-
return modifyResponse ? modifyResponse(resToModify) : resToModify;
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
const meta = res.getExternalMeta();
|
|
183
|
-
const status = getStatus(res);
|
|
184
|
-
const headers = getHeaders(res);
|
|
185
|
-
// Useful for logging
|
|
186
|
-
const errorWithMeta = Object.assign(error, {
|
|
187
|
-
__meta: meta,
|
|
188
|
-
status,
|
|
189
|
-
headers,
|
|
190
|
-
});
|
|
191
|
-
throw modifyError ? modifyError(errorWithMeta, adaptedReq) : errorWithMeta;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
fork(forkOptions = {}, mergeOptionsConfig = {}) {
|
|
195
|
-
return new HttpClientAdapter({
|
|
196
|
-
options: mergeOptions(this.options, forkOptions, mergeOptionsConfig),
|
|
197
|
-
makeRequest: this.makeRequest,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function createAdapter(options) {
|
|
203
|
-
const makeRequest = createTinkoffRequest(options);
|
|
204
|
-
const httpClientAdapter = new HttpClientAdapter({ options, makeRequest });
|
|
205
|
-
return httpClientAdapter;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export { HttpClientAdapter, createAdapter, createTinkoffRequest, mergeOptions };
|
|
1
|
+
export { createAdapter } from './createAdapter.browser.js';
|
|
2
|
+
export { HttpClientAdapter } from './httpClientAdapter.browser.js';
|
|
3
|
+
export { createTinkoffRequest } from './createTinkoffRequest.browser.js';
|
|
4
|
+
export { mergeOptions } from './mergeOptions.browser.js';
|
package/lib/index.es.js
CHANGED
|
@@ -1,218 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import memoryCache from '@tinkoff/request-plugin-cache-memory';
|
|
6
|
-
import validate from '@tinkoff/request-plugin-validate';
|
|
7
|
-
import http$1, { isServerError, isNetworkFail, getStatus, getHeaders } from '@tinkoff/request-plugin-protocol-http';
|
|
8
|
-
import transformUrl from '@tinkoff/request-plugin-transform-url';
|
|
9
|
-
import circuitBreaker from '@tinkoff/request-plugin-circuit-breaker';
|
|
10
|
-
import retry from '@tinkoff/request-plugin-retry';
|
|
11
|
-
import http from 'http';
|
|
12
|
-
import https from 'https';
|
|
13
|
-
import { BaseHttpClient } from '@tramvai/http-client';
|
|
14
|
-
import compose from '@tinkoff/utils/function/compose';
|
|
15
|
-
|
|
16
|
-
const createAgent = (options = {
|
|
17
|
-
keepAlive: true,
|
|
18
|
-
scheduling: 'lifo',
|
|
19
|
-
}) => {
|
|
20
|
-
return {
|
|
21
|
-
http: new http.Agent(options),
|
|
22
|
-
https: new https.Agent(options),
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const defaultAgent = createAgent();
|
|
27
|
-
function createTinkoffRequest(options) {
|
|
28
|
-
const { logger, name, disableCache, enableCircuitBreaker, createCache, cacheTime = 30000, defaultTimeout, validator, errorValidator, errorModificator, circuitBreakerOptions = {}, getCacheKey, lruOptions = { max: 1000, maxAge: cacheTime }, agent, querySerializer, retryOptions, ...defaults } = options;
|
|
29
|
-
const log = logger && logger(`${name}:initialization`);
|
|
30
|
-
const plugins = [];
|
|
31
|
-
plugins.push({
|
|
32
|
-
init: (context, next) => {
|
|
33
|
-
next({
|
|
34
|
-
request: {
|
|
35
|
-
timeout: defaultTimeout,
|
|
36
|
-
...context.getRequest(),
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
plugins.push(transformUrl({
|
|
42
|
-
baseUrl: defaults.baseUrl,
|
|
43
|
-
transform: ({ baseUrl, path, url }) => {
|
|
44
|
-
// если пользователь передал `url`, не модифицируем его, ожидается что это абсолютный URI
|
|
45
|
-
if (url) {
|
|
46
|
-
if (process.env.NODE_ENV === 'development') {
|
|
47
|
-
if (url.indexOf('http') !== 0 && url.indexOf('//') !== 0) {
|
|
48
|
-
log === null || log === void 0 ? void 0 : log.error(`url запроса должен содержать протокол и хост! текущее значение: ${url}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return url;
|
|
52
|
-
}
|
|
53
|
-
if (baseUrl && path) {
|
|
54
|
-
const baseUrlHasTrailSlash = baseUrl.slice(-1) === '/';
|
|
55
|
-
const pathHasLeadSlash = path.slice(0, 1) === '/';
|
|
56
|
-
const needSlash = !baseUrlHasTrailSlash;
|
|
57
|
-
if (pathHasLeadSlash) {
|
|
58
|
-
// eslint-disable-next-line no-param-reassign
|
|
59
|
-
path = path.substring(1);
|
|
60
|
-
}
|
|
61
|
-
return `${baseUrl}${needSlash ? '/' : ''}${path}`;
|
|
62
|
-
}
|
|
63
|
-
if (process.env.NODE_ENV === 'development') {
|
|
64
|
-
if (!baseUrl && !path) {
|
|
65
|
-
log === null || log === void 0 ? void 0 : log.error(`запрос должен содержать url, или baseUrl с полным путем запроса, или baseUrl вместе с path!`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return baseUrl || path || '';
|
|
69
|
-
},
|
|
70
|
-
}));
|
|
71
|
-
plugins.push(logPlugin({
|
|
72
|
-
logger,
|
|
73
|
-
name,
|
|
74
|
-
showQueryFields: true,
|
|
75
|
-
showPayloadFields: true,
|
|
76
|
-
}));
|
|
77
|
-
plugins.push(memoryCache({
|
|
78
|
-
shouldExecute: !disableCache,
|
|
79
|
-
lruOptions,
|
|
80
|
-
allowStale: true,
|
|
81
|
-
getCacheKey,
|
|
82
|
-
memoryConstructor: createCache,
|
|
83
|
-
}));
|
|
84
|
-
plugins.push(deduplicateCache(getCacheKey ? { getCacheKey } : undefined));
|
|
85
|
-
if (enableCircuitBreaker) {
|
|
86
|
-
plugins.push(circuitBreaker({
|
|
87
|
-
isSystemError: either(isServerError, isNetworkFail),
|
|
88
|
-
...circuitBreakerOptions,
|
|
89
|
-
}));
|
|
90
|
-
}
|
|
91
|
-
plugins.push({
|
|
92
|
-
error: (context, next) => {
|
|
93
|
-
const state = context.getState();
|
|
94
|
-
const error = errorModificator === null || errorModificator === void 0 ? void 0 : errorModificator(state);
|
|
95
|
-
if (error) {
|
|
96
|
-
return next({
|
|
97
|
-
error,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
return next();
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
if (validator || errorValidator) {
|
|
104
|
-
plugins.push(validate({
|
|
105
|
-
validator,
|
|
106
|
-
errorValidator,
|
|
107
|
-
allowFallback: true,
|
|
108
|
-
}));
|
|
109
|
-
}
|
|
110
|
-
plugins.push(http$1({
|
|
111
|
-
agent: agent || defaultAgent,
|
|
112
|
-
querySerializer: querySerializer || undefined,
|
|
113
|
-
}));
|
|
114
|
-
if (retryOptions) {
|
|
115
|
-
plugins.push(retry(retryOptions));
|
|
116
|
-
}
|
|
117
|
-
const makeRequest = request(plugins);
|
|
118
|
-
return makeRequest;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Опции `modifyRequest`, `modifyResponse` и `modifyError`, при наличии в обоих аргументах,
|
|
123
|
-
* объединяются через метод `compose`, сначала выполняется метод из первого аргумента, затем из второго.
|
|
124
|
-
*/
|
|
125
|
-
// eslint-disable-next-line complexity
|
|
126
|
-
function mergeOptions(options, nextOptions, config) {
|
|
127
|
-
if (config === null || config === void 0 ? void 0 : config.replace) {
|
|
128
|
-
return {
|
|
129
|
-
...options,
|
|
130
|
-
...nextOptions,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
const result = {
|
|
134
|
-
...options,
|
|
135
|
-
...nextOptions,
|
|
136
|
-
query: {
|
|
137
|
-
...options.query,
|
|
138
|
-
...nextOptions.query,
|
|
139
|
-
},
|
|
140
|
-
headers: {
|
|
141
|
-
...options.headers,
|
|
142
|
-
...nextOptions.headers,
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
const composeModifier = (modifier) => {
|
|
146
|
-
if (options[modifier] && nextOptions[modifier]) {
|
|
147
|
-
// eslint-disable-next-line no-param-reassign
|
|
148
|
-
result[modifier] = compose(nextOptions[modifier], options[modifier]);
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
composeModifier('modifyRequest');
|
|
152
|
-
composeModifier('modifyResponse');
|
|
153
|
-
composeModifier('modifyError');
|
|
154
|
-
return result;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
class HttpClientAdapter extends BaseHttpClient {
|
|
158
|
-
constructor({ options, makeRequest, }) {
|
|
159
|
-
super();
|
|
160
|
-
this.options = options;
|
|
161
|
-
this.makeRequest = makeRequest;
|
|
162
|
-
}
|
|
163
|
-
async request(req) {
|
|
164
|
-
// применяем дефолтные опции до вызова modifyRequest на объекте запроса
|
|
165
|
-
const optionsWithDefaults = mergeOptions(this.options, req);
|
|
166
|
-
const { modifyRequest, modifyResponse, modifyError, ...reqWithDefaults } = optionsWithDefaults;
|
|
167
|
-
const { method, body, requestType, ...adaptedReq } = modifyRequest
|
|
168
|
-
? modifyRequest(reqWithDefaults)
|
|
169
|
-
: reqWithDefaults;
|
|
170
|
-
if (method) {
|
|
171
|
-
adaptedReq.httpMethod = method;
|
|
172
|
-
}
|
|
173
|
-
if (body) {
|
|
174
|
-
adaptedReq.payload = body;
|
|
175
|
-
}
|
|
176
|
-
if (requestType) {
|
|
177
|
-
adaptedReq.type = requestType;
|
|
178
|
-
}
|
|
179
|
-
const res = this.makeRequest(adaptedReq);
|
|
180
|
-
try {
|
|
181
|
-
const payload = await res;
|
|
182
|
-
const status = getStatus(res);
|
|
183
|
-
const headers = getHeaders(res);
|
|
184
|
-
const resToModify = {
|
|
185
|
-
payload,
|
|
186
|
-
status,
|
|
187
|
-
headers,
|
|
188
|
-
};
|
|
189
|
-
return modifyResponse ? modifyResponse(resToModify) : resToModify;
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
const meta = res.getExternalMeta();
|
|
193
|
-
const status = getStatus(res);
|
|
194
|
-
const headers = getHeaders(res);
|
|
195
|
-
// Useful for logging
|
|
196
|
-
const errorWithMeta = Object.assign(error, {
|
|
197
|
-
__meta: meta,
|
|
198
|
-
status,
|
|
199
|
-
headers,
|
|
200
|
-
});
|
|
201
|
-
throw modifyError ? modifyError(errorWithMeta, adaptedReq) : errorWithMeta;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
fork(forkOptions = {}, mergeOptionsConfig = {}) {
|
|
205
|
-
return new HttpClientAdapter({
|
|
206
|
-
options: mergeOptions(this.options, forkOptions, mergeOptionsConfig),
|
|
207
|
-
makeRequest: this.makeRequest,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function createAdapter(options) {
|
|
213
|
-
const makeRequest = createTinkoffRequest(options);
|
|
214
|
-
const httpClientAdapter = new HttpClientAdapter({ options, makeRequest });
|
|
215
|
-
return httpClientAdapter;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export { HttpClientAdapter, createAdapter, createTinkoffRequest, mergeOptions };
|
|
1
|
+
export { createAdapter } from './createAdapter.es.js';
|
|
2
|
+
export { HttpClientAdapter } from './httpClientAdapter.es.js';
|
|
3
|
+
export { createTinkoffRequest } from './createTinkoffRequest.es.js';
|
|
4
|
+
export { mergeOptions } from './mergeOptions.es.js';
|
package/lib/index.js
CHANGED
|
@@ -2,240 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var memoryCache = require('@tinkoff/request-plugin-cache-memory');
|
|
10
|
-
var validate = require('@tinkoff/request-plugin-validate');
|
|
11
|
-
var http$1 = require('@tinkoff/request-plugin-protocol-http');
|
|
12
|
-
var transformUrl = require('@tinkoff/request-plugin-transform-url');
|
|
13
|
-
var circuitBreaker = require('@tinkoff/request-plugin-circuit-breaker');
|
|
14
|
-
var retry = require('@tinkoff/request-plugin-retry');
|
|
15
|
-
var http = require('http');
|
|
16
|
-
var https = require('https');
|
|
17
|
-
var httpClient = require('@tramvai/http-client');
|
|
18
|
-
var compose = require('@tinkoff/utils/function/compose');
|
|
5
|
+
var createAdapter = require('./createAdapter.js');
|
|
6
|
+
var httpClientAdapter = require('./httpClientAdapter.js');
|
|
7
|
+
var createTinkoffRequest = require('./createTinkoffRequest.js');
|
|
8
|
+
var mergeOptions = require('./mergeOptions.js');
|
|
19
9
|
|
|
20
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
21
10
|
|
|
22
|
-
var either__default = /*#__PURE__*/_interopDefaultLegacy(either);
|
|
23
|
-
var request__default = /*#__PURE__*/_interopDefaultLegacy(request);
|
|
24
|
-
var logPlugin__default = /*#__PURE__*/_interopDefaultLegacy(logPlugin);
|
|
25
|
-
var deduplicateCache__default = /*#__PURE__*/_interopDefaultLegacy(deduplicateCache);
|
|
26
|
-
var memoryCache__default = /*#__PURE__*/_interopDefaultLegacy(memoryCache);
|
|
27
|
-
var validate__default = /*#__PURE__*/_interopDefaultLegacy(validate);
|
|
28
|
-
var http__default$1 = /*#__PURE__*/_interopDefaultLegacy(http$1);
|
|
29
|
-
var transformUrl__default = /*#__PURE__*/_interopDefaultLegacy(transformUrl);
|
|
30
|
-
var circuitBreaker__default = /*#__PURE__*/_interopDefaultLegacy(circuitBreaker);
|
|
31
|
-
var retry__default = /*#__PURE__*/_interopDefaultLegacy(retry);
|
|
32
|
-
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
33
|
-
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
34
|
-
var compose__default = /*#__PURE__*/_interopDefaultLegacy(compose);
|
|
35
11
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
http: new http__default["default"].Agent(options),
|
|
42
|
-
https: new https__default["default"].Agent(options),
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const defaultAgent = createAgent();
|
|
47
|
-
function createTinkoffRequest(options) {
|
|
48
|
-
const { logger, name, disableCache, enableCircuitBreaker, createCache, cacheTime = 30000, defaultTimeout, validator, errorValidator, errorModificator, circuitBreakerOptions = {}, getCacheKey, lruOptions = { max: 1000, maxAge: cacheTime }, agent, querySerializer, retryOptions, ...defaults } = options;
|
|
49
|
-
const log = logger && logger(`${name}:initialization`);
|
|
50
|
-
const plugins = [];
|
|
51
|
-
plugins.push({
|
|
52
|
-
init: (context, next) => {
|
|
53
|
-
next({
|
|
54
|
-
request: {
|
|
55
|
-
timeout: defaultTimeout,
|
|
56
|
-
...context.getRequest(),
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
plugins.push(transformUrl__default["default"]({
|
|
62
|
-
baseUrl: defaults.baseUrl,
|
|
63
|
-
transform: ({ baseUrl, path, url }) => {
|
|
64
|
-
// если пользователь передал `url`, не модифицируем его, ожидается что это абсолютный URI
|
|
65
|
-
if (url) {
|
|
66
|
-
if (process.env.NODE_ENV === 'development') {
|
|
67
|
-
if (url.indexOf('http') !== 0 && url.indexOf('//') !== 0) {
|
|
68
|
-
log === null || log === void 0 ? void 0 : log.error(`url запроса должен содержать протокол и хост! текущее значение: ${url}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return url;
|
|
72
|
-
}
|
|
73
|
-
if (baseUrl && path) {
|
|
74
|
-
const baseUrlHasTrailSlash = baseUrl.slice(-1) === '/';
|
|
75
|
-
const pathHasLeadSlash = path.slice(0, 1) === '/';
|
|
76
|
-
const needSlash = !baseUrlHasTrailSlash;
|
|
77
|
-
if (pathHasLeadSlash) {
|
|
78
|
-
// eslint-disable-next-line no-param-reassign
|
|
79
|
-
path = path.substring(1);
|
|
80
|
-
}
|
|
81
|
-
return `${baseUrl}${needSlash ? '/' : ''}${path}`;
|
|
82
|
-
}
|
|
83
|
-
if (process.env.NODE_ENV === 'development') {
|
|
84
|
-
if (!baseUrl && !path) {
|
|
85
|
-
log === null || log === void 0 ? void 0 : log.error(`запрос должен содержать url, или baseUrl с полным путем запроса, или baseUrl вместе с path!`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return baseUrl || path || '';
|
|
89
|
-
},
|
|
90
|
-
}));
|
|
91
|
-
plugins.push(logPlugin__default["default"]({
|
|
92
|
-
logger,
|
|
93
|
-
name,
|
|
94
|
-
showQueryFields: true,
|
|
95
|
-
showPayloadFields: true,
|
|
96
|
-
}));
|
|
97
|
-
plugins.push(memoryCache__default["default"]({
|
|
98
|
-
shouldExecute: !disableCache,
|
|
99
|
-
lruOptions,
|
|
100
|
-
allowStale: true,
|
|
101
|
-
getCacheKey,
|
|
102
|
-
memoryConstructor: createCache,
|
|
103
|
-
}));
|
|
104
|
-
plugins.push(deduplicateCache__default["default"](getCacheKey ? { getCacheKey } : undefined));
|
|
105
|
-
if (enableCircuitBreaker) {
|
|
106
|
-
plugins.push(circuitBreaker__default["default"]({
|
|
107
|
-
isSystemError: either__default["default"](http$1.isServerError, http$1.isNetworkFail),
|
|
108
|
-
...circuitBreakerOptions,
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
plugins.push({
|
|
112
|
-
error: (context, next) => {
|
|
113
|
-
const state = context.getState();
|
|
114
|
-
const error = errorModificator === null || errorModificator === void 0 ? void 0 : errorModificator(state);
|
|
115
|
-
if (error) {
|
|
116
|
-
return next({
|
|
117
|
-
error,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
return next();
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
if (validator || errorValidator) {
|
|
124
|
-
plugins.push(validate__default["default"]({
|
|
125
|
-
validator,
|
|
126
|
-
errorValidator,
|
|
127
|
-
allowFallback: true,
|
|
128
|
-
}));
|
|
129
|
-
}
|
|
130
|
-
plugins.push(http__default$1["default"]({
|
|
131
|
-
agent: agent || defaultAgent,
|
|
132
|
-
querySerializer: querySerializer || undefined,
|
|
133
|
-
}));
|
|
134
|
-
if (retryOptions) {
|
|
135
|
-
plugins.push(retry__default["default"](retryOptions));
|
|
136
|
-
}
|
|
137
|
-
const makeRequest = request__default["default"](plugins);
|
|
138
|
-
return makeRequest;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Опции `modifyRequest`, `modifyResponse` и `modifyError`, при наличии в обоих аргументах,
|
|
143
|
-
* объединяются через метод `compose`, сначала выполняется метод из первого аргумента, затем из второго.
|
|
144
|
-
*/
|
|
145
|
-
// eslint-disable-next-line complexity
|
|
146
|
-
function mergeOptions(options, nextOptions, config) {
|
|
147
|
-
if (config === null || config === void 0 ? void 0 : config.replace) {
|
|
148
|
-
return {
|
|
149
|
-
...options,
|
|
150
|
-
...nextOptions,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
const result = {
|
|
154
|
-
...options,
|
|
155
|
-
...nextOptions,
|
|
156
|
-
query: {
|
|
157
|
-
...options.query,
|
|
158
|
-
...nextOptions.query,
|
|
159
|
-
},
|
|
160
|
-
headers: {
|
|
161
|
-
...options.headers,
|
|
162
|
-
...nextOptions.headers,
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
const composeModifier = (modifier) => {
|
|
166
|
-
if (options[modifier] && nextOptions[modifier]) {
|
|
167
|
-
// eslint-disable-next-line no-param-reassign
|
|
168
|
-
result[modifier] = compose__default["default"](nextOptions[modifier], options[modifier]);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
composeModifier('modifyRequest');
|
|
172
|
-
composeModifier('modifyResponse');
|
|
173
|
-
composeModifier('modifyError');
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
class HttpClientAdapter extends httpClient.BaseHttpClient {
|
|
178
|
-
constructor({ options, makeRequest, }) {
|
|
179
|
-
super();
|
|
180
|
-
this.options = options;
|
|
181
|
-
this.makeRequest = makeRequest;
|
|
182
|
-
}
|
|
183
|
-
async request(req) {
|
|
184
|
-
// применяем дефолтные опции до вызова modifyRequest на объекте запроса
|
|
185
|
-
const optionsWithDefaults = mergeOptions(this.options, req);
|
|
186
|
-
const { modifyRequest, modifyResponse, modifyError, ...reqWithDefaults } = optionsWithDefaults;
|
|
187
|
-
const { method, body, requestType, ...adaptedReq } = modifyRequest
|
|
188
|
-
? modifyRequest(reqWithDefaults)
|
|
189
|
-
: reqWithDefaults;
|
|
190
|
-
if (method) {
|
|
191
|
-
adaptedReq.httpMethod = method;
|
|
192
|
-
}
|
|
193
|
-
if (body) {
|
|
194
|
-
adaptedReq.payload = body;
|
|
195
|
-
}
|
|
196
|
-
if (requestType) {
|
|
197
|
-
adaptedReq.type = requestType;
|
|
198
|
-
}
|
|
199
|
-
const res = this.makeRequest(adaptedReq);
|
|
200
|
-
try {
|
|
201
|
-
const payload = await res;
|
|
202
|
-
const status = http$1.getStatus(res);
|
|
203
|
-
const headers = http$1.getHeaders(res);
|
|
204
|
-
const resToModify = {
|
|
205
|
-
payload,
|
|
206
|
-
status,
|
|
207
|
-
headers,
|
|
208
|
-
};
|
|
209
|
-
return modifyResponse ? modifyResponse(resToModify) : resToModify;
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
const meta = res.getExternalMeta();
|
|
213
|
-
const status = http$1.getStatus(res);
|
|
214
|
-
const headers = http$1.getHeaders(res);
|
|
215
|
-
// Useful for logging
|
|
216
|
-
const errorWithMeta = Object.assign(error, {
|
|
217
|
-
__meta: meta,
|
|
218
|
-
status,
|
|
219
|
-
headers,
|
|
220
|
-
});
|
|
221
|
-
throw modifyError ? modifyError(errorWithMeta, adaptedReq) : errorWithMeta;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
fork(forkOptions = {}, mergeOptionsConfig = {}) {
|
|
225
|
-
return new HttpClientAdapter({
|
|
226
|
-
options: mergeOptions(this.options, forkOptions, mergeOptionsConfig),
|
|
227
|
-
makeRequest: this.makeRequest,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function createAdapter(options) {
|
|
233
|
-
const makeRequest = createTinkoffRequest(options);
|
|
234
|
-
const httpClientAdapter = new HttpClientAdapter({ options, makeRequest });
|
|
235
|
-
return httpClientAdapter;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
exports.HttpClientAdapter = HttpClientAdapter;
|
|
239
|
-
exports.createAdapter = createAdapter;
|
|
240
|
-
exports.createTinkoffRequest = createTinkoffRequest;
|
|
241
|
-
exports.mergeOptions = mergeOptions;
|
|
12
|
+
exports.createAdapter = createAdapter.createAdapter;
|
|
13
|
+
exports.HttpClientAdapter = httpClientAdapter.HttpClientAdapter;
|
|
14
|
+
exports.createTinkoffRequest = createTinkoffRequest.createTinkoffRequest;
|
|
15
|
+
exports.mergeOptions = mergeOptions.mergeOptions;
|