@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
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+
3
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
5
+ _Object$defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.intercept = intercept;
9
+ exports.prepareFetchOptions = prepareFetchOptions;
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
11
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
12
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
13
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
14
+ var _deleteProperty = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/delete-property"));
15
+ var _events = require("events");
16
+ /* eslint-disable import/prefer-default-export */
17
+
18
+ /**
19
+ * @param {Object} options
20
+ * @param {Array<Object>} interceptors
21
+ * @param {string} key
22
+ * @param {Object | undefined} res
23
+ * @private
24
+ * @returns {Promise}
25
+ */
26
+ function intercept(options, interceptors, key) {
27
+ var res = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
28
+ var successKey = "on".concat(key);
29
+ var errorKey = "on".concat(key, "Error");
30
+ return interceptors.reduce(function (promise, interceptor) {
31
+ return promise.then(function (result) {
32
+ interceptor.logOptions(options);
33
+ if (interceptor[successKey]) {
34
+ return interceptor[successKey](options, result);
35
+ }
36
+ return _promise.default.resolve(result);
37
+ }, function (reason) {
38
+ interceptor.logOptions(options);
39
+ if (interceptor[errorKey]) {
40
+ return interceptor[errorKey](options, reason);
41
+ }
42
+ return _promise.default.reject(reason);
43
+ });
44
+ }, _promise.default.resolve(res));
45
+ }
46
+
47
+ /**
48
+ * Prepare options for a fetch.
49
+ * @param {object} options
50
+ * @returns {Promise}
51
+ */
52
+ function prepareFetchOptions(_x) {
53
+ return _prepareFetchOptions.apply(this, arguments);
54
+ }
55
+ function _prepareFetchOptions() {
56
+ _prepareFetchOptions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(options) {
57
+ return _regenerator.default.wrap(function _callee$(_context) {
58
+ while (1) switch (_context.prev = _context.next) {
59
+ case 0:
60
+ if (options.url) {
61
+ options.uri = options.url;
62
+ options.url = null;
63
+ }
64
+ options.headers = options.headers || {};
65
+ if (options.json) {
66
+ // don't override existing accept header declared by user
67
+ options.headers.accept = options.headers.accept || options.headers.Accept || 'application/json';
68
+
69
+ // don't override existing content-type header declared by user
70
+ if (options.method !== 'GET' && options.method !== 'HEAD') {
71
+ options.headers['content-type'] = options.headers['content-type'] || options.headers['Content-Type'] || 'application/json';
72
+ options.body = (0, _stringify.default)(options.json === true ? options.body : options.json);
73
+ }
74
+ } else if (options.json !== undefined) {
75
+ (0, _deleteProperty.default)(options, 'json');
76
+ }
77
+ options.download = new _events.EventEmitter();
78
+ options.upload = new _events.EventEmitter();
79
+ options.keepalive = true;
80
+ return _context.abrupt("return", intercept(options, options.interceptors, 'Request').then(function () {
81
+ return options;
82
+ }));
83
+ case 7:
84
+ case "end":
85
+ return _context.stop();
86
+ }
87
+ }, _callee);
88
+ }));
89
+ return _prepareFetchOptions.apply(this, arguments);
90
+ }
91
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["intercept","options","interceptors","key","res","undefined","successKey","errorKey","reduce","promise","interceptor","then","result","logOptions","resolve","reason","reject","prepareFetchOptions","url","uri","headers","json","accept","Accept","method","body","download","EventEmitter","upload","keepalive"],"sources":["utils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\nimport {EventEmitter} from 'events';\nimport Interceptor from '../lib/interceptor';\n\n/**\n * @param {Object} options\n * @param {Array<Object>} interceptors\n * @param {string} key\n * @param {Object | undefined} res\n * @private\n * @returns {Promise}\n */\nexport function intercept(\n options: object,\n interceptors: Array<Interceptor>,\n key: string,\n res: object = undefined\n): Promise<any> {\n const successKey = `on${key}`;\n const errorKey = `on${key}Error`;\n\n return interceptors.reduce(\n (promise, interceptor) =>\n promise.then(\n (result) => {\n interceptor.logOptions(options);\n if (interceptor[successKey]) {\n return interceptor[successKey](options, result);\n }\n\n return Promise.resolve(result);\n },\n (reason) => {\n interceptor.logOptions(options);\n if (interceptor[errorKey]) {\n return interceptor[errorKey](options, reason);\n }\n\n return Promise.reject(reason);\n }\n ),\n Promise.resolve(res)\n );\n}\n\n/**\n * Prepare options for a fetch.\n * @param {object} options\n * @returns {Promise}\n */\nexport async function prepareFetchOptions(options: any): Promise<any> {\n if (options.url) {\n options.uri = options.url;\n options.url = null;\n }\n\n options.headers = options.headers || {};\n\n if (options.json) {\n // don't override existing accept header declared by user\n options.headers.accept = options.headers.accept || options.headers.Accept || 'application/json';\n\n // don't override existing content-type header declared by user\n if (options.method !== 'GET' && options.method !== 'HEAD') {\n options.headers['content-type'] =\n options.headers['content-type'] || options.headers['Content-Type'] || 'application/json';\n options.body = JSON.stringify(options.json === true ? options.body : options.json);\n }\n } else if (options.json !== undefined) {\n Reflect.deleteProperty(options, 'json');\n }\n\n options.download = new EventEmitter();\n options.upload = new EventEmitter();\n options.keepalive = true;\n\n return intercept(options, options.interceptors, 'Request').then(() => options);\n}\n"],"mappings":";;;;;;;;;;;;;;AACA;AADA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,SAAS,CACvBC,OAAe,EACfC,YAAgC,EAChCC,GAAW,EAEG;EAAA,IADdC,GAAW,uEAAGC,SAAS;EAEvB,IAAMC,UAAU,eAAQH,GAAG,CAAE;EAC7B,IAAMI,QAAQ,eAAQJ,GAAG,UAAO;EAEhC,OAAOD,YAAY,CAACM,MAAM,CACxB,UAACC,OAAO,EAAEC,WAAW;IAAA,OACnBD,OAAO,CAACE,IAAI,CACV,UAACC,MAAM,EAAK;MACVF,WAAW,CAACG,UAAU,CAACZ,OAAO,CAAC;MAC/B,IAAIS,WAAW,CAACJ,UAAU,CAAC,EAAE;QAC3B,OAAOI,WAAW,CAACJ,UAAU,CAAC,CAACL,OAAO,EAAEW,MAAM,CAAC;MACjD;MAEA,OAAO,iBAAQE,OAAO,CAACF,MAAM,CAAC;IAChC,CAAC,EACD,UAACG,MAAM,EAAK;MACVL,WAAW,CAACG,UAAU,CAACZ,OAAO,CAAC;MAC/B,IAAIS,WAAW,CAACH,QAAQ,CAAC,EAAE;QACzB,OAAOG,WAAW,CAACH,QAAQ,CAAC,CAACN,OAAO,EAAEc,MAAM,CAAC;MAC/C;MAEA,OAAO,iBAAQC,MAAM,CAACD,MAAM,CAAC;IAC/B,CAAC,CACF;EAAA,GACH,iBAAQD,OAAO,CAACV,GAAG,CAAC,CACrB;AACH;;AAEA;AACA;AACA;AACA;AACA;AAJA,SAKsBa,mBAAmB;EAAA;AAAA;AAAA;EAAA,+FAAlC,iBAAmChB,OAAY;IAAA;MAAA;QAAA;UACpD,IAAIA,OAAO,CAACiB,GAAG,EAAE;YACfjB,OAAO,CAACkB,GAAG,GAAGlB,OAAO,CAACiB,GAAG;YACzBjB,OAAO,CAACiB,GAAG,GAAG,IAAI;UACpB;UAEAjB,OAAO,CAACmB,OAAO,GAAGnB,OAAO,CAACmB,OAAO,IAAI,CAAC,CAAC;UAEvC,IAAInB,OAAO,CAACoB,IAAI,EAAE;YAChB;YACApB,OAAO,CAACmB,OAAO,CAACE,MAAM,GAAGrB,OAAO,CAACmB,OAAO,CAACE,MAAM,IAAIrB,OAAO,CAACmB,OAAO,CAACG,MAAM,IAAI,kBAAkB;;YAE/F;YACA,IAAItB,OAAO,CAACuB,MAAM,KAAK,KAAK,IAAIvB,OAAO,CAACuB,MAAM,KAAK,MAAM,EAAE;cACzDvB,OAAO,CAACmB,OAAO,CAAC,cAAc,CAAC,GAC7BnB,OAAO,CAACmB,OAAO,CAAC,cAAc,CAAC,IAAInB,OAAO,CAACmB,OAAO,CAAC,cAAc,CAAC,IAAI,kBAAkB;cAC1FnB,OAAO,CAACwB,IAAI,GAAG,wBAAexB,OAAO,CAACoB,IAAI,KAAK,IAAI,GAAGpB,OAAO,CAACwB,IAAI,GAAGxB,OAAO,CAACoB,IAAI,CAAC;YACpF;UACF,CAAC,MAAM,IAAIpB,OAAO,CAACoB,IAAI,KAAKhB,SAAS,EAAE;YACrC,6BAAuBJ,OAAO,EAAE,MAAM,CAAC;UACzC;UAEAA,OAAO,CAACyB,QAAQ,GAAG,IAAIC,oBAAY,EAAE;UACrC1B,OAAO,CAAC2B,MAAM,GAAG,IAAID,oBAAY,EAAE;UACnC1B,OAAO,CAAC4B,SAAS,GAAG,IAAI;UAAC,iCAElB7B,SAAS,CAACC,OAAO,EAAEA,OAAO,CAACC,YAAY,EAAE,SAAS,CAAC,CAACS,IAAI,CAAC;YAAA,OAAMV,OAAO;UAAA,EAAC;QAAA;QAAA;UAAA;MAAA;IAAA;EAAA,CAC/E;EAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/http-core",
3
- "version": "3.0.0-beta.3",
3
+ "version": "3.0.0-beta.300",
4
4
  "description": "Core HTTP library for the Cisco Webex",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -24,18 +24,18 @@
