/
prettify-object.js
112 lines (96 loc) 路 3.45 KB
/
prettify-object.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
'use strict'
module.exports = prettifyObject
const {
LOGGER_KEYS
} = require('../constants')
const stringifySafe = require('fast-safe-stringify')
const joinLinesWithIndentation = require('./join-lines-with-indentation')
const prettifyError = require('./prettify-error')
/**
* @typedef {object} PrettifyObjectParams
* @property {object} log The object to prettify.
* @property {boolean} [excludeLoggerKeys] Indicates if known logger specific
* keys should be excluded from prettification. Default: `true`.
* @property {string[]} [skipKeys] A set of object keys to exclude from the
* * prettified result. Default: `[]`.
* @property {PrettyContext} context The context object built from parsing
* the options.
*/
/**
* Prettifies a standard object. Special care is taken when processing the object
* to handle child objects that are attached to keys known to contain error
* objects.
*
* @param {PrettifyObjectParams} input
*
* @returns {string} The prettified string. This can be as little as `''` if
* there was nothing to prettify.
*/
function prettifyObject ({
log,
excludeLoggerKeys = true,
skipKeys = [],
context
}) {
const {
EOL: eol,
IDENT: ident,
customPrettifiers,
errorLikeObjectKeys: errorLikeKeys,
objectColorizer,
singleLine,
colorizer
} = context
const keysToIgnore = [].concat(skipKeys)
/* istanbul ignore else */
if (excludeLoggerKeys === true) Array.prototype.push.apply(keysToIgnore, LOGGER_KEYS)
let result = ''
// Split object keys into two categories: error and non-error
const { plain, errors } = Object.entries(log).reduce(({ plain, errors }, [k, v]) => {
if (keysToIgnore.includes(k) === false) {
// Pre-apply custom prettifiers, because all 3 cases below will need this
const pretty = typeof customPrettifiers[k] === 'function'
? customPrettifiers[k](v, k, log, { colors: colorizer.colors })
: v
if (errorLikeKeys.includes(k)) {
errors[k] = pretty
} else {
plain[k] = pretty
}
}
return { plain, errors }
}, { plain: {}, errors: {} })
if (singleLine) {
// Stringify the entire object as a single JSON line
/* istanbul ignore else */
if (Object.keys(plain).length > 0) {
result += objectColorizer.greyMessage(stringifySafe(plain))
}
result += eol
// Avoid printing the escape character on escaped backslashes.
result = result.replace(/\\\\/gi, '\\')
} else {
// Put each object entry on its own line
Object.entries(plain).forEach(([keyName, keyValue]) => {
// custom prettifiers are already applied above, so we can skip it now
let lines = typeof customPrettifiers[keyName] === 'function'
? keyValue
: stringifySafe(keyValue, null, 2)
if (lines === undefined) return
// Avoid printing the escape character on escaped backslashes.
lines = lines.replace(/\\\\/gi, '\\')
const joinedLines = joinLinesWithIndentation({ input: lines, ident, eol })
result += `${ident}${keyName}:${joinedLines.startsWith(eol) ? '' : ' '}${joinedLines}${eol}`
})
}
// Errors
Object.entries(errors).forEach(([keyName, keyValue]) => {
// custom prettifiers are already applied above, so we can skip it now
const lines = typeof customPrettifiers[keyName] === 'function'
? keyValue
: stringifySafe(keyValue, null, 2)
if (lines === undefined) return
result += prettifyError({ keyName, lines, eol, ident })
})
return result
}