Skip to content

Commit

Permalink
Improve jsdoc blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
jsumners committed Sep 3, 2023
1 parent 7a4a4eb commit 403de72
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 84 deletions.
10 changes: 6 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ const prettifyQuery = value => {
}
```

Additionally, `customPrettifiers` can be used to format the `time`, `hostname`, `pid`, `name`, `caller` and `level`
outputs:
Additionally, `customPrettifiers` can be used to format the `time`, `hostname`,
`pid`, `name`, `caller` and `level` outputs:

```js
{
Expand Down Expand Up @@ -335,15 +335,17 @@ const levelPrettifier = logLevel => `LEVEL: ${levelColorize(logLevel)}`
}
```

`messageFormat` option allows you to customize the message output. A template `string` like this can define the format:
`messageFormat` option allows you to customize the message output.
A template `string` like this can define the format:

```js
{
messageFormat: '{levelLabel} - {pid} - url:{req.url}'
}
```

In addition to this, if / end statement blocks can also be specified. Else statements and nested conditions are not supported.
In addition to this, if / end statement blocks can also be specified.
Else statements and nested conditions are not supported.

```js
{
Expand Down
83 changes: 82 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,57 @@ const jsonParser = input => {
}
}

/**
* @typedef {object} PinoPrettyOptions
* @property {boolean} [colorize] Indicates if colors should be used when
* prettifying. The default will be determined by the terminal capabilities at
* run time.
* @property {boolean} [colorizeObjects=true] Apply coloring to rendered objects
* when coloring is enabled.
* @property {boolean} [crlf=false] End lines with `\r\n` instead of `\n`.
* @property {K_ERROR_LIKE_KEYS} [errorLikeObjectKeys] A list of string property
* names to consider as error objects.
* @property {string} [errorProps=''] A comma separated list of properties on
* error objects to include in the output.
* @property {string|null} [customLevels=null] A comma separated list of user
* defined level names and numbers, e.g. `err:99,info:1`.
* @property {string|null} [customColors=null] A comma separated list of colors
* to use for specific level labels, e.g. `err:red,info:blue`.
* @property {boolean} [useOnlyCustomProps=true] When true, only custom levels
* and colors will be used if they have been provided.
* @property {boolean} [levelFirst=false] When true, the log level will be the
* first field in the prettified output.
* @property {string} [messageKey='msg'] Defines the key in incoming logs that
* contains the message of the log, if present.
* @property {null|MessageFormatString|MessageFormatFunction} [messageFormat=null]
* When a string, defines how the prettified line should be formatted according
* to defined tokens. When a function, a synchronous function that returns a
* formatted string.
* @property {string} [timestampKey='time'] Defines the key in incoming logs
* that contains the timestamp of the log, if present.
* @property {boolean} [translateTime=true] When true, will translate a
* JavaScript date integer into a human-readable string.
* @property {object} [outputStream=process.stdout] The stream to write
* prettified log lines to.
* @property {CustomPrettifiers} [customPrettifiers={}] A set of prettifier
* functions to apply to keys defined in this object.
* @property {boolean} [hideObject=false] When `true`, data objects will be
* omitted from the output (except for error objects).
* @property {string} [ignore='hostname'] A comma separated list of log keys
* to omit when outputting the prettified log information.
* @property {undefined|string} [include=undefined] A comma separated list of
* log keys to include in the prettified log information. Only the keys in this
* list will be included in the output.
* @property {boolean} [singleLine=false] When `true` any objects, except error
* objects, in the log data will be printed as a single line instead as multiple
* lines.
*/