24
24
  ]
25
25
  },
26
26
  "devDependencies": {
27
- "@webex/test-helper-chai": "3.0.0-beta.3",
28
- "@webex/test-helper-file": "3.0.0-beta.3",
29
- "@webex/test-helper-make-local-url": "3.0.0-beta.3",
30
- "@webex/test-helper-mocha": "3.0.0-beta.3",
27
+ "@webex/test-helper-chai": "3.0.0-beta.300",
28
+ "@webex/test-helper-file": "3.0.0-beta.300",
29
+ "@webex/test-helper-make-local-url": "3.0.0-beta.300",
30
+ "@webex/test-helper-mocha": "3.0.0-beta.300",
31
31
  "sinon": "^9.2.4"
32
32
  },
33
33
  "dependencies": {
34
- "@webex/common": "3.0.0-beta.3",
35
- "@webex/http-core": "3.0.0-beta.3",
36
- "@webex/internal-plugin-device": "3.0.0-beta.3",
37
- "@webex/test-helper-test-users": "3.0.0-beta.3",
38
- "@webex/webex-core": "3.0.0-beta.3",
34
+ "@webex/common": "3.0.0-beta.300",
35
+ "@webex/http-core": "3.0.0-beta.300",
36
+ "@webex/internal-plugin-device": "3.0.0-beta.300",
37
+ "@webex/test-helper-test-users": "3.0.0-beta.300",
38
+ "@webex/webex-core": "3.0.0-beta.300",
39
39
  "file-type": "^16.0.1",
40
40
  "global": "^4.4.0",
41
41
  "is-function": "^1.0.1",
@@ -182,6 +182,6 @@ export default function makeSubTypes(Base) {
182
182
  statusCode = parseInt(statusCode, 10);
183
183
 
184
184
  return Base[statusCode] || Base;
185
- }
185
+ },
186
186
  });
