+node and bun compat

This commit is contained in:
IanKulin
2025-09-28 10:10:32 +08:00
parent ab1de2da1f
commit 1cf8a0fae9
3 changed files with 118 additions and 5 deletions

View File

@@ -25,6 +25,7 @@ $ deno run --allow-env --allow-sys your-script.js
## Quick Start ## Quick Start
```typescript ```typescript
// Deno
import Logger from "@iankulin/logger"; import Logger from "@iankulin/logger";
const logger = new Logger(); const logger = new Logger();
@@ -36,6 +37,7 @@ logger.error("Something went wrong");
```typescript ```typescript
// Deno
import Logger from "jsr:@iankulin/logger"; import Logger from "jsr:@iankulin/logger";
// Create a new logger instance // Create a new logger instance
@@ -157,6 +159,7 @@ devLogger.info("Development info message");
- **1.0.1** - Minor updates - **1.0.1** - Minor updates
- Deno flavoured demo in readme - Deno flavoured demo in readme
- Add JSDoc to boost JSR score - Add JSDoc to boost JSR score
- **1.1.0** - Add Node and Bun support
## AI Disclosure ## AI Disclosure

View File

@@ -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, * 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 * 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. * built-in util.format-style string formatting with %s, %d, %j, and other specifiers.
* *
* Compatible with Deno, Node.js, and Bun runtimes.
*
* @module logger * @module logger
* @example * @example
* ```ts * ```ts
@@ -135,6 +137,67 @@ function format(f: unknown, ...args: unknown[]): string {
return str; 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. * Available log levels in order of priority.
* *
@@ -200,7 +263,7 @@ export interface LogEntry {
levelNumber: number; levelNumber: number;
/** Formatted timestamp string */ /** Formatted timestamp string */
time: string; time: string;
/** Process ID of the current Deno process */ /** Process ID of the current process */
pid: number; pid: number;
/** Hostname of the current machine */ /** Hostname of the current machine */
hostname: string; hostname: string;
@@ -371,7 +434,7 @@ class Logger {
}; };
// Detect if output is redirected to a file // Detect if output is redirected to a file
this.isRedirected = !Deno.stdout.isTerminal(); this.isRedirected = !isTerminal();
// Initialize formatters registry // Initialize formatters registry
this.formatters = { this.formatters = {
@@ -583,8 +646,8 @@ class Logger {
level, level,
levelNumber: this.options.levels[level], levelNumber: this.options.levels[level],
time: time, time: time,
pid: Deno.pid, pid: getPid(),
hostname: Deno.hostname(), hostname: getHostname(),
msg: format(message, ...args), msg: format(message, ...args),
}; };

47
package.json Normal file
View File

@@ -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"
}