@webex/http-core 2.59.3-next.1 → 2.59.4

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.
Files changed (43) hide show
  1. package/.eslintrc.js +6 -6
  2. package/README.md +64 -64
  3. package/babel.config.js +3 -3
  4. package/dist/http-error-subtypes.js +57 -57
  5. package/dist/http-error-subtypes.js.map +1 -1
  6. package/dist/http-error.js +25 -25
  7. package/dist/http-error.js.map +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/interceptors/http-status.js +13 -13
  10. package/dist/interceptors/http-status.js.map +1 -1
  11. package/dist/lib/detect.js +6 -6
  12. package/dist/lib/detect.js.map +1 -1
  13. package/dist/lib/interceptor.js +34 -34
  14. package/dist/lib/interceptor.js.map +1 -1
  15. package/dist/lib/xhr.js +2 -2
  16. package/dist/lib/xhr.js.map +1 -1
  17. package/dist/progress-event.js +6 -6
  18. package/dist/progress-event.js.map +1 -1
  19. package/dist/request/index.js +11 -11
  20. package/dist/request/index.js.map +1 -1
  21. package/dist/request/request.js +14 -14
  22. package/dist/request/request.js.map +1 -1
  23. package/dist/request/request.shim.js +65 -65
  24. package/dist/request/request.shim.js.map +1 -1
  25. package/jest.config.js +3 -3
  26. package/package.json +17 -18
  27. package/process +1 -1
  28. package/src/http-error-subtypes.js +187 -187
  29. package/src/http-error.js +147 -147
  30. package/src/index.js +58 -58
  31. package/src/interceptors/http-status.js +63 -63
  32. package/src/lib/detect.js +33 -33
  33. package/src/lib/interceptor.js +95 -95
  34. package/src/lib/xhr.js +258 -258
  35. package/src/progress-event.js +37 -37
  36. package/src/request/index.js +62 -62
  37. package/src/request/request.js +109 -109
  38. package/src/request/request.shim.js +304 -304
  39. package/test/integration/spec/http-error.js +188 -188
  40. package/test/integration/spec/interceptor.js +71 -71
  41. package/test/integration/spec/progress-event.js +83 -83
  42. package/test/integration/spec/request.js +310 -310
  43. package/test/unit/spec/interceptors/http-status.js +49 -49
