@webex/http-core 3.0.0-beta.3 → 3.0.0-beta.300

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 (45) hide show
  1. package/README.md +0 -1
  2. package/dist/http-error-subtypes.js +2 -147
  3. package/dist/http-error-subtypes.js.map +1 -1
  4. package/dist/http-error.js +9 -38
  5. package/dist/http-error.js.map +1 -1
  6. package/dist/index.js +54 -30
  7. package/dist/index.js.map +1 -1
  8. package/dist/interceptors/http-status.js +7 -30
  9. package/dist/interceptors/http-status.js.map +1 -1
  10. package/dist/lib/detect.js +28 -48
  11. package/dist/lib/detect.js.map +1 -1
  12. package/dist/lib/interceptor.js +7 -23
  13. package/dist/lib/interceptor.js.map +1 -1
  14. package/dist/lib/xhr.js +49 -93
  15. package/dist/lib/xhr.js.map +1 -1
  16. package/dist/progress-event.js +0 -7
  17. package/dist/progress-event.js.map +1 -1
  18. package/dist/request/index.js +3 -44
  19. package/dist/request/index.js.map +1 -1
  20. package/dist/request/request.js +5 -23
  21. package/dist/request/request.js.map +1 -1
  22. package/dist/request/request.shim.js +39 -91
  23. package/dist/request/request.shim.js.map +1 -1
  24. package/dist/request/utils.js +91 -0
  25. package/dist/request/utils.js.map +1 -0
  26. package/package.json +10 -10
  27. package/src/http-error-subtypes.js +1 -1
  28. package/src/http-error.js +15 -23
  29. package/src/index.js +59 -9
  30. package/src/interceptors/http-status.js +7 -5
  31. package/src/lib/detect.js +0 -1
  32. package/src/lib/interceptor.js +2 -4
  33. package/src/lib/xhr.js +201 -194
  34. package/src/progress-event.js +10 -5
  35. package/src/request/index.js +4 -36
  36. package/src/request/request.js +16 -14
  37. package/src/request/request.shim.js +51 -39
  38. package/src/request/utils.ts +78 -0
  39. package/test/integration/spec/http-error.js +11 -11
  40. package/test/integration/spec/interceptor.js +20 -13
  41. package/test/integration/spec/progress-event.js +8 -8
  42. package/test/integration/spec/request.js +136 -127
  43. package/test/unit/spec/index.js +58 -0
  44. package/test/unit/spec/interceptors/http-status.js +14 -11
  45. package/test/unit/spec/request/utils.js +77 -0
@@ -22,7 +22,15 @@ import detect from '../lib/detect';
22
22
  */
