-
-
Notifications
You must be signed in to change notification settings - Fork 595
/
Copy pathencode.js
110 lines (100 loc) · 2.87 KB
/
encode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* @flow
*/
import ParseACL from './ParseACL';
import ParseFile from './ParseFile';
import ParseGeoPoint from './ParseGeoPoint';
import ParsePolygon from './ParsePolygon';
import ParseObject from './ParseObject';
import { Op } from './ParseOp';
import ParseRelation from './ParseRelation';
const MAX_RECURSIVE_CALLS = 999;
function encode(
value: mixed,
disallowObjects: boolean,
forcePointers: boolean,
seen: Array<mixed>,
offline: boolean,
counter: number = 0
): any {
counter++;
if (counter > MAX_RECURSIVE_CALLS) {
const message = 'Maximum recursive calls exceeded in encode function. Potential infinite recursion detected.';
console.error(message);
console.error('Value causing potential infinite recursion:', value);
console.error('Disallow objects:', disallowObjects);
console.error('Force pointers:', forcePointers);
console.error('Seen:', seen);
console.error('Offline:', offline);
throw new Error(message);
}
if (value instanceof ParseObject) {
if (disallowObjects) {
throw new Error('Parse Objects not allowed here');
}
const seenEntry = value.id ? value.className + ':' + value.id : value;
if (
forcePointers ||
!seen ||
seen.indexOf(seenEntry) > -1 ||
value.dirty() ||
Object.keys(value._getServerData()).length < 1
) {
if (offline && value._getId().startsWith('local')) {
return value.toOfflinePointer();
}
return value.toPointer();
}
seen = seen.concat(seenEntry);
return value._toFullJSON(seen, offline);
}
if (
value instanceof Op ||
value instanceof ParseACL ||
value instanceof ParseGeoPoint ||
value instanceof ParsePolygon ||
value instanceof ParseRelation
) {
return value.toJSON();
}
if (value instanceof ParseFile) {
if (!value.url()) {
throw new Error('Tried to encode an unsaved file.');
}
return value.toJSON();
}
if (Object.prototype.toString.call(value) === '[object Date]') {
if (isNaN(value)) {
throw new Error('Tried to encode an invalid date.');
}
return { __type: 'Date', iso: (value: any).toJSON() };
}
if (
Object.prototype.toString.call(value) === '[object RegExp]' &&
typeof value.source === 'string'
) {
return value.source;
}
if (Array.isArray(value)) {
return value.map(v => {
return encode(v, disallowObjects, forcePointers, seen, offline, counter);
});
}
if (value && typeof value === 'object') {
const output = {};
for (const k in value) {
output[k] = encode(value[k], disallowObjects, forcePointers, seen, offline, counter);
}
return output;
}
return value;
}
export default function (
value: mixed,
disallowObjects?: boolean,
forcePointers?: boolean,
seen?: Array<mixed>,
offline?: boolean
): any {
return encode(value, !!disallowObjects, !!forcePointers, seen || [], offline, 0);
}