diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25d3996..6b9a366 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,4 @@ -# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://github.com/marketplace/actions/setup-node-js-environment +# @see: https://github.com/marketplace/actions/setup-node-js-environment name: CI @@ -17,14 +16,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x, 20.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node: [ 20 ] + name: Node ${{ matrix.node }} steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - # cache: 'npm' - - run: npm install --ignore-scripts - - run: npm run all + - uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + - run: npm version + - run: npm install --ignore-scripts + - run: npm run all diff --git a/.gitignore b/.gitignore index 6b86644..6f27b55 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ tmp/ package-lock.json yarn.lock pnpm-lock.yaml + +.env* \ No newline at end of file diff --git a/README.md b/README.md index 9ffbb67..f7ee31b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ > debug with levels [![NPM version](https://badge.fury.io/js/debug-level.svg)](https://www.npmjs.com/package/debug-level/) -[![Build Status](https://github.com/commenthol/debug-level/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/commenthol/debug-level/actions/workflows/ci.yml?query=branch%3Amain) +[![CI](https://github.com/commenthol/debug-level/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/commenthol/debug-level/actions/workflows/ci.yml) A universal JavaScript logging/ debugging utility which works in node and browsers. diff --git a/package.json b/package.json index 100be40..5b066c2 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "example": "npm run build:example && npm run start:example", "changelog": "conv-changelog -i CHANGELOG.md -o", "lint": "eslint --ext .js .", - "prepublishOnly": "npm run all", "readme": "markedpp --github -i README.md -o README.md", "start:example": "DEBUG=* node examples/app/server.cjs", "test": "mocha", @@ -79,15 +78,15 @@ "flatstr": "^1.0.12", "map-lru": "^2.0.0", "ms": "^2.1.3", - "sonic-boom": "^3.8.0" + "sonic-boom": "^4.0.1" }, "devDependencies": { - "@babel/cli": "^7.23.9", - "@babel/core": "^7.24.0", - "@babel/preset-env": "^7.24.0", + "@babel/cli": "^7.24.8", + "@babel/core": "^7.24.9", + "@babel/preset-env": "^7.24.8", "assert": "^2.1.0", "babel-loader": "^9.1.3", - "c8": "^9.1.0", + "c8": "^10.1.2", "conv-changelog": "^1.0.0", "eslint": "^8.57.0", "eslint-config-standard": "^17.1.0", @@ -102,13 +101,13 @@ "karma-sourcemap-loader": "^0.4.0", "karma-spec-reporter": "^0.0.36", "karma-webpack": "^5.0.1", - "mocha": "^10.3.0", - "npm-run-all2": "^6.1.2", - "rimraf": "^5.0.5", - "rollup": "^4.13.0", - "sinon": "^17.0.1", - "typescript": "^5.4.2", - "webpack": "^5.90.3", + "mocha": "^10.7.0", + "npm-run-all2": "^6.2.2", + "rimraf": "^6.0.1", + "rollup": "^4.19.0", + "sinon": "^18.0.0", + "typescript": "^5.5.3", + "webpack": "^5.93.0", "webpack-cli": "^5.1.4" }, "optionalDependencies": { diff --git a/src/Format.js b/src/Format.js index 6f97abf..e27343f 100644 --- a/src/Format.js +++ b/src/Format.js @@ -26,13 +26,22 @@ export class Format { } _formatOpts () { + /** + * @param {any} any + * @returns {string} + */ + // @ts-expect-error + const stringify = (any) => fastStringify(any, null, this.opts.spaces) this.formatOpts = { - // @ts-expect-error - stringify: (o) => fastStringify(o, null, this.opts.spaces), + stringify, spaces: this.opts.spaces } } + /** + * @param {...any} args + * @returns {string} + */ stringify (...args) { // @ts-expect-error return fastStringify(...args) diff --git a/src/LogBase.js b/src/LogBase.js index 1f64caf..be71aab 100644 --- a/src/LogBase.js +++ b/src/LogBase.js @@ -13,7 +13,7 @@ const time = { } /** - * @typedef {import('./utils').Level} Level + * @typedef {import('./utils.js').Level} Level * * @typedef {object} ExtLogBaseOptions * @property {Level} [level] log level diff --git a/src/Sonic.js b/src/Sonic.js index 8233153..d89063c 100644 --- a/src/Sonic.js +++ b/src/Sonic.js @@ -30,6 +30,8 @@ export class Sonic { const { fd, path } = streamDescriptor(stream) + /** @type {import('sonic-boom').SonicBoom} */ + // @ts-expect-error this.stream = new SonicBoom({ fd, dest: path, minLength, sync: true }) this.stream.on('error', filterBrokenPipe.bind(null, this.stream)) @@ -90,10 +92,13 @@ export class SonicStreams extends Map { * @returns {string} */ static hash (opts) { - return 'sonic!' + Object.keys(opts || {}) - .sort() - .map((key) => `${key}:${opts[key]}`) - .join('!') + return ( + 'sonic!' + + Object.keys(opts || {}) + .sort() + .map((key) => `${key}:${opts[key]}`) + .join('!') + ) } /** diff --git a/src/browser.js b/src/browser.js index 0c9eaef..0674095 100644 --- a/src/browser.js +++ b/src/browser.js @@ -16,8 +16,8 @@ import { wrapConsole } from './wrapConsole.js' import { errSerializer } from './serializers/err.js' /** - * @typedef {import('./utils').Level} Level - * @typedef {import('./LogBase').LogBaseOptions} LogBaseOptions + * @typedef {import('./utils.js').Level} Level + * @typedef {import('./LogBase.js').LogBaseOptions} LogBaseOptions * * @typedef {object} ExtLogOptionsBrowser * @property {string} [url] url to report errors diff --git a/src/httpLogs.js b/src/httpLogs.js index d44bffc..260f7ec 100644 --- a/src/httpLogs.js +++ b/src/httpLogs.js @@ -40,7 +40,6 @@ export function httpLogs (namespace, opts) { } options.serializers = { ...serializers, - // @ts-expect-error ...(options.Log.serializers || {}), ...(options.serializers || {}) } diff --git a/src/index.js b/src/index.js index 2d48bae..4f18a6c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -/** @typedef {import('./utils').Level} Level */ +/** @typedef {import('./utils.js').Level} Level */ /** @typedef {import('./node.js').LogOptions & {Log: typeof Log}} LogOptions */ /** @typedef {import('./node.js').LogOptionWrapConsole} LogOptionWrapConsole */ /** @typedef {import('./node.js').LogOptionHandleExitEvents} LogOptionHandleExitEvents */ diff --git a/src/node.js b/src/node.js index c7caa74..3f0aeb1 100644 --- a/src/node.js +++ b/src/node.js @@ -17,7 +17,7 @@ import { LogBase } from './LogBase.js' import { wrapConsole } from './wrapConsole.js' import { wrapDebug } from './wrapDebug.js' import { Sonic, sonicStreams } from './Sonic.js' -import { errSerializer } from './serializers/err.js' +import { errSerializer } from './serializers/index.js' import { Format } from './Format.js' const env = process.env.NODE_ENV || 'development' @@ -25,8 +25,8 @@ const isDevEnv = /^dev/.test(env) // anything which starts with dev is seen as d const EXIT_EVENTS = ['unhandledRejection', 'uncaughtException'] -/** @typedef {import('./LogBase').LogBaseOptions} LogBaseOptions */ -/** @typedef {import('./utils').Level} Level */ +/** @typedef {import('./LogBase.js').LogBaseOptions} LogBaseOptions */ +/** @typedef {import('./utils.js').Level} Level */ /** * @typedef {object} ExtLogOptions * @property {boolean} [serverinfo] log serverinfo like hostname and pid @@ -304,6 +304,9 @@ export class Log extends LogBase { Log.isDevEnv = isDevEnv Log.Sonic = Sonic +Log.serializers = { + err: errSerializer +} /** * @credits pino/lib/tools.js diff --git a/tsconfig.json b/tsconfig.json index dd18dc3..319eefc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,21 @@ { "compilerOptions": { - "allowSyntheticDefaultImports": true, "allowJs": true, + "allowSyntheticDefaultImports": true, "checkJs": true, "declaration": true, "declarationDir": "types", - "moduleResolution": "node", + "emitDeclarationOnly": true, + "module": "nodenext", + "moduleResolution": "nodenext", + "noEmitOnError": false, "noImplicitAny": false, + "skipLibCheck": true, "strict": true, - "module": "esnext", "target": "esnext", - "emitDeclarationOnly": true, - "noEmitOnError": true }, "include": [ - "src/*.js", - "src/serializers/*.js", - "src/ecs/*.js", + "src", ], "exclude": [ "node_modules", diff --git a/types/Format.d.ts b/types/Format.d.ts index 03d5018..06b77a1 100644 --- a/types/Format.d.ts +++ b/types/Format.d.ts @@ -14,9 +14,13 @@ export class Format { get spaces(): number | undefined; _formatOpts(): void; formatOpts: { - stringify: (o: any) => string; + stringify: (any: any) => string; spaces: number | undefined; } | undefined; + /** + * @param {...any} args + * @returns {string} + */ stringify(...args: any[]): string; /** * formats arguments like `util.format` diff --git a/types/LogBase.d.ts b/types/LogBase.d.ts index cc54131..bfa9ad4 100644 --- a/types/LogBase.d.ts +++ b/types/LogBase.d.ts @@ -1,5 +1,5 @@ /** - * @typedef {import('./utils').Level} Level + * @typedef {import('./utils.js').Level} Level * * @typedef {object} ExtLogBaseOptions * @property {Level} [level] log level @@ -67,8 +67,8 @@ export class LogBase { */ protected _log(nlevel: any, fmt: any, args: any): void; } -export type Timestamp = 'epoch' | 'unix' | 'iso'; -export type Level = import('./utils').Level; +export type Timestamp = "epoch" | "unix" | "iso"; +export type Level = import("./utils.js").Level; export type ExtLogBaseOptions = { /** * log level @@ -107,6 +107,6 @@ export type ExtLogBaseOptions = { */ serializers?: object; }; -export type FormatOption = import('./Format.js').FormatOption; +export type FormatOption = import("./Format.js").FormatOption; export type LogBaseOptions = FormatOption & ExtLogBaseOptions; import { Format } from './Format.js'; diff --git a/types/Sonic.d.ts b/types/Sonic.d.ts index 92f4edd..6316769 100644 --- a/types/Sonic.d.ts +++ b/types/Sonic.d.ts @@ -6,7 +6,8 @@ export class Sonic { constructor(stream: NodeJS.WriteStream, opts?: SonicOptions); _timer: any; _timeout: number; - stream: SonicBoom; + /** @type {import('sonic-boom').SonicBoom} */ + stream: import("sonic-boom").SonicBoom; /** * @param {string} data * @returns {boolean} @@ -46,4 +47,3 @@ export type SonicOptions = { */ timeout?: number | undefined; }; -import SonicBoom from 'sonic-boom'; diff --git a/types/browser.d.ts b/types/browser.d.ts index 728d8b1..22caf61 100644 --- a/types/browser.d.ts +++ b/types/browser.d.ts @@ -45,7 +45,7 @@ export class Log extends LogBase { /** * log level */ - level: import("./utils.js").Level; + level: import("./LogBase.js").Level; /** * namespaces for logging */ @@ -73,7 +73,7 @@ export class Log extends LogBase { /** * serializers to be applied on object properties */ - serializers: any; + serializers: object; /** * url to report errors */ @@ -127,8 +127,8 @@ export namespace Log { } } export default Log; -export type Level = import('./utils').Level; -export type LogBaseOptions = import('./LogBase').LogBaseOptions; +export type Level = import("./utils.js").Level; +export type LogBaseOptions = import("./LogBase.js").LogBaseOptions; export type ExtLogOptionsBrowser = { /** * url to report errors diff --git a/types/ecs/LogEcs.d.ts b/types/ecs/LogEcs.d.ts index 55941b7..d5e7f7e 100644 --- a/types/ecs/LogEcs.d.ts +++ b/types/ecs/LogEcs.d.ts @@ -24,7 +24,7 @@ export namespace LogEcs { export { ecsSerializers as serializers }; } export type EcsSerializer = (val: any, escFields: object) => void; -export type LogOptionsEcs = import('../node.js').LogOptions & { +export type LogOptionsEcs = import("../node.js").LogOptions & { serializers: Record; }; import { Log } from '../node.js'; diff --git a/types/httpLogs.d.ts b/types/httpLogs.d.ts index 8fc8438..6a3f68a 100644 --- a/types/httpLogs.d.ts +++ b/types/httpLogs.d.ts @@ -19,9 +19,9 @@ * @returns {(req: IncomingMessageWithId, res: ServerResponse, next: Function) => void} connect middleware */ export function httpLogs(namespace?: string | undefined, opts?: LogOptionsHttpLog | undefined): (req: IncomingMessageWithId, res: ServerResponse, next: Function) => void; -export type IncomingMessage = import('node:http').IncomingMessage; -export type ServerResponse = import('node:http').ServerResponse; -export type LogOptions = import('./node.js').LogOptions; +export type IncomingMessage = import("node:http").IncomingMessage; +export type ServerResponse = import("node:http").ServerResponse; +export type LogOptions = import("./node.js").LogOptions; export type ExtIncomingMessageId = { /** * request Id diff --git a/types/index.d.ts b/types/index.d.ts index f8cc0a8..2c6260d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,14 +1,14 @@ export default Log; -export type Level = import('./utils').Level; -export type LogOptions = import('./node.js').LogOptions & { +export type Level = import("./utils.js").Level; +export type LogOptions = import("./node.js").LogOptions & { Log: typeof Log; }; -export type LogOptionWrapConsole = import('./node.js').LogOptionWrapConsole; -export type LogOptionHandleExitEvents = import('./node.js').LogOptionHandleExitEvents; -export type LogOptionsEcs = import('./ecs/LogEcs.js').LogOptionsEcs; -export type MwLogOption = import('./browserLogs.js').MwLogOption; -export type LogOptionsHttpLog = import('./httpLogs.js').LogOptionsHttpLog; -export type IncomingMessageWithId = import('./httpLogs.js').IncomingMessageWithId; +export type LogOptionWrapConsole = import("./node.js").LogOptionWrapConsole; +export type LogOptionHandleExitEvents = import("./node.js").LogOptionHandleExitEvents; +export type LogOptionsEcs = import("./ecs/LogEcs.js").LogOptionsEcs; +export type MwLogOption = import("./browserLogs.js").MwLogOption; +export type LogOptionsHttpLog = import("./httpLogs.js").LogOptionsHttpLog; +export type IncomingMessageWithId = import("./httpLogs.js").IncomingMessageWithId; import { Log } from './node.js'; import { LogEcs } from './ecs/LogEcs.js'; import { logger } from './logger.js'; diff --git a/types/logger.d.ts b/types/logger.d.ts index 47bb329..8b5c9c1 100644 --- a/types/logger.d.ts +++ b/types/logger.d.ts @@ -6,4 +6,4 @@ * @param {LogOptions} [opts] */ export function logger(namespace: string, opts?: import("./index.js").LogOptions | undefined): any; -export type LogOptions = import('./index.js').LogOptions; +export type LogOptions = import("./index.js").LogOptions; diff --git a/types/node.d.ts b/types/node.d.ts index 0b906ef..cac72e6 100644 --- a/types/node.d.ts +++ b/types/node.d.ts @@ -79,7 +79,7 @@ export class Log extends LogBase { /** * serializers to be applied on object properties */ - serializers: any; + serializers: object; /** * log serverinfo like hostname and pid */ @@ -136,9 +136,12 @@ export class Log extends LogBase { export namespace Log { export { isDevEnv }; export { Sonic }; + export namespace serializers { + export { errSerializer as err }; + } } -export type LogBaseOptions = import('./LogBase').LogBaseOptions; -export type Level = import('./utils').Level; +export type LogBaseOptions = import("./LogBase.js").LogBaseOptions; +export type Level = import("./utils.js").Level; export type ExtLogOptions = { /** * log serverinfo like hostname and pid @@ -178,4 +181,5 @@ import { LogBase } from './LogBase.js'; declare function toJson(obj: object, serializers: object, spaces?: number | undefined): string; import { Sonic } from './Sonic.js'; declare const isDevEnv: boolean; +import { errSerializer } from './serializers/index.js'; export {}; diff --git a/types/utils.d.ts b/types/utils.d.ts index 88baa44..d6fb816 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -71,4 +71,4 @@ export function inspectNamespaces(obj: any): { namespaces: any; } | undefined; export function random(len: any): string; -export type Level = 'LOG' | 'FATAL' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE' | 'OFF'; +export type Level = "LOG" | "FATAL" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "TRACE" | "OFF";