/
index.js
130 lines (125 loc) · 4.21 KB
/
index.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* @copyright 2016- commenthol
* @license MIT
*/
'use strict'
// dependencies
var util = require('./internal/utils')
var Ref = require('./internal/reference')
/**
* serializes an object to javascript
*
* @example <caption>serializing regex, date, buffer, ...</caption>
* var serialize = require('serialize-to-js').serialize;
* var obj = {
* str: '<script>var a = 0 > 1</script>',
* num: 3.1415,
* bool: true,
* nil: null,
* undef: undefined,
* obj: { foo: 'bar' },
* arr: [1, '2'],
* regexp: /^test?$/,
* date: new Date(),
* buffer: new Buffer('data'),
* }
* console.log(serialize(obj))
* // > {str: "\u003Cscript\u003Evar a = 0 \u003E 1\u003C\u002Fscript\u003E", num: 3.1415, bool: true, nil: null, undef: undefined, obj: {foo: "bar"}, arr: [1, "2"], regexp: /^test?$/, date: new Date("2016-04-15T16:22:52.009Z"), buffer: new Buffer('ZGF0YQ==', 'base64')}
*
* @example <caption>serializing while respecting references</caption>
* var serialize = require('serialize-to-js').serialize;
* var obj = { object: { regexp: /^test?$/ } };
* obj.reference = obj.object;
* var opts = { reference: true };
* console.log(serialize(obj, opts));
* //> {object: {regexp: /^test?$/}}
* console.log(opts.references);
* //> [ [ '.reference', '.object' ] ]
*
* @param {Object|Array|Function|Any} source - source to serialize
* @param {Object} [opts] - options
* @param {Boolean} opts.ignoreCircular - ignore circular objects
* @param {Boolean} opts.reference - reference instead of a copy (requires post-processing of opts.references)
* @param {Boolean} opts.unsafe - do not escape chars `<>/`
* @return {String} serialized representation of `source`
*/
function serialize (source, opts) {
var out = ''
var key
var tmp
var type
var i
opts = opts || {}
if (!opts._visited) {
opts._visited = []
}
if (!opts._refs) {
opts.references = []
opts._refs = new Ref(opts.references)
}
if (util.isNull(source)) {
out += 'null'
} else if (util.isArray(source)) {
tmp = source.map(function (item) {
return serialize(item, opts)
})
out += '[' + tmp.join(', ') + ']'
} else if (util.isFunction(source)) {
tmp = source.toString()
// append function to es6 function within obj
out += !/^\s*(function|\([^)]*\)\s*=>)/m.test(tmp) ? 'function ' + tmp : tmp
} else if (util.isObject(source)) {
if (util.isRegExp(source)) {
out += 'new RegExp("' + source.source + '", "' + source.flags + '")'
} else if (util.isDate(source)) {
out += 'new Date("' + source.toJSON() + '")'
} else if (util.isError(source)) {
out += 'new Error(' + (source.message ? '"' + source.message + '"' : '') + ')'
} else if (util.isBuffer(source)) {
// check for buffer first otherwise tests fail on node@4.4
// looks like buffers are accidentially detected as typed arrays
out += "Buffer.from('" + source.toString('base64') + "', 'base64')"
} else if ((type = util.isTypedArray(source))) {
tmp = []
for (i = 0; i < source.length; i++) {
tmp.push(source[i])
}
out += 'new ' + type + '(' +
'[' + tmp.join(', ') + ']' +
')'
} else {
tmp = []
// copy properties if not circular
if (!~opts._visited.indexOf(source)) {
opts._visited.push(source)
for (key in source) {
if (source.hasOwnProperty(key)) {
if (opts.reference && util.isObject(source[key])) {
opts._refs.push(key)
if (!opts._refs.hasReference(source[key])) {
tmp.push(Ref.wrapkey(key) + ': ' + serialize(source[key], opts))
}
opts._refs.pop()
} else {
tmp.push(Ref.wrapkey(key) + ': ' + serialize(source[key], opts))
}
}
}
out += '{' + tmp.join(', ') + '}'
opts._visited.pop()
} else {
if (opts.ignoreCircular) {
out += '{/*[Circular]*/}'
} else {
throw new Error('can not convert circular structures.')
}
}
}
} else if (util.isString(source)) {
out += '"' + (opts.unsafe ? util.unsafeString(source) : util.safeString(source)) + '"'
} else {
out += '' + source
}
return out
}
module.exports = serialize