| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 | "use strict";Object.defineProperty(exports, "__esModule", {  value: true});exports.UnsetOp = exports.SetOp = exports.RemoveOp = exports.RelationOp = exports.Op = exports.IncrementOp = exports.AddUniqueOp = exports.AddOp = void 0;exports.opFromJSON = opFromJSON;var _arrayContainsObject = _interopRequireDefault(require("./arrayContainsObject"));var _decode = _interopRequireDefault(require("./decode"));var _encode = _interopRequireDefault(require("./encode"));var _ParseObject = _interopRequireDefault(require("./ParseObject"));var _ParseRelation = _interopRequireDefault(require("./ParseRelation"));var _unique = _interopRequireDefault(require("./unique"));function _interopRequireDefault(obj) {  return obj && obj.__esModule ? obj : {    default: obj  };}/** * @flow */function opFromJSON(json /*: { [key: string]: any }*/) /*: ?Op*/{  if (!json || !json.__op) {    return null;  }  switch (json.__op) {    case 'Delete':      return new UnsetOp();    case 'Increment':      return new IncrementOp(json.amount);    case 'Add':      return new AddOp((0, _decode.default)(json.objects));    case 'AddUnique':      return new AddUniqueOp((0, _decode.default)(json.objects));    case 'Remove':      return new RemoveOp((0, _decode.default)(json.objects));    case 'AddRelation':      {        const toAdd = (0, _decode.default)(json.objects);        if (!Array.isArray(toAdd)) {          return new RelationOp([], []);        }        return new RelationOp(toAdd, []);      }    case 'RemoveRelation':      {        const toRemove = (0, _decode.default)(json.objects);        if (!Array.isArray(toRemove)) {          return new RelationOp([], []);        }        return new RelationOp([], toRemove);      }    case 'Batch':      {        let toAdd = [];        let toRemove = [];        for (let i = 0; i < json.ops.length; i++) {          if (json.ops[i].__op === 'AddRelation') {            toAdd = toAdd.concat((0, _decode.default)(json.ops[i].objects));          } else if (json.ops[i].__op === 'RemoveRelation') {            toRemove = toRemove.concat((0, _decode.default)(json.ops[i].objects));          }        }        return new RelationOp(toAdd, toRemove);      }  }  return null;}class Op {  // Empty parent class  applyTo() /*: mixed*/{} /* eslint-disable-line no-unused-vars */  mergeWith() /*: ?Op*/{} /* eslint-disable-line no-unused-vars */  toJSON() /*: mixed*/{}}exports.Op = Op;class SetOp extends Op {  /*:: _value: ?mixed;*/  constructor(value /*: mixed*/) {    super();    this._value = value;  }  applyTo() /*: mixed*/{    return this._value;  }  mergeWith() /*: SetOp*/{    return new SetOp(this._value);  }  toJSON(offline /*:: ?: boolean*/) {    return (0, _encode.default)(this._value, false, true, undefined, offline);  }}exports.SetOp = SetOp;class UnsetOp extends Op {  applyTo() {    return undefined;  }  mergeWith() /*: UnsetOp*/{    return new UnsetOp();  }  toJSON() /*: { __op: string }*/{    return {      __op: 'Delete'    };  }}exports.UnsetOp = UnsetOp;class IncrementOp extends Op {  /*:: _amount: number;*/  constructor(amount /*: number*/) {    super();    if (typeof amount !== 'number') {      throw new TypeError('Increment Op must be initialized with a numeric amount.');    }    this._amount = amount;  }  applyTo(value /*: ?mixed*/) /*: number*/{    if (typeof value === 'undefined') {      return this._amount;    }    if (typeof value !== 'number') {      throw new TypeError('Cannot increment a non-numeric value.');    }    return this._amount + value;  }  mergeWith(previous /*: Op*/) /*: Op*/{    if (!previous) {      return this;    }    if (previous instanceof SetOp) {      return new SetOp(this.applyTo(previous._value));    }    if (previous instanceof UnsetOp) {      return new SetOp(this._amount);    }    if (previous instanceof IncrementOp) {      return new IncrementOp(this.applyTo(previous._amount));    }    throw new Error('Cannot merge Increment Op with the previous Op');  }  toJSON() /*: { __op: string, amount: number }*/{    return {      __op: 'Increment',      amount: this._amount    };  }}exports.IncrementOp = IncrementOp;class AddOp extends Op {  /*:: _value: Array<mixed>;*/  constructor(value /*: mixed | Array<mixed>*/) {    super();    this._value = Array.isArray(value) ? value : [value];  }  applyTo(value /*: mixed*/) /*: Array<mixed>*/{    if (value == null) {      return this._value;    }    if (Array.isArray(value)) {      return value.concat(this._value);    }    throw new Error('Cannot add elements to a non-array value');  }  mergeWith(previous /*: Op*/) /*: Op*/{    if (!previous) {      return this;    }    if (previous instanceof SetOp) {      return new SetOp(this.applyTo(previous._value));    }    if (previous instanceof UnsetOp) {      return new SetOp(this._value);    }    if (previous instanceof AddOp) {      return new AddOp(this.applyTo(previous._value));    }    throw new Error('Cannot merge Add Op with the previous Op');  }  toJSON() /*: { __op: string, objects: mixed }*/{    return {      __op: 'Add',      objects: (0, _encode.default)(this._value, false, true)    };  }}exports.AddOp = AddOp;class AddUniqueOp extends Op {  /*:: _value: Array<mixed>;*/  constructor(value /*: mixed | Array<mixed>*/) {    super();    this._value = (0, _unique.default)(Array.isArray(value) ? value : [value]);  }  applyTo(value /*: mixed | Array<mixed>*/) /*: Array<mixed>*/{    if (value == null) {      return this._value || [];    }    if (Array.isArray(value)) {      const toAdd = [];      this._value.forEach(v => {        if (v instanceof _ParseObject.default) {          if (!(0, _arrayContainsObject.default)(value, v)) {            toAdd.push(v);          }        } else {          if (value.indexOf(v) < 0) {            toAdd.push(v);          }        }      });      return value.concat(toAdd);    }    throw new Error('Cannot add elements to a non-array value');  }  mergeWith(previous /*: Op*/) /*: Op*/{    if (!previous) {      return this;    }    if (previous instanceof SetOp) {      return new SetOp(this.applyTo(previous._value));    }    if (previous instanceof UnsetOp) {      return new SetOp(this._value);    }    if (previous instanceof AddUniqueOp) {      return new AddUniqueOp(this.applyTo(previous._value));    }    throw new Error('Cannot merge AddUnique Op with the previous Op');  }  toJSON() /*: { __op: string, objects: mixed }*/{    return {      __op: 'AddUnique',      objects: (0, _encode.default)(this._value, false, true)    };  }}exports.AddUniqueOp = AddUniqueOp;class RemoveOp extends Op {  /*:: _value: Array<mixed>;*/  constructor(value /*: mixed | Array<mixed>*/) {    super();    this._value = (0, _unique.default)(Array.isArray(value) ? value : [value]);  }  applyTo(value /*: mixed | Array<mixed>*/) /*: Array<mixed>*/{    if (value == null) {      return [];    }    if (Array.isArray(value)) {      // var i = value.indexOf(this._value);      const removed = value.concat([]);      for (let i = 0; i < this._value.length; i++) {        let index = removed.indexOf(this._value[i]);        while (index > -1) {          removed.splice(index, 1);          index = removed.indexOf(this._value[i]);        }        if (this._value[i] instanceof _ParseObject.default && this._value[i].id) {          for (let j = 0; j < removed.length; j++) {            if (removed[j] instanceof _ParseObject.default && this._value[i].id === removed[j].id) {              removed.splice(j, 1);              j--;            }          }        }      }      return removed;    }    throw new Error('Cannot remove elements from a non-array value');  }  mergeWith(previous /*: Op*/) /*: Op*/{    if (!previous) {      return this;    }    if (previous instanceof SetOp) {      return new SetOp(this.applyTo(previous._value));    }    if (previous instanceof UnsetOp) {      return new UnsetOp();    }    if (previous instanceof RemoveOp) {      const uniques = previous._value.concat([]);      for (let i = 0; i < this._value.length; i++) {        if (this._value[i] instanceof _ParseObject.default) {          if (!(0, _arrayContainsObject.default)(uniques, this._value[i])) {            uniques.push(this._value[i]);          }        } else {          if (uniques.indexOf(this._value[i]) < 0) {            uniques.push(this._value[i]);          }        }      }      return new RemoveOp(uniques);    }    throw new Error('Cannot merge Remove Op with the previous Op');  }  toJSON() /*: { __op: string, objects: mixed }*/{    return {      __op: 'Remove',      objects: (0, _encode.default)(this._value, false, true)    };  }}exports.RemoveOp = RemoveOp;class RelationOp extends Op {  /*:: _targetClassName: ?string;*/  /*:: relationsToAdd: Array<string>;*/  /*:: relationsToRemove: Array<string>;*/  constructor(adds /*: Array<ParseObject | string>*/, removes /*: Array<ParseObject | string>*/) {    super();    this._targetClassName = null;    if (Array.isArray(adds)) {      this.relationsToAdd = (0, _unique.default)(adds.map(this._extractId, this));    }    if (Array.isArray(removes)) {      this.relationsToRemove = (0, _unique.default)(removes.map(this._extractId, this));    }  }  _extractId(obj /*: string | ParseObject*/) /*: string*/{    if (typeof obj === 'string') {      return obj;    }    if (!obj.id) {      throw new Error('You cannot add or remove an unsaved Parse Object from a relation');    }    if (!this._targetClassName) {      this._targetClassName = obj.className;    }    if (this._targetClassName !== obj.className) {      throw new Error('Tried to create a Relation with 2 different object types: ' + this._targetClassName + ' and ' + obj.className + '.');    }    return obj.id;  }  applyTo(value /*: mixed*/, object /*:: ?: { className: string, id: ?string }*/, key /*:: ?: string*/) /*: ?ParseRelation*/{    if (!value) {      if (!object || !key) {        throw new Error('Cannot apply a RelationOp without either a previous value, or an object and a key');      }      const parent = new _ParseObject.default(object.className);      if (object.id && object.id.indexOf('local') === 0) {        parent._localId = object.id;      } else if (object.id) {        parent.id = object.id;      }      const relation = new _ParseRelation.default(parent, key);      relation.targetClassName = this._targetClassName;      return relation;    }    if (value instanceof _ParseRelation.default) {      if (this._targetClassName) {        if (value.targetClassName) {          if (this._targetClassName !== value.targetClassName) {            throw new Error('Related object must be a ' + value.targetClassName + ', but a ' + this._targetClassName + ' was passed in.');          }        } else {          value.targetClassName = this._targetClassName;        }      }      return value;    } else {      throw new Error('Relation cannot be applied to a non-relation field');    }  }  mergeWith(previous /*: Op*/) /*: Op*/{    if (!previous) {      return this;    } else if (previous instanceof UnsetOp) {      throw new Error('You cannot modify a relation after deleting it.');    } else if (previous instanceof SetOp && previous._value instanceof _ParseRelation.default) {      return this;    } else if (previous instanceof RelationOp) {      if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {        throw new Error('Related object must be of class ' + previous._targetClassName + ', but ' + (this._targetClassName || 'null') + ' was passed in.');      }      const newAdd = previous.relationsToAdd.concat([]);      this.relationsToRemove.forEach(r => {        const index = newAdd.indexOf(r);        if (index > -1) {          newAdd.splice(index, 1);        }      });      this.relationsToAdd.forEach(r => {        const index = newAdd.indexOf(r);        if (index < 0) {          newAdd.push(r);        }      });      const newRemove = previous.relationsToRemove.concat([]);      this.relationsToAdd.forEach(r => {        const index = newRemove.indexOf(r);        if (index > -1) {          newRemove.splice(index, 1);        }      });      this.relationsToRemove.forEach(r => {        const index = newRemove.indexOf(r);        if (index < 0) {          newRemove.push(r);        }      });      const newRelation = new RelationOp(newAdd, newRemove);      newRelation._targetClassName = this._targetClassName;      return newRelation;    }    throw new Error('Cannot merge Relation Op with the previous Op');  }  toJSON() /*: { __op?: string, objects?: mixed, ops?: mixed }*/{    const idToPointer = id => {      return {        __type: 'Pointer',        className: this._targetClassName,        objectId: id      };    };    let adds = null;    let removes = null;    let pointers = null;    if (this.relationsToAdd.length > 0) {      pointers = this.relationsToAdd.map(idToPointer);      adds = {        __op: 'AddRelation',        objects: pointers      };    }    if (this.relationsToRemove.length > 0) {      pointers = this.relationsToRemove.map(idToPointer);      removes = {        __op: 'RemoveRelation',        objects: pointers      };    }    if (adds && removes) {      return {        __op: 'Batch',        ops: [adds, removes]      };    }    return adds || removes || {};  }}exports.RelationOp = RelationOp;
 |