From 2ddcaf61227674e9f3baf8bd6598176203ffbee2 Mon Sep 17 00:00:00 2001 From: Agostino Cavarero Date: Wed, 1 Nov 2023 00:19:46 +0100 Subject: [PATCH 1/3] fix: types --- pino.d.ts | 50 +++++++++++++++++++-------------------- test/types/pino.test-d.ts | 22 ++++++++++++++--- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/pino.d.ts b/pino.d.ts index 52f86bbac..1d57c8861 100644 --- a/pino.d.ts +++ b/pino.d.ts @@ -31,13 +31,13 @@ type TimeFn = () => string; type MixinFn = (mergeObject: object, level: number) => object; type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object; -type CustomLevelLogger = Options extends { customLevels: Record } ? Record : Record +type CustomLevelLogger = CustomLevels extends Record ? Record : Record /** * A synchronous callback that will run on each creation of a new child. * @param child: The newly created child logger instance. */ -type OnChildCallback = (child: pino.Logger) => void +type OnChildCallback = {}> = (child: pino.Logger) => void export interface redactOptions { paths: string[]; @@ -45,7 +45,7 @@ export interface redactOptions { remove?: boolean; } -export interface LoggerExtras extends EventEmitter { +export interface LoggerExtras = {}> extends EventEmitter { /** * Exposes the Pino package version. Also available on the exported pino function. */ @@ -60,7 +60,7 @@ export interface LoggerExtras extends EventEmitter { /** * Define additional logging levels. */ - customLevels: { [key: string]: number }; + customLevels: CustomLevels; /** * Use only defined `customLevels` and omit Pino's levels. */ @@ -80,12 +80,12 @@ export interface LoggerExtras extends EventEmitter { * @param options: an options object that will override child logger inherited options. * @returns a child logger instance. */ - child(bindings: pino.Bindings, options?: ChildOptions): pino.Logger; + child>(bindings: pino.Bindings, options?: ChildLoggerOptions): pino.Logger; /** * This can be used to modify the callback function on creation of a new child. */ - onChild: OnChildCallback; + onChild: OnChildCallback; /** * Registers a listener function that is triggered when the level is changed. @@ -95,12 +95,12 @@ export interface LoggerExtras extends EventEmitter { * @param event: only ever fires the `'level-change'` event * @param listener: The listener is passed four arguments: `levelLabel`, `levelValue`, `previousLevelLabel`, `previousLevelValue`. */ - on(event: "level-change", listener: pino.LevelChangeEventListener): this; - addListener(event: "level-change", listener: pino.LevelChangeEventListener): this; - once(event: "level-change", listener: pino.LevelChangeEventListener): this; - prependListener(event: "level-change", listener: pino.LevelChangeEventListener): this; - prependOnceListener(event: "level-change", listener: pino.LevelChangeEventListener): this; - removeListener(event: "level-change", listener: pino.LevelChangeEventListener): this; + on(event: "level-change", listener: pino.LevelChangeEventListener): this; + addListener(event: "level-change", listener: pino.LevelChangeEventListener): this; + once(event: "level-change", listener: pino.LevelChangeEventListener): this; + prependListener(event: "level-change", listener: pino.LevelChangeEventListener): this; + prependOnceListener(event: "level-change", listener: pino.LevelChangeEventListener): this; + removeListener(event: "level-change", listener: pino.LevelChangeEventListener): this; /** * A utility method for determining if a given log level will write to the destination. @@ -225,17 +225,17 @@ declare namespace pino { type SerializerFn = (value: any) => any; type WriteFn = (o: object) => void; - type LevelChangeEventListener = ( + type LevelChangeEventListener = {}> = ( lvl: LevelWithSilentOrString, val: number, prevLvl: LevelWithSilentOrString, prevVal: number, - logger: Logger + logger: Logger ) => void; type LogDescriptor = Record; - type Logger = BaseLogger & LoggerExtras & CustomLevelLogger; + type Logger = {}> = BaseLogger & LoggerExtras & CustomLevelLogger; type SerializedError = pinoStdSerializers.SerializedError; type SerializedResponse = pinoStdSerializers.SerializedResponse; @@ -320,7 +320,7 @@ declare namespace pino { (msg: string, ...args: any[]): void; } - interface LoggerOptions { + interface LoggerOptions> { transport?: TransportSingleOptions | TransportMultiOptions | TransportPipelineOptions /** * Avoid error causes by circular references in the object tree. Default: `true`. @@ -353,7 +353,7 @@ declare namespace pino { * Use this option to define additional logging levels. * The keys of the object correspond the namespace of the log level, and the values should be the numerical value of the level. */ - customLevels?: { [key: string]: number }; + customLevels?: CustomLevels; /** * Use this option to only use defined `customLevels` and omit Pino's levels. * Logger's default `level` must be changed to a value in `customLevels` in order to use `useOnlyCustomLevels` @@ -638,10 +638,10 @@ declare namespace pino { crlf?: boolean; } - interface ChildLoggerOptions { + interface ChildLoggerOptions> { level?: LevelOrString; serializers?: { [key: string]: SerializerFn }; - customLevels?: { [key: string]: number }; + customLevels?: CustomLevels; formatters?: { level?: (label: string, number: number) => object; bindings?: (bindings: Bindings) => object; @@ -791,7 +791,7 @@ declare namespace pino { * relative protocol is enabled. Default: process.stdout * @returns a new logger instance. */ -declare function pino(optionsOrStream?: Options): Logger; +declare function pino(optionsOrStream?: LoggerOptions | DestinationStream): Logger; /** * @param [options]: an options object @@ -799,7 +799,7 @@ declare function pino(options * relative protocol is enabled. Default: process.stdout * @returns a new logger instance. */ -declare function pino(options: Options, stream: DestinationStream): Logger; +declare function pino(options: LoggerOptions, stream: DestinationStream): Logger; // Pass through all the top-level exports, allows `import {version} from "pino"` @@ -820,9 +820,9 @@ export type Level = pino.Level; export type LevelOrString = pino.LevelOrString; export type LevelWithSilent = pino.LevelWithSilent; export type LevelWithSilentOrString = pino.LevelWithSilentOrString; -export type LevelChangeEventListener = pino.LevelChangeEventListener; +export type LevelChangeEventListener = pino.LevelChangeEventListener; export type LogDescriptor = pino.LogDescriptor; -export type Logger = pino.Logger; +export type Logger = {}> = pino.Logger; export type SerializedError = pino.SerializedError; export type SerializerFn = pino.SerializerFn; export type SerializedRequest = pino.SerializedRequest; @@ -831,12 +831,12 @@ export type WriteFn = pino.WriteFn; // Interfaces export interface BaseLogger extends pino.BaseLogger {} -export interface ChildLoggerOptions extends pino.ChildLoggerOptions {} +export interface ChildLoggerOptions> extends pino.ChildLoggerOptions {} export interface DestinationStream extends pino.DestinationStream {} export interface LevelMapping extends pino.LevelMapping {} export interface LogEvent extends pino.LogEvent {} export interface LogFn extends pino.LogFn {} -export interface LoggerOptions extends pino.LoggerOptions {} +export interface LoggerOptions> extends pino.LoggerOptions {} export interface MultiStreamOptions extends pino.MultiStreamOptions {} export interface MultiStreamRes extends pino.MultiStreamRes {} export interface StreamEntry extends pino.StreamEntry {} diff --git a/test/types/pino.test-d.ts b/test/types/pino.test-d.ts index 0641ad0cc..0e6c91144 100644 --- a/test/types/pino.test-d.ts +++ b/test/types/pino.test-d.ts @@ -108,8 +108,7 @@ pino({ }); pino({ base: null }); -// @ts-expect-error -if ("pino" in log) console.log(`pino version: ${log.pino}`); +if ("pino" in log) console.log(`pino version: `); expectType(log.flush()); log.flush((err?: Error) => undefined); @@ -342,4 +341,21 @@ const fn = (logger: Pick) => {} const customLevelChildLogger = customLevelLogger.child({ name: "child" }) -fn(customLevelChildLogger); // missing foo typing +expectError(fn(customLevelChildLogger)); // missing foo typing + +// unknown option +expectError( + pino({ + hello: 'world' + }) +); + +// unknown option +expectError( + pino({ + hello: 'world', + customLevels: { + 'log': 30 + } + }) +); From 1f8158cc786dcfb5c7b5d9527441ec6e4bacf746 Mon Sep 17 00:00:00 2001 From: Agostino Cavarero Date: Wed, 1 Nov 2023 15:14:26 +0100 Subject: [PATCH 2/3] fix: type default value --- pino.d.ts | 4 ++-- test/types/pino.test-d.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pino.d.ts b/pino.d.ts index 1d57c8861..0a78be8db 100644 --- a/pino.d.ts +++ b/pino.d.ts @@ -31,7 +31,7 @@ type TimeFn = () => string; type MixinFn = (mergeObject: object, level: number) => object; type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object; -type CustomLevelLogger = CustomLevels extends Record ? Record : Record +type CustomLevelLogger> = Record /** * A synchronous callback that will run on each creation of a new child. @@ -80,7 +80,7 @@ export interface LoggerExtras = {}> * @param options: an options object that will override child logger inherited options. * @returns a child logger instance. */ - child>(bindings: pino.Bindings, options?: ChildLoggerOptions): pino.Logger; + child = {}>(bindings: pino.Bindings, options?: ChildLoggerOptions): pino.Logger; /** * This can be used to modify the callback function on creation of a new child. diff --git a/test/types/pino.test-d.ts b/test/types/pino.test-d.ts index 0e6c91144..b9a4bfdb4 100644 --- a/test/types/pino.test-d.ts +++ b/test/types/pino.test-d.ts @@ -108,7 +108,8 @@ pino({ }); pino({ base: null }); -if ("pino" in log) console.log(`pino version: `); +// @ts-expect-error +if ("pino" in log) console.log(`pino version: ${log.pino}`); expectType(log.flush()); log.flush((err?: Error) => undefined); @@ -321,6 +322,9 @@ cclog3.childLevel('') // child itself cclog3.childLevel2('') +const ccclog3 = clog3.child({}) +expectError(ccclog3.nonLevel('')) + const withChildCallback = pino({ onChild: (child: Logger) => {} }) @@ -341,7 +345,7 @@ const fn = (logger: Pick) => {} const customLevelChildLogger = customLevelLogger.child({ name: "child" }) -expectError(fn(customLevelChildLogger)); // missing foo typing +fn(customLevelChildLogger); // missing foo typing // unknown option expectError( From d1d75e5703879d7b74b2d90d07e2b483eec3c1f1 Mon Sep 17 00:00:00 2001 From: Agostino Cavarero Date: Wed, 29 Nov 2023 19:50:02 +0100 Subject: [PATCH 3/3] chore: refactor types --- pino.d.ts | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pino.d.ts b/pino.d.ts index 0a78be8db..fb6337783 100644 --- a/pino.d.ts +++ b/pino.d.ts @@ -31,13 +31,13 @@ type TimeFn = () => string; type MixinFn = (mergeObject: object, level: number) => object; type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object; -type CustomLevelLogger> = Record +type CustomLevelLogger = { [level in CustomLevels]: LogFn } /** * A synchronous callback that will run on each creation of a new child. * @param child: The newly created child logger instance. */ -type OnChildCallback = {}> = (child: pino.Logger) => void +type OnChildCallback = (child: pino.Logger) => void export interface redactOptions { paths: string[]; @@ -45,7 +45,7 @@ export interface redactOptions { remove?: boolean; } -export interface LoggerExtras = {}> extends EventEmitter { +export interface LoggerExtras extends EventEmitter { /** * Exposes the Pino package version. Also available on the exported pino function. */ @@ -60,7 +60,7 @@ export interface LoggerExtras = {}> /** * Define additional logging levels. */ - customLevels: CustomLevels; + customLevels: { [level in CustomLevels]: number }; /** * Use only defined `customLevels` and omit Pino's levels. */ @@ -80,7 +80,7 @@ export interface LoggerExtras = {}> * @param options: an options object that will override child logger inherited options. * @returns a child logger instance. */ - child = {}>(bindings: pino.Bindings, options?: ChildLoggerOptions): pino.Logger; + child(bindings: pino.Bindings, options?: ChildLoggerOptions): pino.Logger; /** * This can be used to modify the callback function on creation of a new child. @@ -225,7 +225,7 @@ declare namespace pino { type SerializerFn = (value: any) => any; type WriteFn = (o: object) => void; - type LevelChangeEventListener = {}> = ( + type LevelChangeEventListener = ( lvl: LevelWithSilentOrString, val: number, prevLvl: LevelWithSilentOrString, @@ -235,7 +235,7 @@ declare namespace pino { type LogDescriptor = Record; - type Logger = {}> = BaseLogger & LoggerExtras & CustomLevelLogger; + type Logger = BaseLogger & LoggerExtras & CustomLevelLogger; type SerializedError = pinoStdSerializers.SerializedError; type SerializedResponse = pinoStdSerializers.SerializedResponse; @@ -320,7 +320,7 @@ declare namespace pino { (msg: string, ...args: any[]): void; } - interface LoggerOptions> { + interface LoggerOptions { transport?: TransportSingleOptions | TransportMultiOptions | TransportPipelineOptions /** * Avoid error causes by circular references in the object tree. Default: `true`. @@ -353,7 +353,7 @@ declare namespace pino { * Use this option to define additional logging levels. * The keys of the object correspond the namespace of the log level, and the values should be the numerical value of the level. */ - customLevels?: CustomLevels; + customLevels?: { [level in CustomLevels]: number }; /** * Use this option to only use defined `customLevels` and omit Pino's levels. * Logger's default `level` must be changed to a value in `customLevels` in order to use `useOnlyCustomLevels` @@ -638,10 +638,10 @@ declare namespace pino { crlf?: boolean; } - interface ChildLoggerOptions> { + interface ChildLoggerOptions { level?: LevelOrString; serializers?: { [key: string]: SerializerFn }; - customLevels?: CustomLevels; + customLevels?: { [level in CustomLevels]: number }; formatters?: { level?: (label: string, number: number) => object; bindings?: (bindings: Bindings) => object; @@ -791,7 +791,7 @@ declare namespace pino { * relative protocol is enabled. Default: process.stdout * @returns a new logger instance. */ -declare function pino(optionsOrStream?: LoggerOptions | DestinationStream): Logger; +declare function pino(optionsOrStream?: LoggerOptions | DestinationStream): Logger; /** * @param [options]: an options object @@ -799,7 +799,7 @@ declare function pino(opti * relative protocol is enabled. Default: process.stdout * @returns a new logger instance. */ -declare function pino(options: LoggerOptions, stream: DestinationStream): Logger; +declare function pino(options: LoggerOptions, stream: DestinationStream): Logger; // Pass through all the top-level exports, allows `import {version} from "pino"` @@ -820,9 +820,9 @@ export type Level = pino.Level; export type LevelOrString = pino.LevelOrString; export type LevelWithSilent = pino.LevelWithSilent; export type LevelWithSilentOrString = pino.LevelWithSilentOrString; -export type LevelChangeEventListener = pino.LevelChangeEventListener; +export type LevelChangeEventListener = pino.LevelChangeEventListener; export type LogDescriptor = pino.LogDescriptor; -export type Logger = {}> = pino.Logger; +export type Logger = pino.Logger; export type SerializedError = pino.SerializedError; export type SerializerFn = pino.SerializerFn; export type SerializedRequest = pino.SerializedRequest; @@ -831,12 +831,12 @@ export type WriteFn = pino.WriteFn; // Interfaces export interface BaseLogger extends pino.BaseLogger {} -export interface ChildLoggerOptions> extends pino.ChildLoggerOptions {} +export interface ChildLoggerOptions extends pino.ChildLoggerOptions {} export interface DestinationStream extends pino.DestinationStream {} export interface LevelMapping extends pino.LevelMapping {} export interface LogEvent extends pino.LogEvent {} export interface LogFn extends pino.LogFn {} -export interface LoggerOptions> extends pino.LoggerOptions {} +export interface LoggerOptions extends pino.LoggerOptions {} export interface MultiStreamOptions extends pino.MultiStreamOptions {} export interface MultiStreamRes extends pino.MultiStreamRes {} export interface StreamEntry extends pino.StreamEntry {}