@k03mad/request 2.0.0 → 2.2.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/app/lib/curl.js CHANGED
@@ -4,7 +4,6 @@ import prettyBytes from 'pretty-bytes';
4
4
  const {bgWhite, black, blue, dim, green, magenta, red, white, yellow} = chalk;
5
5
 
6
6
  /**
7
- * Сформировать curl-строку из опций got
8
7
  * @param {string} url
9
8
  * @param {object} [opts]
10
9
  * @param {string} [opts.method]
@@ -25,12 +24,10 @@ export default (url, {
25
24
  }, res) => {
26
25
  const msg = [];
27
26
 
28
- // если третий параметр — объект ошибки, то все необходимое на уровень ниже, в ключе response
29
27
  if (res?.response) {
30
28
  res = res.response;
31
29
  }
32
30
 
33
- // 200 [800 ms] [3.15 kB]
34
31
  if (res?.statusCode) {
35
32
  msg.push(bgWhite(black(res.statusCode)));
36
33
  }
package/app/lib/queue.js CHANGED
@@ -6,9 +6,9 @@ const debug = _debug('mad:queue');
6
6
  // const rps = num => ({intervalCap: num, interval: 1000});
7
7
  const concurrency = num => ({concurrency: num});
8
8
 
9
- // первый уровеньхост (* — любой, кроме уже перечисленных)
10
- // второй уровеньметод (* — любой, кроме уже перечисленных)
11
- // третий уровеньнастройки очереди из p-queue
9
+ // first levelhost
10
+ // second levelmethod
11
+ // third level — p-queue options
12
12
  const requestQueue = {
13
13
  '*': {
14
14
  '*': concurrency(3),
@@ -16,7 +16,6 @@ const requestQueue = {
16
16
  };
17
17
 
18
18
  /**
19
- * Поставить логирование и вернуть очередь
20
19
  * @param {string} host
21
20
  * @param {string} method
22
21
  * @param {object} opts
@@ -44,20 +43,16 @@ const getLoggedQueue = (host, method, opts) => {
44
43
  };
45
44
 
46
45
  /**
47
- * Получить очередь по хосту и методу
48
46
  * @param {string} host
49
47
  * @param {string} method
50
48
  * @returns {object}
51
49
  */
