RESTController.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. "use strict";
  2. var _Object$keys = require("@babel/runtime-corejs3/core-js-stable/object/keys");
  3. var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols");
  4. var _filterInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/filter");
  5. var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");
  6. var _forEachInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/for-each");
  7. var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors");
  8. var _Object$defineProperties = require("@babel/runtime-corejs3/core-js-stable/object/define-properties");
  9. var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
  10. var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
  11. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
  12. var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));
  13. var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));
  14. var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));
  15. var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
  16. var _setTimeout2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set-timeout"));
  17. var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
  18. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  19. var _ParseError = _interopRequireDefault(require("./ParseError"));
  20. var _promiseUtils = require("./promiseUtils");
  21. function ownKeys(object, enumerableOnly) {
  22. var keys = _Object$keys(object);
  23. if (_Object$getOwnPropertySymbols) {
  24. var symbols = _Object$getOwnPropertySymbols(object);
  25. enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) {
  26. return _Object$getOwnPropertyDescriptor(object, sym).enumerable;
  27. })), keys.push.apply(keys, symbols);
  28. }
  29. return keys;
  30. }
  31. function _objectSpread(target) {
  32. for (var i = 1; i < arguments.length; i++) {
  33. var _context5, _context6;
  34. var source = null != arguments[i] ? arguments[i] : {};
  35. i % 2 ? _forEachInstanceProperty(_context5 = ownKeys(Object(source), !0)).call(_context5, function (key) {
  36. (0, _defineProperty2.default)(target, key, source[key]);
  37. }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context6 = ownKeys(Object(source))).call(_context6, function (key) {
  38. _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key));
  39. });
  40. }
  41. return target;
  42. }
  43. /**
  44. * Copyright (c) 2015-present, Parse, LLC.
  45. * All rights reserved.
  46. *
  47. * This source code is licensed under the BSD-style license found in the
  48. * LICENSE file in the root directory of this source tree. An additional grant
  49. * of patent rights can be found in the PATENTS file in the same directory.
  50. *
  51. * @flow
  52. */
  53. /* global XMLHttpRequest, XDomainRequest */
  54. var _require = require('uuid'),
  55. uuidv4 = _require.v4;
  56. var XHR = null;
  57. if (typeof XMLHttpRequest !== 'undefined') {
  58. XHR = XMLHttpRequest;
  59. }
  60. XHR = require('./Xhr.weapp');
  61. var useXDomainRequest = false;
  62. if (typeof XDomainRequest !== 'undefined' && !('withCredentials' in new XMLHttpRequest())) {
  63. useXDomainRequest = true;
  64. }
  65. function ajaxIE9(method
  66. /*: string*/
  67. , url
  68. /*: string*/
  69. , data
  70. /*: any*/
  71. , headers
  72. /*:: ?: any*/
  73. , options
  74. /*:: ?: FullOptions*/
  75. ) {
  76. return new _promise.default(function (resolve, reject) {
  77. var xdr = new XDomainRequest();
  78. xdr.onload = function () {
  79. var response;
  80. try {
  81. response = JSON.parse(xdr.responseText);
  82. } catch (e) {
  83. reject(e);
  84. }
  85. if (response) {
  86. resolve({
  87. response: response
  88. });
  89. }
  90. };
  91. xdr.onerror = xdr.ontimeout = function () {
  92. // Let's fake a real error message.
  93. var fakeResponse = {
  94. responseText: (0, _stringify.default)({
  95. code: _ParseError.default.X_DOMAIN_REQUEST,
  96. error: "IE's XDomainRequest does not supply error info."
  97. })
  98. };
  99. reject(fakeResponse);
  100. };
  101. xdr.onprogress = function () {
  102. if (options && typeof options.progress === 'function') {
  103. options.progress(xdr.responseText);
  104. }
  105. };
  106. xdr.open(method, url);
  107. xdr.send(data);
  108. if (options && typeof options.requestTask === 'function') {
  109. options.requestTask(xdr);
  110. }
  111. });
  112. }
  113. var RESTController = {
  114. ajax: function (method
  115. /*: string*/
  116. , url
  117. /*: string*/
  118. , data
  119. /*: any*/
  120. , headers
  121. /*:: ?: any*/
  122. , options
  123. /*:: ?: FullOptions*/
  124. ) {
  125. var _context;
  126. if (useXDomainRequest) {
  127. return ajaxIE9(method, url, data, headers, options);
  128. }
  129. var promise = (0, _promiseUtils.resolvingPromise)();
  130. var isIdempotent = _CoreManager.default.get('IDEMPOTENCY') && (0, _includes.default)(_context = ['POST', 'PUT']).call(_context, method);
  131. var requestId = isIdempotent ? uuidv4() : '';
  132. var attempts = 0;
  133. var dispatch = function dispatch() {
  134. if (XHR == null) {
  135. throw new Error('Cannot make a request: No definition of XMLHttpRequest was found.');
  136. }
  137. var handled = false;
  138. var xhr = new XHR();
  139. xhr.onreadystatechange = function () {
  140. if (xhr.readyState !== 4 || handled || xhr._aborted) {
  141. return;
  142. }
  143. handled = true;
  144. if (xhr.status >= 200 && xhr.status < 300) {
  145. var response;
  146. try {
  147. response = JSON.parse(xhr.responseText);
  148. if (typeof xhr.getResponseHeader === 'function') {
  149. var _context2;
  150. if ((0, _includes.default)(_context2 = xhr.getAllResponseHeaders() || '').call(_context2, 'x-parse-job-status-id: ')) {
  151. response = xhr.getResponseHeader('x-parse-job-status-id');
  152. }
  153. }
  154. } catch (e) {
  155. promise.reject(e.toString());
  156. }
  157. if (response) {
  158. promise.resolve({
  159. response: response,
  160. status: xhr.status,
  161. xhr: xhr
  162. });
  163. }
  164. } else if (xhr.status >= 500 || xhr.status === 0) {
  165. // retry on 5XX or node-xmlhttprequest error
  166. if (++attempts < _CoreManager.default.get('REQUEST_ATTEMPT_LIMIT')) {
  167. // Exponentially-growing random delay
  168. var delay = Math.round(Math.random() * 125 * Math.pow(2, attempts));
  169. (0, _setTimeout2.default)(dispatch, delay);
  170. } else if (xhr.status === 0) {
  171. promise.reject('Unable to connect to the Parse API');
  172. } else {
  173. // After the retry limit is reached, fail
  174. promise.reject(xhr);
  175. }
  176. } else {
  177. promise.reject(xhr);
  178. }
  179. };
  180. headers = headers || {};
  181. if (typeof headers['Content-Type'] !== 'string') {
  182. // Avoid pre-flight
  183. headers['Content-Type'] = 'text/plain';
  184. }
  185. if (_CoreManager.default.get('IS_NODE')) {
  186. var _context3;
  187. headers['User-Agent'] = (0, _concat.default)(_context3 = "Parse/".concat(_CoreManager.default.get('VERSION'), " (NodeJS ")).call(_context3, process.versions.node, ")");
  188. }
  189. if (isIdempotent) {
  190. headers['X-Parse-Request-Id'] = requestId;
  191. }
  192. if (_CoreManager.default.get('SERVER_AUTH_TYPE') && _CoreManager.default.get('SERVER_AUTH_TOKEN')) {
  193. var _context4;
  194. headers.Authorization = (0, _concat.default)(_context4 = "".concat(_CoreManager.default.get('SERVER_AUTH_TYPE'), " ")).call(_context4, _CoreManager.default.get('SERVER_AUTH_TOKEN'));
  195. }
  196. var customHeaders = _CoreManager.default.get('REQUEST_HEADERS');
  197. for (var key in customHeaders) {
  198. headers[key] = customHeaders[key];
  199. }
  200. function handleProgress(type, event) {
  201. if (options && typeof options.progress === 'function') {
  202. if (event.lengthComputable) {
  203. options.progress(event.loaded / event.total, event.loaded, event.total, {
  204. type: type
  205. });
  206. } else {
  207. options.progress(null, null, null, {
  208. type: type
  209. });
  210. }
  211. }
  212. }
  213. xhr.onprogress = function (event) {
  214. handleProgress('download', event);
  215. };
  216. if (xhr.upload) {
  217. xhr.upload.onprogress = function (event) {
  218. handleProgress('upload', event);
  219. };
  220. }
  221. xhr.open(method, url, true);
  222. for (var h in headers) {
  223. xhr.setRequestHeader(h, headers[h]);
  224. }
  225. xhr.onabort = function () {
  226. promise.resolve({
  227. response: {
  228. results: []
  229. },
  230. status: 0,
  231. xhr: xhr
  232. });
  233. };
  234. xhr.send(data);
  235. if (options && typeof options.requestTask === 'function') {
  236. options.requestTask(xhr);
  237. }
  238. };
  239. dispatch();
  240. return promise;
  241. },
  242. request: function (method
  243. /*: string*/
  244. , path
  245. /*: string*/
  246. , data
  247. /*: mixed*/
  248. , options
  249. /*:: ?: RequestOptions*/
  250. ) {
  251. options = options || {};
  252. var url = _CoreManager.default.get('SERVER_URL');
  253. if (url[url.length - 1] !== '/') {
  254. url += '/';
  255. }
  256. url += path;
  257. var payload = {};
  258. if (data && (0, _typeof2.default)(data) === 'object') {
  259. for (var k in data) {
  260. payload[k] = data[k];
  261. }
  262. } // Add context
  263. var _options = options,
  264. context = _options.context;
  265. if (context !== undefined) {
  266. payload._context = context;
  267. }
  268. if (method !== 'POST') {
  269. payload._method = method;
  270. method = 'POST';
  271. }
  272. payload._ApplicationId = _CoreManager.default.get('APPLICATION_ID');
  273. var jsKey = _CoreManager.default.get('JAVASCRIPT_KEY');
  274. if (jsKey) {
  275. payload._JavaScriptKey = jsKey;
  276. }
  277. payload._ClientVersion = _CoreManager.default.get('VERSION');
  278. var _options2 = options,
  279. useMasterKey = _options2.useMasterKey;
  280. if (typeof useMasterKey === 'undefined') {
  281. useMasterKey = _CoreManager.default.get('USE_MASTER_KEY');
  282. }
  283. if (useMasterKey) {
  284. if (_CoreManager.default.get('MASTER_KEY')) {
  285. delete payload._JavaScriptKey;
  286. payload._MasterKey = _CoreManager.default.get('MASTER_KEY');
  287. }
  288. }
  289. if (_CoreManager.default.get('FORCE_REVOCABLE_SESSION')) {
  290. payload._RevocableSession = '1';
  291. }
  292. var _options3 = options,
  293. installationId = _options3.installationId;
  294. var installationIdPromise;
  295. if (installationId && typeof installationId === 'string') {
  296. installationIdPromise = _promise.default.resolve(installationId);
  297. } else {
  298. var installationController = _CoreManager.default.getInstallationController();
  299. installationIdPromise = installationController.currentInstallationId();
  300. }
  301. return installationIdPromise.then(function (iid) {
  302. payload._InstallationId = iid;
  303. var userController = _CoreManager.default.getUserController();
  304. if (options && typeof options.sessionToken === 'string') {
  305. return _promise.default.resolve(options.sessionToken);
  306. }
  307. if (userController) {
  308. return userController.currentUserAsync().then(function (user) {
  309. if (user) {
  310. return _promise.default.resolve(user.getSessionToken());
  311. }
  312. return _promise.default.resolve(null);
  313. });
  314. }
  315. return _promise.default.resolve(null);
  316. }).then(function (token) {
  317. if (token) {
  318. payload._SessionToken = token;
  319. }
  320. var payloadString = (0, _stringify.default)(payload);
  321. return RESTController.ajax(method, url, payloadString, {}, options).then(function (_ref) {
  322. var response = _ref.response,
  323. status = _ref.status;
  324. if (options.returnStatus) {
  325. return _objectSpread(_objectSpread({}, response), {}, {
  326. _status: status
  327. });
  328. }
  329. return response;
  330. });
  331. }).catch(RESTController.handleError);
  332. },
  333. handleError: function (response) {
  334. // Transform the error into an instance of ParseError by trying to parse
  335. // the error string as JSON
  336. var error;
  337. if (response && response.responseText) {
  338. try {
  339. var errorJSON = JSON.parse(response.responseText);
  340. error = new _ParseError.default(errorJSON.code, errorJSON.error);
  341. } catch (e) {
  342. // If we fail to parse the error text, that's okay.
  343. error = new _ParseError.default(_ParseError.default.INVALID_JSON, "Received an error with invalid JSON from Parse: ".concat(response.responseText));
  344. }
  345. } else {
  346. var message = response.message ? response.message : response;
  347. error = new _ParseError.default(_ParseError.default.CONNECTION_FAILED, "XMLHttpRequest failed: ".concat((0, _stringify.default)(message)));
  348. }
  349. return _promise.default.reject(error);
  350. },
  351. _setXHR: function (xhr
  352. /*: any*/
  353. ) {
  354. XHR = xhr;
  355. },
  356. _getXHR: function () {
  357. return XHR;
  358. }
  359. };
  360. module.exports = RESTController;