-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
sanitize-node.js
77 lines (64 loc) · 1.57 KB
/
sanitize-node.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
import _ from "lodash"
/**
* Make data serializable
* @param {(Object|Array)} data to sanitize
* @param {boolean} isNode = true
* @param {Set<string>} path = new Set
*/
const sanitizeNode = (data, isNode = true, path = new Set()) => {
const isPlainObject = _.isPlainObject(data)
if (isPlainObject || _.isArray(data)) {
if (path.has(data)) return data
path.add(data)
const returnData = isPlainObject ? {} : []
let anyFieldChanged = false
_.each(data, (o, key) => {
if (isNode && key === `internal`) {
returnData[key] = o
return
}
returnData[key] = sanitizeNode(o, false, path)
if (returnData[key] !== o) {
anyFieldChanged = true
}
})
if (anyFieldChanged) {
data = omitUndefined(returnData)
}
// arrays and plain objects are supported - no need to to sanitize
return data
}
if (!isTypeSupported(data)) {
return undefined
} else {
return data
}
}
/**
* @param {Object|Array} data
* @returns {Object|Array} data without undefined values
*/
const omitUndefined = data => {
const isPlainObject = _.isPlainObject(data)
if (isPlainObject) {
return _.pickBy(data, p => p !== undefined)
}
return data.filter(p => p !== undefined)
}
/**
* @param {*} data
* @return {boolean}
*/
const isTypeSupported = data => {
if (data === null) {
return true
}
const type = typeof data
const isSupported =
type === `number` ||
type === `string` ||
type === `boolean` ||
data instanceof Date
return isSupported
}
module.exports = sanitizeNode