ParseFile.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  7. var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
  8. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  9. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  10. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  11. var _ParseError = _interopRequireDefault(require("./ParseError"));
  12. var _Xhr = _interopRequireDefault(require("./Xhr.weapp"));
  13. var XHR = null;
  14. if (typeof XMLHttpRequest !== 'undefined') {
  15. XHR = XMLHttpRequest;
  16. }
  17. function b64Digit(number) {
  18. if (number < 26) {
  19. return String.fromCharCode(65 + number);
  20. }
  21. if (number < 52) {
  22. return String.fromCharCode(97 + (number - 26));
  23. }
  24. if (number < 62) {
  25. return String.fromCharCode(48 + (number - 52));
  26. }
  27. if (number === 62) {
  28. return '+';
  29. }
  30. if (number === 63) {
  31. return '/';
  32. }
  33. throw new TypeError('Tried to encode large digit ' + number + ' in base64.');
  34. }
  35. var ParseFile = function () {
  36. function ParseFile(name, data, type, metadata, tags) {
  37. (0, _classCallCheck2.default)(this, ParseFile);
  38. var specifiedType = type || '';
  39. this._name = name;
  40. this._metadata = metadata || {};
  41. this._tags = tags || {};
  42. if (data !== undefined) {
  43. if (Array.isArray(data)) {
  44. this._data = ParseFile.encodeBase64(data);
  45. this._source = {
  46. format: 'base64',
  47. base64: this._data,
  48. type: specifiedType
  49. };
  50. } else if (typeof Blob !== 'undefined' && data instanceof Blob) {
  51. this._source = {
  52. format: 'file',
  53. file: data,
  54. type: specifiedType
  55. };
  56. } else if (data && typeof data.uri === 'string' && data.uri !== undefined) {
  57. this._source = {
  58. format: 'uri',
  59. uri: data.uri,
  60. type: specifiedType
  61. };
  62. } else if (data && typeof data.base64 === 'string') {
  63. var base64 = data.base64.split(',').slice(-1)[0];
  64. var dataType = specifiedType || data.base64.split(';').slice(0, 1)[0].split(':').slice(1, 2)[0] || 'text/plain';
  65. this._data = base64;
  66. this._source = {
  67. format: 'base64',
  68. base64: base64,
  69. type: dataType
  70. };
  71. } else {
  72. throw new TypeError('Cannot create a Parse.File with that data.');
  73. }
  74. }
  75. }
  76. return (0, _createClass2.default)(ParseFile, [{
  77. key: "getData",
  78. value: function () {
  79. var _getData = (0, _asyncToGenerator2.default)(function* () {
  80. var _this = this;
  81. if (this._data) {
  82. return this._data;
  83. }
  84. if (!this._url) {
  85. throw new Error('Cannot retrieve data for unsaved ParseFile.');
  86. }
  87. var controller = _CoreManager.default.getFileController();
  88. var result = yield controller.download(this._url, {
  89. requestTask: function (task) {
  90. return _this._requestTask = task;
  91. }
  92. });
  93. this._data = result.base64;
  94. return this._data;
  95. });
  96. function getData() {
  97. return _getData.apply(this, arguments);
  98. }
  99. return getData;
  100. }()
  101. }, {
  102. key: "name",
  103. value: function () {
  104. return this._name;
  105. }
  106. }, {
  107. key: "url",
  108. value: function (options) {
  109. options = options || {};
  110. if (!this._url) {
  111. return;
  112. }
  113. if (options.forceSecure) {
  114. return this._url.replace(/^http:\/\//i, 'https://');
  115. } else {
  116. return this._url;
  117. }
  118. }
  119. }, {
  120. key: "metadata",
  121. value: function () {
  122. return this._metadata;
  123. }
  124. }, {
  125. key: "tags",
  126. value: function () {
  127. return this._tags;
  128. }
  129. }, {
  130. key: "save",
  131. value: function (options) {
  132. var _this2 = this;
  133. options = options || {};
  134. options.requestTask = function (task) {
  135. return _this2._requestTask = task;
  136. };
  137. options.metadata = this._metadata;
  138. options.tags = this._tags;
  139. var controller = _CoreManager.default.getFileController();
  140. if (!this._previousSave) {
  141. if (this._source.format === 'file') {
  142. this._previousSave = controller.saveFile(this._name, this._source, options).then(function (res) {
  143. _this2._name = res.name;
  144. _this2._url = res.url;
  145. _this2._data = null;
  146. _this2._requestTask = null;
  147. return _this2;
  148. });
  149. } else if (this._source.format === 'uri') {
  150. this._previousSave = controller.download(this._source.uri, options).then(function (result) {
  151. if (!(result && result.base64)) {
  152. return {};
  153. }
  154. var newSource = {
  155. format: 'base64',
  156. base64: result.base64,
  157. type: result.contentType
  158. };
  159. _this2._data = result.base64;
  160. _this2._requestTask = null;
  161. return controller.saveBase64(_this2._name, newSource, options);
  162. }).then(function (res) {
  163. _this2._name = res.name;
  164. _this2._url = res.url;
  165. _this2._requestTask = null;
  166. return _this2;
  167. });
  168. } else {
  169. this._previousSave = controller.saveBase64(this._name, this._source, options).then(function (res) {
  170. _this2._name = res.name;
  171. _this2._url = res.url;
  172. _this2._requestTask = null;
  173. return _this2;
  174. });
  175. }
  176. }
  177. if (this._previousSave) {
  178. return this._previousSave;
  179. }
  180. }
  181. }, {
  182. key: "cancel",
  183. value: function () {
  184. if (this._requestTask && typeof this._requestTask.abort === 'function') {
  185. this._requestTask._aborted = true;
  186. this._requestTask.abort();
  187. }
  188. this._requestTask = null;
  189. }
  190. }, {
  191. key: "destroy",
  192. value: function () {
  193. var _this3 = this;
  194. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  195. if (!this._name) {
  196. throw new _ParseError.default(_ParseError.default.FILE_DELETE_UNNAMED_ERROR, 'Cannot delete an unnamed file.');
  197. }
  198. var destroyOptions = {
  199. useMasterKey: true
  200. };
  201. if (options.hasOwnProperty('useMasterKey')) {
  202. destroyOptions.useMasterKey = !!options.useMasterKey;
  203. }
  204. var controller = _CoreManager.default.getFileController();
  205. return controller.deleteFile(this._name, destroyOptions).then(function () {
  206. _this3._data = undefined;
  207. _this3._requestTask = null;
  208. return _this3;
  209. });
  210. }
  211. }, {
  212. key: "toJSON",
  213. value: function () {
  214. return {
  215. __type: 'File',
  216. name: this._name,
  217. url: this._url
  218. };
  219. }
  220. }, {
  221. key: "equals",
  222. value: function (other) {
  223. if (this === other) {
  224. return true;
  225. }
  226. return other instanceof ParseFile && this.name() === other.name() && this.url() === other.url() && typeof this.url() !== 'undefined';
  227. }
  228. }, {
  229. key: "setMetadata",
  230. value: function (metadata) {
  231. var _this4 = this;
  232. if (metadata && typeof metadata === 'object') {
  233. Object.keys(metadata).forEach(function (key) {
  234. _this4.addMetadata(key, metadata[key]);
  235. });
  236. }
  237. }
  238. }, {
  239. key: "addMetadata",
  240. value: function (key, value) {
  241. if (typeof key === 'string') {
  242. this._metadata[key] = value;
  243. }
  244. }
  245. }, {
  246. key: "setTags",
  247. value: function (tags) {
  248. var _this5 = this;
  249. if (tags && typeof tags === 'object') {
  250. Object.keys(tags).forEach(function (key) {
  251. _this5.addTag(key, tags[key]);
  252. });
  253. }
  254. }
  255. }, {
  256. key: "addTag",
  257. value: function (key, value) {
  258. if (typeof key === 'string') {
  259. this._tags[key] = value;
  260. }
  261. }
  262. }], [{
  263. key: "fromJSON",
  264. value: function (obj) {
  265. if (obj.__type !== 'File') {
  266. throw new TypeError('JSON object does not represent a ParseFile');
  267. }
  268. var file = new ParseFile(obj.name);
  269. file._url = obj.url;
  270. return file;
  271. }
  272. }, {
  273. key: "encodeBase64",
  274. value: function (bytes) {
  275. var chunks = [];
  276. chunks.length = Math.ceil(bytes.length / 3);
  277. for (var i = 0; i < chunks.length; i++) {
  278. var b1 = bytes[i * 3];
  279. var b2 = bytes[i * 3 + 1] || 0;
  280. var b3 = bytes[i * 3 + 2] || 0;
  281. var has2 = i * 3 + 1 < bytes.length;
  282. var has3 = i * 3 + 2 < bytes.length;
  283. chunks[i] = [b64Digit(b1 >> 2 & 0x3f), b64Digit(b1 << 4 & 0x30 | b2 >> 4 & 0x0f), has2 ? b64Digit(b2 << 2 & 0x3c | b3 >> 6 & 0x03) : '=', has3 ? b64Digit(b3 & 0x3f) : '='].join('');
  284. }
  285. return chunks.join('');
  286. }
  287. }]);
  288. }();
  289. var DefaultController = {
  290. saveFile: function () {
  291. var _saveFile = (0, _asyncToGenerator2.default)(function* (name, source, options) {
  292. if (source.format !== 'file') {
  293. throw new Error('saveFile can only be used with File-type sources.');
  294. }
  295. var base64Data = yield new Promise(function (res, rej) {
  296. var reader = new FileReader();
  297. reader.onload = function () {
  298. return res(reader.result);
  299. };
  300. reader.onerror = function (error) {
  301. return rej(error);
  302. };
  303. reader.readAsDataURL(source.file);
  304. });
  305. var _base64Data$split = base64Data.split(','),
  306. _base64Data$split2 = (0, _slicedToArray2.default)(_base64Data$split, 2),
  307. first = _base64Data$split2[0],
  308. second = _base64Data$split2[1];
  309. var data = second ? second : first;
  310. var newSource = {
  311. format: 'base64',
  312. base64: data,
  313. type: source.type || (source.file ? source.file.type : undefined)
  314. };
  315. return yield DefaultController.saveBase64(name, newSource, options);
  316. });
  317. function saveFile() {
  318. return _saveFile.apply(this, arguments);
  319. }
  320. return saveFile;
  321. }(),
  322. saveBase64: function (name, source) {
  323. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  324. if (source.format !== 'base64') {
  325. throw new Error('saveBase64 can only be used with Base64-type sources.');
  326. }
  327. var data = {
  328. base64: source.base64,
  329. fileData: {
  330. metadata: Object.assign({}, options.metadata),
  331. tags: Object.assign({}, options.tags)
  332. }
  333. };
  334. delete options.metadata;
  335. delete options.tags;
  336. if (source.type) {
  337. data._ContentType = source.type;
  338. }
  339. return _CoreManager.default.getRESTController().request('POST', 'files/' + name, data, options);
  340. },
  341. download: function (uri, options) {
  342. if (XHR) {
  343. return this.downloadAjax(uri, options);
  344. } else {
  345. return Promise.reject('Cannot make a request: No definition of XMLHttpRequest was found.');
  346. }
  347. },
  348. downloadAjax: function (uri, options) {
  349. return new Promise(function (resolve, reject) {
  350. var xhr = new XHR();
  351. xhr.open('GET', uri, true);
  352. xhr.responseType = 'arraybuffer';
  353. xhr.onerror = function (e) {
  354. reject(e);
  355. };
  356. xhr.onreadystatechange = function () {
  357. if (xhr.readyState !== xhr.DONE) {
  358. return;
  359. }
  360. if (!this.response) {
  361. return resolve({});
  362. }
  363. var bytes = new Uint8Array(this.response);
  364. resolve({
  365. base64: ParseFile.encodeBase64(bytes),
  366. contentType: xhr.getResponseHeader('content-type')
  367. });
  368. };
  369. options.requestTask(xhr);
  370. xhr.send();
  371. });
  372. },
  373. deleteFile: function (name, options) {
  374. var headers = {
  375. 'X-Parse-Application-ID': _CoreManager.default.get('APPLICATION_ID')
  376. };
  377. if (options.useMasterKey) {
  378. headers['X-Parse-Master-Key'] = _CoreManager.default.get('MASTER_KEY');
  379. }
  380. var url = _CoreManager.default.get('SERVER_URL');
  381. if (url[url.length - 1] !== '/') {
  382. url += '/';
  383. }
  384. url += 'files/' + name;
  385. return _CoreManager.default.getRESTController().ajax('DELETE', url, '', headers).catch(function (response) {
  386. if (!response || response === 'SyntaxError: Unexpected end of JSON input') {
  387. return Promise.resolve();
  388. } else {
  389. return _CoreManager.default.getRESTController().handleError(response);
  390. }
  391. });
  392. },
  393. _setXHR: function (xhr) {
  394. XHR = xhr;
  395. },
  396. _getXHR: function () {
  397. return XHR;
  398. }
  399. };
  400. _CoreManager.default.setFileController(DefaultController);
  401. var _default = exports.default = ParseFile;
  402. exports.b64Digit = b64Digit;