1 |
|
// Load modules |
2 |
|
|
3 |
1 |
require('colors'); |
4 |
1 |
var Hoek = require('hoek'); |
5 |
|
|
6 |
|
|
7 |
|
// declare internals |
8 |
|
|
9 |
1 |
var internals = { |
10 |
|
indentLevel: 0, |
11 |
|
seen: [], |
12 |
|
colors: { |
13 |
|
BoolFalse: 'red.bold', |
14 |
|
BoolTrue: 'green.bold', |
15 |
|
Circular: 'grey.bold', |
16 |
|
Date: 'green', |
17 |
|
Function: 'cyan', |
18 |
|
Key: 'white.bold', |
19 |
|
Null: 'red.bold', |
20 |
|
Number: 'blue.bold', |
21 |
|
RegExp: 'magenta', |
22 |
|
String: 'yellow', |
23 |
|
Undefined: 'red.inverse' |
24 |
|
}, |
25 |
|
defaults: { |
26 |
|
plain: false |
27 |
|
} |
28 |
|
}; |
29 |
|
|
30 |
1 |
internals.purdy = function (object, options) { |
31 |
|
|
32 |
|
return console.log(internals.stringify(object, options)); |
33 |
|
}; |
34 |
|
|
35 |
1 |
internals.stringify = function (object, options) { |
36 |
|
|
37 |
17 |
internals.settings = Hoek.applyToDefaults(internals.defaults, options || {}); |
38 |
17 |
return internals.travel(object); |
39 |
|
}; |
40 |
|
|
41 |
1 |
internals.purdy.stringify = internals.stringify; |
42 |
|
|
43 |
|
|
44 |
1 |
module.exports = internals.purdy; |
45 |
|
|
46 |
|
|
47 |
1 |
internals.travel = function (object, addIndentLevel) { |
48 |
|
|
49 |
37 |
var type = toString.call(object).split(' ')[1].slice(0,-1); |
50 |
37 |
var format = ''; |
51 |
|
|
52 |
37 |
if (internals[type]) { |
53 |
19 |
format = internals[type](object); |
54 |
|
} |
55 |
|
else { |
56 |
18 |
format = object + ''; |
57 |
|
} |
58 |
|
|
59 |
37 |
return internals.colorize(format, type); |
60 |
|
}; |
61 |
|
|
62 |
1 |
internals.colorize = function (string, type) { |
63 |
|
|
64 |
63 |
if (internals.settings.plain) { |
65 |
1 |
return string; |
66 |
|
} |
67 |
|
|
68 |
62 |
var colors = internals.colors[type]; |
69 |
62 |
if (!colors) { |
70 |
14 |
return string; |
71 |
|
} |
72 |
|
|
73 |
48 |
var colorArr = colors.split('.'); |
74 |
|
|
75 |
48 |
for (var i = 0, il = colorArr.length; i < il; ++i) { |
76 |
88 |
var color = colorArr[i]; |
77 |
88 |
string = string[color]; |
78 |
|
} |
79 |
|
|
80 |
48 |
return string; |
81 |
|
}; |
82 |
|
|
83 |
|
|
84 |
1 |
internals.lengthCompare = function (a,b) { |
85 |
1 |
return a.length - b.length |
86 |
|
}; |
87 |
|
|
88 |
1 |
internals.Object = function(object) { |
89 |
|
|
90 |
5 |
if (Object.keys(object).length === 0) { |
91 |
1 |
return '{}'; |
92 |
|
} |
93 |
|
|
94 |
4 |
if (internals.seen.indexOf(object) !== -1) { |
95 |
1 |
return internals.colorize('[Circular]', 'Circular'); |
96 |
|
} |
97 |
3 |
internals.seen.push(object); |
98 |
|
|
99 |
3 |
var keys = Object.keys(object); |
100 |
3 |
var out = '{\n'; |
101 |
3 |
internals.indentLevel = internals.indentLevel + 1; |
102 |
|
|
103 |
3 |
var longest = Hoek.clone(keys).sort(internals.lengthCompare)[keys.length - 1]; |
104 |
|
|
105 |
3 |
for (var i = 0, il = keys.length; i < il; ++i) { |
106 |
4 |
var key = keys[i]; |
107 |
4 |
var item = object[key]; |
108 |
4 |
out = out + internals.indent() + '' + (internals.printMember(key, longest) + ':') + ' ' + internals.travel(item); |
109 |
4 |
if (i !== il - 1) { |
110 |
1 |
out = out + ','; |
111 |
|
} |
112 |
4 |
out = out + '\n'; |
113 |
|
} |
114 |
3 |
internals.indentLevel = internals.indentLevel - 1; |
115 |
3 |
out = out + internals.indent() + '}'; |
116 |
3 |
return out; |
117 |
|
}; |
118 |
|
|
119 |
|
|
120 |
1 |
internals.Array = function (array) { |
121 |
|
|
122 |
7 |
if (array.length === 0) { |
123 |
1 |
return '[]'; |
124 |
|
} |
125 |
|
|
126 |
6 |
if (internals.seen.indexOf(array) !== -1) { |
127 |
1 |
return internals.colorize('[Circular]', 'Circular'); |
128 |
|
} |
129 |
5 |
internals.seen.push(array); |
130 |
|
|
131 |
5 |
var out = '[\n'; |
132 |
5 |
internals.indentLevel = internals.indentLevel + 1; |
133 |
|
|
134 |
5 |
for (var i = 0, il = array.length; i < il; ++i) { |
135 |
16 |
var item = array[i]; |
136 |
16 |
out = out + internals.indent() + '' + ('[' + internals.printMember(i, il) + ']') + ' ' + internals.travel(item); |
137 |
16 |
if (i !== il - 1) { |
138 |
11 |
out = out + ','; |
139 |
|
} |
140 |
16 |
out = out + '\n'; |
141 |
|
} |
142 |
5 |
internals.indentLevel = internals.indentLevel - 1; |
143 |
5 |
out = out + internals.indent() + ']'; |
144 |
5 |
return out; |
145 |
|
}; |
146 |
|
|
147 |
1 |
internals.String = function(str) { |
148 |
|
|
149 |
3 |
return '\'' + str + '\''; |
150 |
|
}; |
151 |
|
|
152 |
|
|
153 |
1 |
internals.Boolean = function(bool) { |
154 |
|
|
155 |
2 |
if (bool === true) { |
156 |
1 |
return internals.colorize(bool + '', 'BoolTrue'); |
157 |
|
} |
158 |
1 |
return internals.colorize(bool + '', 'BoolFalse'); |
159 |
|
}; |
160 |
|
|
161 |
|
|
162 |
1 |
internals.Function = function(func) { |
163 |
2 |
if (func.name) { |
164 |
1 |
return internals.colorize('[Function: ' + func.name + ']', 'Function'); |
165 |
|
} |
166 |
1 |
return internals.colorize('[Function: ?]', 'Function'); |
167 |
|
}; |
168 |
|
|
169 |
1 |
internals.indent = function () { |
170 |
|
|
171 |
28 |
return internals.spaces(internals.indentLevel * 4); |
172 |
|
}; |
173 |
|
|
174 |
|
|
175 |
1 |
internals.spaces = function (count) { |
176 |
|
|
177 |
48 |
var out = ''; |
178 |
48 |
for (var i = 0; i < count; i++) { |
179 |
141 |
out = out + ' '; |
180 |
|
} |
181 |
|
|
182 |
48 |
return out; |
183 |
|
}; |
184 |
|
|
185 |
|
|
186 |
1 |
internals.printMember = function (member, max) { |
187 |
|
|
188 |
20 |
var memberLength = (member + '').length; |
189 |
20 |
var maxLength = (max + '').length; |
190 |
20 |
var toShift = maxLength - memberLength; |
191 |
20 |
return internals.colorize(internals.spaces(toShift) + member, 'Key'); |
192 |
|
}; |
193 |
|
|