Skip to content

Commit

Permalink
Merge pull request #9 from anru/tune-typings
Browse files Browse the repository at this point in the history
Get rid of typing issues in Signales constructor options
  • Loading branch information
anru authored Mar 31, 2021
2 parents 26c7953 + 5ea878c commit c2eef9f
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 28 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "signales",
"version": "2.0.4",
"version": "2.0.5",
"description": "Highly configurable logging utility",
"license": "MIT",
"repository": "anru/signales",
Expand Down Expand Up @@ -39,7 +39,7 @@
"devDependencies": {
"@types/node": "^11.11.3",
"tsd": "^0.14.0",
"typescript": "^4.1.3"
"typescript": "^4.2.3"
},
"author": {
"name": "Klaus Sinani",
Expand Down
4 changes: 2 additions & 2 deletions src/logger-types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';
import figures from 'figures'
import type { DefaultLogTypes, LoggerTypesConf } from './types'
import type { DefaultLoggerTypes } from './types'

const logTypes: LoggerTypesConf<DefaultLogTypes> = {
const logTypes: DefaultLoggerTypes = {
error: {
badge: figures.cross,
color: 'red',
Expand Down
12 changes: 8 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
ScopeFormatter, DefaultLogLevels,
} from './types'

export type SignaleEntrypoint = typeof Signale & { Signale: SignaleConstructor}
export type SignaleEntrypoint = typeof Signale & { Signale: SignaleConstructor }

const signale: SignaleEntrypoint = Object.assign(new Signale(), {
Signale,
Expand All @@ -25,8 +25,9 @@ export {
Signales,
}

// utility type
export type SignaleConstructorOptions<T extends string = DefaultLogTypes, L extends string = DefaultLogLevels> = ConstructorOptions<T, L>
// type for backward compartibility
// same as ConstructorOptions
export type SignaleConstructorOptions<T extends string = never, L extends string = never> = ConstructorOptions<T, L>

// re-export types
export {
Expand All @@ -35,7 +36,10 @@ export {
InstanceConfiguration,
LoggerFunction,
LoggerTypesConf,
ScopeFormatter
ScopeFormatter,
DefaultLogTypes,
DefaultLogLevels,
ConstructorOptions,
}

export default signale
23 changes: 12 additions & 11 deletions src/signale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
DefaultLogTypes, InstanceConfiguration,
LoggerConfiguration, LoggerFunction,
LoggerTypesConf,
DefaultLoggerTypes,
DefaultLogLevels, ScopeFormatter, Secrets
} from './types'

Expand Down Expand Up @@ -52,17 +53,17 @@ function barsScopeFormatter(scopes: string[]): string {
return scopes.map(scope => `[${scope}]`).join(' ')
}

class SignaleImpl<T extends string = DefaultLogTypes, L extends string = DefaultLogLevels> {
class SignaleImpl<T extends string = never, L extends string = never> {
_interactive: boolean
_config: InstanceConfiguration
_customTypes: Partial<LoggerTypesConf<T, L>>
_customLogLevels: Record<string, number>
_customTypes: LoggerTypesConf<T, L> & Partial<LoggerTypesConf<DefaultLogTypes, L>>
_customLogLevels: Partial<Record<DefaultLogLevels, number>> & Record<L, number>
_logLevels: Record<string, number>
_disabled: boolean
_scopeName: string | string[]
_timers: Map<string, number>
_seqTimers: Array<string>
_types: LoggerTypesConf<DefaultLogTypes | T, L>
_types: Record<T, Partial<LoggerConfiguration<L>>> & DefaultLoggerTypes<L>
_stream: WritableStream | WritableStream[]
_longestLabel: string
_secrets: Secrets
Expand Down Expand Up @@ -165,16 +166,16 @@ class SignaleImpl<T extends string = DefaultLogTypes, L extends string = Default

_getLongestLabel(): string {
const {_types} = this
const labels = Object.keys(_types).map(x => _types[x as T].label)
const labels = Object.keys(_types).map(x => _types[x as T].label || '')
return labels.reduce((x, y) => x.length > y.length ? x : y)
}

_validateLogLevel(level: L | DefaultLogLevels | undefined): L | DefaultLogLevels {
return level && Object.keys(this._logLevels).includes(level) ? level : 'debug'
}

_mergeTypes(standard: LoggerTypesConf<DefaultLogTypes>, custom: Partial<LoggerTypesConf<T, L>>): LoggerTypesConf<T | DefaultLogTypes, L> {
const types: LoggerTypesConf<T | DefaultLogTypes, L> = Object.assign({}, standard) as LoggerTypesConf<T | DefaultLogTypes, L>
_mergeTypes(standard: DefaultLoggerTypes<L>, custom: LoggerTypesConf<T, L>): Record<T, Partial<LoggerConfiguration<L>>> & DefaultLoggerTypes<L> {
const types: Record<T, Partial<LoggerConfiguration<L>>> & DefaultLoggerTypes<L> = Object.assign({}, standard) as Record<T, Partial<LoggerConfiguration<L>>> & DefaultLoggerTypes<L>

Object.keys(custom).forEach(type => {
types[type as T] = Object.assign({}, types[type as T], custom[type as T])
Expand Down Expand Up @@ -255,7 +256,7 @@ class SignaleImpl<T extends string = DefaultLogTypes, L extends string = Default
return (suffix || prefix) ? '' : this._formatMessage(args)
}

_buildSignale(type: LoggerConfiguration<L>, ...args: any[]): string {
_buildSignale(type: Partial<LoggerConfiguration<L>>, ...args: any[]): string {
let msg
let additional: AdditionalFormatObj = {}

Expand Down Expand Up @@ -468,11 +469,11 @@ class SignaleImpl<T extends string = DefaultLogTypes, L extends string = Default
}
}

export type SignaleType<T extends string = DefaultLogTypes, L extends string = DefaultLogLevels> = Record<T, LoggerFunction> &
export type SignaleType<T extends string = never, L extends string = never> = Record<T, LoggerFunction> &
Record<DefaultLogTypes, LoggerFunction> & SignaleImpl<T, L> &
(new <T extends string = DefaultLogTypes, L extends string = DefaultLogLevels>(options?: ConstructorOptions<T, L>) => SignaleType<T, L>)
(new <T extends string = never, L extends string = never>(options?: ConstructorOptions<T, L>) => SignaleType<T, L>)

export type SignaleConstructor<T extends string = DefaultLogTypes, L extends string = DefaultLogLevels> =
export type SignaleConstructor<T extends string = never, L extends string = never> =
new (options?: ConstructorOptions<T, L>) => SignaleType<T, L>

export default SignaleImpl as unknown as SignaleType
14 changes: 9 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ export type DefaultLogLevels = 'info' | 'timer' | 'debug' | 'warn' | 'error'
// alias for backward-compatibility
export type LogLevel = DefaultLogLevels

export interface LoggerConfiguration<L extends string = DefaultLogLevels> {
export interface LoggerConfiguration<L extends string = never> {
badge: string,
color: ChalkColor | '',
label: string,
logLevel?: L | DefaultLogLevels,
stream?: WritableStream | WritableStream[],
}

export type LoggerTypesConf<T extends string, L extends string = DefaultLogLevels> = Record<T, LoggerConfiguration<L>>
export type LoggerTypesConf<T extends string, L extends string = never> = Record<T, Partial<LoggerConfiguration<L>>>
export type DefaultLoggerTypes<L extends string = never> = Record<DefaultLogTypes, LoggerConfiguration<L>>

export interface InstanceConfiguration {
displayBadge?: boolean,
Expand All @@ -63,15 +64,18 @@ export interface InstanceConfiguration {

export type ScopeFormatter = (scopePath: string[]) => string

export interface ConstructorOptions<T extends string, L extends string = DefaultLogLevels> {
export interface ConstructorOptions<T extends string = never, L extends string = never> {
config?: InstanceConfiguration,
disabled?: boolean,
interactive?: boolean,
logLevel?: L | DefaultLogLevels,
logLevels?: Record<L, number>,
logLevels?: Partial<Record<DefaultLogLevels, number>> & Record<L, number>,
scope?: string | string[],
scopeFormatter?: ScopeFormatter,
secrets?: Secrets,
stream?: WritableStream | WritableStream[],
types?: Partial<LoggerTypesConf<T, L>>,
// we can't negate DefaultLogTypes from string
// see https://github.com/microsoft/TypeScript/pull/29317 (not merged as for 31 march 2021)
// so we can't distinguish logger configuration between default log types and passed one
types?: LoggerTypesConf<T, L> & Partial<LoggerTypesConf<DefaultLogTypes, L>>
}
3 changes: 3 additions & 0 deletions test-d/custom-log-levels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const custom = new Signale({
},
logLevel: 'sherlock',
types: {
debug: {
color: 'grey',
},
sherlock: {
badge: '🔎',
color: 'yellow',
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1202,10 +1202,10 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"

typescript@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
typescript@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==

unique-string@^2.0.0:
version "2.0.0"
Expand Down

0 comments on commit c2eef9f

Please sign in to comment.