source: node_modules/jsonify/lib/stringify.js@ d24f17c

main
Last change on this file since d24f17c was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[d24f17c]1'use strict';
2
3var escapable = /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
4var gap;
5var indent;
6var meta = { // table of character substitutions
7 '\b': '\\b',
8 '\t': '\\t',
9 '\n': '\\n',
10 '\f': '\\f',
11 '\r': '\\r',
12 '"': '\\"',
13 '\\': '\\\\'
14};
15var rep;
16
17function quote(string) {
18 // If the string contains no control characters, no quote characters, and no
19 // backslash characters, then we can safely slap some quotes around it.
20 // Otherwise we must also replace the offending characters with safe escape sequences.
21
22 escapable.lastIndex = 0;
23 return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
24 var c = meta[a];
25 return typeof c === 'string' ? c
26 : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
27 }) + '"' : '"' + string + '"';
28}
29
30function str(key, holder) {
31 // Produce a string from holder[key].
32 var i; // The loop counter.
33 var k; // The member key.
34 var v; // The member value.
35 var length;
36 var mind = gap;
37 var partial;
38 var value = holder[key];
39
40 // If the value has a toJSON method, call it to obtain a replacement value.
41 if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
42 value = value.toJSON(key);
43 }
44
45 // If we were called with a replacer function, then call the replacer to obtain a replacement value.
46 if (typeof rep === 'function') {
47 value = rep.call(holder, key, value);
48 }
49
50 // What happens next depends on the value's type.
51 switch (typeof value) {
52 case 'string':
53 return quote(value);
54
55 case 'number':
56 // JSON numbers must be finite. Encode non-finite numbers as null.
57 return isFinite(value) ? String(value) : 'null';
58
59 case 'boolean':
60 case 'null':
61 // If the value is a boolean or null, convert it to a string. Note:
62 // typeof null does not produce 'null'. The case is included here in
63 // the remote chance that this gets fixed someday.
64 return String(value);
65
66 case 'object':
67 if (!value) {
68 return 'null';
69 }
70 gap += indent;
71 partial = [];
72
73 // Array.isArray
74 if (Object.prototype.toString.apply(value) === '[object Array]') {
75 length = value.length;
76 for (i = 0; i < length; i += 1) {
77 partial[i] = str(i, value) || 'null';
78 }
79
80 // Join all of the elements together, separated with commas, and wrap them in brackets.
81 v = partial.length === 0 ? '[]' : gap
82 ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
83 : '[' + partial.join(',') + ']';
84 gap = mind;
85 return v;
86 }
87
88 // If the replacer is an array, use it to select the members to be stringified.
89 if (rep && typeof rep === 'object') {
90 length = rep.length;
91 for (i = 0; i < length; i += 1) {
92 k = rep[i];
93 if (typeof k === 'string') {
94 v = str(k, value);
95 if (v) {
96 partial.push(quote(k) + (gap ? ': ' : ':') + v);
97 }
98 }
99 }
100 } else {
101 // Otherwise, iterate through all of the keys in the object.
102 for (k in value) {
103 if (Object.prototype.hasOwnProperty.call(value, k)) {
104 v = str(k, value);
105 if (v) {
106 partial.push(quote(k) + (gap ? ': ' : ':') + v);
107 }
108 }
109 }
110 }
111
112 // Join all of the member texts together, separated with commas, and wrap them in braces.
113
114 v = partial.length === 0 ? '{}' : gap
115 ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
116 : '{' + partial.join(',') + '}';
117 gap = mind;
118 return v;
119 default:
120 }
121}
122
123module.exports = function (value, replacer, space) {
124 var i;
125 gap = '';
126 indent = '';
127
128 // If the space parameter is a number, make an indent string containing that many spaces.
129 if (typeof space === 'number') {
130 for (i = 0; i < space; i += 1) {
131 indent += ' ';
132 }
133 } else if (typeof space === 'string') {
134 // If the space parameter is a string, it will be used as the indent string.
135 indent = space;
136 }
137
138 // If there is a replacer, it must be a function or an array. Otherwise, throw an error.
139 rep = replacer;
140 if (
141 replacer
142 && typeof replacer !== 'function'
143 && (typeof replacer !== 'object' || typeof replacer.length !== 'number')
144 ) {
145 throw new Error('JSON.stringify');
146 }
147
148 // Make a fake root object containing our value under the key of ''.
149 // Return the result of stringifying the value.
150 return str('', { '': value });
151};
Note: See TracBrowser for help on using the repository browser.