52
50
  export default (host, method = 'GET') => {
53
- // проверка на предустановленные настройки очереди для хоста и метода
54
51
  for (const elem of [method, '*']) {
55
- // очередь уже проинициализирована
56
52
  if (requestQueue[host]?.[elem]?._events) {
57
53
  return requestQueue[host][elem];
58
54
  }
59
55
 
60
- // очередь нужно проинициализировать
61
56
  if (requestQueue[host]?.[elem]) {
62
57
  const opts = requestQueue[host][elem];
63
58
  requestQueue[host][elem] = new PQueue(opts);
@@ -65,21 +60,18 @@ export default (host, method = 'GET') => {
65
60
  }
66
61
  }
67
62
 
68
- // инициализация очереди для хоста без текущего метода в предустановках
69
63
  if (requestQueue[host]) {
70
64
  const opts = requestQueue['*']['*'];
71
65
  requestQueue[host]['*'] = new PQueue(opts);
72
66
  return getLoggedQueue(host, '*', opts);
73
67
  }
74
68
 
75
- // инициализация очереди для хоста с методом из предустановок для всех очередей
76
69
  if (requestQueue['*'][method]) {
77
70
  const opts = requestQueue['*'][method];
78
71
  requestQueue[host] = {[method]: new PQueue(opts)};
79
72
  return getLoggedQueue(host, method, opts);
80
73
  }
81
74
 
82
- // нет ни хоста не метода в предустановках
83
75
  const opts = requestQueue['*']['*'];
84
76
  requestQueue[host] = {'*': new PQueue(opts)};
85
77
  return getLoggedQueue(host, '*', opts);
@@ -8,38 +8,37 @@ import getQueue from './queue.js';
8
8
  const {blue, cyan, dim, green, red, yellow} = chalk;
9
9
  const debug = _debug('mad:request');
10
10
 
11
- /**
12
- * @param {object} opts
13
- */
14
- const prepareRequestOpts = (opts = {}) => {
15
- const UA = 'curl/8.1.2';
16
-
17
- if (opts.dnsCache === undefined) {
18
- opts.dnsCache = true;
19
- }
20
-
21
- if (!opts.timeout) {
22
- opts.timeout = {request: 15_000};
23
- }
24
-
25
- if (!opts.headers) {
26
- opts.headers = {'user-agent': UA};
27
- } else if (!opts.headers['user-agent']) {
28
- opts.headers['user-agent'] = UA;
11
+ const gotCache = new Map();
12
+
13
+ const cacheGotResponseKeys = [
14
+ 'body',
15
+ 'headers',
16
+ 'method',
17
+ 'statusCode',
18
+ 'statusMessage',
19
+ 'timings',
20
+ ];
21
+
22
+ const gotDefaultOpts = got.extend({
23
+ dnsCache: true,
24
+ timeout: {request: 15_000},
25
+ headers: {'user-agent': 'curl/7.81.0'},
26
+ });
27
+
28
+ const cacheDebug = msgArr => {
29
+ if (process.env.DEBUG) {
30
+ debug(msgArr.join(' :: '));
29
31
  }
30
32
  };
31
33
 
32
34
  /**
33
- * Отправить запрос
34
35
  * @param {string} url
35
36
  * @param {object} opts
36
37
  * @returns {object}
37
38
  */
38
39
  const sendRequest = async (url, opts) => {
39
- prepareRequestOpts(opts);
40
-
41
40
  try {
42
- const response = await got(url, opts);
41
+ const response = await gotDefaultOpts(url, opts);
43
42
 
44
43
  if (!opts.responseType) {
45
44
  try {
@@ -52,22 +51,25 @@ const sendRequest = async (url, opts) => {
52
51
  } catch (err) {
53
52
  debug(getCurl(url, opts, err));
54
53
 
55
- err.__pretty = {};
56
-
57
- err.__pretty.req = [
58
- err?.response?.statusCode,
54
+ err.__req = [
55
+ err?.response?.statusCode || err?.code,
59
56
  err?.options?.method,
60
57
  url,
61
- err?.response?.ip ? `(${err.response.ip})` : '',
62
- ].join(' ');
58
+ ].join(' ').trim();
63
59
 
64
- err.__pretty.opts = opts;
60
+ if (err?.response?.ip) {
61
+ err.__ip = err.response.ip;
62
+ }
63
+
64
+ if (Object.keys(opts).length > 0) {
65
+ err.__opts = opts;
66
+ }
65
67
 
66
68
  if (err?.response?.body) {
67
69
  try {
68
- err.__pretty.body = JSON.parse(err.response.body);
70
+ err.__res = JSON.parse(err.response.body);
69
71
  } catch {
70
- err.__pretty.body = err.response.body;
72
+ err.__res = err.response.body;
71
73
  }
72
74
  }
73
75
 
@@ -79,21 +81,12 @@ const sendRequest = async (url, opts) => {
79
81
  }
80
82
  };
81
83
 
82
- export const cache = new Map();
83
-
84
84
  /**
85
- * Отправить запрос c выбором использования очереди
86
85
  * @param {string} url
87
86
  * @param {object} [opts]
88
- * @param {object} [params]
89
- * @param {boolean} [params.skipQueue]
90
87
  * @returns {Promise<object>}
91
88
  */
92
- export const request = (url, opts = {}, {skipQueue} = {}) => {
93
- if (skipQueue) {
94
- return sendRequest(url, opts);
95
- }
96
-
89
+ export const request = (url, opts = {}) => {
97
90
  const queue = getQueue(new URL(url).host, opts.method);
98
91
  return queue.add(() => sendRequest(url, opts));
99
92
  };
@@ -110,41 +103,31 @@ export const requestCache = (url, opts = {}, {cacheBy, expire = 43_200} = {}) =>
110
103
  const queue = getQueue(new URL(url).host, opts.method);
111
104
 
112
105
  return queue.add(async () => {
113
- prepareRequestOpts(opts);
114
-
115
- const cacheGotResponseKeys = [
116
- 'body',
117
- 'headers',
118
- 'method',
119
- 'statusCode',
120
- 'statusMessage',
121
- 'timings',
122
- ];
123
-
124
106
  const cacheKey = `${url}::${JSON.stringify(cacheBy || opts)}`;
125
- const log = `${blue(url)}\n${dim(cacheKey)}`;
107
+ const urlLog = `${blue(url)}\n${dim(cacheKey)}`;
126
108
 
127
109
  try {
128
- if (cache.has(cacheKey)) {
129
- const {cachedResponse, date} = cache.get(cacheKey);
110
+ if (gotCache.has(cacheKey)) {
111
+ const {cachedResponse, date} = gotCache.get(cacheKey);
130
112
 
131
113
  const measurement = 'seconds';
132
114
  const currentDiff = Math.round((Date.now() - date) / 1000);
115
+ const diffLog = `${currentDiff}/${expire} ${measurement} left`;
133
116
 
134
117
  if (currentDiff < expire) {
135
- debug(`${green('FROM CACHE')} :: ${currentDiff}/${expire} ${measurement} left :: ${log}`);
118
+ cacheDebug([green('FROM CACHE'), diffLog, urlLog]);
136
119
  return {cacheKey, ...cachedResponse};
137
120
  }
138
121
 
139
- debug(`${red('CACHE EXPIRED')} :: ${currentDiff}/${expire} ${measurement} left :: ${log}`);
122
+ cacheDebug([yellow('CACHE EXPIRED'), diffLog, urlLog]);
140
123
  } else {
141
- debug(`${yellow('CACHE NOT FOUND')} :: ${log}`);
124
+ cacheDebug([blue('CACHE NOT FOUND'), urlLog]);
142
125
  }
143
126
  } catch (err) {
144
- debug(`${red('CACHE ERROR')} :: ${dim(err)} :: ${log}`);
127
+ cacheDebug([red('CACHE ERROR'), dim(err), urlLog]);
145
128
  }
146
129
 
147
- const res = await request(url, opts, {skipQueue: true});
130
+ const res = await sendRequest(url, opts);
148
131
 
149
132
  const cachedResponse = {};
150
133
 
@@ -152,8 +135,8 @@ export const requestCache = (url, opts = {}, {cacheBy, expire = 43_200} = {}) =>
152
135
  cachedResponse[key] = res[key];
153
136
  });
154
137
 
155
- cache.set(cacheKey, {date: Date.now(), cachedResponse});
156
- debug(`${cyan('CACHE SAVED')} :: ${log}`);
138
+ gotCache.set(cacheKey, {date: Date.now(), cachedResponse});
139
+ cacheDebug([cyan('CACHE SAVED'), urlLog]);
157
140
 
158
141
  return res;
159
142
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k03mad/request",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Request library",
5
5
  "maintainers": [
6
6
  "Kirill Molchanov <k03.mad@gmail.com"
@@ -20,7 +20,7 @@
20
20
  "pretty-bytes": "6.1.1"
21
21
  },
22
22
  "devDependencies": {
23
- "@k03mad/eslint-config": "12.0.5",
23
+ "@k03mad/eslint-config": "12.0.6",
24
24
  "@microsoft/eslint-formatter-sarif": "3.0.0",
25
25
  "eslint": "8.46.0",
26
26
  "eslint-plugin-import": "2.28.0",