23
23
  export default function _request(options) {
24
24
  return new Promise((resolve) => {
25
- const params = pick(options, 'method', 'uri', 'withCredentials', 'headers', 'timeout', 'responseType');
25
+ const params = pick(
26
+ options,
27
+ 'method',
28
+ 'uri',
29
+ 'withCredentials',
30
+ 'headers',
31
+ 'timeout',
32
+ 'responseType'
33
+ );
26
34
 
27
35
  // Set `response` to `true` to approximate an `HttpResponse` object
28
36
  params.response = true;
@@ -37,54 +45,64 @@ export default function _request(options) {
37
45
  setPayload(params, options);
38
46
  setQs(params, options);
39
47
 
40
- options.logger.debug(`start http ${options.method ? options.method : 'request'} to ${options.uri}`);
48
+ options.logger.debug(
49
+ `start http ${options.method ? options.method : 'request'} to ${options.uri}`
50
+ );
41
51
 
42
52
  const x = xhr(params, (error, response) => {
43
53
  /* istanbul ignore next */
44
54
  if (error) {
45
- options.logger.warn(error);
55
+ options.logger.warn(
56
+ `XHR error for ${options.method || 'request'} to ${options.uri} :`,
57
+ error
58
+ );
46
59
  }
47
60
 
48
61
  /* istanbul ignore else */
49
62
  if (response) {
50
63
  if (response.statusCode >= 400) {
51
- options.logger.warn(`http ${options.method ? options.method : 'request'} to ${options.uri} result: ${response.statusCode}`);
52
- }
53
- else {
54
- options.logger.debug(`http ${options.method ? options.method : 'request'} to ${options.uri} result: ${response.statusCode}`);
64
+ options.logger.warn(
65
+ `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
66
+ response.statusCode
67
+ }`
68
+ );
69
+ } else {
70
+ options.logger.debug(
71
+ `http ${options.method ? options.method : 'request'} to ${options.uri} result: ${
72
+ response.statusCode
73
+ }`
74
+ );
55
75
  }
56
76
  response.options = options;
57
77
  processResponseJson(response, params);
58
78
  resolve(response);
59
- }
60
- else {
79
+ } else {
61
80
  resolve({
62
81
  statusCode: 0,
63
82
  options,
64
83
  headers: options.headers,
65
84
  method: options.method,
66
85
  url: options.uri,
67
- body: error
86
+ body: error,
68
87
  });
69
88
  }
70
89
  });
71
90
 
72
91
  x.onprogress = options.download.emit.bind(options.download, 'progress');
73
- })
74
- .catch((error) => {
75
- options.logger.warn(error);
76
-
77
- /* eslint arrow-body-style: [0] */
78
- /* istanbul ignore next */
79
- return {
80
- statusCode: 0,
81
- options,
82
- headers: options.headers,
83
- method: options.method,
84
- url: options.uri,
85
- body: error
86
- };
87
- });
92
+ }).catch((error) => {
93
+ options.logger.warn(error);
94
+
95
+ /* eslint arrow-body-style: [0] */
96
+ /* istanbul ignore next */
97
+ return {
98
+ statusCode: 0,
99
+ options,
100
+ headers: options.headers,
101
+ method: options.method,
102
+ url: options.uri,
103
+ body: error,
104
+ };
105
+ });
88
106
 
89
107
  /**
90
108
  * @param {Object} params
@@ -121,8 +139,7 @@ export default function _request(options) {
121
139
  if (o.auth) {
122
140
  if (o.auth.bearer) {
123
141
  params.headers.authorization = `Bearer ${o.auth.bearer}`;
124
- }
125
- else {
142
+ } else {
126
143
  const user = o.auth.user || o.auth.username;
127
144
  const pass = o.auth.pass || o.auth.password;
128
145
 
@@ -157,7 +174,7 @@ export default function _request(options) {
157
174
  // raynos/xhr defaults withCredentials to true if cors is true, so we need
158
175
  // to make it explicitly false by default
159
176
  withCredentials: false,
160
- timeout: 0
177
+ timeout: 0,
161
178
  };
162
179
 
163
180
  defaults(params, pick(o, Object.keys(defs)), defs);
@@ -184,7 +201,7 @@ export default function _request(options) {
184
201
  async function setContentType(params, o) {
185
202
  if (o.body instanceof Blob || o.body instanceof ArrayBuffer) {
186
203
  o.json = params.json = false;
187
- params.headers['content-type'] = params.headers['content-type'] || await detect(o.body);
204
+ params.headers['content-type'] = params.headers['content-type'] || (await detect(o.body));
188
205
  }
189
206
  }
190
207
 
@@ -238,8 +255,7 @@ export default function _request(options) {
238
255
  if (value.name) {
239
256
  value.filename = value.name;
240
257
  form.append(key, value, value.name);
241
- }
242
- else {
258
+ } else {
243
259
  form.append(key, value);
244
260
  }
245
261
  }
@@ -253,13 +269,11 @@ export default function _request(options) {
253
269
  function setPayload(params, o) {
254
270
  if ((!('json' in o) || o.json === true) && o.body) {
255
271
  params.json = o.body;
256
- }
257
- else if (o.form) {
272
+ } else if (o.form) {
258
273
  params.headers['Content-Type'] = 'application/x-www-form-urlencoded';
259
274
  params.body = qs.stringify(o.form);
260
275
  Reflect.deleteProperty(params, 'json');
261
- }
262
- else if (o.formData) {
276
+ } else if (o.formData) {
263
277
  params.body = Object.keys(o.formData).reduce((fd, key) => {
264
278
  const value = o.formData[key];
265
279
 
@@ -267,8 +281,7 @@ export default function _request(options) {
267
281
 
268
282
  return fd;
269
283
  }, new FormData());
270
- }
271
- else {
284
+ } else {
272
285
  params.body = o.body;
273
286
  Reflect.deleteProperty(params, 'json');
274
287
  }
@@ -286,8 +299,7 @@ export default function _request(options) {
286
299
  if (!params.json && typeof response.body !== 'object') {
287
300
  try {
288
301
  response.body = JSON.parse(response.body);
289
- }
290
- catch (e) {
302
+ } catch (e) {
291
303
  /* eslint no-empty: [0] */