187
187
  }
package/src/http-error.js CHANGED
@@ -23,14 +23,7 @@ export default class HttpError extends Exception {
23
23
  *
24
24
  * @type {Array}
25
25
  */
26
- static errorKeys = [
27
- 'error',
28
- 'errorString',
29
- 'response',
30
- 'errorResponse',
31
- 'message',
32
- 'msg'
33
- ];
26
+ static errorKeys = ['error', 'errorString', 'response', 'errorResponse', 'message', 'msg'];
34
27
 
35
28
  /**
36
29
  * Default error string if no error can be extracted from the http response
@@ -55,8 +48,7 @@ export default class HttpError extends Exception {
55
48
  try {
56
49
  body = JSON.parse(body);
57
50
  message = this.parseObject(body);
58
- }
59
- catch (err) {
51
+ } catch (err) {
60
52
  message = body;
61
53
  }
62
54
  break;
@@ -73,52 +65,52 @@ export default class HttpError extends Exception {
73
65
  Object.defineProperties(this, {
74
66
  body: {
75
67
  enumerable: false,
76
- value: body
68
+ value: body,
77
69
  },
78
70
  httpVersion: {
79
71
  enumerable: false,
80
- value: res.httpVersion
72
+ value: res.httpVersion,
81
73
  },
82
74
  headers: {
83
75
  enumerable: false,
84
- value: res.headers || {}
76
+ value: res.headers || {},
85
77
  },
86
78
  rawHeaders: {
87
79
  enumerable: false,
88
- value: res.rawHeaders || []
80
+ value: res.rawHeaders || [],
89
81
  },
90
82
  trailers: {
91
83
  enumerable: false,
92
- value: res.trailers || {}
84
+ value: res.trailers || {},
93
85
  },
94
86
  rawTrailers: {
95
87
  enumerable: false,
96
- value: res.rawTrailers || []
88
+ value: res.rawTrailers || [],
97
89
  },
98
90
  method: {
99
91
  enumerable: false,
100
- value: res.method
92
+ value: res.method,
101
93
  },
102
94
  url: {
103
95
  enumerable: false,
104
- value: res.url
96
+ value: res.url,
105
97
  },
106
98
  statusCode: {
107
99
  enumerable: false,
108
- value: res.statusCode
100
+ value: res.statusCode,
109
101
  },
110
102
  statusMessage: {
111
103
  enumerable: false,
112
- value: res.statusMessage
104
+ value: res.statusMessage,
113
105
  },
114
106
  socket: {
115
107
  enumerable: false,
116
- value: res.socket
108
+ value: res.socket,
117
109
  },
118
110
  _res: {
119
111
  enumerable: false,
120
- value: res
121
- }
112
+ value: res,
113
+ },
122
114
  });
123
115
 
124
116
  return message;
package/src/index.js CHANGED
@@ -6,6 +6,7 @@ import {assign, curry, defaults as lodashDefaults, isString} from 'lodash';
6
6
 
7
7
  import HttpStatusInterceptor from './interceptors/http-status';
8
8
  import _request from './request';
9
+ import {prepareFetchOptions as _prepareFetchOptions} from './request/utils';
9
10
 
10
11
  // Curry protorequest so we generate a function with default options built in.
11
12
  const protorequest = curry(function protorequest(defaultOptions, options) {
@@ -20,17 +21,12 @@ const protorequest = curry(function protorequest(defaultOptions, options) {
20
21
  }
21
22
 
22
23
  // Hide useless elements from logs
23
- [
24
- 'download',
25
- 'interceptors',
26
- 'logger',
27
- 'upload'
28
- ].forEach((prop) => {
24
+ ['download', 'interceptors', 'logger', 'upload'].forEach((prop) => {
29
25
  let descriptor = Reflect.getOwnPropertyDescriptor(options, prop);
30
26
 
31
27
  descriptor = assign({}, descriptor, {
32
28
  enumerable: false,
33
- writable: true
29
+ writable: true,
34
30
  });
35
31
  Reflect.defineProperty(options, prop, descriptor);
36
32
  });
@@ -46,12 +42,66 @@ const protorequest = curry(function protorequest(defaultOptions, options) {
46
42
  return _request(options);
47
43
  });
48
44
 
45
+ export const protoprepareFetchOptions = curry(function protoprepareFetchOptions(
46
+ defaultOptions,
47
+ options
48
+ ) {
49
+ // Hide useless elements from logs
50
+ ['download', 'interceptors', 'logger', 'upload'].forEach((prop) => {
51
+ let descriptor = Reflect.getOwnPropertyDescriptor(options, prop);
52
+
53
+ descriptor = assign({}, descriptor, {
54
+ enumerable: false,
55
+ writable: true,
56
+ });
57
+ Reflect.defineProperty(options, prop, descriptor);
58
+ });
59
+
60
+ lodashDefaults(options, defaultOptions);
61
+
62
+ options.logger = options.logger || this.logger || console;
63
+
64
+ return _prepareFetchOptions(options);
65
+ });
66
+
67
+ /**
68
+ * Sets the $timings value(s) before the request/fetch.
69
+ * This function is only useful if you are about to send a request
70
+ * using prepared fetch options; normally it is done in webex.request();
71
+ *
72
+ * @param {any} options
73
+ * @returns {any} the updated options object
74
+ */
75
+ const setRequestTimings = (options) => {
76
+ const now = new Date().getTime();
77
+ options.$timings = options.$timings || {};
78
+ options.$timings.requestStart = now;
79
+ options.$timings.networkStart = now;
80
+
81
+ return options;
82
+ };
83
+
84
+ /**
85
+ * Submits a metric from pre-built request options via the fetch API. Updates
86
+ * the "$timings" values to Date.now() since the existing times were set when
87
+ * the options were built (not submitted).
88
+ *
89
+ * @param {any} options - the pre-built request options for submitting a metric
90
+ * @returns {Promise} promise that resolves to a response object
91
+ */
92
+ export const setTimingsAndFetch = (options) => {
93
+ const opts = setRequestTimings(options);
94
+
95
+ // call the fetch API
96
+ return fetch(opts.uri, opts);
97
+ };
98
+
49
99
  const defaultOptions = {
50
100
  json: true,
51
101
  interceptors: [
52
102
  // Reminder: this is supposed to be an instantiated interceptor.
53
- HttpStatusInterceptor.create()
54
- ]
103
+ HttpStatusInterceptor.create(),
104
+ ],
55
105
  };