@@ -1,304 +1,304 @@
1
- /* eslint-disable no-underscore-dangle */
2
- /*!
3
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
4
- */
5
-
6
- /* eslint-env browser */
7
-
8
- // Note: several code paths are ignored in this file. As far as I can tell, any
9
- // error conditions that would provoke those paths are otherwise prevented and
10
- // reported.
11
-
12
- import {defaults, isArray, pick} from 'lodash';
13
- import qs from 'qs';
14
-
15
- import xhr from '../lib/xhr';
16
- import detect from '../lib/detect';
17
-
18
- /**
19
- * @name request
20
- * @param {Object} options
21
- * @returns {Promise}
22
- */
23
- export default function _request(options) {
24
- return new Promise((resolve) => {
25
- const params = pick(
26
- options,
27
- 'method',
28
- 'uri',
29
- 'withCredentials',
30
- 'headers',
31
- 'timeout',
32
- 'responseType'
33
- );
34
-
35
- // Set `response` to `true` to approximate an `HttpResponse` object
36
- params.response = true;
37
-
38
- setXhr(params);
39
- bindProgressEvents(params, options);
40
- setAuth(params, options);
41
- setCookies(params, options);
42
- setDefaults(params, options);
43
- setResponseType(params, options);
44
- setContentType(params, options);
45
- setPayload(params, options);
46
- setQs(params, options);
47
-
48
- options.logger.debug(
49
- `start http ${options.method ? options.method : 'request'} to ${options.uri}`
50
- );
51
-
52
- const x = xhr(params, (error, response) => {
53
- /* istanbul ignore next */
54
- if (error) {
55
- options.logger.warn(error);
56
- }
57
-
58
- /* istanbul ignore else */
59
- if (response) {
60
- if (response.statusCode >= 400) {
61
- options.logger.warn(
62
- `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
63
- response.statusCode
64
- }`
65
- );
66
- } else {
67
- options.logger.debug(
68
- `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
69
- response.statusCode
70
- }`
71
- );
72
- }
73
- response.options = options;
74
- processResponseJson(response, params);
75
- resolve(response);
76
- } else {
77
- resolve({
78
- statusCode: 0,
79
- options,
80
- headers: options.headers,
81
- method: options.method,
82
- url: options.uri,
83
- body: error,
84
- });
85
- }
86
- });
87
-
88
- x.onprogress = options.download.emit.bind(options.download, 'progress');
89
- }).catch((error) => {
90
- options.logger.warn(error);
91
-
92
- /* eslint arrow-body-style: [0] */
93
- /* istanbul ignore next */
94
- return {
95
- statusCode: 0,
96
- options,
97
- headers: options.headers,
98
- method: options.method,
99
- url: options.uri,
100
- body: error,
101
- };
102
- });
103
-
104
- /**
105
- * @param {Object} params
106
- * @param {Object} o
107
- * @private
108
- * @returns {undefined}
109
- */
110
- function bindProgressEvents(params, o) {
111
- if (params.method && ['PATCH', 'POST', 'PUT'].includes(params.method.toUpperCase())) {
112
- if (!params.xhr) {
113
- params.xhr = new XMLHttpRequest();
114
- }
115
- params.xhr.upload.onprogress = o.upload.emit.bind(o.upload, 'progress');
116
- }
117
- }
118
-
119
- /**
120
- * @param {Object} params
121
- * @param {Object} o
122
- * @private
123
- * @returns {undefined}
124
- */
125
- function setXhr(params) {
126
- params.xhr = new XMLHttpRequest();
127
- }
128
-
129
- /**
130
- * @param {Object} params
131
- * @param {Object} o
132
- * @private
133
- * @returns {undefined}
134
- */
135
- function setAuth(params, o) {
136
- if (o.auth) {
137
- if (o.auth.bearer) {
138
- params.headers.authorization = `Bearer ${o.auth.bearer}`;
139
- } else {
140
- const user = o.auth.user || o.auth.username;
141
- const pass = o.auth.pass || o.auth.password;
142
-
143
- const token = btoa(`${user}:${pass}`);
144
-
145
- params.headers.authorization = `Basic ${token}`;
146
- }
147
- }
148
- }
149
-
150
- /**
151
- * @param {Object} params
152
- * @param {Object} o
153
- * @private
154
- * @returns {undefined}
155
- */
156
- function setCookies(params, o) {
157
- if (o.jar) {
158
- params.withCredentials = true;
159
- }
160
- }
161
-
162
- /**
163
- * @param {Object} params
164
- * @param {Object} o
165
- * @private
166
- * @returns {undefined}
167
- */
168
- function setDefaults(params, o) {
169
- const defs = {
170
- cors: true,
171
- // raynos/xhr defaults withCredentials to true if cors is true, so we need
172
- // to make it explicitly false by default
173
- withCredentials: false,
174
- timeout: 0,
175
- };
176
-
177
- defaults(params, pick(o, Object.keys(defs)), defs);
178
- }
179
-
180
- /**
181
- * @param {Object} params
182
- * @param {Object} o
183
- * @private
184
- * @returns {undefined}
185
- */
186
- function setResponseType(params, o) {
187
- if (o.responseType === 'buffer') {
188
- params.responseType = 'arraybuffer';
189
- }
190
- }
191
-
192
- /**
193
- * @param {Object} params
194
- * @param {Object} o
195
- * @private
196
- * @returns {undefined}
197
- */
198
- async function setContentType(params, o) {
199
- if (o.body instanceof Blob || o.body instanceof ArrayBuffer) {
200
- o.json = params.json = false;
201
- params.headers['content-type'] = params.headers['content-type'] || (await detect(o.body));
202
- }
203
- }
204
-
205
- /**
206
- * @param {Object} params
207
- * @param {Object} o
208
- * @private
209
- * @returns {undefined}
210
- */
211
- function setQs(params, o) {
212
- if (o.qs) {
213
- params.uri += `?${qs.stringify(o.qs)}`;
214
- }
215
- }
216
-
217
- /**
218
- * Converts arraybuffers to blobs before uploading them
219
- * @param {mixed} file
220
- * @private
221
- * @returns {mixed}
222
- */
223
- function ensureBlob(file) {
224
- if (file instanceof ArrayBuffer) {
225
- const ret = file.type ? new Blob([file], {type: file.type}) : new Blob([file]);
226
-
227
- ret.filename = file.filename || file.name || 'untitled';
228
-
229
- return ret;
230
- }
231
-
232
- return file;
233
- }
234
-
235
- /**
236
- * Appends an item to a form
237
- * @param {FormData} form
238
- * @param {string} key
239
- * @param {mixed} value
240
- * @returns {undefined}
241
- */
242
- function append(form, key, value) {
243
- if (isArray(value)) {
244
- for (const v of value) {
245
- append(form, key, v);
246
- }
247
-
248
- return;
249
- }
250
-
251
- value = ensureBlob(value);
252
- if (value.name) {
253
- value.filename = value.name;
254
- form.append(key, value, value.name);
255
- } else {
256
- form.append(key, value);
257
- }
258
- }
259
-
260
- /**
261
- * @param {Object} params
262
- * @param {Object} o
263
- * @private
264
- * @returns {undefined}
265
- */
266
- function setPayload(params, o) {
267
- if ((!('json' in o) || o.json === true) && o.body) {
268
- params.json = o.body;
269
- } else if (o.form) {
270
- params.headers['Content-Type'] = 'application/x-www-form-urlencoded';
271
- params.body = qs.stringify(o.form);
272
- Reflect.deleteProperty(params, 'json');
273
- } else if (o.formData) {
274
- params.body = Object.keys(o.formData).reduce((fd, key) => {
275
- const value = o.formData[key];
276
-
277
- append(fd, key, value);
278
-
279
- return fd;
280
- }, new FormData());
281
- } else {
282
- params.body = o.body;
283
- Reflect.deleteProperty(params, 'json');
284
- }
285
- }
286
-
287
- /**
288
- * @param {Object} response
289
- * @param {Object} params
290
- * @private
291
- * @returns {undefined}
292
- */
293
- function processResponseJson(response, params) {
294
- // If params.json is not defined, xhr won't deserialize the response
295
- // so we should give it a shot just in case.
296
- if (!params.json && typeof response.body !== 'object') {
297
- try {
298
- response.body = JSON.parse(response.body);
299
- } catch (e) {
300
- /* eslint no-empty: [0] */
301
- }
302
- }
303
- }
304
- }
1
+ /* eslint-disable no-underscore-dangle */
2
+ /*!
3
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
4
+ */
5
+
6
+ /* eslint-env browser */
7
+
8
+ // Note: several code paths are ignored in this file. As far as I can tell, any
9
+ // error conditions that would provoke those paths are otherwise prevented and
10
+ // reported.
11
+
12
+ import {defaults, isArray, pick} from 'lodash';
13
+ import qs from 'qs';
14
+
15
+ import xhr from '../lib/xhr';
16
+ import detect from '../lib/detect';
17
+
18
+ /**
19
+ * @name request
20
+ * @param {Object} options
21
+ * @returns {Promise}
22
+ */
23
+ export default function _request(options) {
24
+ return new Promise((resolve) => {
25
+ const params = pick(
26
+ options,
27
+ 'method',
28
+ 'uri',
29
+ 'withCredentials',
30
+ 'headers',
31
+ 'timeout',
32
+ 'responseType'
33
+ );
34
+
35
+ // Set `response` to `true` to approximate an `HttpResponse` object
36
+ params.response = true;
37
+
38
+ setXhr(params);
39
+ bindProgressEvents(params, options);
40
+ setAuth(params, options);
41
+ setCookies(params, options);
42
+ setDefaults(params, options);
43
+ setResponseType(params, options);
44
+ setContentType(params, options);
45
+ setPayload(params, options);
46
+ setQs(params, options);
47
+
48
+ options.logger.debug(
49
+ `start http ${options.method ? options.method : 'request'} to ${options.uri}`
50
+ );
51
+
52
+ const x = xhr(params, (error, response) => {
53
+ /* istanbul ignore next */
54
+ if (error) {
55
+ options.logger.warn(error);
56
+ }
57
+
58
+ /* istanbul ignore else */
59
+ if (response) {
60
+ if (response.statusCode >= 400) {
61
+ options.logger.warn(
62
+ `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
63
+ response.statusCode
64
+ }`
65
+ );
66
+ } else {
67
+ options.logger.debug(
68
+ `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
69
+ response.statusCode
70
+ }`
71
+ );
72
+ }
73
+ response.options = options;
74
+ processResponseJson(response, params);
75
+ resolve(response);
76
+ } else {
77
+ resolve({
78
+ statusCode: 0,
79
+ options,
80
+ headers: options.headers,
81
+ method: options.method,
82
+ url: options.uri,
83
+ body: error,
84
+ });
85
+ }
86
+ });
87
+
88
+ x.onprogress = options.download.emit.bind(options.download, 'progress');
89
+ }).catch((error) => {
90
+ options.logger.warn(error);
91
+
92
+ /* eslint arrow-body-style: [0] */
93
+ /* istanbul ignore next */
94
+ return {
95
+ statusCode: 0,
96
+ options,
97
+ headers: options.headers,
98
+ method: options.method,
99
+ url: options.uri,
100
+ body: error,
101
+ };
102
+ });
103
+
104
+ /**
105
+ * @param {Object} params
106
+ * @param {Object} o
107
+ * @private
108
+ * @returns {undefined}
109
+ */
110
+ function bindProgressEvents(params, o) {
111
+ if (params.method && ['PATCH', 'POST', 'PUT'].includes(params.method.toUpperCase())) {
112
+ if (!params.xhr) {
113
+ params.xhr = new XMLHttpRequest();
114
+ }
115
+ params.xhr.upload.onprogress = o.upload.emit.bind(o.upload, 'progress');
116
+ }
117
+ }
118
+
119
+ /**
120
+ * @param {Object} params
121
+ * @param {Object} o
122
+ * @private
123
+ * @returns {undefined}
124
+ */
125
+ function setXhr(params) {
126
+ params.xhr = new XMLHttpRequest();
127
+ }
128
+
129
+ /**
130
+ * @param {Object} params
131
+ * @param {Object} o
132
+ * @private
133
+ * @returns {undefined}
134
+ */
135
+ function setAuth(params, o) {
136
+ if (o.auth) {
137
+ if (o.auth.bearer) {
138
+ params.headers.authorization = `Bearer ${o.auth.bearer}`;
139
+ } else {
140
+ const user = o.auth.user || o.auth.username;
141
+ const pass = o.auth.pass || o.auth.password;
142
+
143
+ const token = btoa(`${user}:${pass}`);
144
+
145
+ params.headers.authorization = `Basic ${token}`;
146
+ }
147
+ }
148
+ }
149
+
150
+ /**
151
+ * @param {Object} params
152
+ * @param {Object} o
153
+ * @private
154
+ * @returns {undefined}
155
+ */
156
+ function setCookies(params, o) {
157
+ if (o.jar) {
158
+ params.withCredentials = true;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * @param {Object} params
164
+ * @param {Object} o
165
+ * @private
166
+ * @returns {undefined}
167
+ */
168
+ function setDefaults(params, o) {
169
+ const defs = {
170
+ cors: true,
171
+ // raynos/xhr defaults withCredentials to true if cors is true, so we need
172
+ // to make it explicitly false by default
173
+ withCredentials: false,
174
+ timeout: 0,
175
+ };
176
+
177
+ defaults(params, pick(o, Object.keys(defs)), defs);
178
+ }
179
+
180
+ /**
181
+ * @param {Object} params
182
+ * @param {Object} o
183
+ * @private
184
+ * @returns {undefined}
185
+ */
186
+ function setResponseType(params, o) {
187
+ if (o.responseType === 'buffer') {
188
+ params.responseType = 'arraybuffer';
189
+ }
190
+ }
191
+
192
+ /**
193
+ * @param {Object} params
194
+ * @param {Object} o
195
+ * @private
196
+ * @returns {undefined}
197
+ */
198
+ async function setContentType(params, o) {
199
+ if (o.body instanceof Blob || o.body instanceof ArrayBuffer) {
200
+ o.json = params.json = false;
201
+ params.headers['content-type'] = params.headers['content-type'] || (await detect(o.body));
202
+ }
203
+ }
204
+
205
+ /**
206
+ * @param {Object} params
207
+ * @param {Object} o
208
+ * @private
209
+ * @returns {undefined}
210
+ */
211
+ function setQs(params, o) {
212
+ if (o.qs) {
213
+ params.uri += `?${qs.stringify(o.qs)}`;
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Converts arraybuffers to blobs before uploading them
219
+ * @param {mixed} file
220
+ * @private
221
+ * @returns {mixed}
222
+ */
223
+ function ensureBlob(file) {
224
+ if (file instanceof ArrayBuffer) {
225
+ const ret = file.type ? new Blob([file], {type: file.type}) : new Blob([file]);
226
+
227
+ ret.filename = file.filename || file.name || 'untitled';
228
+
229
+ return ret;
230
+ }
231
+
232
+ return file;
233
+ }
234
+
235
+ /**
236
+ * Appends an item to a form
237
+ * @param {FormData} form
238
+ * @param {string} key
239
+ * @param {mixed} value
240
+ * @returns {undefined}
241
+ */
242
+ function append(form, key, value) {
243
+ if (isArray(value)) {
244
+ for (const v of value) {
245
+ append(form, key, v);
246
+ }
247
+
248
+ return;
249
+ }
250
+
251
+ value = ensureBlob(value);
252
+ if (value.name) {
253
+ value.filename = value.name;
254
+ form.append(key, value, value.name);
255
+ } else {
256
+ form.append(key, value);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * @param {Object} params
262
+ * @param {Object} o
263
+ * @private
264
+ * @returns {undefined}
265
+ */
266
+ function setPayload(params, o) {
267
+ if ((!('json' in o) || o.json === true) && o.body) {
268
+ params.json = o.body;
269
+ } else if (o.form) {
270
+ params.headers['Content-Type'] = 'application/x-www-form-urlencoded';
271
+ params.body = qs.stringify(o.form);
272
+ Reflect.deleteProperty(params, 'json');
273
+ } else if (o.formData) {
274
+ params.body = Object.keys(o.formData).reduce((fd, key) => {
275
+ const value = o.formData[key];
276
+
277
+ append(fd, key, value);
278
+
279
+ return fd;
280
+ }, new FormData());
281
+ } else {
282
+ params.body = o.body;
283
+ Reflect.deleteProperty(params, 'json');
284
+ }
285
+ }
286
+
287
+ /**
288
+ * @param {Object} response
289
+ * @param {Object} params
290
+ * @private
291
+ * @returns {undefined}
292
+ */
293
+ function processResponseJson(response, params) {
294
+ // If params.json is not defined, xhr won't deserialize the response
295
+ // so we should give it a shot just in case.
296
+ if (!params.json && typeof response.body !== 'object') {
297
+ try {
298
+ response.body = JSON.parse(response.body);
299
+ } catch (e) {
300
+ /* eslint no-empty: [0] */
301
+ }
302
+ }
303
+ }
304
+ }