/**
* The default options that will be used when prettifying log lines.
*
* @type {PinoPrettyOptions}
*/
const defaultOptions = {
colorize: isColorSupported,
colorizeObjects: true,
Expand All @@ -43,7 +94,6 @@ const defaultOptions = {
messageFormat: null,
timestampKey: TIMESTAMP_KEY,
translateTime: true,
useMetadata: false,
outputStream: process.stdout,
customPrettifiers: {},
hideObject: false,
Expand All @@ -52,6 +102,13 @@ const defaultOptions = {
singleLine: false
}

/**
* Processes the supplied options and returns a function that accepts log data
* and produces a prettified log string.
*
* @param {PinoPrettyOptions} options Configuration for the prettifier.
* @returns {LogPrettifierFunc}
*/
function prettyFactory (options) {
const opts = Object.assign({}, defaultOptions, options)
const EOL = opts.crlf ? '\r\n' : '\n'
Expand Down Expand Up @@ -101,6 +158,14 @@ function prettyFactory (options) {

return pretty

/**
* Orchestrates processing the received log data according to the provided
* configuration and returns a prettified log string.
*
* @typedef {function} LogPrettifierFunc
* @param {string|object} inputData A log string or a log-like object.
* @returns {string} A string that represents the prettified log data.
*/
function pretty (inputData) {
let log
if (!isObject(inputData)) {
Expand Down Expand Up @@ -209,6 +274,22 @@ function prettyFactory (options) {
}
}

/**
* @typedef {PinoPrettyOptions} BuildStreamOpts
* @property {object|number|string} [destination] A destination stream, file
* descriptor, or target path to a file.
* @property {boolean} [append]
* @property {boolean} [mkdir]
* @property {boolean} [sync=false]
*/

/**
* Constructs a {@link LogPrettifierFunc} and a stream to which the produced
* prettified log data will be written.
*
* @param {BuildStreamOpts} opts
* @returns {Transform | (Transform & OnUnknown)}
*/
function build (opts = {}) {
const pretty = prettyFactory(opts)
return abstractTransport(function (source) {
Expand Down
16 changes: 10 additions & 6 deletions lib/utils/filter-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ const fastCopy = createCopier({})

const deleteLogProperty = require('./delete-log-property')

/**
* @typedef {object} FilterLogParams
* @property {object} log The log object to be modified.
* @property {Set<string> | Array<string> | undefined} ignoreKeys
* An array of strings identifying the properties to be removed.
* @property {Set<string> | Array<string> | undefined} includeKeys
* An array of strings identifying the properties to be included.
*/

/**
* Filter a log object by removing or including keys accordingly.
* When `includeKeys` is passed, `ignoredKeys` will be ignored.
* One of ignoreKeys or includeKeys must be pass in.
*
* @param {object} input
* @param {object} input.log The log object to be modified.
* @param {Set<string> | Array<string> | undefined} input.ignoreKeys
* An array of strings identifying the properties to be removed.
* @param {Set<string> | Array<string> | undefined} input.includeKeys
* An array of strings identifying the properties to be included.
* @param {FilterLogParams} input
*
* @returns {object} A new `log` object instance that
* either only includes the keys in ignoreKeys
Expand Down
73 changes: 73 additions & 0 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,76 @@ for (const file of files) {

module.exports[snakeName] = require(`./${kebabName}.js`)
}

// The remainder of this file consists of jsdoc blocks that are difficult to
// determine a more appropriate "home" for. As an example, the blocks associated
// with custom prettifiers could live in either the `prettify-level`,
// `prettify-metadata`, or `prettify-time` files since they are the primary
// files where such code is used. But we want a central place to define common
// doc blocks, so we are picking this file as the answer.

/**
* A hash of log property names mapped to prettifier functions. When the
* incoming log data is being processed for prettification, any key on the log
* that matches a key in a custom prettifiers hash will be prettified using
* that matching custom prettifier. The value passed to the custom prettifier
* will the value associated with the corresponding log key.
*
* The hash may contain any arbitrary keys for arbitrary log properties, but it
* may also contain a set of predefined key names that map to well-known log
* properties. These keys are:
*
* + `time` (for the timestamp field)
* + `level` (for the level label field; value may be a level number instead
* of a level label)
* + `hostname`
* + `pid`
* + `name`
* + `caller`
*
* @typedef {Object.<string, CustomPrettifierFunc>} CustomPrettifiers
*/

/**
* A synchronous function to be used for prettifying a log property. It must
* return a string.
*
* @typedef {function} CustomPrettifierFunc
* @param {any} value The value to be prettified for the key associated with
* the prettifier.
* @returns {string}
*/

/**
* A tokenized string that indicates how the prettified log line should be
* formatted. Tokens are either log properties enclosed in curly braces, e.g.
* `{levelLabel}`, `{pid}`, or `{req.url}`, or conditional directives in curly
* braces. The only conditional directives supported are `if` and `end`, e.g.
* `{if pid}{pid}{end}`; every `if` must have a matching `end`. Nested
* conditions are not supported.
*
* @typedef {string} MessageFormatString
*
* @example
* `{levelLabel} - {if pid}{pid} - {end}url:{req.url}`
*/

/**
* A function that accepts a log object, name of the message key, and name of
* the level label key and returns a formatted log line.
*
* Note: this function must be synchronous.
*
* @typedef {function} MessageFormatFunction
* @param {object} log The log object to be processed.
* @param {string} messageKey The name of the key in the `log` object that
* contains the log message.
* @param {string} levelLabel The name of the key in the `log` object that
* contains the log level name.
* @returns {string}
*
* @example
* function (log, messageKey, levelLabel) {
* return `${log[levelLabel]} - ${log[messageKey]}`
* }
*/
11 changes: 6 additions & 5 deletions lib/utils/interpret-conditionals.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ module.exports = interpretConditionals
const getPropertyValue = require('./get-property-value')

/**
* Translates all conditional blocks from within the messageFormat. Translates any matching
* {if key}{key}{end} statements and returns everything between if and else blocks if the key provided
* was found in log.
* Translates all conditional blocks from within the messageFormat. Translates
* any matching {if key}{key}{end} statements and returns everything between
* if and else blocks if the key provided was found in log.
*
* @param {string} messageFormat A format string or function that defines how the
* logged message should be conditionally formatted, e.g. `'{if level}{level}{end} - {if req.id}{req.id}{end}'`.
* @param {MessageFormatString|MessageFormatFunction} messageFormat A format
* string or function that defines how the logged message should be
* conditionally formatted.
* @param {object} log The log object to be modified.
*
* @returns {string} The parsed messageFormat.
Expand Down
14 changes: 9 additions & 5 deletions lib/utils/join-lines-with-indentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

module.exports = joinLinesWithIndentation

/**
* @typedef {object} JoinLinesWithIndentationParams
* @property {string} input The string to split and reformat.
* @property {string} [ident] The indentation string. Default: ` ` (4 spaces).
* @property {string} [eol] The end of line sequence to use when rejoining
* the lines. Default: `'\n'`.
*/

/**
* Given a string with line separators, either `\r\n` or `\n`, add indentation
* to all lines subsequent to the first line and rejoin the lines using an
* end of line sequence.
*
* @param {object} input
* @param {string} input.input The string to split and reformat.
* @param {string} [input.ident] The indentation string. Default: ` ` (4 spaces).
* @param {string} [input.eol] The end of line sequence to use when rejoining
* the lines. Default: `'\n'`.
* @param {JoinLinesWithIndentationParams} input
*
* @returns {string} A string with lines subsequent to the first indented
* with the given indentation sequence.
Expand Down
24 changes: 14 additions & 10 deletions lib/utils/prettify-error-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,26 @@ const joinLinesWithIndentation = require('./join-lines-with-indentation')
const prettifyObject = require('./prettify-object')

/**
* Given a log object that has a `type: 'Error'` key, prettify the object and
* return the result. In other
*
* @param {object} input
* @param {object} input.log The error log to prettify.
* @param {string} [input.messageKey] The name of the key that contains a
* @typedef {object} PrettifyErrorLogParams
* @property {object} log The error log to prettify.
* @property {string} [messageKey] The name of the key that contains a
* general log message. This is not the error's message property but the logger
* messsage property. Default: `MESSAGE_KEY` constant.
* @param {string} [input.ident] The sequence to use for indentation. Default: `' '`.
* @param {string} [input.eol] The sequence to use for EOL. Default: `'\n'`.
* @param {string[]} [input.errorLikeKeys] A set of keys that should be considered
* @property {string} [ident] The sequence to use for indentation. Default: `' '`.
* @property {string} [eol] The sequence to use for EOL. Default: `'\n'`.
* @property {string[]} [errorLikeKeys] A set of keys that should be considered
* to have error objects as values. Default: `ERROR_LIKE_KEYS` constant.
* @param {string[]} [input.errorProperties] A set of specific error object
* @property {string[]} [errorProperties] A set of specific error object
* properties, that are not the value of `messageKey`, `type`, or `stack`, to
* include in the prettified result. The first entry in the list may be `'*'`
* to indicate that all sibling properties should be prettified. Default: `[]`.
*/

/**
* Given a log object that has a `type: 'Error'` key, prettify the object and
* return the result. In other
*
* @param {PrettifyErrorLogParams} input
*
* @returns {string} A string that represents the prettified error log.
*/
Expand Down
19 changes: 13 additions & 6 deletions lib/utils/prettify-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ module.exports = prettifyError

const joinLinesWithIndentation = require('./join-lines-with-indentation')

/**
* @typedef {object} PrettifyErrorParams
* @property {string} keyName The key assigned to this error in the log object.
* @property {string} lines The STRINGIFIED error. If the error field has a
* custom prettifier, that should be pre-applied as well.
* @property {string} ident The indentation sequence to use.
* @property {string} eol The EOL sequence to use.
*/

/**
* Prettifies an error string into a multi-line format.
* @param {object} input
* @param {string} input.keyName The key assigned to this error in the log object
* @param {string} input.lines The STRINGIFIED error. If the error field has a
* custom prettifier, that should be pre-applied as well
* @param {string} input.ident The indentation sequence to use
* @param {string} input.eol The EOL sequence to use
*
* @param {PrettifyErrorParams} input
*
* @returns {string}
*/
function prettifyError ({ keyName, lines, eol, ident }) {
let result = ''
Expand Down
23 changes: 15 additions & 8 deletions lib/utils/prettify-level.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@ const defaultColorizer = require('../colors')()

const getPropertyValue = require('./get-property-value')

/**
* @typedef {object} PrettifyLevelParams
* @property {object} log The log object.
* @property {function} [colorizer] A colorizer function that accepts a level
* value and returns a colorized string. Default: a no-op colorizer.
* @property {string} [levelKey='level'] The key to find the level under.
* @property {CustomPrettifierFunc} [prettifier] A user-supplied formatter
* to be called instead of colorizer.
* @property {object} [customLevels] The custom levels where key as the level
* index and value as the level name.
* @property {object} [customLevelNames] The custom level names where key is
* the level name and value is the level index.
*/

/**
* Checks if the passed in log has a `level` value and returns a prettified
* string for that level if so.
*
* @param {object} input
* @param {object} input.log The log object.
* @param {function} [input.colorizer] A colorizer function that accepts a level
* value and returns a colorized string. Default: a no-op colorizer.
* @param {string} [input.levelKey='level'] The key to find the level under.
* @param {function} [input.prettifier] A user-supplied formatter to be called instead of colorizer.
* @param {object} [input.customLevels] The custom levels where key as the level index and value as the level name.
* @param {object} [input.customLevelNames] The custom level names where key is the level name and value is the level index.
* @param {PrettifyLevelParams} input
*
* @returns {undefined|string} If `log` does not have a `level` property then
* `undefined` will be returned. Otherwise, a string from the specified
Expand Down
Loading

0 comments on commit 403de72

Please sign in to comment.