@mepkg/maxios 2.0.0 → 3.0.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/package.json +4 -4
- package/src/helpers.js +35 -0
- package/src/maxios.js +88 -55
- package/src/tls-client.js +12 -37
package/package.json
CHANGED
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"test:watch": "node --test --watch 'tests/**/*.test.js'"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"axios": "1.
|
|
17
|
+
"axios": "1.17.0",
|
|
18
|
+
"es-toolkit": "^1.47.1",
|
|
18
19
|
"hpagent": "^1.2.0",
|
|
19
|
-
"
|
|
20
|
-
"melperjs": "^17.0.0"
|
|
20
|
+
"melperjs": "^17.1.1"
|
|
21
21
|
},
|
|
22
|
-
"version": "
|
|
22
|
+
"version": "3.0.0"
|
|
23
23
|
}
|
package/src/helpers.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {cookiesFromResponse, cookiesToHeader} from "melperjs";
|
|
2
|
+
import isNil from "es-toolkit/compat/isNil";
|
|
3
|
+
import omitBy from "es-toolkit/compat/omitBy";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export function jsonMethod(throwOnError = false) {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(this.data);
|
|
9
|
+
} catch (error) {
|
|
10
|
+
if (throwOnError) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function attachJsonMethod(response) {
|
|
18
|
+
response.json = jsonMethod;
|
|
19
|
+
return response;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function mergeResponseCookies(cookies, response) {
|
|
23
|
+
if (!cookies) return cookies;
|
|
24
|
+
const parsed = omitBy(cookiesFromResponse(response), isNil);
|
|
25
|
+
return {...cookies, ...parsed};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function attachRequestCookies(cookies, request) {
|
|
29
|
+
if (!cookies) return;
|
|
30
|
+
request.headers = request.headers || {};
|
|
31
|
+
if (isNil(request.headers.cookie) && isNil(request.headers.Cookie)) {
|
|
32
|
+
const header = cookiesToHeader(cookies);
|
|
33
|
+
header && (request.headers.cookie = header);
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/maxios.js
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
|
-
import {HttpProxyAgent, HttpsProxyAgent} from "hpagent";
|
|
2
|
-
import {cookiesFromResponse, cookiesToHeader} from "melperjs";
|
|
3
|
-
import {isNil, omitBy} from "lodash-es";
|
|
4
1
|
import axios from "axios";
|
|
5
|
-
|
|
2
|
+
import {HttpProxyAgent, HttpsProxyAgent} from "hpagent";
|
|
3
|
+
import isNil from "es-toolkit/compat/isNil";
|
|
4
|
+
import omitBy from "es-toolkit/compat/omitBy";
|
|
5
|
+
import {attachRequestCookies, attachJsonMethod, mergeResponseCookies} from "./helpers.js";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An axios response augmented by Maxios with a `finalUrl` and a `json()` helper.
|
|
10
|
+
* @typedef {import("axios").AxiosResponse & {
|
|
11
|
+
* finalUrl: string,
|
|
12
|
+
* json: (throwOnError?: boolean) => any
|
|
13
|
+
* }} MaxiosResponse
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Maxios constructor options. Any axios option (`headers`, `validateStatus`,
|
|
18
|
+
* `maxRedirects`, `responseType`, ...) is forwarded to `axios.create`.
|
|
19
|
+
* @typedef {Omit<import("axios").AxiosRequestConfig, "proxy"> & {
|
|
20
|
+
* proxy?: string | null,
|
|
21
|
+
* cookies?: Record<string, string> | false
|
|
22
|
+
* }} MaxiosConfig
|
|
23
|
+
*/
|
|
6
24
|
|
|
7
25
|
export class Maxios {
|
|
8
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @param {MaxiosConfig} [options]
|
|
28
|
+
*/
|
|
29
|
+
constructor({proxy = null, cookies = {}, ...config} = {}) {
|
|
9
30
|
this.proxy = proxy;
|
|
10
31
|
this.cookies = cookies;
|
|
11
|
-
this.config = config
|
|
32
|
+
this.config = config;
|
|
12
33
|
|
|
13
34
|
this.config.responseType = config.responseType || "text";
|
|
14
35
|
this.config.timeout = config.timeout || 10000;
|
|
@@ -19,108 +40,120 @@ export class Maxios {
|
|
|
19
40
|
this.config.httpsAgent = new HttpsProxyAgent({proxy, timeout: proxyTimeout});
|
|
20
41
|
this.config.httpAgent = new HttpProxyAgent({proxy, timeout: proxyTimeout});
|
|
21
42
|
} catch (e) {
|
|
22
|
-
e.message = "Proxy Error | " + e.message;
|
|
43
|
+
e.message = "Proxy Configuration Error | " + e.message;
|
|
23
44
|
throw e;
|
|
24
45
|
}
|
|
25
46
|
}
|
|
47
|
+
/** @type {import("axios").AxiosInstance} */
|
|
26
48
|
this.client = axios.create(this.config);
|
|
27
49
|
|
|
28
50
|
this.client.interceptors.request.use((request) => {
|
|
29
|
-
this
|
|
51
|
+
attachRequestCookies(this.cookies, request);
|
|
30
52
|
return request;
|
|
31
53
|
});
|
|
32
54
|
this.client.interceptors.response.use(response => {
|
|
33
|
-
this
|
|
34
|
-
|
|
55
|
+
this.cookies = mergeResponseCookies(this.cookies, response);
|
|
56
|
+
attachJsonMethod(response);
|
|
35
57
|
this.#attachFinalUrl(response);
|
|
36
58
|
return response;
|
|
37
59
|
}, error => {
|
|
38
60
|
if (error.response) {
|
|
39
|
-
this
|
|
40
|
-
|
|
61
|
+
this.cookies = mergeResponseCookies(this.cookies, error.response);
|
|
62
|
+
attachJsonMethod(error.response);
|
|
41
63
|
this.#attachFinalUrl(error.response);
|
|
42
64
|
}
|
|
43
65
|
return Promise.reject(error);
|
|
44
66
|
});
|
|
45
67
|
}
|
|
46
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
71
|
+
* @returns {Promise<MaxiosResponse>}
|
|
72
|
+
*/
|
|
47
73
|
async request(config = {}) {
|
|
48
74
|
config.headers = omitBy(config.headers, isNil);
|
|
49
|
-
return this.client.request(config);
|
|
75
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.request(config));
|
|
50
76
|
}
|
|
51
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @param {string} url
|
|
80
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
81
|
+
* @returns {Promise<MaxiosResponse>}
|
|
82
|
+
*/
|
|
52
83
|
async get(url, config = {}) {
|
|
53
84
|
config.headers = omitBy(config.headers, isNil);
|
|
54
|
-
return this.client.get(url, config);
|
|
85
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.get(url, config));
|
|
55
86
|
}
|
|
56
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @param {string} url
|
|
90
|
+
* @param {*} [data]
|
|
91
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
92
|
+
* @returns {Promise<MaxiosResponse>}
|
|
93
|
+
*/
|
|
57
94
|
async post(url, data = {}, config = {}) {
|
|
58
95
|
config.headers = omitBy(config.headers, isNil);
|
|
59
|
-
return this.client.post(url, data, config);
|
|
96
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.post(url, data, config));
|
|
60
97
|
}
|
|
61
98
|
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} url
|
|
101
|
+
* @param {*} [data]
|
|
102
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
103
|
+
* @returns {Promise<MaxiosResponse>}
|
|
104
|
+
*/
|
|
62
105
|
async put(url, data = {}, config = {}) {
|
|
63
106
|
config.headers = omitBy(config.headers, isNil);
|
|
64
|
-
return this.client.put(url, data, config);
|
|
107
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.put(url, data, config));
|
|
65
108
|
}
|
|
66
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @param {string} url
|
|
112
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
113
|
+
* @returns {Promise<MaxiosResponse>}
|
|
114
|
+
*/
|
|
67
115
|
async delete(url, config = {}) {
|
|
68
116
|
config.headers = omitBy(config.headers, isNil);
|
|
69
|
-
return this.client.delete(url, config);
|
|
117
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.delete(url, config));
|
|
70
118
|
}
|
|
71
119
|
|
|
120
|
+
/**
|
|
121
|
+
* @param {string} url
|
|
122
|
+
* @param {*} [data]
|
|
123
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
124
|
+
* @returns {Promise<MaxiosResponse>}
|
|
125
|
+
*/
|
|
72
126
|
async patch(url, data = {}, config = {}) {
|
|
73
127
|
config.headers = omitBy(config.headers, isNil);
|
|
74
|
-
return this.client.patch(url, data, config);
|
|
128
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.patch(url, data, config));
|
|
75
129
|
}
|
|
76
130
|
|
|
131
|
+
/**
|
|
132
|
+
* @param {string} url
|
|
133
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
134
|
+
* @returns {Promise<MaxiosResponse>}
|
|
135
|
+
*/
|
|
77
136
|
async head(url, config = {}) {
|
|
78
137
|
config.headers = omitBy(config.headers, isNil);
|
|
79
|
-
return this.client.head(url, config);
|
|
138
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.head(url, config));
|
|
80
139
|
}
|
|
81
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @param {string} url
|
|
143
|
+
* @param {import("axios").AxiosRequestConfig} [config]
|
|
144
|
+
* @returns {Promise<MaxiosResponse>}
|
|
145
|
+
*/
|
|
82
146
|
async options(url, config = {}) {
|
|
83
147
|
config.headers = omitBy(config.headers, isNil);
|
|
84
|
-
return this.client.options(url, config);
|
|
148
|
+
return /** @type {Promise<MaxiosResponse>} */ (this.client.options(url, config));
|
|
85
149
|
}
|
|
86
150
|
|
|
87
151
|
#attachFinalUrl = (response) => {
|
|
88
|
-
response.finalUrl = response?.request?.res?.responseUrl
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
#attachJsonMethod = (response) => {
|
|
92
|
-
response.json = function (isSilent = false) {
|
|
93
|
-
try {
|
|
94
|
-
return JSON.parse(this.data);
|
|
95
|
-
} catch (error) {
|
|
96
|
-
if (isSilent) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
#responseCookies = (response) => {
|
|
105
|
-
if (!this.cookies) return;
|
|
106
|
-
const parsed = cookiesFromResponse(response);
|
|
107
|
-
Object.keys(parsed).forEach(key => {
|
|
108
|
-
if (!parsed[key]) {
|
|
109
|
-
delete parsed[key];
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
this.cookies = {...this.cookies, ...parsed};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
#requestCookies = (request) => {
|
|
116
|
-
if (!this.cookies) return;
|
|
117
|
-
request.headers = request.headers || {};
|
|
118
|
-
if (!request.headers.cookie && !request.headers.Cookie) {
|
|
119
|
-
const header = cookiesToHeader(this.cookies);
|
|
120
|
-
header && (request.headers.cookie = header);
|
|
121
|
-
}
|
|
152
|
+
response.finalUrl = response?.request?.res?.responseUrl
|
|
153
|
+
|| (response?.config && this.client.getUri(response.config))
|
|
154
|
+
|| "";
|
|
122
155
|
}
|
|
123
156
|
|
|
124
157
|
}
|
|
125
158
|
|
|
126
|
-
export const maxios = new Maxios(
|
|
159
|
+
export const maxios = new Maxios({cookies: false});
|
package/src/tls-client.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import {Exception} from "melperjs";
|
|
2
|
+
import isNil from "es-toolkit/compat/isNil";
|
|
3
|
+
import omitBy from "es-toolkit/compat/omitBy";
|
|
3
4
|
import {maxios} from "./maxios.js";
|
|
5
|
+
import {attachRequestCookies, jsonMethod, mergeResponseCookies} from "./helpers.js";
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
export const TLS_SERVER = {
|
|
@@ -9,7 +11,9 @@ export const TLS_SERVER = {
|
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export class TlsClient {
|
|
12
|
-
constructor(
|
|
14
|
+
constructor({
|
|
15
|
+
proxy = null,
|
|
16
|
+
cookies = {},
|
|
13
17
|
tlsServer = TLS_SERVER,
|
|
14
18
|
timeout = 30000,
|
|
15
19
|
httpVersion = 2,
|
|
@@ -19,7 +23,7 @@ export class TlsClient {
|
|
|
19
23
|
requestBodyFormat = "text",
|
|
20
24
|
responseBodyFormat = "text",
|
|
21
25
|
validateStatus = (status) => (status >= 200 && status <= 299) || (maxRedirects && status >= 300 && status <= 399)
|
|
22
|
-
} = {}
|
|
26
|
+
} = {}) {
|
|
23
27
|
this.proxy = proxy;
|
|
24
28
|
this.config = {
|
|
25
29
|
timeout,
|
|
@@ -93,9 +97,9 @@ export class TlsClient {
|
|
|
93
97
|
"responseBodyFormat": responseBodyFormat || this.config.responseBodyFormat,
|
|
94
98
|
"key": this.tlsServer.key
|
|
95
99
|
};
|
|
96
|
-
this
|
|
100
|
+
attachRequestCookies(this.cookies, request);
|
|
97
101
|
const axiosResponse = await maxios.post(this.tlsServer.url + "/execute", request, {
|
|
98
|
-
timeout: request.timeout
|
|
102
|
+
timeout: request.timeout,
|
|
99
103
|
maxRedirects: 0,
|
|
100
104
|
validateStatus: status => status === 200
|
|
101
105
|
});
|
|
@@ -112,18 +116,9 @@ export class TlsClient {
|
|
|
112
116
|
headers: responseHeaders,
|
|
113
117
|
data: result.body,
|
|
114
118
|
finalUrl: result.final_url,
|
|
115
|
-
json:
|
|
116
|
-
try {
|
|
117
|
-
return JSON.parse(this.data);
|
|
118
|
-
} catch (error) {
|
|
119
|
-
if (isSilent) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
119
|
+
json: jsonMethod
|
|
125
120
|
};
|
|
126
|
-
this
|
|
121
|
+
this.cookies = mergeResponseCookies(this.cookies, tlsResponse);
|
|
127
122
|
validateStatus = validateStatus || this.config.validateStatus;
|
|
128
123
|
if (validateStatus(result.code)) {
|
|
129
124
|
return tlsResponse;
|
|
@@ -180,24 +175,4 @@ export class TlsClient {
|
|
|
180
175
|
return this.request(config);
|
|
181
176
|
}
|
|
182
177
|
|
|
183
|
-
#responseCookies = (response) => {
|
|
184
|
-
if (!this.cookies) return;
|
|
185
|
-
const parsed = cookiesFromResponse(response);
|
|
186
|
-
Object.keys(parsed).forEach(key => {
|
|
187
|
-
if (!parsed[key]) {
|
|
188
|
-
delete parsed[key];
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
this.cookies = {...this.cookies, ...parsed};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
#requestCookies = (request) => {
|
|
195
|
-
if (!this.cookies) return;
|
|
196
|
-
request.headers = request.headers || {};
|
|
197
|
-
if (!request.headers.cookie && !request.headers.Cookie) {
|
|
198
|
-
const header = cookiesToHeader(this.cookies);
|
|
199
|
-
header && (request.headers.cookie = header);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
178
|
}
|