ParseOp.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.UnsetOp = exports.SetOp = exports.RemoveOp = exports.RelationOp = exports.Op = exports.IncrementOp = exports.AddUniqueOp = exports.AddOp = void 0;
  6. exports.opFromJSON = opFromJSON;
  7. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  8. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  9. var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
  10. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  11. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  12. var _arrayContainsObject = _interopRequireDefault(require("./arrayContainsObject"));
  13. var _decode = _interopRequireDefault(require("./decode"));
  14. var _encode = _interopRequireDefault(require("./encode"));
  15. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  16. var _ParseRelation = _interopRequireDefault(require("./ParseRelation"));
  17. var _unique = _interopRequireDefault(require("./unique"));
  18. function _callSuper(t, o, e) {
  19. return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e));
  20. }
  21. function _isNativeReflectConstruct() {
  22. try {
  23. var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
  24. } catch (t) {}
  25. return (_isNativeReflectConstruct = function () {
  26. return !!t;
  27. })();
  28. }
  29. function opFromJSON(json) {
  30. if (!json || !json.__op) {
  31. return null;
  32. }
  33. switch (json.__op) {
  34. case 'Delete':
  35. return new UnsetOp();
  36. case 'Increment':
  37. return new IncrementOp(json.amount);
  38. case 'Add':
  39. return new AddOp((0, _decode.default)(json.objects));
  40. case 'AddUnique':
  41. return new AddUniqueOp((0, _decode.default)(json.objects));
  42. case 'Remove':
  43. return new RemoveOp((0, _decode.default)(json.objects));
  44. case 'AddRelation':
  45. {
  46. var toAdd = (0, _decode.default)(json.objects);
  47. if (!Array.isArray(toAdd)) {
  48. return new RelationOp([], []);
  49. }
  50. return new RelationOp(toAdd, []);
  51. }
  52. case 'RemoveRelation':
  53. {
  54. var toRemove = (0, _decode.default)(json.objects);
  55. if (!Array.isArray(toRemove)) {
  56. return new RelationOp([], []);
  57. }
  58. return new RelationOp([], toRemove);
  59. }
  60. case 'Batch':
  61. {
  62. var _toAdd = [];
  63. var _toRemove = [];
  64. for (var i = 0; i < json.ops.length; i++) {
  65. if (json.ops[i].__op === 'AddRelation') {
  66. _toAdd = _toAdd.concat((0, _decode.default)(json.ops[i].objects));
  67. } else if (json.ops[i].__op === 'RemoveRelation') {
  68. _toRemove = _toRemove.concat((0, _decode.default)(json.ops[i].objects));
  69. }
  70. }
  71. return new RelationOp(_toAdd, _toRemove);
  72. }
  73. }
  74. return null;
  75. }
  76. var Op = exports.Op = function () {
  77. function Op() {
  78. (0, _classCallCheck2.default)(this, Op);
  79. }
  80. return (0, _createClass2.default)(Op, [{
  81. key: "applyTo",
  82. value: function () {}
  83. }, {
  84. key: "mergeWith",
  85. value: function () {}
  86. }, {
  87. key: "toJSON",
  88. value: function () {}
  89. }]);
  90. }();
  91. var SetOp = exports.SetOp = function (_Op) {
  92. function SetOp(value) {
  93. var _this;
  94. (0, _classCallCheck2.default)(this, SetOp);
  95. _this = _callSuper(this, SetOp);
  96. _this._value = value;
  97. return _this;
  98. }
  99. (0, _inherits2.default)(SetOp, _Op);
  100. return (0, _createClass2.default)(SetOp, [{
  101. key: "applyTo",
  102. value: function () {
  103. return this._value;
  104. }
  105. }, {
  106. key: "mergeWith",
  107. value: function () {
  108. return new SetOp(this._value);
  109. }
  110. }, {
  111. key: "toJSON",
  112. value: function (offline) {
  113. return (0, _encode.default)(this._value, false, true, undefined, offline);
  114. }
  115. }]);
  116. }(Op);
  117. var UnsetOp = exports.UnsetOp = function (_Op2) {
  118. function UnsetOp() {
  119. (0, _classCallCheck2.default)(this, UnsetOp);
  120. return _callSuper(this, UnsetOp, arguments);
  121. }
  122. (0, _inherits2.default)(UnsetOp, _Op2);
  123. return (0, _createClass2.default)(UnsetOp, [{
  124. key: "applyTo",
  125. value: function () {
  126. return undefined;
  127. }
  128. }, {
  129. key: "mergeWith",
  130. value: function () {
  131. return new UnsetOp();
  132. }
  133. }, {
  134. key: "toJSON",
  135. value: function () {
  136. return {
  137. __op: 'Delete'
  138. };
  139. }
  140. }]);
  141. }(Op);
  142. var IncrementOp = exports.IncrementOp = function (_Op3) {
  143. function IncrementOp(amount) {
  144. var _this2;
  145. (0, _classCallCheck2.default)(this, IncrementOp);
  146. _this2 = _callSuper(this, IncrementOp);
  147. if (typeof amount !== 'number') {
  148. throw new TypeError('Increment Op must be initialized with a numeric amount.');
  149. }
  150. _this2._amount = amount;
  151. return _this2;
  152. }
  153. (0, _inherits2.default)(IncrementOp, _Op3);
  154. return (0, _createClass2.default)(IncrementOp, [{
  155. key: "applyTo",
  156. value: function (value) {
  157. if (typeof value === 'undefined') {
  158. return this._amount;
  159. }
  160. if (typeof value !== 'number') {
  161. throw new TypeError('Cannot increment a non-numeric value.');
  162. }
  163. return this._amount + value;
  164. }
  165. }, {
  166. key: "mergeWith",
  167. value: function (previous) {
  168. if (!previous) {
  169. return this;
  170. }
  171. if (previous instanceof SetOp) {
  172. return new SetOp(this.applyTo(previous._value));
  173. }
  174. if (previous instanceof UnsetOp) {
  175. return new SetOp(this._amount);
  176. }
  177. if (previous instanceof IncrementOp) {
  178. return new IncrementOp(this.applyTo(previous._amount));
  179. }
  180. throw new Error('Cannot merge Increment Op with the previous Op');
  181. }
  182. }, {
  183. key: "toJSON",
  184. value: function () {
  185. return {
  186. __op: 'Increment',
  187. amount: this._amount
  188. };
  189. }
  190. }]);
  191. }(Op);
  192. var AddOp = exports.AddOp = function (_Op4) {
  193. function AddOp(value) {
  194. var _this3;
  195. (0, _classCallCheck2.default)(this, AddOp);
  196. _this3 = _callSuper(this, AddOp);
  197. _this3._value = Array.isArray(value) ? value : [value];
  198. return _this3;
  199. }
  200. (0, _inherits2.default)(AddOp, _Op4);
  201. return (0, _createClass2.default)(AddOp, [{
  202. key: "applyTo",
  203. value: function (value) {
  204. if (value == null) {
  205. return this._value;
  206. }
  207. if (Array.isArray(value)) {
  208. return value.concat(this._value);
  209. }
  210. throw new Error('Cannot add elements to a non-array value');
  211. }
  212. }, {
  213. key: "mergeWith",
  214. value: function (previous) {
  215. if (!previous) {
  216. return this;
  217. }
  218. if (previous instanceof SetOp) {
  219. return new SetOp(this.applyTo(previous._value));
  220. }
  221. if (previous instanceof UnsetOp) {
  222. return new SetOp(this._value);
  223. }
  224. if (previous instanceof AddOp) {
  225. return new AddOp(this.applyTo(previous._value));
  226. }
  227. throw new Error('Cannot merge Add Op with the previous Op');
  228. }
  229. }, {
  230. key: "toJSON",
  231. value: function () {
  232. return {
  233. __op: 'Add',
  234. objects: (0, _encode.default)(this._value, false, true)
  235. };
  236. }
  237. }]);
  238. }(Op);
  239. var AddUniqueOp = exports.AddUniqueOp = function (_Op5) {
  240. function AddUniqueOp(value) {
  241. var _this4;
  242. (0, _classCallCheck2.default)(this, AddUniqueOp);
  243. _this4 = _callSuper(this, AddUniqueOp);
  244. _this4._value = (0, _unique.default)(Array.isArray(value) ? value : [value]);
  245. return _this4;
  246. }
  247. (0, _inherits2.default)(AddUniqueOp, _Op5);
  248. return (0, _createClass2.default)(AddUniqueOp, [{
  249. key: "applyTo",
  250. value: function (value) {
  251. if (value == null) {
  252. return this._value || [];
  253. }
  254. if (Array.isArray(value)) {
  255. var ParseObject = _CoreManager.default.getParseObject();
  256. var toAdd = [];
  257. this._value.forEach(function (v) {
  258. if (v instanceof ParseObject) {
  259. if (!(0, _arrayContainsObject.default)(value, v)) {
  260. toAdd.push(v);
  261. }
  262. } else {
  263. if (value.indexOf(v) < 0) {
  264. toAdd.push(v);
  265. }
  266. }
  267. });
  268. return value.concat(toAdd);
  269. }
  270. throw new Error('Cannot add elements to a non-array value');
  271. }
  272. }, {
  273. key: "mergeWith",
  274. value: function (previous) {
  275. if (!previous) {
  276. return this;
  277. }
  278. if (previous instanceof SetOp) {
  279. return new SetOp(this.applyTo(previous._value));
  280. }
  281. if (previous instanceof UnsetOp) {
  282. return new SetOp(this._value);
  283. }
  284. if (previous instanceof AddUniqueOp) {
  285. return new AddUniqueOp(this.applyTo(previous._value));
  286. }
  287. throw new Error('Cannot merge AddUnique Op with the previous Op');
  288. }
  289. }, {
  290. key: "toJSON",
  291. value: function () {
  292. return {
  293. __op: 'AddUnique',
  294. objects: (0, _encode.default)(this._value, false, true)
  295. };
  296. }
  297. }]);
  298. }(Op);
  299. var RemoveOp = exports.RemoveOp = function (_Op6) {
  300. function RemoveOp(value) {
  301. var _this5;
  302. (0, _classCallCheck2.default)(this, RemoveOp);
  303. _this5 = _callSuper(this, RemoveOp);
  304. _this5._value = (0, _unique.default)(Array.isArray(value) ? value : [value]);
  305. return _this5;
  306. }
  307. (0, _inherits2.default)(RemoveOp, _Op6);
  308. return (0, _createClass2.default)(RemoveOp, [{
  309. key: "applyTo",
  310. value: function (value) {
  311. if (value == null) {
  312. return [];
  313. }
  314. if (Array.isArray(value)) {
  315. var ParseObject = _CoreManager.default.getParseObject();
  316. var removed = value.concat([]);
  317. for (var i = 0; i < this._value.length; i++) {
  318. var index = removed.indexOf(this._value[i]);
  319. while (index > -1) {
  320. removed.splice(index, 1);
  321. index = removed.indexOf(this._value[i]);
  322. }
  323. if (this._value[i] instanceof ParseObject && this._value[i].id) {
  324. for (var j = 0; j < removed.length; j++) {
  325. if (removed[j] instanceof ParseObject && this._value[i].id === removed[j].id) {
  326. removed.splice(j, 1);
  327. j--;
  328. }
  329. }
  330. }
  331. }
  332. return removed;
  333. }
  334. throw new Error('Cannot remove elements from a non-array value');
  335. }
  336. }, {
  337. key: "mergeWith",
  338. value: function (previous) {
  339. if (!previous) {
  340. return this;
  341. }
  342. if (previous instanceof SetOp) {
  343. return new SetOp(this.applyTo(previous._value));
  344. }
  345. if (previous instanceof UnsetOp) {
  346. return new UnsetOp();
  347. }
  348. if (previous instanceof RemoveOp) {
  349. var ParseObject = _CoreManager.default.getParseObject();
  350. var uniques = previous._value.concat([]);
  351. for (var i = 0; i < this._value.length; i++) {
  352. if (this._value[i] instanceof ParseObject) {
  353. if (!(0, _arrayContainsObject.default)(uniques, this._value[i])) {
  354. uniques.push(this._value[i]);
  355. }
  356. } else {
  357. if (uniques.indexOf(this._value[i]) < 0) {
  358. uniques.push(this._value[i]);
  359. }
  360. }
  361. }
  362. return new RemoveOp(uniques);
  363. }
  364. throw new Error('Cannot merge Remove Op with the previous Op');
  365. }
  366. }, {
  367. key: "toJSON",
  368. value: function () {
  369. return {
  370. __op: 'Remove',
  371. objects: (0, _encode.default)(this._value, false, true)
  372. };
  373. }
  374. }]);
  375. }(Op);
  376. var RelationOp = exports.RelationOp = function (_Op7) {
  377. function RelationOp(adds, removes) {
  378. var _this6;
  379. (0, _classCallCheck2.default)(this, RelationOp);
  380. _this6 = _callSuper(this, RelationOp);
  381. _this6._targetClassName = null;
  382. if (Array.isArray(adds)) {
  383. _this6.relationsToAdd = (0, _unique.default)(adds.map(_this6._extractId, _this6));
  384. }
  385. if (Array.isArray(removes)) {
  386. _this6.relationsToRemove = (0, _unique.default)(removes.map(_this6._extractId, _this6));
  387. }
  388. return _this6;
  389. }
  390. (0, _inherits2.default)(RelationOp, _Op7);
  391. return (0, _createClass2.default)(RelationOp, [{
  392. key: "_extractId",
  393. value: function (obj) {
  394. if (typeof obj === 'string') {
  395. return obj;
  396. }
  397. if (!obj.id) {
  398. throw new Error('You cannot add or remove an unsaved Parse Object from a relation');
  399. }
  400. if (!this._targetClassName) {
  401. this._targetClassName = obj.className;
  402. }
  403. if (this._targetClassName !== obj.className) {
  404. throw new Error('Tried to create a Relation with 2 different object types: ' + this._targetClassName + ' and ' + obj.className + '.');
  405. }
  406. return obj.id;
  407. }
  408. }, {
  409. key: "applyTo",
  410. value: function (value, parent, key) {
  411. if (!value) {
  412. if (!parent || !key) {
  413. throw new Error('Cannot apply a RelationOp without either a previous value, or an object and a key');
  414. }
  415. var relation = new _ParseRelation.default(parent, key);
  416. relation.targetClassName = this._targetClassName;
  417. return relation;
  418. }
  419. if (value instanceof _ParseRelation.default) {
  420. if (this._targetClassName) {
  421. if (value.targetClassName) {
  422. if (this._targetClassName !== value.targetClassName) {
  423. throw new Error('Related object must be a ' + value.targetClassName + ', but a ' + this._targetClassName + ' was passed in.');
  424. }
  425. } else {
  426. value.targetClassName = this._targetClassName;
  427. }
  428. }
  429. return value;
  430. } else {
  431. throw new Error('Relation cannot be applied to a non-relation field');
  432. }
  433. }
  434. }, {
  435. key: "mergeWith",
  436. value: function (previous) {
  437. if (!previous) {
  438. return this;
  439. } else if (previous instanceof UnsetOp) {
  440. throw new Error('You cannot modify a relation after deleting it.');
  441. } else if (previous instanceof SetOp && previous._value instanceof _ParseRelation.default) {
  442. return this;
  443. } else if (previous instanceof RelationOp) {
  444. if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {
  445. throw new Error('Related object must be of class ' + previous._targetClassName + ', but ' + (this._targetClassName || 'null') + ' was passed in.');
  446. }
  447. var newAdd = previous.relationsToAdd.concat([]);
  448. this.relationsToRemove.forEach(function (r) {
  449. var index = newAdd.indexOf(r);
  450. if (index > -1) {
  451. newAdd.splice(index, 1);
  452. }
  453. });
  454. this.relationsToAdd.forEach(function (r) {
  455. var index = newAdd.indexOf(r);
  456. if (index < 0) {
  457. newAdd.push(r);
  458. }
  459. });
  460. var newRemove = previous.relationsToRemove.concat([]);
  461. this.relationsToAdd.forEach(function (r) {
  462. var index = newRemove.indexOf(r);
  463. if (index > -1) {
  464. newRemove.splice(index, 1);
  465. }
  466. });
  467. this.relationsToRemove.forEach(function (r) {
  468. var index = newRemove.indexOf(r);
  469. if (index < 0) {
  470. newRemove.push(r);
  471. }
  472. });
  473. var newRelation = new RelationOp(newAdd, newRemove);
  474. newRelation._targetClassName = this._targetClassName;
  475. return newRelation;
  476. }
  477. throw new Error('Cannot merge Relation Op with the previous Op');
  478. }
  479. }, {
  480. key: "toJSON",
  481. value: function () {
  482. var _this7 = this;
  483. var idToPointer = function (id) {
  484. return {
  485. __type: 'Pointer',
  486. className: _this7._targetClassName,
  487. objectId: id
  488. };
  489. };
  490. var pointers = null;
  491. var adds = null;
  492. var removes = null;
  493. if (this.relationsToAdd.length > 0) {
  494. pointers = this.relationsToAdd.map(idToPointer);
  495. adds = {
  496. __op: 'AddRelation',
  497. objects: pointers
  498. };
  499. }
  500. if (this.relationsToRemove.length > 0) {
  501. pointers = this.relationsToRemove.map(idToPointer);
  502. removes = {
  503. __op: 'RemoveRelation',
  504. objects: pointers
  505. };
  506. }
  507. if (adds && removes) {
  508. return {
  509. __op: 'Batch',
  510. ops: [adds, removes]
  511. };
  512. }
  513. return adds || removes || {};
  514. }
  515. }]);
  516. }(Op);
  517. _CoreManager.default.setParseOp({
  518. Op: Op,
  519. opFromJSON: opFromJSON,
  520. SetOp: SetOp,
  521. UnsetOp: UnsetOp,
  522. IncrementOp: IncrementOp,
  523. AddOp: AddOp,
  524. RelationOp: RelationOp,
  525. RemoveOp: RemoveOp,
  526. AddUniqueOp: AddUniqueOp
  527. });