diff --git a/eslint.config.js b/eslint.config.js index 64329d36..deeafeff 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -5,11 +5,32 @@ import tseslint from 'typescript-eslint'; import eslintConfigPrettier from 'eslint-config-prettier'; export default tseslint.config( - eslint.configs.recommended, - ...tseslint.configs.strictTypeChecked, - ...tseslint.configs.stylisticTypeChecked, { - ignores: ['dist/*', 'docs/*'], + languageOptions: { + parserOptions: { + project: './tsconfig.prod.json', + tsconfigRootDir: import.meta.dirname, + }, + }, + extends: [ + eslint.configs.recommended, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + eslintConfigPrettier, + ], + rules: { + '@typescript-eslint/restrict-template-expressions': [ + 'error', + { + allowNumber: true, + allowBoolean: true, + allowAny: true, + allowNullish: true, + }, + ], + }, }, - eslintConfigPrettier + { + ignores: ['dist/', 'docs/'], + } ); diff --git a/package.json b/package.json index c434aa6a..b9736c86 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "scripts": { "prebuild": "npm run clean", - "build": "tsc --project tsconfig.prod.json && tsc-alias && rm ./dist/demo_funcs.js && rm ./dist/demo_funcs.d.ts", + "build": "tsc --project tsconfig.prod.json && tsc-alias && rm -f ./dist/demo_funcs.js && rm -f ./dist/demo_funcs.d.ts", "build:demo": "tsc --project tsconfig.json && tsc-alias", "clean": "rm -rf ./dist", "docs:build": "vuepress build docs", diff --git a/src/_types/configuration.ts b/src/_types/configuration.ts index 4662584c..e71028c8 100644 --- a/src/_types/configuration.ts +++ b/src/_types/configuration.ts @@ -10,7 +10,7 @@ export type Format = (typeof formats)[number]; /** * Configuration data points that are also emitted with log data. */ -export interface ConfigurationData = Record> { +export interface ConfigurationData = Record> { /** * The level of logs to render. * @@ -67,7 +67,7 @@ export interface ConfigurationData = Record = Record> +export interface Configuration = Record> extends ConfigurationData { /** * Applies middleware to execute along with the log. @@ -115,7 +115,6 @@ export interface Filters { * The log levels to filter. */ export type LevelSelector = - | '*' | string | number | string[] @@ -145,9 +144,8 @@ export interface FilterConfig { /** * Partial configuration provided by the user. */ -export type UserConfiguration = Record> = Partial< - Configuration ->; +export type UserConfiguration = Record> = + Partial>; /** * Extended configuration if the user specifies a the formatter as "common". diff --git a/src/_types/log.ts b/src/_types/log.ts index f23e7b58..5418093d 100644 --- a/src/_types/log.ts +++ b/src/_types/log.ts @@ -63,16 +63,12 @@ export type IObject = Record; /** * Type for the constructor of a Formatter class. */ -export interface FormatterConstructor { - new (cfg: Configuration, level: LevelConfiguration): Formatter; -} +export type FormatterConstructor = new (cfg: Configuration, level: LevelConfiguration) => Formatter; /** * Type for the constructor of an adze class. */ -export interface AdzeConstructor { - new (cfg: UserConfiguration, modifierData?: ModifierData): adze; -} +export type AdzeConstructor = new (cfg: UserConfiguration, modifierData?: ModifierData) => adze; export interface ModifierData { method?: Method; diff --git a/src/adze-global.ts b/src/adze-global.ts index 26d9d605..aa26b18d 100644 --- a/src/adze-global.ts +++ b/src/adze-global.ts @@ -1,11 +1,4 @@ -import { - Configuration, - Label, - LabelMap, - LevelSelector, - LogListener, - UserConfiguration, -} from './_types'; +import { Label, LabelMap, LevelSelector, LogListener, UserConfiguration } from './_types'; import { defaultConfiguration } from './constants'; import { normalizeLevelSelector } from './functions'; import Log from './log'; @@ -18,7 +11,7 @@ import Tools from './tools'; */ type ListenersMap = Map>; -export default class AdzeGlobal = Record> { +export default class AdzeGlobal = Record> { /** * Global Adze configuration overrides. */ @@ -122,7 +115,7 @@ export default class AdzeGlobal = Record { + normalizedLevels.forEach((level: number) => { if (this._levelsToListeners.has(level)) { const levelContainer = this._levelsToListeners.get(level) as Map; levelContainer.set(id, listener); diff --git a/src/configuration.ts b/src/configuration.ts index 2bbd5127..6d0f083e 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -30,7 +30,7 @@ export class Configuration implements IConfiguration { } public get activeLevel(): Level | number { - return this.glblCfg?.activeLevel ?? this.logCfg?.activeLevel ?? dfltCfg.activeLevel; + return this.glblCfg?.activeLevel ?? this.logCfg.activeLevel ?? dfltCfg.activeLevel; } public set activeLevel(level: Level | number) { @@ -38,7 +38,7 @@ export class Configuration implements IConfiguration { } public get cache(): boolean { - return this.glblCfg?.cache ?? this.logCfg?.cache ?? dfltCfg.cache; + return this.glblCfg?.cache ?? this.logCfg.cache ?? dfltCfg.cache; } public set cache(value: boolean) { @@ -46,7 +46,7 @@ export class Configuration implements IConfiguration { } public get cacheSize(): number { - return this.glblCfg?.cacheSize ?? this.logCfg?.cacheSize ?? dfltCfg.cacheSize; + return this.glblCfg?.cacheSize ?? this.logCfg.cacheSize ?? dfltCfg.cacheSize; } public set cacheSize(size: number) { @@ -54,23 +54,23 @@ export class Configuration implements IConfiguration { } public get dump(): boolean { - return this.glblCfg?.dump ?? this.logCfg?.dump ?? dfltCfg.dump; + return this.glblCfg?.dump ?? this.logCfg.dump ?? dfltCfg.dump; } public set dump(value: boolean) { this.logCfg.dump = value; } - public get meta(): Record { - return { ...this.logCfg?.meta, ...this.glblCfg?.meta }; + public get meta(): Record { + return { ...this.logCfg.meta, ...this.glblCfg?.meta }; } - public set meta(value: Record) { + public set meta(value: Record) { this.logCfg.meta = value; } public get silent(): boolean { - return this.glblCfg?.silent ?? this.logCfg?.silent ?? dfltCfg.silent; + return this.glblCfg?.silent ?? this.logCfg.silent ?? dfltCfg.silent; } public set silent(value: boolean) { @@ -78,7 +78,7 @@ export class Configuration implements IConfiguration { } public get showTimestamp(): boolean { - return this.glblCfg?.showTimestamp ?? this.logCfg?.showTimestamp ?? dfltCfg.showTimestamp; + return this.glblCfg?.showTimestamp ?? this.logCfg.showTimestamp ?? dfltCfg.showTimestamp; } public set showTimestamp(value: boolean) { @@ -86,7 +86,7 @@ export class Configuration implements IConfiguration { } public get withEmoji(): boolean { - return this.glblCfg?.withEmoji ?? this.logCfg?.withEmoji ?? dfltCfg.withEmoji; + return this.glblCfg?.withEmoji ?? this.logCfg.withEmoji ?? dfltCfg.withEmoji; } public set withEmoji(value: boolean) { @@ -94,7 +94,7 @@ export class Configuration implements IConfiguration { } public get format(): string { - return this.glblCfg?.format ?? this.logCfg?.format ?? dfltCfg.format; + return this.glblCfg?.format ?? this.logCfg.format ?? dfltCfg.format; } public set format(value: string) { @@ -102,7 +102,7 @@ export class Configuration implements IConfiguration { } public get levels(): Record { - return { ...dfltCfg.levels, ...(this.logCfg?.levels ?? {}), ...(this.glblCfg?.levels ?? {}) }; + return { ...dfltCfg.levels, ...(this.logCfg.levels ?? {}), ...(this.glblCfg?.levels ?? {}) }; } public set levels(value: Record) { @@ -110,7 +110,7 @@ export class Configuration implements IConfiguration { } public get middleware(): Middleware[] | undefined { - return [...(this.glblCfg?.middleware ?? []), ...(this.logCfg?.middleware ?? [])]; + return [...(this.glblCfg?.middleware ?? []), ...(this.logCfg.middleware ?? [])]; } public set middleware(value: Middleware[] | undefined) { @@ -118,7 +118,7 @@ export class Configuration implements IConfiguration { } public get filters(): Filters | undefined { - return this.glblCfg?.filters ?? this.logCfg?.filters; + return this.glblCfg?.filters ?? this.logCfg.filters; } public set filters(value: Filters | undefined) { @@ -126,7 +126,7 @@ export class Configuration implements IConfiguration { } public get timestampFormatter(): TimestampFormatter | undefined { - return this.glblCfg?.timestampFormatter ?? this.logCfg?.timestampFormatter; + return this.glblCfg?.timestampFormatter ?? this.logCfg.timestampFormatter; } public set timestampFormatter(value: TimestampFormatter | undefined) { @@ -136,7 +136,7 @@ export class Configuration implements IConfiguration { public get formatters(): Record { return { ...dfltCfg.formatters, - ...(this.logCfg?.formatters ?? {}), + ...(this.logCfg.formatters ?? {}), ...(this.glblCfg?.formatters ?? {}), }; } diff --git a/src/constants.ts b/src/constants.ts index 52204374..1322199c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,7 +3,7 @@ import CommonFormatter from './formatters/common'; import JsonFormatter from './formatters/json'; import PrettyFormatter from './formatters/pretty'; import StandardFormatter from './formatters/standard/standard'; -import { isChrome, isSafari } from './functions/global'; +import { isChrome, isSafari } from './functions'; /** * All valid log terminators. These are the terminators that can be called to end a log chain. diff --git a/src/demo_funcs.ts b/src/demo_funcs.ts index 77648ae0..d1e45461 100644 --- a/src/demo_funcs.ts +++ b/src/demo_funcs.ts @@ -11,9 +11,10 @@ import adze, { isBrowser, } from './index'; import { StandardLogFormatMeta } from './formatters/standard/types'; +import Log from './log'; if (isBrowser()) { - // @ts-ignore + // @ts-expect-error Setting adze to the window if in the browser window.adze = adze; } @@ -60,6 +61,7 @@ async function runDemo() { listener(); } +// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars async function performance() { setup({ withEmoji: true, @@ -95,7 +97,7 @@ async function performance() { teardown(); } -async function defaultLevels() { +function defaultLevels() { setup({ withEmoji: true, activeLevel: 1337, @@ -350,13 +352,19 @@ function counting() { function tests() { // @ts-expect-error Intentional error to test the assertion + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.assert(2 === 4).log('This is a failed assertion!'); // @ts-expect-error Intentional error to test the assertion + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.assert(2 === 4).log('This is a failed assertion with emoji!'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.assert(4 === 4).log('This passed so it should not show!'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.if(2 === 2).log('This condition passed!'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.if(2 === 2).log('This condition passed with emoji!'); // @ts-expect-error Intentional error to test the assertion + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.if(2 === 4).log('This condition failed so it should not show!'); } @@ -533,7 +541,7 @@ async function json() { }, req_id: '12345', req: await serializeRequest(request, true), - res: await serializeResponse(response), + res: serializeResponse(response), latency: 4444444, }) .ns('foobar', 'baz') @@ -552,8 +560,8 @@ async function json() { function listener() { const store = setup(); - const id = store.addListener('*', (log) => { - // console.log(log.data); + const id = store.addListener('*', (log: Log) => { + console.log('Log level logged from listener', log.data?.level); }); adze.withEmoji.log('This is a log'); adze.ns('derp').log('This is a namespaced log'); @@ -562,6 +570,7 @@ function listener() { teardown(); } +// eslint-disable-next-line @typescript-eslint/no-unused-vars function time() { setup(); adze.timeNow.log('This is a time log'); diff --git a/src/formatters/common/common.ts b/src/formatters/common/common.ts index 572bbeca..19ddd015 100644 --- a/src/formatters/common/common.ts +++ b/src/formatters/common/common.ts @@ -1,6 +1,5 @@ import Formatter from '../formatter'; -import { Configuration } from '../../configuration'; -import { LevelConfiguration, ModifierData } from '../../_types'; +import { ModifierData } from '../../_types'; import { format } from 'date-fns/format'; /** @@ -18,10 +17,6 @@ export default class CommonFormatter extends Formatter { protected timestampFormatFunction: (date: Date) => string = (date: Date) => format(date, 'dd/MMM/yyyy:HH:mm:ss xx'); - constructor(cfg: Configuration, level: LevelConfiguration) { - super(cfg, level); - } - /** * Format the log message for the browser. */ @@ -42,16 +37,17 @@ export default class CommonFormatter extends Formatter { * **Example:** 127.0.0.1 user-identifier frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 */ private formatMessage(_: ModifierData, timestamp: string, args: unknown[]): unknown[] { - if (this.cfg.meta?.hostname === undefined) { + if (this.cfg.meta.hostname === undefined) { console.warn( new Error( "Adze: 'hostname' is required for the common log format. Please provide this value in your log's meta data." ) ); } - const hostname = this.cfg.meta?.hostname; - const ident = this.cfg.meta?.ident ?? '-'; - const user = this.cfg.meta?.user ?? '-'; - return [`${hostname} ${ident} ${user} [${timestamp}] ${args[0]}`]; + const hostname = this.cfg.meta.hostname as string; + const ident = (this.cfg.meta.ident as string | undefined) ?? '-'; + const user = (this.cfg.meta.user as string | undefined) ?? '-'; + const firstArg = args[0] as string; + return [`${hostname} ${ident} ${user} [${timestamp}] ${firstArg}`]; } } diff --git a/src/formatters/formatter.ts b/src/formatters/formatter.ts index 7b5aca16..990f0972 100644 --- a/src/formatters/formatter.ts +++ b/src/formatters/formatter.ts @@ -44,9 +44,7 @@ export default abstract class Formatter { * this formatter instance. */ public get timestampFormatter(): (date: Date) => string { - return this.cfg?.timestampFormatter - ? this.cfg?.timestampFormatter - : this.timestampFormatFunction; + return this.cfg.timestampFormatter ? this.cfg.timestampFormatter : this.timestampFormatFunction; } /** @@ -114,15 +112,12 @@ export default abstract class Formatter { private failsNamespacesFilter(mods: ModifierData): boolean { if (this.cfg.filters?.namespaces === undefined) return false; if (this.cfg.filters.namespaces.values.length > 0 && mods.namespace === undefined) return true; - if (this.cfg.filters?.namespaces.type === 'include') { + if (this.cfg.filters.namespaces.type === 'include') { const namespaces = mods.namespace ?? []; - return isNotIncluded(this.cfg.filters?.namespaces.values, namespaces); + return isNotIncluded(this.cfg.filters.namespaces.values, namespaces); } - if (this.cfg.filters?.namespaces.type === 'exclude') { - const namespaces = mods.namespace ?? []; - return isExcluded(this.cfg.filters?.namespaces.values, namespaces); - } - return false; + const namespaces = mods.namespace ?? []; + return isExcluded(this.cfg.filters.namespaces.values, namespaces); } /** @@ -130,14 +125,11 @@ export default abstract class Formatter { */ private failsLabelsFilter(mods: ModifierData): boolean { if (this.cfg.filters?.labels === undefined) return false; - if (this.cfg.filters.labels.values?.length > 0 && mods.label === undefined) return true; + if (this.cfg.filters.labels.values.length > 0 && mods.label === undefined) return true; const label = mods.label ? [mods.label.name] : []; - if (this.cfg.filters?.labels.type === 'include') { - return isNotIncluded(this.cfg.filters?.labels.values, label); + if (this.cfg.filters.labels.type === 'include') { + return isNotIncluded(this.cfg.filters.labels.values, label); } - if (this.cfg.filters?.labels.type === 'exclude') { - return isExcluded(this.cfg.filters?.labels.values, label); - } - return false; + return isExcluded(this.cfg.filters.labels.values, label); } } diff --git a/src/formatters/json/functions.ts b/src/formatters/json/functions.ts index 5528f948..1e1bbabe 100644 --- a/src/formatters/json/functions.ts +++ b/src/formatters/json/functions.ts @@ -12,14 +12,15 @@ import { JsonLogHttpRequest, JsonLogHttpResponse, JsonLogError } from './types'; */ export async function serializeRequest( request: Request, - includeUsername: boolean = false + includeUsername = false ): Promise { const url = new URL(request.url); + const json = (await request.json()) as unknown; return { headers: getHeaders(request.headers), method: request.method as HttpMethod, url: request.url, - body: await request.json(), + body: json ? JSON.stringify(json) : undefined, remoteAddress: url.host.split(':')[0], remotePort: getPortFromUrl(url), username: includeUsername ? getUsername(request.headers) : undefined, @@ -39,8 +40,9 @@ function getPortFromUrl(url: URL): number | undefined { * Converts a Headers object to a plain object. */ function getHeaders(headers: Headers): Record { - let headerObj: Record = {}; + const headerObj: Record = {}; headers.forEach((v, k) => (headerObj[k] = v)); + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { Authorization, authorization, ...rest } = headerObj; return rest; } @@ -63,7 +65,7 @@ function getUsername(headers: Headers): string | undefined { /** * Serializes a Response object into a JSON Log HTTP Response object. */ -export async function serializeResponse(response: Response): Promise { +export function serializeResponse(response: Response): JsonLogHttpResponse { const url = new URL(response.url); const headerString = Object.keys(getHeaders(response.headers)).reduce( (s, k, v) => `${s}${k}: ${v}\r\n`, diff --git a/src/formatters/json/json.ts b/src/formatters/json/json.ts index 5d654ef4..0735d76c 100644 --- a/src/formatters/json/json.ts +++ b/src/formatters/json/json.ts @@ -1,6 +1,5 @@ import Formatter from '../formatter'; -import { Configuration } from '../../configuration'; -import { LevelConfiguration, ModifierData } from '../../_types'; +import { ModifierData } from '../../_types'; import { formatISO } from 'date-fns/formatISO'; import { JsonLog, JsonLogOptionalFields, JsonLogRequiredFields } from './types'; import { hasRequiredFields } from './type-guards'; @@ -15,10 +14,6 @@ export default class JsonFormatter extends Formatter { */ protected timestampFormatFunction: (date: Date) => string = (date: Date) => formatISO(date); - constructor(cfg: Configuration, level: LevelConfiguration) { - super(cfg, level); - } - /** * Format the log message for the browser. */ @@ -39,9 +34,9 @@ export default class JsonFormatter extends Formatter { private formatMessage(mods: ModifierData, timestamp: string, _args: unknown[]): unknown[] { const global = setup(); const args = [..._args]; - const msg = args.shift(); - if (this.cfg.meta && hasRequiredFields(this.cfg.meta)) { - const { levelName, src, err, req_id, req, res, latency, hostname, name, ...meta } = this.cfg + const msg = args.shift() as string; + if (hasRequiredFields(this.cfg.meta)) { + const { src, err, req_id, req, res, latency, hostname, name, ...meta } = this.cfg .meta as JsonLogRequiredFields & JsonLogOptionalFields; const { namespace, label } = mods; const json: JsonLog = { @@ -50,7 +45,7 @@ export default class JsonFormatter extends Formatter { levelName: this.level.levelName, name, hostname, - msg: `${msg}`, + msg: msg, args, pid: global.pid, time: timestamp, diff --git a/src/formatters/json/type-guards.ts b/src/formatters/json/type-guards.ts index 18271489..7722b0d2 100644 --- a/src/formatters/json/type-guards.ts +++ b/src/formatters/json/type-guards.ts @@ -3,6 +3,7 @@ import { JsonLogRequiredFields } from './types'; /** * Validates that the log meta data contains the required fields for a JSON log. */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function hasRequiredFields(meta: Record): meta is JsonLogRequiredFields { return typeof meta.name === 'string' && typeof meta.hostname === 'string'; } diff --git a/src/formatters/pretty/pretty.ts b/src/formatters/pretty/pretty.ts index ba649e47..3763f74b 100644 --- a/src/formatters/pretty/pretty.ts +++ b/src/formatters/pretty/pretty.ts @@ -1,5 +1,4 @@ import Formatter from '../formatter'; -import { Configuration } from '../../configuration'; import { addPadding, applyChalkStyles, @@ -10,16 +9,12 @@ import { formatNamespace, initialCaps, } from '../../functions'; -import { LevelConfiguration, ModifierData } from '../../_types'; +import { ModifierData } from '../../_types'; /** * Formats log messages in a pretty, human-readable manner. */ export default class PrettyFormatter extends Formatter { - constructor(cfg: Configuration, level: LevelConfiguration) { - super(cfg, level); - } - /** * Format the log message for the browser. */ @@ -27,9 +22,9 @@ export default class PrettyFormatter extends Formatter { const leader = this.formatLeader(); const meta = this.formatMeta(mods, timestamp); if (this.cfg.withEmoji) { - return [leader, 'font-size: 12px;', this.level.style, meta, ...(args ?? [])]; + return [leader, 'font-size: 12px;', this.level.style, meta, ...args]; } - return [leader, this.level.style, meta, ...(args ?? [])]; + return [leader, this.level.style, meta, ...args]; } /** @@ -45,7 +40,7 @@ export default class PrettyFormatter extends Formatter { message.push(styledLeader); meta !== '' ? message.push(meta) : null; - return [styledLeader, meta, ...(args ?? [])]; + return [styledLeader, meta, ...args]; } /** @@ -87,10 +82,10 @@ export default class PrettyFormatter extends Formatter { * Formats the time elapsed string. */ private formatTime(mods: ModifierData): string { - const timeLeader = `${this.cfg.withEmoji ? '⏱ ' : 'Time elapsed: '}`; + const timeLeader = this.cfg.withEmoji ? '⏱ ' : 'Time elapsed: '; if (mods.timeNow) { return `(${timeLeader}${mods.timeNow})`; } - return mods.label?.timeElapsed ? `(${timeLeader}${mods.label?.timeElapsed})` : ''; + return mods.label?.timeElapsed ? `(${timeLeader}${mods.label.timeElapsed})` : ''; } } diff --git a/src/formatters/standard/standard.ts b/src/formatters/standard/standard.ts index 96dc9d53..a7a62c25 100644 --- a/src/formatters/standard/standard.ts +++ b/src/formatters/standard/standard.ts @@ -1,8 +1,7 @@ import Formatter from '../formatter'; -import { Configuration } from '../../configuration'; -import { LevelConfiguration, ModifierData } from '../../_types'; +import { ModifierData } from '../../_types'; import { formatISO } from 'date-fns/formatISO'; -import { isObject } from '../../functions'; +import { isNumber, isObject, isString } from '../../functions'; /** * Formats log messages for stdout lines. @@ -15,10 +14,6 @@ export default class StandardFormatter extends Formatter { */ protected timestampFormatFunction: (date: Date) => string = (date: Date) => formatISO(date); - constructor(cfg: Configuration, level: LevelConfiguration) { - super(cfg, level); - } - /** * Format the log message for the browser. */ @@ -38,17 +33,15 @@ export default class StandardFormatter extends Formatter { */ private formatMessage(timestamp: string, mods: ModifierData, args: unknown[]): unknown[] { let leader = ''; - if (this.cfg.meta) { - const { appname, hostname, port } = this.cfg.meta; - let _port = port ? `/${port}` : ''; - let appPort = appname ? `${appname}${_port}` : ''; - let _host = hostname ? ` on ${hostname}: ` : ''; - let namespace = this.formatNamespace(mods.namespace); - let label = mods.label ? `[${mods.label.name}] ` : ''; - leader = `${appPort}${_host}${namespace}${label}`; - } + const { appname, hostname, port } = this.cfg.meta; + const _port = isNumber(port) ? `/${port}` : ''; + const appPort = isString(appname) ? `${appname}${_port}` : ''; + const _host = isString(hostname) ? ` on ${hostname}: ` : ''; + const namespace = this.formatNamespace(mods.namespace); + const label = mods.label ? `[${mods.label.name}] ` : ''; + leader = `${appPort}${_host}${namespace}${label}`; return [ - `[${timestamp}] ${this.level.levelName.toUpperCase()}: ${leader}${args[0]} `, + `[${timestamp}] ${this.level.levelName.toUpperCase()}: ${leader}${args[0] as string} `, args .map((arg) => (isObject(arg) ? JSON.stringify(arg) : arg)) .slice(1) diff --git a/src/functions/chalk-dummy.ts b/src/functions/chalk-dummy.ts index 67152a71..37c13e56 100644 --- a/src/functions/chalk-dummy.ts +++ b/src/functions/chalk-dummy.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ export class Chalk { constructor(_: { level: 0 | 1 | 2 | 3 }) {} } diff --git a/src/functions/data.ts b/src/functions/data.ts index 021f5095..529bdb9f 100644 --- a/src/functions/data.ts +++ b/src/functions/data.ts @@ -15,7 +15,7 @@ export function stacktrace(): string | undefined { export function getSearchParams(): URLSearchParams | undefined { const ctxt = globalThis; if (envIsWindow(ctxt)) { - return new URLSearchParams(ctxt?.location.search.substring(1)); + return new URLSearchParams(ctxt.location.search.substring(1)); } } diff --git a/src/functions/filters.ts b/src/functions/filters.ts index d247d89a..753944c3 100644 --- a/src/functions/filters.ts +++ b/src/functions/filters.ts @@ -14,7 +14,8 @@ export function normalizeLevelSelector( if (selector === '*') return Object.values(levels).map((lvl) => lvl.level); // If it's a string, convert it to a number and coerce it to a number array. if (isString(selector)) { - return levels[selector] ? [levels[selector].level] : []; + // it's actually not always truthy eslint... you fool... + return [levels[selector].level]; } // If it's a number, coerce it to a number array. if (isNumber(selector)) return [selector]; diff --git a/src/functions/formatters.ts b/src/functions/formatters.ts index 3e7a3a04..7af8f57d 100644 --- a/src/functions/formatters.ts +++ b/src/functions/formatters.ts @@ -28,7 +28,7 @@ export function formatCount(count?: number): string { * Formats the assertion result for printing. */ export function formatAssert(expression?: boolean, withEmoji?: boolean): string { - return expression !== undefined && expression === false + return expression !== undefined && !expression ? `${withEmoji ? '❌ ' : ''}Assertion failed:` : ''; } @@ -37,7 +37,7 @@ export function formatAssert(expression?: boolean, withEmoji?: boolean): string * Formats the if statement result for printing. */ export function formatIf(expression?: boolean, withEmoji?: boolean): string { - return expression !== undefined && expression === true + return expression !== undefined && expression ? `${withEmoji ? '✅ ' : ''}Expression passed:` : ''; } diff --git a/src/functions/global.ts b/src/functions/global.ts index e52519e5..bdfdfa60 100644 --- a/src/functions/global.ts +++ b/src/functions/global.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-var */ import { UserConfiguration } from '../_types'; import AdzeGlobal from '../adze-global'; @@ -14,7 +15,7 @@ declare global { * Initialize the global log store for Adze. This is used for creating global configuration * overrides, storing labels, and optionally caching logs. */ -export function setup = Record>( +export function setup = Record>( cfg?: UserConfiguration ): AdzeGlobal { const store = globalThis.$adzeGlobal; @@ -82,7 +83,7 @@ export function isTestEnvironment(): boolean { export function isChrome(): boolean { const _glbl = globalThis; if (envIsWindow(_glbl)) { - return _glbl.navigator?.userAgent?.indexOf('Chrome') > -1; + return _glbl.navigator.userAgent.includes('Chrome'); } return false; } @@ -93,7 +94,7 @@ export function isChrome(): boolean { export function isFirefox(): boolean { const _glbl = globalThis; if (envIsWindow(_glbl)) { - return _glbl.navigator?.userAgent?.indexOf('Firefox') > -1; + return _glbl.navigator.userAgent.includes('Firefox'); } return false; } @@ -104,7 +105,7 @@ export function isFirefox(): boolean { export function isSafari(): boolean { const _glbl = globalThis; if (envIsWindow(_glbl)) { - return _glbl.navigator?.userAgent?.indexOf('Safari') > -1 && !isChrome(); + return _glbl.navigator.userAgent.includes('Safari') && !isChrome(); } return false; } diff --git a/src/functions/seal.ts b/src/functions/seal.ts index 96773094..f5878e39 100644 --- a/src/functions/seal.ts +++ b/src/functions/seal.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Modifier, ModifierData } from '..'; import { Configuration } from '../configuration'; import Log from '../log'; @@ -5,7 +6,9 @@ import Log from '../log'; /** * Required type for creating mixins in TypeScript. */ -type Constructor = new (...args: any[]) => {}; +type Constructor = new (...args: any[]) => { + /* noop */ +}; /** * A mixin function for creating a sealed log instance that inherits properties from the parent. diff --git a/src/functions/type-guards.ts b/src/functions/type-guards.ts index 53797727..3055f7e5 100644 --- a/src/functions/type-guards.ts +++ b/src/functions/type-guards.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { LevelSelector, Method, MethodWithArgs, MethodWithoutArgs, SpecialMethod } from '../_types'; import { methodsWithArgs, diff --git a/src/log.ts b/src/log.ts index e2fe1cc9..652acf6f 100644 --- a/src/log.ts +++ b/src/log.ts @@ -24,6 +24,7 @@ import { } from './functions'; import { Middleware } from './middleware'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function isCallback(maybeFunction: unknown): maybeFunction is (...args: any[]) => void { return typeof maybeFunction === 'function'; } @@ -58,7 +59,9 @@ export default class Log { this.globalStore = setup(cfg); this._modifierData = modifierData ?? {}; this._cfg = new Configuration(cfg); - this.doHook((m) => (m.constructed ? m.constructed(this) : null)); + this.doHook((m) => { + if (m.constructed) m.constructed(this); + }); } //////////////////////////////////////////////////////// @@ -114,7 +117,7 @@ export default class Log { * This is a non-standard API. */ public static alert(...args: [M, ...unknown[]]): void { - return new this().alert(...args); + new this().alert(...args); } /** @@ -144,7 +147,7 @@ export default class Log { * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/error) */ public static error(...args: [M, ...unknown[]]): void { - return new this().error(...args); + new this().error(...args); } /** @@ -176,7 +179,7 @@ export default class Log { * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/warn) */ public static warn(...args: [M, ...unknown[]]): void { - return new this().warn(...args); + new this().warn(...args); } /** @@ -208,7 +211,7 @@ export default class Log { * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/info) */ public static info(...args: [M, ...unknown[]]): void { - return new this().info(...args); + new this().info(...args); } /** @@ -238,7 +241,7 @@ export default class Log { * This is a non-standard API. */ public static fail(...args: [M, ...unknown[]]): void { - return new this().fail(...args); + new this().fail(...args); } /** @@ -266,7 +269,7 @@ export default class Log { * This is a non-standard API. */ public static success(...args: [M, ...unknown[]]): void { - return new this().success(...args); + new this().success(...args); } /** @@ -296,7 +299,7 @@ export default class Log { * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) */ public static log(args_0: M, ...args: unknown[]): void { - return new this().log(...[args_0, ...args]); + new this().log(...[args_0, ...args]); } /** @@ -326,7 +329,7 @@ export default class Log { * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) */ public static debug(...args: [M, ...unknown[]]): void { - return new this().debug(...args); + new this().debug(...args); } /** @@ -360,7 +363,7 @@ export default class Log { * This is a non-standard API. */ public static verbose(...args: [M, ...unknown[]]): void { - return new this().verbose(...args); + new this().verbose(...args); } /** @@ -404,6 +407,7 @@ export default class Log { * Adze configuration object under the levels property. */ public custom(levelName: string, ...args: [M, ...unknown[]]): this { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!this._cfg.levels[levelName]) { console.warn(new Error('Custom log level not found in configuration.')); return this; @@ -560,7 +564,7 @@ export default class Log { * ``` */ public static thread(key: string, value: T): void { - return new this().thread(key, value); + new this().thread(key, value); } //////////////////////////////////////////////////////// @@ -698,7 +702,7 @@ export default class Log { * * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/dir) */ - public get dir(): Log> { + public get dir(): Log> { this.modifierQueue.push([ 'dir', (data: ModifierData) => { @@ -706,7 +710,7 @@ export default class Log { return data; }, ]); - return this as Log>; + return this as Log>; } /** @@ -715,7 +719,7 @@ export default class Log { * * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/dir) */ - public static get dir(): Log> { + public static get dir(): Log> { return new this().dir; } @@ -958,7 +962,7 @@ export default class Log { * * This is a non-standard API. */ - public meta = Record>(meta: T): this { + public meta = Record>(meta: T): this { this.modifierQueue.push([ 'meta', (data: ModifierData, ctxt: Log) => { @@ -990,7 +994,7 @@ export default class Log { this.modifierQueue.push([ 'namespace', (data: ModifierData) => { - let arr = data.namespace ?? []; + const arr = data.namespace ?? []; data.namespace = arr.length > 0 ? [...arr, ...namespace] : namespace; return data; }, @@ -1079,7 +1083,7 @@ export default class Log { * * MDN API Docs [here](https://developer.mozilla.org/en-US/docs/Web/API/Console/table) */ - public static get table(): Log { + public static get table(): Log { return new this().table; } @@ -1125,7 +1129,7 @@ export default class Log { this.modifierQueue.push([ 'timeEnd', (data: ModifierData) => { - if (data.label && data.label?.timeStart) { + if (data.label?.timeStart) { data.label.timeElapsed = formatTime(hrtime(data.label.timeStart)); } return data; @@ -1253,11 +1257,9 @@ export default class Log { public print(data: LogData): void { // Skip printing if the Adze environment is set to test. if (isTestEnvironment()) return; - if (data) { + if (data.message.length > 0) { // Don't print if it is configured to be silent. if (data.silent) return; - // Don't print if the message is empty. - if (data.message.length < 1) return; // Only print the message with arguments if it is using a method that allows arguments. if (isMethodWithArgs(data.method)) { console[data.method](...data.message); @@ -1265,7 +1267,7 @@ export default class Log { console[data.method](); } } else { - console.warn(new Error('Adze: Cannot reprint a log that has never been previously printed.')); + console.warn(new Error('Adze: Cannot print a log that has never been previously printed.')); } } @@ -1274,10 +1276,10 @@ export default class Log { //////////////////////////////////////////////////////// private terminate(terminator: string, args: unknown[]): void { - // TODO: For performance reasons, check if the terminator is allowed before doing anything else. - // Run the beforeTerminated middleware hooks - this.doHook((m) => (m.beforeTerminated ? m.beforeTerminated(this, terminator, args) : null)); + this.doHook((m) => { + if (m.beforeTerminated) m.beforeTerminated(this, terminator, args); + }); // Run the modifier queue to modify the data object. this.runModifierQueue(); @@ -1298,9 +1300,9 @@ export default class Log { if (this._cfg.dump && this.modifierData.label?.context) { message.push(this.modifierData.label.context); } - this.doHook((m) => - m.beforeFormatApplied ? m.beforeFormatApplied(this, this._cfg.format, message) : null - ); + this.doHook((m) => { + if (m.beforeFormatApplied) m.beforeFormatApplied(this, this._cfg.format, message); + }); const { activeLevel, cache, cacheSize, dump, format, meta, showTimestamp, silent, withEmoji } = this._cfg; const data: LogData = { @@ -1320,9 +1322,9 @@ export default class Log { timestamp, message, }; - this.doHook((m) => - m.afterFormatApplied ? m.afterFormatApplied(this, this._cfg.format, message) : null - ); + this.doHook((m) => { + if (m.afterFormatApplied) m.afterFormatApplied(this, this._cfg.format, message); + }); // save the data to this instance this._data = data; @@ -1330,22 +1332,28 @@ export default class Log { this.globalStore.addLogToCache(this); } - this.doHook((m) => (m.beforePrint ? m.beforePrint(this) : null)); + this.doHook((m) => { + if (m.beforePrint) m.beforePrint(this); + }); // Print the log to the console. this.print(this._data); - this.doHook((m) => (m.afterTerminated ? m.afterTerminated(this, terminator, args) : null)); + this.doHook((m) => { + if (m.afterTerminated) m.afterTerminated(this, terminator, args); + }); // Fire all of the log listeners and pass this log instance to them. - this.globalStore.getListeners(level.level).forEach((listener: LogListener) => listener(this)); + this.globalStore.getListeners(level.level).forEach((listener: LogListener) => { + listener(this); + }); } /** * Returns a formatter constructor based on the provided format. */ private selectFormatter(format: string): FormatterConstructor { - return this._cfg?.formatters[format]; + return this._cfg.formatters[format]; } /** @@ -1361,13 +1369,13 @@ export default class Log { private runModifierQueue(): void { this.modifierQueue.forEach(([modName, modFunc]) => { const result = modFunc(this.modifierData, this); - this.doHook((m) => - m.beforeModifierApplied ? m.beforeModifierApplied(this, modName, result) : null - ); + this.doHook((m) => { + if (m.beforeModifierApplied) m.beforeModifierApplied(this, modName, result); + }); this._modifierData = result; - this.doHook((m) => - m.afterModifierApplied ? m.afterModifierApplied(this, modName, result) : null - ); + this.doHook((m) => { + if (m.afterModifierApplied) m.afterModifierApplied(this, modName, result); + }); }); } @@ -1375,6 +1383,8 @@ export default class Log { * Execute a middleware hook. */ private doHook(cb: (middleware: Middleware) => void): void { - this._cfg.middleware?.forEach((middleware: Middleware) => cb(middleware)); + this._cfg.middleware?.forEach((middleware: Middleware) => { + cb(middleware); + }); } } diff --git a/src/middleware.ts b/src/middleware.ts index 284ae8be..ff9f9f04 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -4,6 +4,7 @@ import Log from './log'; export type TargetEnvironment = 'server' | 'browser' | 'both'; +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging export interface Middleware { /** * Hook that is called during construction of a log instance. @@ -42,6 +43,7 @@ export interface Middleware { /** * Middleware abstract class that can be extended to create custom middleware. */ +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging export abstract class Middleware { /** * The target environment for this middleware. @@ -84,9 +86,13 @@ export abstract class Middleware { /** * Load dependencies for the server environment. */ - protected async loadServerDependencies() {} + protected async loadServerDependencies() { + /* noop */ + } /** * Load dependencies for the browser environment. */ - protected async loadBrowserDependencies() {} + protected async loadBrowserDependencies() { + /* noop */ + } } diff --git a/src/tools.ts b/src/tools.ts index d49a41c3..3c721ec7 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -24,7 +24,9 @@ export default class Tools { */ public filterByLabel(label: string): void { const logs = filterByLabel(label, this.globalStore.cache); - logs.forEach((log) => render(log)); + logs.forEach((log) => { + render(log); + }); } /** @@ -32,7 +34,9 @@ export default class Tools { */ public filterByNamespace(...namespace: string[]): void { const logs = filterByNamespace(namespace, this.globalStore.cache); - logs.forEach((log) => render(log)); + logs.forEach((log) => { + render(log); + }); } /** @@ -40,13 +44,17 @@ export default class Tools { */ public filterByLevel(level: LevelSelector): void { const logs = filterByLevel(level, this.globalStore.cache); - logs.forEach((log) => render(log)); + logs.forEach((log) => { + render(log); + }); } /** * Rerenders all logs that have been cached. */ public renderAll(): void { - this.globalStore.cache.forEach((log) => render(log)); + this.globalStore.cache.forEach((log) => { + render(log); + }); } } diff --git a/test/formatters/common/log.terminators.ts b/test/formatters/common/log.terminators.ts index 72414e2a..eee2dfdd 100644 --- a/test/formatters/common/log.terminators.ts +++ b/test/formatters/common/log.terminators.ts @@ -1,5 +1,5 @@ -import { afterEach, describe, expect, test, vi } from 'vitest'; -import adze, { CommonLogFormatMeta, LevelConfig, setup, teardown } from '../../../src'; +import { expect, vi } from 'vitest'; +import adze, { CommonLogFormatMeta, LevelConfiguration, setup } from '../../../src'; import { isMatch } from 'date-fns'; export const printCommonAlert = () => { @@ -147,7 +147,7 @@ export const printCommonVerbose = () => { export const printCommonCustom = () => { console.log = vi.fn(); - const leetLevel: LevelConfig = { + const leetLevel: LevelConfiguration = { levelName: 'leetLevel', level: 1337, method: 'log', @@ -206,7 +206,10 @@ export const commonTimestamp = () => { }) .alert('This is an alert log.'); expect(console.error).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const message = fn.mock.calls[0][0]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access const timestamp = message.split('[')[1].split(']')[0]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument expect(isMatch(timestamp, 'dd/MMM/yyyy:HH:mm:ss xx')).toBe(true); }; diff --git a/test/formatters/formatting.test.ts b/test/formatters/formatting.test.ts index 6141e37b..4e61f224 100644 --- a/test/formatters/formatting.test.ts +++ b/test/formatters/formatting.test.ts @@ -1,6 +1,5 @@ -import { JSDOM } from 'jsdom'; import { afterEach, describe, expect, test, vi } from 'vitest'; -import adze, { setup, TableData, teardown } from '../../src'; +import adze, { teardown } from '../../src'; import { applyChalkStyles } from '../../src/functions'; import { getLogConfig } from '../../src/constants'; diff --git a/test/formatters/json/log.terminators.ts b/test/formatters/json/log.terminators.ts index 92551775..6c53330d 100644 --- a/test/formatters/json/log.terminators.ts +++ b/test/formatters/json/log.terminators.ts @@ -8,7 +8,7 @@ import adze, { } from '../../../src'; import { isMatch } from 'date-fns'; -export const printJsonAlert = async () => { +export const printJsonAlert = () => { const fn = vi.fn(); console.error = fn; setup({ format: 'json', timestampFormatter: () => '2024-07-31T13:19:25-04:00' }); @@ -21,7 +21,8 @@ export const printJsonAlert = async () => { .alert('This is an alert log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); - const log = JSON.parse(fn.mock.calls[0][0]); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument + const log: string = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, level: 0, @@ -48,6 +49,7 @@ export const printJsonError = () => { .error('This is an error log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -75,6 +77,7 @@ export const printJsonWarn = () => { .warn('This is a warn log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -102,6 +105,7 @@ export const printJsonInfo = () => { .info('This is an info log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -129,6 +133,7 @@ export const printJsonFail = () => { .fail('This is a fail log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -156,6 +161,7 @@ export const printJsonSuccess = () => { .success('This is a success log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -183,6 +189,7 @@ export const printJsonLog = () => { .log('This is a log log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -214,6 +221,7 @@ export const printJsonDebug = () => { .debug('This is a debug log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -245,6 +253,7 @@ export const printJsonVerbose = () => { .verbose('This is a verbose log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -286,6 +295,7 @@ export const printJsonCustom = () => { .custom('leetLevel', 'This is a custom log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -316,6 +326,7 @@ export const noEmoji = () => { .log('This is a log log.', 'foo'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, @@ -346,7 +357,9 @@ export const defaultTimestamp = () => { .log('This is a log log.', 'foo'); expect(console.log).toHaveBeenCalledTimes(1); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access expect(isMatch(log.time, "yyyy-MM-dd'T'HH:mm:ssxxx")).toBe(true); }; @@ -373,6 +386,7 @@ export const incrementingPids = () => { expect(fn).toHaveBeenCalledTimes(2); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log1 = JSON.parse(fn.mock.calls[0][0]); expect(log1).toEqual({ v: 1, @@ -386,6 +400,7 @@ export const incrementingPids = () => { time: '2024-07-31T13:19:25-04:00', }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log2 = JSON.parse(fn.mock.calls[1][0]); expect(log2).toEqual({ v: 1, @@ -436,13 +451,14 @@ export const printsOptionalFields = async () => { hello: 'world', }, req: await serializeRequest(request), - res: await serializeResponse(response), + res: serializeResponse(response), req_id: '12345', src: 'test.ts', }) .alert('This is an alert log.'); expect(fn).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument const log = JSON.parse(fn.mock.calls[0][0]); expect(log).toEqual({ v: 1, diff --git a/test/formatters/pretty/modifiers.browser.test.ts b/test/formatters/pretty/modifiers.browser.test.ts index c052a400..ec682902 100644 --- a/test/formatters/pretty/modifiers.browser.test.ts +++ b/test/formatters/pretty/modifiers.browser.test.ts @@ -201,6 +201,7 @@ describe('modifiers with pretty format in the browser', () => { test('the if modifier prints the log if it passes the condition', () => { console.log = vi.fn(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.if(2 === 2).log('Test log.'); expect(console.log).toHaveBeenCalledWith( '%c Log', @@ -212,6 +213,7 @@ describe('modifiers with pretty format in the browser', () => { test('the if modifier prints the log with an emoji if it passes the condition', () => { console.log = vi.fn(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.if(2 === 2).log('Test log.'); expect(console.log).toHaveBeenCalledWith( '%c🪵 %c Log', @@ -224,7 +226,8 @@ describe('modifiers with pretty format in the browser', () => { test('the assert modifier prints the log if it failes the condition', () => { console.log = vi.fn(); - // @ts-ignore + // @ts-expect-error Testing assertion failure + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.assert(2 === 3).log('Test log.'); expect(console.log).toHaveBeenCalledWith( '%c Log', @@ -236,7 +239,8 @@ describe('modifiers with pretty format in the browser', () => { test('the assert modifier prints the log with an emoji if it failes the condition', () => { console.log = vi.fn(); - // @ts-ignore + // @ts-expect-error Testing assertion failure + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.assert(2 === 3).log('Test log.'); expect(console.log).toHaveBeenCalledWith( '%c🪵 %c Log', @@ -252,7 +256,6 @@ describe('modifiers with pretty format in the browser', () => { setup({ timestampFormatter: () => '2024-08-03T16:37:11-04:00', }); - // @ts-ignore adze.timestamp.log('Test log.'); expect(console.log).toHaveBeenCalledWith( '%c Log', diff --git a/test/formatters/pretty/modifiers.server.test.ts b/test/formatters/pretty/modifiers.server.test.ts index ac9a2375..1c1c24de 100644 --- a/test/formatters/pretty/modifiers.server.test.ts +++ b/test/formatters/pretty/modifiers.server.test.ts @@ -196,6 +196,7 @@ describe('modifiers with pretty format in node', () => { test('the if modifier prints the log if it passes the condition', () => { console.log = vi.fn(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.if(2 === 2).log('Test log.'); expect(console.log).toHaveBeenCalledWith( applyChalkStyles(' Log ', getLogConfig().terminalStyle), @@ -206,6 +207,7 @@ describe('modifiers with pretty format in node', () => { test('the if modifier prints the log with an emoji if it passes the condition', () => { console.log = vi.fn(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.if(2 === 2).log('Test log.'); expect(console.log).toHaveBeenCalledWith( applyChalkStyles('🪵 Log ', getLogConfig().terminalStyle), @@ -216,7 +218,8 @@ describe('modifiers with pretty format in node', () => { test('the assert modifier prints the log if it failes the condition', () => { console.log = vi.fn(); - // @ts-ignore + // @ts-expect-error Testing assertion failure + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.assert(2 === 3).log('Test log.'); expect(console.log).toHaveBeenCalledWith( applyChalkStyles(' Log ', getLogConfig().terminalStyle), @@ -227,7 +230,8 @@ describe('modifiers with pretty format in node', () => { test('the assert modifier prints the log with an emoji if it failes the condition', () => { console.log = vi.fn(); - // @ts-ignore + // @ts-expect-error Testing assertion failure + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition adze.withEmoji.assert(2 === 3).log('Test log.'); expect(console.log).toHaveBeenCalledWith( applyChalkStyles('🪵 Log ', getLogConfig().terminalStyle), @@ -241,7 +245,6 @@ describe('modifiers with pretty format in node', () => { setup({ timestampFormatter: () => '2024-08-03T16:37:11-04:00', }); - // @ts-ignore adze.timestamp.log('Test log.'); expect(console.log).toHaveBeenCalledWith( applyChalkStyles(' Log ', getLogConfig().terminalStyle), diff --git a/test/formatters/pretty/terminators.browser.test.ts b/test/formatters/pretty/terminators.browser.test.ts index 5c2abac4..215db506 100644 --- a/test/formatters/pretty/terminators.browser.test.ts +++ b/test/formatters/pretty/terminators.browser.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, test, vi } from 'vitest'; -import adze, { LevelConfig, setup, teardown } from '../../../src'; +import adze, { LevelConfiguration, setup, teardown } from '../../../src'; /** * @vitest-environment jsdom @@ -105,7 +105,7 @@ describe('terminators with pretty format in the browser', () => { test('prints a custom log', () => { console.log = vi.fn(); - const leetLevel: LevelConfig = { + const leetLevel: LevelConfiguration = { levelName: 'leetLevel', level: 1337, method: 'log', @@ -233,7 +233,7 @@ describe('terminators with emoji', () => { test('prints an emoji custom log', () => { console.log = vi.fn(); - const leetLevel: LevelConfig = { + const leetLevel: LevelConfiguration = { levelName: 'leetLevel', level: 1337, method: 'log', diff --git a/test/formatters/standard/log.terminators.ts b/test/formatters/standard/log.terminators.ts index a2f7a237..bb01f088 100644 --- a/test/formatters/standard/log.terminators.ts +++ b/test/formatters/standard/log.terminators.ts @@ -1,8 +1,8 @@ import { expect, vi } from 'vitest'; -import adze, { StandardLogFormatMeta, LevelConfig, setup } from '../../../src'; +import adze, { StandardLogFormatMeta, LevelConfiguration, setup } from '../../../src'; import { isMatch } from 'date-fns'; -export const printStandardAlert = async () => { +export const printStandardAlert = () => { const fn = vi.fn(); console.error = fn; setup({ format: 'standard', timestampFormatter: () => '2013-01-04T19:01:18.241Z' }); @@ -255,7 +255,7 @@ export const printStandardCustom = () => { const fn = vi.fn(); console.log = fn; - const leetLevel: LevelConfig = { + const leetLevel: LevelConfiguration = { levelName: 'leetLevel', level: 1337, method: 'log', @@ -322,7 +322,9 @@ export const defaultTimestamp = () => { }) .log('This is a log log.', 'foo'); expect(console.log).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const message = fn.mock.calls[0][0]; - const timestamp = message.split('[')[1].split(']')[0]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const timestamp: string = message.split('[')[1].split(']')[0]; expect(isMatch(timestamp, "yyyy-MM-dd'T'HH:mm:ssxxx")).toBe(true); }; diff --git a/test/middleware.browser.test.ts b/test/middleware.browser.test.ts index acc70d64..b4cdcb2a 100644 --- a/test/middleware.browser.test.ts +++ b/test/middleware.browser.test.ts @@ -18,9 +18,11 @@ describe('middleware', () => { class TestMiddleware extends Middleware { protected async loadBrowserDependencies(): Promise { funcBrowser(); + await Promise.resolve(); } protected async loadServerDependencies(): Promise { funcServer(); + await Promise.resolve(); } } setup({ @@ -45,9 +47,11 @@ describe('middleware', () => { protected async loadBrowserDependencies(): Promise { funcBrowser(); + await Promise.resolve(); } protected async loadServerDependencies(): Promise { funcServer(); + await Promise.resolve(); } } const testMiddleware = new TestMiddleware(); diff --git a/test/middleware.server.test.ts b/test/middleware.server.test.ts index 5cea8e24..7ab39e42 100644 --- a/test/middleware.server.test.ts +++ b/test/middleware.server.test.ts @@ -18,9 +18,11 @@ describe('middleware', () => { class TestMiddleware extends Middleware { protected async loadBrowserDependencies(): Promise { funcBrowser(); + await Promise.resolve(); } protected async loadServerDependencies(): Promise { funcNode(); + await Promise.resolve(); } } setup({ @@ -45,9 +47,11 @@ describe('middleware', () => { protected async loadBrowserDependencies(): Promise { funcBrowser(); + await Promise.resolve(); } protected async loadServerDependencies(): Promise { funcNode(); + await Promise.resolve(); } } const testMiddleware = new TestMiddleware(); diff --git a/tsconfig.prod.json b/tsconfig.prod.json index 90071bef..cdc8e9d3 100644 --- a/tsconfig.prod.json +++ b/tsconfig.prod.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", - "include": ["./src/**/*"], + "include": ["./src/**/*", "vitest.config.ts", "eslint.config.js", "./test/**/*"], "exclude": ["./src/demo_funcs"] } diff --git a/vitest.config.ts b/vitest.config.ts index f7f10cde..2e22f149 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ environment: 'jsdom', include: ['test/**/*.{test,spec}.{js,ts}'], fakeTimers: { - toFake: [...(configDefaults.fakeTimers.toFake ?? []), 'performance'], + toFake: [...configDefaults.fakeTimers.toFake, 'performance'], }, restoreMocks: true, },