From 9aea0bdb81cf4187bf171f8892552e4f43bc8a37 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Thu, 25 Jul 2024 10:16:24 -0400 Subject: [PATCH] Type fixes (#522) * Typos * Rewrite index.d.ts based on attw recommendations See https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/MissingExportEquals.md This required deleting some type tests. Since the type tests are testing things that aren't exported, this may be acceptable. * Add Are the Types Wrong to validate going forward * Named export of PinoPretty It's offered by the TypeScript types, but the JS didn't export it, which resulted in errors at runtime. --- Readme.md | 2 +- index.d.ts | 408 +++++++++++++++---------------- index.js | 1 + package.json | 3 +- test/basic.test.js | 2 +- test/types/pino-pretty.test-d.ts | 4 - 6 files changed, 207 insertions(+), 213 deletions(-) diff --git a/Readme.md b/Readme.md index 5004029..44e6344 100644 --- a/Readme.md +++ b/Readme.md @@ -62,7 +62,7 @@ node app.js | pino-pretty feed, to the formatted log line. - `--errorProps` (`-e`): When formatting an error object, display this list of properties. The list should be a comma-separated list of properties Default: `''`. - Do not use this option if logging from pino@7. Support will be removed from future verions. + Do not use this option if logging from pino@7. Support will be removed from future versions. - `--levelFirst` (`-l`): Display the log level name before the logged date and time. - `--errorLikeObjectKeys` (`-k`): Define the log keys that are associated with error like objects. Default: `err,error`. diff --git a/index.d.ts b/index.d.ts index fde5546..2c4c5c8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,229 +10,225 @@ import { Transform } from 'stream'; import { OnUnknown } from 'pino-abstract-transport'; // @ts-ignore fall back to any if pino is not available, i.e. when running pino tests import { DestinationStream, Level } from 'pino'; -import LevelPrettifierExtras = PinoPretty.LevelPrettifierExtras; import * as Colorette from "colorette"; type LogDescriptor = Record; -declare function PinoPretty(options?: PrettyOptions_): PinoPretty.PrettyStream; +declare function PinoPretty(options?: PinoPretty.PrettyOptions): PinoPretty.PrettyStream; +declare namespace PinoPretty { -declare function colorizerFactory( - useColors?: boolean, - customColors?: [number, string][], - useOnlyCustomProps?: boolean, -): { - ( - level?: number | string, - opts?: { - customLevels?: { [level: number]: string }; - customLevelNames?: { [name: string]: number }; - }, - ): string, - message: (input: string | number) => string, - greyMessage: (input: string | number) => string, -} + function colorizerFactory( + useColors?: boolean, + customColors?: [number, string][], + useOnlyCustomProps?: boolean, + ): { + ( + level?: number | string, + opts?: { + customLevels?: { [level: number]: string }; + customLevelNames?: { [name: string]: number }; + }, + ): string, + message: (input: string | number) => string, + greyMessage: (input: string | number) => string, + } -declare function prettyFactory( - options: PrettyOptions_, -): (inputData: any) => string + function prettyFactory(options: PrettyOptions): (inputData: any) => string -interface PrettyOptions_ { - /** - * Hide objects from output (but not error object). - * @default false - */ - hideObject?: boolean; - /** - * Translate the epoch time value into a human readable date and time string. This flag also can set the format - * string to apply when translating the date to human readable format. For a list of available pattern letters - * see the {@link https://www.npmjs.com/package/dateformat|dateformat documentation}. - * - The default format is `yyyy-mm-dd HH:MM:ss.l o` in UTC. - * - Requires a `SYS:` prefix to translate time to the local system's timezone. Use the shortcut `SYS:standard` - * to translate time to `yyyy-mm-dd HH:MM:ss.l o` in system timezone. - * @default false - */ - translateTime?: boolean | string; - /** - * If set to true, it will print the name of the log level as the first field in the log line. - * @default false - */ - levelFirst?: boolean; - /** - * Define the key that contains the level of the log. - * @default "level" - */ - levelKey?: string; - /** - * Output the log level using the specified label. - * @default "levelLabel" - */ - levelLabel?: string; - /** - * The key in the JSON object to use as the highlighted message. - * @default "msg" - * - * Not required when used with pino >= 8.21.0 - */ - messageKey?: string; - /** - * Print each log message on a single line (errors will still be multi-line). - * @default false - */ - singleLine?: boolean; - /** - * The key in the JSON object to use for timestamp display. - * @default "time" - */ - timestampKey?: string; - /** - * The minimum log level to include in the output. - * @default "trace" - */ - minimumLevel?: Level; - /** - * Format output of message, e.g. {level} - {pid} will output message: INFO - 1123 - * @default false - * - * @example - * ```typescript - * { - * messageFormat: (log, messageKey) => { - * const message = log[messageKey]; - * if (log.requestId) return `[${log.requestId}] ${message}`; - * return message; - * } - * } - * ``` - */ - messageFormat?: false | string | PinoPretty.MessageFormatFunc; - /** - * If set to true, will add color information to the formatted output message. - * @default false - */ - colorize?: boolean; - /** - * If set to false while `colorize` is `true`, will output JSON objects without color. - * @default true - */ - colorizeObjects?: boolean; - /** - * Appends carriage return and line feed, instead of just a line feed, to the formatted log line. - * @default false - */ - crlf?: boolean; - /** - * Define the log keys that are associated with error like objects. - * @default ["err", "error"] - * - * Not required to handle custom errorKey when used with pino >= 8.21.0 - */ - errorLikeObjectKeys?: string[]; - /** - * When formatting an error object, display this list of properties. - * The list should be a comma separated list of properties. - * @default "" - */ - errorProps?: string; - /** - * Ignore one or several keys. - * Will be overridden by the option include if include is presented. - * @example "time,hostname" - */ - ignore?: string; - /** - * Include one or several keys. - * @example "time,level" - */ - include?: string; - /** - * Makes messaging synchronous. - * @default false - */ - sync?: boolean; - /** - * The file, file descriptor, or stream to write to. Defaults to 1 (stdout). - * @default 1 - */ - destination?: string | number | DestinationStream | NodeJS.WritableStream; - /** - * Opens the file with the 'a' flag. - * @default true - */ - append?: boolean; - /** - * Ensure directory for destination file exists. - * @default false - */ - mkdir?: boolean; - /** - * Provides the ability to add a custom prettify function for specific log properties. - * `customPrettifiers` is an object, where keys are log properties that will be prettified - * and value is the prettify function itself. - * For example, if a log line contains a query property, you can specify a prettifier for it: - * @default {} - * - * @example - * ```typescript - * { - * customPrettifiers: { - * query: prettifyQuery - * } - * } - * //... - * const prettifyQuery = value => { - * // do some prettify magic - * } - * ``` - */ - customPrettifiers?: Record & - { - level?: PinoPretty.Prettifier - }; - /** - * Change the level names and values to an user custom preset. - * - * Can be a CSV string in 'level_name:level_value' format or an object. - * - * @example ( CSV ) customLevels: 'info:10,some_level:40' - * @example ( Object ) customLevels: { info: 10, some_level: 40 } - * - * Not required when used with pino >= 8.21.0 - */ - customLevels?: string|object; - /** - * Change the level colors to an user custom preset. - * - * Can be a CSV string in 'level_name:color_value' format or an object. - * Also supports 'default' as level_name for fallback color. - * - * @example ( CSV ) customColors: 'info:white,some_level:red' - * @example ( Object ) customColors: { info: 'white', some_level: 'red' } - */ - customColors?: string|object; - /** - * Only use custom levels and colors (if provided); else fallback to default levels and colors. - * - * @default true - */ - useOnlyCustomProps?: boolean; -} + interface PrettyOptions { + /** + * Hide objects from output (but not error object). + * @default false + */ + hideObject?: boolean; + /** + * Translate the epoch time value into a human readable date and time string. This flag also can set the format + * string to apply when translating the date to human readable format. For a list of available pattern letters + * see the {@link https://www.npmjs.com/package/dateformat|dateformat documentation}. + * - The default format is `yyyy-mm-dd HH:MM:ss.l o` in UTC. + * - Requires a `SYS:` prefix to translate time to the local system's timezone. Use the shortcut `SYS:standard` + * to translate time to `yyyy-mm-dd HH:MM:ss.l o` in system timezone. + * @default false + */ + translateTime?: boolean | string; + /** + * If set to true, it will print the name of the log level as the first field in the log line. + * @default false + */ + levelFirst?: boolean; + /** + * Define the key that contains the level of the log. + * @default "level" + */ + levelKey?: string; + /** + * Output the log level using the specified label. + * @default "levelLabel" + */ + levelLabel?: string; + /** + * The key in the JSON object to use as the highlighted message. + * @default "msg" + * + * Not required when used with pino >= 8.21.0 + */ + messageKey?: string; + /** + * Print each log message on a single line (errors will still be multi-line). + * @default false + */ + singleLine?: boolean; + /** + * The key in the JSON object to use for timestamp display. + * @default "time" + */ + timestampKey?: string; + /** + * The minimum log level to include in the output. + * @default "trace" + */ + minimumLevel?: Level; + /** + * Format output of message, e.g. {level} - {pid} will output message: INFO - 1123 + * @default false + * + * @example + * ```typescript + * { + * messageFormat: (log, messageKey) => { + * const message = log[messageKey]; + * if (log.requestId) return `[${log.requestId}] ${message}`; + * return message; + * } + * } + * ``` + */ + messageFormat?: false | string | MessageFormatFunc; + /** + * If set to true, will add color information to the formatted output message. + * @default false + */ + colorize?: boolean; + /** + * If set to false while `colorize` is `true`, will output JSON objects without color. + * @default true + */ + colorizeObjects?: boolean; + /** + * Appends carriage return and line feed, instead of just a line feed, to the formatted log line. + * @default false + */ + crlf?: boolean; + /** + * Define the log keys that are associated with error like objects. + * @default ["err", "error"] + * + * Not required to handle custom errorKey when used with pino >= 8.21.0 + */ + errorLikeObjectKeys?: string[]; + /** + * When formatting an error object, display this list of properties. + * The list should be a comma separated list of properties. + * @default "" + */ + errorProps?: string; + /** + * Ignore one or several keys. + * Will be overridden by the option include if include is presented. + * @example "time,hostname" + */ + ignore?: string; + /** + * Include one or several keys. + * @example "time,level" + */ + include?: string; + /** + * Makes messaging synchronous. + * @default false + */ + sync?: boolean; + /** + * The file, file descriptor, or stream to write to. Defaults to 1 (stdout). + * @default 1 + */ + destination?: string | number | DestinationStream | NodeJS.WritableStream; + /** + * Opens the file with the 'a' flag. + * @default true + */ + append?: boolean; + /** + * Ensure directory for destination file exists. + * @default false + */ + mkdir?: boolean; + /** + * Provides the ability to add a custom prettify function for specific log properties. + * `customPrettifiers` is an object, where keys are log properties that will be prettified + * and value is the prettify function itself. + * For example, if a log line contains a query property, you can specify a prettifier for it: + * @default {} + * + * @example + * ```typescript + * { + * customPrettifiers: { + * query: prettifyQuery + * } + * } + * //... + * const prettifyQuery = value => { + * // do some prettify magic + * } + * ``` + */ + customPrettifiers?: Record & + { + level?: Prettifier + }; + /** + * Change the level names and values to an user custom preset. + * + * Can be a CSV string in 'level_name:level_value' format or an object. + * + * @example ( CSV ) customLevels: 'info:10,some_level:40' + * @example ( Object ) customLevels: { info: 10, some_level: 40 } + * + * Not required when used with pino >= 8.21.0 + */ + customLevels?: string|object; + /** + * Change the level colors to an user custom preset. + * + * Can be a CSV string in 'level_name:color_value' format or an object. + * Also supports 'default' as level_name for fallback color. + * + * @example ( CSV ) customColors: 'info:white,some_level:red' + * @example ( Object ) customColors: { info: 'white', some_level: 'red' } + */ + customColors?: string|object; + /** + * Only use custom levels and colors (if provided); else fallback to default levels and colors. + * + * @default true + */ + useOnlyCustomProps?: boolean; + } -declare function build(options: PrettyOptions_): PinoPretty.PrettyStream; -type isColorSupported = PinoPretty.isColorSupported + function build(options: PrettyOptions): PrettyStream; -declare namespace PinoPretty { type Prettifier = (inputData: string | object, key: string, log: object, extras: PrettifierExtras) => string; type PrettifierExtras = {colors: Colorette.Colorette} & T; type LevelPrettifierExtras = {label: string, labelColorized: string} type MessageFormatFunc = (log: LogDescriptor, messageKey: string, levelLabel: string, extras: PrettifierExtras) => string; - type PrettyOptions = PrettyOptions_; type PrettyStream = Transform & OnUnknown; type ColorizerFactory = typeof colorizerFactory; type PrettyFactory = typeof prettyFactory; type Build = typeof build; type isColorSupported = typeof Colorette.isColorSupported; + + export { build, PinoPretty, PrettyOptions, PrettyStream, colorizerFactory, prettyFactory, isColorSupported }; } -export default PinoPretty; -export { build, PinoPretty, PrettyOptions_ as PrettyOptions, colorizerFactory, prettyFactory, isColorSupported }; +export = PinoPretty; diff --git a/index.js b/index.js index 31d8fa8..2d76def 100644 --- a/index.js +++ b/index.js @@ -176,6 +176,7 @@ function build (opts = {}) { module.exports = build module.exports.build = build +module.exports.PinoPretty = build module.exports.prettyFactory = prettyFactory module.exports.colorizerFactory = colors module.exports.isColorSupported = isColorSupported diff --git a/package.json b/package.json index bf4c3b9..73c42de 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "ci": "standard && tap --coverage-report=lcovonly && npm run test-types", "lint": "standard | snazzy", "test": "tap", - "test-types": "tsc && tsd", + "test-types": "tsc && tsd && attw --pack .", "test:watch": "tap --no-coverage-report -w", "test:report": "tap --coverage-report=html" }, @@ -50,6 +50,7 @@ "strip-json-comments": "^3.1.1" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.15.3", "@types/node": "^20.1.0", "fastbench": "^1.0.1", "pino": "^9.0.0", diff --git a/test/basic.test.js b/test/basic.test.js index ede3f70..89514f5 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -955,7 +955,7 @@ test('basic prettifier tests', (t) => { t.equal(arst, `[${formattedEpoch}] INFO: hello world\n`) }) - t.test('inlude a single key with null object', (t) => { + t.test('include a single key with null object', (t) => { t.plan(1) const pretty = prettyFactory({ include: 'level' }) const obj = new Empty() diff --git a/test/types/pino-pretty.test-d.ts b/test/types/pino-pretty.test-d.ts index bc597f0..9f2acd7 100644 --- a/test/types/pino-pretty.test-d.ts +++ b/test/types/pino-pretty.test-d.ts @@ -51,9 +51,5 @@ expectType(pretty(options)); expectType(PinoPrettyNamed(options)); expectType(PinoPrettyDefault(options)); expectType(PinoPrettyStar.PinoPretty(options)); -expectType(PinoPrettyStar.default(options)); expectType(PinoPrettyCjsImport.PinoPretty(options)); -expectType(PinoPrettyCjsImport.default(options)); expectType(PinoPrettyCjs(options)); -expectType(colorizerFactory); -expectType(prettyFactory);