encode.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Copyright (c) 2015-present, Parse, LLC.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. * @flow
  10. */
  11. import ParseACL from './ParseACL';
  12. import ParseFile from './ParseFile';
  13. import ParseGeoPoint from './ParseGeoPoint';
  14. import ParsePolygon from './ParsePolygon';
  15. import ParseObject from './ParseObject';
  16. import { Op } from './ParseOp';
  17. import ParseRelation from './ParseRelation';
  18. const toString = Object.prototype.toString;
  19. function encode(value
  20. /*: mixed*/
  21. , disallowObjects
  22. /*: boolean*/
  23. , forcePointers
  24. /*: boolean*/
  25. , seen
  26. /*: Array<mixed>*/
  27. )
  28. /*: any*/
  29. {
  30. if (value instanceof ParseObject) {
  31. if (disallowObjects) {
  32. throw new Error('Parse Objects not allowed here');
  33. }
  34. const seenEntry = value.id ? value.className + ':' + value.id : value;
  35. if (forcePointers || !seen || seen.indexOf(seenEntry) > -1 || value.dirty() || Object.keys(value._getServerData()).length < 1) {
  36. return value.toPointer();
  37. }
  38. seen = seen.concat(seenEntry);
  39. return value._toFullJSON(seen);
  40. }
  41. if (value instanceof Op || value instanceof ParseACL || value instanceof ParseGeoPoint || value instanceof ParsePolygon || value instanceof ParseRelation) {
  42. return value.toJSON();
  43. }
  44. if (value instanceof ParseFile) {
  45. if (!value.url()) {
  46. throw new Error('Tried to encode an unsaved file.');
  47. }
  48. return value.toJSON();
  49. }
  50. if (toString.call(value) === '[object Date]') {
  51. if (isNaN(value)) {
  52. throw new Error('Tried to encode an invalid date.');
  53. }
  54. return {
  55. __type: 'Date',
  56. iso: value
  57. /*: any*/
  58. .toJSON()
  59. };
  60. }
  61. if (toString.call(value) === '[object RegExp]' && typeof value.source === 'string') {
  62. return value.source;
  63. }
  64. if (Array.isArray(value)) {
  65. return value.map(v => {
  66. return encode(v, disallowObjects, forcePointers, seen);
  67. });
  68. }
  69. if (value && typeof value === 'object') {
  70. const output = {};
  71. for (const k in value) {
  72. output[k] = encode(value[k], disallowObjects, forcePointers, seen);
  73. }
  74. return output;
  75. }
  76. return value;
  77. }
  78. export default function (value
  79. /*: mixed*/
  80. , disallowObjects
  81. /*:: ?: boolean*/
  82. , forcePointers
  83. /*:: ?: boolean*/
  84. , seen
  85. /*:: ?: Array<mixed>*/
  86. )
  87. /*: any*/
  88. {
  89. return encode(value, !!disallowObjects, !!forcePointers, seen || []);
  90. }