pino-pretty
Advanced tools
Comparing version 9.4.0 to 9.4.1
@@ -165,3 +165,3 @@ 'use strict' | ||
if (prettifiedMessage) { | ||
if (prettifiedMessage !== undefined) { | ||
if (line.length > 0) { | ||
@@ -190,3 +190,3 @@ line = `${line} ${prettifiedMessage}` | ||
} else if (!hideObject) { | ||
const skipKeys = [messageKey, levelKey, timestampKey].filter(key => typeof log[key] === 'string' || typeof log[key] === 'number') | ||
const skipKeys = [messageKey, levelKey, timestampKey].filter(key => typeof log[key] === 'string' || typeof log[key] === 'number' || typeof log[key] === 'boolean') | ||
const prettifiedObject = prettifyObject({ | ||
@@ -193,0 +193,0 @@ input: log, |
@@ -41,4 +41,5 @@ 'use strict' | ||
prettifyError, | ||
getPropertyValue, | ||
deleteLogProperty, | ||
splitIgnoreKey, | ||
splitPropertyKey, | ||
createDate, | ||
@@ -239,4 +240,4 @@ isValidDate | ||
function prettifyLevel ({ log, colorizer = defaultColorizer, levelKey = LEVEL_KEY, prettifier, customLevels, customLevelNames }) { | ||
if (levelKey in log === false) return undefined | ||
const output = log[levelKey] | ||
const output = getPropertyValue(log, levelKey) | ||
if (output === undefined) return undefined | ||
return prettifier ? prettifier(output) : colorizer(output, { customLevels, customLevelNames }) | ||
@@ -269,13 +270,9 @@ } | ||
// return log level as string instead of int | ||
if (p1 === levelLabel && log[levelKey]) { | ||
const condition = useOnlyCustomProps ? customLevels === undefined : customLevels[log[levelKey]] === undefined | ||
return condition ? LEVELS[log[levelKey]] : customLevels[log[levelKey]] | ||
let level | ||
if (p1 === levelLabel && (level = getPropertyValue(log, levelKey)) !== undefined) { | ||
const condition = useOnlyCustomProps ? customLevels === undefined : customLevels[level] === undefined | ||
return condition ? LEVELS[level] : customLevels[level] | ||
} | ||
// Parse nested key access, e.g. `{keyA.subKeyB}`. | ||
return p1.split('.').reduce(function (prev, curr) { | ||
if (prev && prev[curr]) { | ||
return prev[curr] | ||
} | ||
return '' | ||
}, log) | ||
return getPropertyValue(log, p1) || '' | ||
}) | ||
@@ -289,3 +286,3 @@ return colorizer.message(message) | ||
if (messageKey in log === false) return undefined | ||
if (typeof log[messageKey] !== 'string') return undefined | ||
if (typeof log[messageKey] !== 'string' && typeof log[messageKey] !== 'number' && typeof log[messageKey] !== 'boolean') return undefined | ||
return colorizer.message(log[messageKey]) | ||
@@ -517,3 +514,3 @@ } | ||
/** | ||
* Splits the input key delimited by a dot character but not when it is preceded | ||
* Splits the property key delimited by a dot character but not when it is preceded | ||
* by a backslash. | ||
@@ -526,3 +523,3 @@ * | ||
*/ | ||
function splitIgnoreKey (key) { | ||
function splitPropertyKey (key) { | ||
const result = [] | ||
@@ -565,2 +562,27 @@ let backslash = false | ||
/** | ||
* Gets a specified property from an object if it exists. | ||
* | ||
* @param {object} obj The object to be searched. | ||
* @param {string|string[]} property A string, or an array of strings, identifying | ||
* the property to be retrieved from the object. | ||
* Accepts nested properties delimited by a `.`. | ||
* Delimiter can be escaped to preserve property names that contain the delimiter. | ||
* e.g. `'prop1.prop2'` or `'prop2\.domain\.corp.prop2'`. | ||
* | ||
* @returns {*} | ||
*/ | ||
function getPropertyValue (obj, property) { | ||
const props = Array.isArray(property) ? property : splitPropertyKey(property) | ||
for (const prop of props) { | ||
if (!Object.prototype.hasOwnProperty.call(obj, prop)) { | ||
return | ||
} | ||
obj = obj[prop] | ||
} | ||
return obj | ||
} | ||
/** | ||
* Deletes a specified property from a log object if it exists. | ||
@@ -576,13 +598,10 @@ * This function mutates the passed in `log` object. | ||
function deleteLogProperty (log, property) { | ||
const props = splitIgnoreKey(property) | ||
const props = splitPropertyKey(property) | ||
const propToDelete = props.pop() | ||
props.forEach((prop) => { | ||
if (!Object.prototype.hasOwnProperty.call(log, prop)) { | ||
return | ||
} | ||
log = log[prop] | ||
}) | ||
log = getPropertyValue(log, props) | ||
delete log[propToDelete] | ||
if (log !== null && typeof log === 'object' && Object.prototype.hasOwnProperty.call(log, propToDelete)) { | ||
delete log[propToDelete] | ||
} | ||
} | ||
@@ -589,0 +608,0 @@ |
{ | ||
"name": "pino-pretty", | ||
"version": "9.4.0", | ||
"version": "9.4.1", | ||
"description": "Prettifier for Pino log lines", | ||
@@ -51,3 +51,3 @@ "type": "commonjs", | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"@types/node": "^20.1.0", | ||
"pino": "^8.0.0", | ||
@@ -59,4 +59,4 @@ "pre-commit": "^1.2.2", | ||
"tap": "^16.0.0", | ||
"tsd": "^0.25.0", | ||
"typescript": "^4.4.3" | ||
"tsd": "^0.28.0", | ||
"typescript": "^5.0.2" | ||
}, | ||
@@ -63,0 +63,0 @@ "tsd": { |
@@ -5,3 +5,3 @@ <a id="intro"></a> | ||
[![NPM Package Version](https://img.shields.io/npm/v/pino-pretty)](https://www.npmjs.com/package/pino-pretty) | ||
[![Build Status](https://img.shields.io/github/workflow/status/pinojs/pino-pretty/CI)](https://github.com/pinojs/pino-pretty/actions?query=workflow%3ACI) | ||
[![Build Status](https://img.shields.io/github/actions/workflow/status/pinojs/pino-pretty/ci.yml?branch=master)](https://github.com/pinojs/pino-pretty/actions?query=workflow%3ACI) | ||
[![Coverage Status](https://img.shields.io/coveralls/github/pinojs/pino-pretty)](https://coveralls.io/github/pinojs/pino-pretty?branch=master) | ||
@@ -72,3 +72,5 @@ [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) | ||
Default: `msg`. | ||
- `--levelKey` (`--levelKey`): Define the key that contains the level of the log. | ||
- `--levelKey` (`--levelKey`): Define the key that contains the level of the log. Nested keys are supported with each property delimited by a dot character (`.`). | ||
Keys may be escaped to target property names that contains the delimiter itself: | ||
(`--levelKey tags\\.level`). | ||
Default: `level`. | ||
@@ -75,0 +77,0 @@ - `--levelLabel` (`-b`): Output the log level using the specified label. |
@@ -121,2 +121,66 @@ 'use strict' | ||
t.test('can print message key value when its a string', (t) => { | ||
t.plan(1) | ||
const pretty = prettyFactory() | ||
const log = pino({}, new Writable({ | ||
write (chunk, enc, cb) { | ||
const formatted = pretty(chunk.toString()) | ||
t.equal( | ||
formatted, | ||
`[${formattedEpoch}] INFO (${pid}): baz\n` | ||
) | ||
cb() | ||
} | ||
})) | ||
log.info('baz') | ||
}) | ||
t.test('can print message key value when its a number', (t) => { | ||
t.plan(1) | ||
const pretty = prettyFactory() | ||
const log = pino({}, new Writable({ | ||
write (chunk, enc, cb) { | ||
const formatted = pretty(chunk.toString()) | ||
t.equal( | ||
formatted, | ||
`[${formattedEpoch}] INFO (${pid}): 42\n` | ||
) | ||
cb() | ||
} | ||
})) | ||
log.info(42) | ||
}) | ||
t.test('can print message key value when its a Number(0)', (t) => { | ||
t.plan(1) | ||
const pretty = prettyFactory() | ||
const log = pino({}, new Writable({ | ||
write (chunk, enc, cb) { | ||
const formatted = pretty(chunk.toString()) | ||
t.equal( | ||
formatted, | ||
`[${formattedEpoch}] INFO (${pid}): 0\n` | ||
) | ||
cb() | ||
} | ||
})) | ||
log.info(0) | ||
}) | ||
t.test('can print message key value when its a boolean', (t) => { | ||
t.plan(1) | ||
const pretty = prettyFactory() | ||
const log = pino({}, new Writable({ | ||
write (chunk, enc, cb) { | ||
const formatted = pretty(chunk.toString()) | ||
t.equal( | ||
formatted, | ||
`[${formattedEpoch}] INFO (${pid}): true\n` | ||
) | ||
cb() | ||
} | ||
})) | ||
log.info(true) | ||
}) | ||
t.test('can use different message keys', (t) => { | ||
@@ -123,0 +187,0 @@ t.plan(1) |
@@ -166,25 +166,25 @@ 'use strict' | ||
tap.test('#splitIgnoreKey', t => { | ||
t.test('splitIgnoreKey does not change key', async t => { | ||
const result = internals.splitIgnoreKey('data1') | ||
tap.test('#splitPropertyKey', t => { | ||
t.test('splitPropertyKey does not change key', async t => { | ||
const result = internals.splitPropertyKey('data1') | ||
t.same(result, ['data1']) | ||
}) | ||
t.test('splitIgnoreKey splits nested key', async t => { | ||
const result = internals.splitIgnoreKey('data1.data2.data-3') | ||
t.test('splitPropertyKey splits nested key', async t => { | ||
const result = internals.splitPropertyKey('data1.data2.data-3') | ||
t.same(result, ['data1', 'data2', 'data-3']) | ||
}) | ||
t.test('splitIgnoreKey splits nested keys ending with a dot', async t => { | ||
const result = internals.splitIgnoreKey('data1.data2.data-3.') | ||
t.test('splitPropertyKey splits nested keys ending with a dot', async t => { | ||
const result = internals.splitPropertyKey('data1.data2.data-3.') | ||
t.same(result, ['data1', 'data2', 'data-3']) | ||
}) | ||
t.test('splitIgnoreKey splits nested escaped key', async t => { | ||
const result = internals.splitIgnoreKey('logging\\.domain\\.corp/operation.foo.bar-2') | ||
t.test('splitPropertyKey splits nested escaped key', async t => { | ||
const result = internals.splitPropertyKey('logging\\.domain\\.corp/operation.foo.bar-2') | ||
t.same(result, ['logging.domain.corp/operation', 'foo', 'bar-2']) | ||
}) | ||
t.test('splitIgnoreKey splits nested escaped key with special characters', async t => { | ||
const result = internals.splitIgnoreKey('logging\\.domain\\.corp/operation.!\t@#$%^&*()_+=-<>.bar\\.2') | ||
t.test('splitPropertyKey splits nested escaped key with special characters', async t => { | ||
const result = internals.splitPropertyKey('logging\\.domain\\.corp/operation.!\t@#$%^&*()_+=-<>.bar\\.2') | ||
t.same(result, ['logging.domain.corp/operation', '!\t@#$%^&*()_+=-<>', 'bar.2']) | ||
@@ -195,1 +195,32 @@ }) | ||
}) | ||
tap.test('#getPropertyValue', t => { | ||
t.test('getPropertyValue returns the value of the property', async t => { | ||
const result = internals.getPropertyValue({ | ||
foo: 'bar' | ||
}, 'foo') | ||
t.same(result, 'bar') | ||
}) | ||
t.test('getPropertyValue returns the value of the nested property', async t => { | ||
const result = internals.getPropertyValue({ extra: { foo: { value: 'bar' } } }, 'extra.foo.value') | ||
t.same(result, 'bar') | ||
}) | ||
t.test('getPropertyValue returns the value of the nested property using the array of nested property keys', async t => { | ||
const result = internals.getPropertyValue({ extra: { foo: { value: 'bar' } } }, ['extra', 'foo', 'value']) | ||
t.same(result, 'bar') | ||
}) | ||
t.test('getPropertyValue returns undefined for non-existing properties', async t => { | ||
const result = internals.getPropertyValue({ extra: { foo: { value: 'bar' } } }, 'extra.foo.value-2') | ||
t.same(result, undefined) | ||
}) | ||
t.test('getPropertyValue returns undefined for non-existing properties using the array of nested property keys', async t => { | ||
const result = internals.getPropertyValue({ extra: { foo: { value: 'bar' } } }, ['extra', 'foo', 'value-2']) | ||
t.same(result, undefined) | ||
}) | ||
t.end() | ||
}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
188766
4190
372