1 | import copy from 'fast-copy';
|
2 | import qs from 'qs';
|
3 | import asyncToken from './async-token.js';
|
4 | import rateLimitRetry from './rate-limit.js';
|
5 | import rateLimitThrottle from './rate-limit-throttle.js';
|
6 |
|
7 |
|
8 | const HOST_REGEX = /^(?!\w+:\/\/)([^\s:]+\.?[^\s:]+)(?::(\d+))?(?!:)$/;
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | export default function createHttpClient(axios, options) {
|
17 | const defaultConfig = {
|
18 | insecure: false,
|
19 | retryOnError: true,
|
20 |
|
21 | logHandler: (level, data) => {
|
22 | if (level === 'error' && data) {
|
23 | const title = [data.name, data.message].filter((a) => a).join(' - ');
|
24 | console.error(`[error] ${title}`);
|
25 | console.error(data);
|
26 | return;
|
27 | }
|
28 | console.log(`[${level}] ${data}`);
|
29 | },
|
30 |
|
31 | headers: {},
|
32 | httpAgent: false,
|
33 | httpsAgent: false,
|
34 | timeout: 30000,
|
35 | throttle: 0,
|
36 | basePath: '',
|
37 | adapter: undefined,
|
38 | maxContentLength: 1073741824,
|
39 | maxBodyLength: 1073741824,
|
40 | };
|
41 | const config = {
|
42 | ...defaultConfig,
|
43 | ...options,
|
44 | };
|
45 | if (!config.accessToken) {
|
46 | const missingAccessTokenError = new TypeError('Expected parameter accessToken');
|
47 | config.logHandler('error', missingAccessTokenError);
|
48 | throw missingAccessTokenError;
|
49 | }
|
50 |
|
51 | const protocol = config.insecure ? 'http' : 'https';
|
52 | const space = config.space ? `${config.space}/` : '';
|
53 | let hostname = config.defaultHostname;
|
54 | let port = config.insecure ? 80 : 443;
|
55 | if (config.host && HOST_REGEX.test(config.host)) {
|
56 | const parsed = config.host.split(':');
|
57 | if (parsed.length === 2) {
|
58 | ;
|
59 | [hostname, port] = parsed;
|
60 | }
|
61 | else {
|
62 | hostname = parsed[0];
|
63 | }
|
64 | }
|
65 |
|
66 | if (config.basePath) {
|
67 | config.basePath = `/${config.basePath.split('/').filter(Boolean).join('/')}`;
|
68 | }
|
69 | const baseURL = options.baseURL || `${protocol}://${hostname}:${port}${config.basePath}/spaces/${space}`;
|
70 | if (!config.headers.Authorization && typeof config.accessToken !== 'function') {
|
71 | config.headers.Authorization = 'Bearer ' + config.accessToken;
|
72 | }
|
73 | const axiosOptions = {
|
74 |
|
75 | baseURL,
|
76 | headers: config.headers,
|
77 | httpAgent: config.httpAgent,
|
78 | httpsAgent: config.httpsAgent,
|
79 | proxy: config.proxy,
|
80 | timeout: config.timeout,
|
81 | adapter: config.adapter,
|
82 | maxContentLength: config.maxContentLength,
|
83 | maxBodyLength: config.maxBodyLength,
|
84 | paramsSerializer: {
|
85 | serialize: (params) => {
|
86 | return qs.stringify(params);
|
87 | },
|
88 | },
|
89 |
|
90 | logHandler: config.logHandler,
|
91 | responseLogger: config.responseLogger,
|
92 | requestLogger: config.requestLogger,
|
93 | retryOnError: config.retryOnError,
|
94 | };
|
95 | const instance = axios.create(axiosOptions);
|
96 | instance.httpClientParams = options;
|
97 | |
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | instance.cloneWithNewParams = function (newParams) {
|
108 | return createHttpClient(axios, {
|
109 | ...copy(options),
|
110 | ...newParams,
|
111 | });
|
112 | };
|
113 | |
114 |
|
115 |
|
116 |
|
117 | if (config.onBeforeRequest) {
|
118 | instance.interceptors.request.use(config.onBeforeRequest);
|
119 | }
|
120 | if (typeof config.accessToken === 'function') {
|
121 | asyncToken(instance, config.accessToken);
|
122 | }
|
123 | if (config.throttle) {
|
124 | rateLimitThrottle(instance, config.throttle);
|
125 | }
|
126 | rateLimitRetry(instance, config.retryLimit);
|
127 | if (config.onError) {
|
128 | instance.interceptors.response.use((response) => response, config.onError);
|
129 | }
|
130 | return instance;
|
131 | }
|