292
304
  }
293
305
  }
@@ -0,0 +1,78 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ import {EventEmitter} from 'events';
3
+ import Interceptor from '../lib/interceptor';
4
+
5
+ /**
6
+ * @param {Object} options
7
+ * @param {Array<Object>} interceptors
8
+ * @param {string} key
9
+ * @param {Object | undefined} res
10
+ * @private
11
+ * @returns {Promise}
12
+ */
13
+ export function intercept(
14
+ options: object,
15
+ interceptors: Array<Interceptor>,
16
+ key: string,
17
+ res: object = undefined
18
+ ): Promise<any> {
19
+ const successKey = `on${key}`;
20
+ const errorKey = `on${key}Error`;
21
+
22
+ return interceptors.reduce(
23
+ (promise, interceptor) =>
24
+ promise.then(
25
+ (result) => {
26
+ interceptor.logOptions(options);
27
+ if (interceptor[successKey]) {
28
+ return interceptor[successKey](options, result);
29
+ }
30
+
31
+ return Promise.resolve(result);
32
+ },
33
+ (reason) => {
34
+ interceptor.logOptions(options);
35
+ if (interceptor[errorKey]) {
36
+ return interceptor[errorKey](options, reason);
37
+ }
38
+
39
+ return Promise.reject(reason);
40
+ }
41
+ ),
42
+ Promise.resolve(res)
43
+ );
44
+ }
45
+
46
+ /**
47
+ * Prepare options for a fetch.
48
+ * @param {object} options
49
+ * @returns {Promise}
50
+ */
51
+ export async function prepareFetchOptions(options: any): Promise<any> {
52
+ if (options.url) {
53
+ options.uri = options.url;
54
+ options.url = null;
55
+ }
56
+
57
+ options.headers = options.headers || {};
58
+
59
+ if (options.json) {
60
+ // don't override existing accept header declared by user
61
+ options.headers.accept = options.headers.accept || options.headers.Accept || 'application/json';
62
+
63
+ // don't override existing content-type header declared by user
64
+ if (options.method !== 'GET' && options.method !== 'HEAD') {
65
+ options.headers['content-type'] =
66
+ options.headers['content-type'] || options.headers['Content-Type'] || 'application/json';
67
+ options.body = JSON.stringify(options.json === true ? options.body : options.json);
68
+ }
69
+ } else if (options.json !== undefined) {
70
+ Reflect.deleteProperty(options, 'json');
71
+ }
72
+
73
+ options.download = new EventEmitter();
74
+ options.upload = new EventEmitter();
75
+ options.keepalive = true;
76
+
77
+ return intercept(options, options.interceptors, 'Request').then(() => options);
78
+ }
@@ -71,7 +71,7 @@ describe('http-core', () => {
71
71
 
72
72
  it('falls back to a default error message', () => {
73
73
  const res = {
74
- statusCode: 400
74
+ statusCode: 400,
75
75
  };
76
76
 
77
77
  const error = new HttpError(res);
@@ -83,7 +83,7 @@ describe('http-core', () => {
83
83
  const message = 'an error occurred';
84
84
  const res = {
85
85
  statusCode: 400,
86
- body: message
86
+ body: message,
87
87
  };
88
88
 
89
89
  const error = new HttpError(res);
@@ -93,12 +93,12 @@ describe('http-core', () => {
93
93
 
94
94
  it('parses JSON responses', () => {
95
95
  const message = {
96
- data: 'an error'
96
+ data: 'an error',
97
97
  };
98
98
 
99
99
  const res = {
100
100
  statusCode: 400,
101
- body: message
101
+ body: message,
102
102
  };
103
103
 
104
104
  const error = new HttpError(res);
@@ -108,12 +108,12 @@ describe('http-core', () => {
108
108
 
109
109
  it('parses stringified JSON responses', () => {
110
110
  const message = JSON.stringify({
111
- data: 'an error'
111
+ data: 'an error',
112
112
  });
113
113
 
114
114
  const res = {
115
115
  statusCode: 400,
116
- body: message
116
+ body: message,
117
117
  };
118
118
 
119
119
  const error = new HttpError(res);
@@ -126,8 +126,8 @@ describe('http-core', () => {
126
126
  const res = {
127
127
  statusCode: 400,
128
128
  body: {
129
- error: message
130
- }
129
+ error: message,
130
+ },
131
131
  };
132
132
 
133
133
  const error = new HttpError(res);
@@ -141,9 +141,9 @@ describe('http-core', () => {
141
141
  statusCode: 400,
142
142
  body: {
143
143
  error: {
144
- errorString: message
145
- }
146
- }
144
+ errorString: message,
145
+ },
146
+ },
147
147
  };
148
148
 
149
149
  const error = new HttpError(res);
@@ -13,15 +13,21 @@ describe('http-core', () => {
13
13
  describe('interceptor', () => {
14
14
  let webex;
15
15
 
16
- before('create users', () => testUsers.create({count: 1})
17
- .then(([user]) => new Promise((resolve) => {
18
- setTimeout(() => resolve(user), 3000);
19
- }))
20
- .then((user) => {
21
- webex = new WebexCore({credentials: user.token});
22
- })
23
- .then(() => webex.internal.device.register())
24
- .then(() => webex.internal.services.waitForCatalog('postauth', 10)));
16
+ before('create users', () =>
17
+ testUsers
18
+ .create({count: 1})
19
+ .then(
20
+ ([user]) =>
21
+ new Promise((resolve) => {
22
+ setTimeout(() => resolve(user), 3000);
23
+ })
24
+ )
25
+ .then((user) => {
26
+ webex = new WebexCore({credentials: user.token});
27
+ })
28
+ .then(() => webex.internal.device.register())
29
+ .then(() => webex.internal.services.waitForCatalog('postauth', 10))
30
+ );
25
31
 
26
32
  describe('logOptions', () => {
27
33
  let flagged;
@@ -46,10 +52,11 @@ describe('http-core', () => {
46
52
  it('calls logger plugin', () => {
47
53
  const spy = sinon.spy(webex.logger, 'info');
48
54
 
49
- return webex.request({
50
- service: 'hydra',
51
- resource: 'people/me'
52
- })
55
+ return webex
56
+ .request({
57
+ service: 'hydra',
58
+ resource: 'people/me',
59
+ })
53
60
  .then(() => {
54
61
  assert.called(spy);
55
62
  });
@@ -47,35 +47,35 @@ describe('http-core', () => {
47
47
  {
48
48
  loaded: undefined,
49
49
  total: undefined,
50
- result: false
50
+ result: false,
51
51
  },
52
52
  {
53
53
  loaded: 10,
54
54
  total: undefined,
55
- result: false
55
+ result: false,
56
56
  },
57
57
  {
58
58
  loaded: undefined,
59
59
  total: 10,
60
- result: false
60
+ result: false,
61
61
  },
62
62
  {
63
63
  loaded: 10,
64
64
  total: 10,
65
- result: true
65
+ result: true,
66
66
  },
67
67
  {
68
68
  loaded: 10,
69
69
  total: 0,
70
- result: false
70
+ result: false,
71
71
  },
72
72
  {
73
73
  loaded: 0,
74
74
  total: 0,
75
- result: false
76
- }
75
+ result: false,
76
+ },
77
77
  ].forEach((item) => {
78
- assert.equal((new ProgressEvent(item.loaded, item.total)).lengthComputable, item.result);
78
+ assert.equal(new ProgressEvent(item.loaded, item.total).lengthComputable, item.result);
79
79
  });
80
80
  });
81
81
  });