56
106
 
57
107
  export const defaults = protorequest;
@@ -18,12 +18,12 @@ export default class HttpStatusInterceptor extends Interceptor {
18
18
  */
19
19
  constructor(webex, options) {
20
20
  super(webex);
21
- const ErrorConstructor = options && (options.error || options.ErrorConstructor) || HttpError;
21
+ const ErrorConstructor = (options && (options.error || options.ErrorConstructor)) || HttpError;
22
22
 
23
23
  Object.defineProperties(this, {
24
24
  ErrorConstructor: {
25
- value: ErrorConstructor
26
- }
25
+ value: ErrorConstructor,
26
+ },
27
27
  });
28
28
  }
29
29
 
@@ -46,9 +46,11 @@ export default class HttpStatusInterceptor extends Interceptor {
46
46
  return Promise.resolve(response);
47
47
  }
48
48
  // to handle locus redirects
49
- if (response.statusCode === 404 &&
49
+ if (
50
+ response.statusCode === 404 &&
50
51
  response.body &&
51
- response.body.errorCode === LOCUS_REDIRECT_ERROR) {
52
+ response.body.errorCode === LOCUS_REDIRECT_ERROR
53
+ ) {
52
54
  return Promise.resolve(response);
53
55
  }
54
56
  }
package/src/lib/detect.js CHANGED
@@ -10,7 +10,6 @@ import {fromBuffer} from 'file-type';
10
10
  * @returns {Promise<string>}
11
11
  */
12
12
  export default async function detect(buffer) {
13
- /* global Blob */
14
13
  if (
15
14
  !(buffer instanceof Blob) &&
16
15
  !(buffer instanceof ArrayBuffer) &&
@@ -20,7 +20,7 @@ export default class Interceptor {
20
20
 
21
21
  Reflect.defineProperty(this, key, {
22
22
  enumerable: true,
23
- value
23
+ value,
24
24
  });
25
25
  });
26
26
  }
@@ -43,9 +43,7 @@ export default class Interceptor {
43
43
  // prepend a header for the interceptor
44
44
  logger.info('/***** Interceptor ****************************************************\\');
45
45
 
46
- logger.info(
47
- `${this.constructor.name} - ${JSON.stringify(options, null, 2)}`
48
- );
46
+ logger.info(`${this.constructor.name} - ${JSON.stringify(options, null, 2)}`);
49
47
  }
50
48
 
51
49
  /**