From 1cf8a0fae908b2015b73e855cb9242607aa46502 Mon Sep 17 00:00:00 2001 From: IanKulin Date: Sun, 28 Sep 2025 10:10:32 +0800 Subject: [PATCH] +node and bun compat --- README.md | 3 +++ lib/logger.ts | 73 +++++++++++++++++++++++++++++++++++++++++++++++---- package.json | 47 +++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 package.json diff --git a/README.md b/README.md index fe43177..ecfd7a3 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ $ deno run --allow-env --allow-sys your-script.js ## Quick Start ```typescript +// Deno import Logger from "@iankulin/logger"; const logger = new Logger(); @@ -36,6 +37,7 @@ logger.error("Something went wrong"); ```typescript +// Deno import Logger from "jsr:@iankulin/logger"; // Create a new logger instance @@ -157,6 +159,7 @@ devLogger.info("Development info message"); - **1.0.1** - Minor updates - Deno flavoured demo in readme - Add JSDoc to boost JSR score +- **1.1.0** - Add Node and Bun support ## AI Disclosure diff --git a/lib/logger.ts b/lib/logger.ts index 0fc7f8b..be97fbc 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -1,10 +1,12 @@ /** - * @fileoverview A comprehensive Deno-based logging library with configurable levels, formatting, and caller detection. + * @fileoverview A comprehensive cross-platform logging library with configurable levels, formatting, and caller detection. * * This module provides a Logger class that supports multiple log levels, JSON and simple text formatting, * automatic TTY detection for colored output, and optional caller information inclusion. It includes * built-in util.format-style string formatting with %s, %d, %j, and other specifiers. * + * Compatible with Deno, Node.js, and Bun runtimes. + * * @module logger * @example * ```ts @@ -135,6 +137,67 @@ function format(f: unknown, ...args: unknown[]): string { return str; } +// Cross-platform process interface +interface NodeProcess { + pid: number; + versions?: { + node?: string; + bun?: string; + }; + stdout?: { + isTTY?: boolean; + }; +} + +// Cross-platform global interface +interface CrossPlatformGlobal { + process?: NodeProcess; + require?: (module: string) => unknown; +} + +// Runtime detection and cross-platform utilities +const runtime = { + isDeno: typeof Deno !== 'undefined', + isNode: typeof (globalThis as CrossPlatformGlobal).process !== 'undefined' && + Boolean((globalThis as CrossPlatformGlobal).process?.versions?.node), + isBun: typeof (globalThis as CrossPlatformGlobal).process !== 'undefined' && + Boolean((globalThis as CrossPlatformGlobal).process?.versions?.bun), +}; + +// Cross-platform API wrappers +function getPid(): number { + if (runtime.isDeno) { + return Deno.pid; + } + return (globalThis as CrossPlatformGlobal).process?.pid || 0; +} + +function getHostname(): string { + if (runtime.isDeno) { + return Deno.hostname(); + } + // For Node.js/Bun, we need to import os module + if (runtime.isNode || runtime.isBun) { + try { + // Try accessing require if available + const requireFn = (globalThis as CrossPlatformGlobal)?.require || eval('require'); + const os = requireFn?.('os') as { hostname?: () => string }; + return os?.hostname?.() || 'localhost'; + } catch { + // Fallback if require is not available + return 'localhost'; + } + } + return 'localhost'; +} + +function isTerminal(): boolean { + if (runtime.isDeno) { + return Deno.stdout.isTerminal(); + } + return (globalThis as CrossPlatformGlobal).process?.stdout?.isTTY || false; +} + /** * Available log levels in order of priority. * @@ -200,7 +263,7 @@ export interface LogEntry { levelNumber: number; /** Formatted timestamp string */ time: string; - /** Process ID of the current Deno process */ + /** Process ID of the current process */ pid: number; /** Hostname of the current machine */ hostname: string; @@ -371,7 +434,7 @@ class Logger { }; // Detect if output is redirected to a file - this.isRedirected = !Deno.stdout.isTerminal(); + this.isRedirected = !isTerminal(); // Initialize formatters registry this.formatters = { @@ -583,8 +646,8 @@ class Logger { level, levelNumber: this.options.levels[level], time: time, - pid: Deno.pid, - hostname: Deno.hostname(), + pid: getPid(), + hostname: getHostname(), msg: format(message, ...args), }; diff --git a/package.json b/package.json new file mode 100644 index 0000000..247dcdb --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "@iankulin/logger", + "version": "1.1.0", + "description": "A comprehensive cross-platform logging library with configurable levels, formatting, and caller detection. Compatible with Deno, Node.js, and Bun.", + "license": "MIT", + "type": "module", + "main": "./lib/logger.ts", + "exports": { + ".": { + "import": "./lib/logger.ts", + "require": "./lib/logger.ts" + } + }, + "files": [ + "lib/", + "README.md", + "LICENSE" + ], + "scripts": { + "dev": "node demo.js", + "test": "node --test test/", + "lint": "echo 'Linting with deno lint'", + "check": "tsc --noEmit lib/logger.ts" + }, + "engines": { + "node": ">=18.0.0" + }, + "keywords": [ + "logger", + "logging", + "cross-platform", + "deno", + "nodejs", + "bun", + "typescript", + "structured-logging", + "json-logging" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/iankulin/d-logger.git" + }, + "bugs": { + "url": "https://github.com/iankulin/d-logger/issues" + }, + "homepage": "https://github.com/iankulin/d-logger#readme" +} \ No newline at end of file