@mepkg/maxios 2.0.1 → 3.0.1

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