Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions .eslintrc.json

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x]
node-version: [20.x]

env:
CI: true
COVERAGE: ${{ matrix.node-version == '18.x' && true || false }}
COVERAGE: ${{ matrix.node-version == '20.x' && true || false }}

steps:
- uses: actions/checkout@v3
Expand Down
8 changes: 0 additions & 8 deletions .husky/pre-commit

This file was deleted.

25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

## [4.10.0] - 2025-09-25

### Breaking
- Custom `transportFormatted` overrides now receive `logMeta` as the fourth argument; pass five parameters to also receive `settings`, otherwise adjust implementations that previously read `settings` from the fourth position.
- Deprecated runtime entry points under `src/runtime/**` and related browser mappings have been removed; use the primary `Logger` export instead of importing runtime-specific helpers.
- Logger metadata now exposes lowercase runtime identifiers (for example `node`, `browser`, `deno`, `bun`, `worker`) and normalized versions without the leading `v`; adjust consumers that compared against `Nodejs` or relied on the old format.

### Added
- Introduced universal runtime detection that recognises Node.js, browsers, web workers, Deno, and Bun, enriching metadata with runtime versions and hostnames when available.
- Documented first-class Deno and Bun usage, refreshed examples under `examples/server`, and aligned development scripts (`npm run dev-ts*`).
- Pretty transports now detect when the browser console supports CSS, rendering styled output with `%c` tokens and gracefully falling back when styling is unavailable.
- Error formatting captures chained `Error.cause` entries (up to depth five) and includes them in both pretty error blocks and JSON error objects.

### Changed
- The core logger automatically locates the first user stack frame instead of relying on hard-coded depths, producing stable file and line metadata across bundlers; manual `stackDepthLevel` overrides continue to work.
- Placeholder formatting now routes through a shared `buildPrettyMeta` utility, improving consistency for custom templates and nested style tokens.
- Masking internals normalise and cache case-insensitive keys, reducing repeated allocations and keeping behaviour consistent when toggling mask options.
- Browser styling defaults keep ANSI colouring enabled unless explicitly disabled, letting CSS-capable consoles honour `stylePrettyLogs` without runtime-specific tweaks.

### Fixed
- Runtime error detection now treats objects with an `Error`-suffixed name as errors, ensuring they are formatted via the error transport.
- Browser stack parsing guards against malformed frames, avoiding crashes when devtools emit unexpected stack entries.
- Logging no longer fails when `process.cwd()` throws (for example under restricted permissions); environment helpers fall back to cached working directories and hostname detection across Node, Deno, and Bun.
101 changes: 57 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

⚡ **Fast and powerful**<br>
🪶 **Lightweight and flexible**<br>
🏗 **Universal: Works in Browsers and Node.js**<br>
🏗 **Universal: Works in Browsers, Node.js, Deno and Bun**<br>
👮‍️ **Fully typed with TypeScript support (native source maps)**<br>
🗃 **_Pretty_ or `JSON` output**<br>
📝 **Customizable log level**<br>
Expand Down Expand Up @@ -53,62 +53,65 @@ Donations help me allocate more time for my open source work.
npm install tslog
```

In order to run a native ES module in Node.js, you have to do two things:
### Node.js

1) Set `"type": "module"` in `package.json`.
2) For now, start with `--experimental-specifier-resolution=node`
Enable native ESM by setting `"type": "module"` and run Node with source maps for accurate stack traces:

Example `package.json`
```json5
{
"name": "NAME",
"version": "1.0.0",
"main": "index.js",
// here:
"type": "module",
"scripts": {
"build": "tsc -p .",
// and here:
"start": "node --enable-source-maps --experimental-specifier-resolution=node index.js"
"start": "node --enable-source-maps dist/index.js"
},
"dependencies": {
"tslog": "^4"
},
"devDependencies": {
"typescript": "^4"
},
"engines": {
"node": ">=16"
}
}
```

With this `package.json` you can simply build and run it:
After building (`npm run build`), start your app with:

```bash
npm run build
npm start
```

**Otherwise:**
Other handy entry points:

ESM: Node.js with JavaScript:
```bash
node --enable-source-maps --experimental-specifier-resolution=node
- `node --enable-source-maps dist/index.cjs` – run the CommonJS bundle.
- `node --enable-source-maps --loader ts-node/esm src/index.ts` – execute TypeScript via `ts-node` in ESM mode.
- `node --enable-source-maps --require ts-node/register src/index.ts` – execute TypeScript via `ts-node` in CommonJS mode.

### Deno

```ts
// main.ts
import { Logger } from "npm:tslog";

const logger = new Logger();
logger.info("Hello from Deno");
```

CJS: Node.js with JavaScript:
```bash
node --enable-source-maps
deno run main.ts
# grant optional metadata access: deno run --allow-env main.ts
```

ESM: Node.js with TypeScript and `ts-node`:
```bash
node --enable-source-maps --experimental-specifier-resolution=node --no-warnings --loader ts-node/esm
### Bun

```ts
// main.ts
import { Logger } from "tslog";

const logger = new Logger();
logger.info("Hello from Bun");
```

CJS: Node.js with TypeScript and `ts-node`:
```bash
node --enable-source-maps --no-warnings --loader ts-node/cjs
bun run main.ts
# or add "dev": "bun run src/main.ts" to package.json scripts
```

Browser:
Expand Down Expand Up @@ -166,7 +169,7 @@ logger.fatal(new Error("I am a pretty Error with a stacktrace."));

## All Features

- **Universal:** Works in browsers and Node.js
- **Universal:** Works in browsers, Node.js, Deno, and Bun
- **Tested:** Great code coverage, CI
- **Super customizable:** Every aspect can be overwritten
- **Fully typed:** Written in TypeScript, with native TypeScript support
Expand Down Expand Up @@ -240,7 +243,7 @@ In addition to the default log level, custom log level can be defined in the sam
> **Tip:** Also the generic logging method (log()) returns a _JSON_ representation of the log message (`ILogObject`).

```typescript
import { BaseLogger, ILogObjMeta, ISettingsParam, ILogObj } from "./BaseLogger";
import { BaseLogger, ILogObjMeta, ISettingsParam, ILogObj } from "tslog";

export class CustomLogger<LogObj> extends BaseLogger<LogObj> {
constructor(settings?: ISettingsParam<LogObj>, logObj?: LogObj) {
Expand Down Expand Up @@ -371,9 +374,9 @@ secondSubLogger.silly("foo bar 2");

Output:
```bash
2022-11-17 10:45:47.705 SILLY [/examples/nodejs/index2.ts:51 MainLogger] foo bar
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:54 MainLogger:FirstSubLogger ] foo bar 1
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:57 MainLogger:FirstSubLogger:SecondSubLogger] foo bar 2
2022-11-17 10:45:47.705 SILLY [/examples/server/index2.ts:51 MainLogger] foo bar
2022-11-17 10:45:47.706 SILLY [/examples/server/index2.ts:54 MainLogger:FirstSubLogger ] foo bar 1
2022-11-17 10:45:47.706 SILLY [/examples/server/index2.ts:57 MainLogger:FirstSubLogger:SecondSubLogger] foo bar 2
```

#### minLevel
Expand Down Expand Up @@ -455,8 +458,8 @@ Following settings are available for styling:
- `prettyInspectOptions`: <a href="https://nodejs.org/api/util.html#utilinspectobject-options" target="_blank">Available options</a>

### Customizing template tokens
It's possible to add user defined tokes, by overwriting the `addPlaceholders` in the `settings.overwrite`. this callback allows to add or overwrite tokens in the `placeholderValues`.
for example, to add the token: `{{custom}}`;
You can add your own template tokens by overriding `settings.overwrite.addPlaceholders`. The callback receives the current metadata object and the placeholder map so you can add or overwrite entries.
For example, to add the token `{{custom}}`:
```javascript
const logger = new Logger({
type: "pretty",
Expand All @@ -468,10 +471,10 @@ Following settings are available for styling:
},
});
```
this would yield in the token `{{custom}}` being replaced with `"test"`
This replaces `{{custom}}` with the string `"test"` in the rendered output.

- **Styling:**
- `stylePrettyLogs`: defines whether logs should be styled and colorized
- `stylePrettyLogs`: defines whether logs should be styled and colorized (ANSI in server runtimes, CSS in browsers that support it)
- `prettyLogStyles`: provides colors and styles for different placeholders and can also be dependent on the value (e.g. log level)
- Level 1: template placeholder (defines a style for a certain template placeholder, s. above, without brackets).
- Level 2: Either a string with one style (e.g. `white`), or an array of styles (e.g. `["bold", "white"]`), or a nested object with key being a value.
Expand All @@ -485,6 +488,8 @@ Following settings are available for styling:
`tslog` collects meta information for every log, like runtime, code position etc. The meta information collected depends on the runtime (browser or Node.js) and is accessible through the `LogObj`.
You can define the property containing this meta information with `metaProperty`, which is "_meta" by default.

`tslog` automatically determines the first caller frame outside of the library, even in bundled environments such as Vite or Next.js. If you need to override the detected frame, provide `stackDepthLevel` when constructing a `Logger`.

#### Pretty templates and styles (color settings)

```typescript
Expand Down Expand Up @@ -676,13 +681,21 @@ For `pretty` logs:
formatLogObj: <LogObj>(maskedArgs: unknown[], settings: ISettings<LogObj>) => {
// format LogObj attributes to a string and return it
},
transportFormatted: (logMetaMarkup: string, logArgs: unknown[], logErrors: string[], settings: unknown) => {
transportFormatted: (
logMetaMarkup: string,
logArgs: unknown[],
logErrors: string[],
logMeta?: IMeta,
settings?: ISettings<LogObj>
) => {
// overwrite the default transport for formatted (e.g. pretty) log levels. e.g. replace console with StdOut, write to file etc.
},
},
});
```

> **Note:** `transportFormatted` receives the resolved log meta as an optional fourth argument and the active settings as an optional fifth argument. Handlers that still accept only three arguments continue to work unchanged.

For `JSON` logs (no formatting happens here):
```typescript
const logger = new Logger({
Expand All @@ -701,9 +714,9 @@ For `JSON` logs (no formatting happens here):
const logger = new Logger({
type: "pretty",
overwrite: {
transportFormatted: (logMetaMarkup, logArgs, logErrors) => {
transportFormatted: (logMetaMarkup, logArgs, logErrors, logMeta) => {
// Send different log levels to appropriate console methods
const logLevel = logMetaMarkup.trim().split("\t")[1]; // Extract log level from the markup
const logLevel = logMeta?.logLevelName ?? logMetaMarkup.trim().split("\t")[1];
switch (logLevel) {
case "WARN":
console.warn(logMetaMarkup, ...logArgs, ...logErrors);
Expand Down Expand Up @@ -749,18 +762,18 @@ const logMsg = logger.info("Test");
// '0': 'Test',
// foo: 'bar',
// _meta: {
// runtime: 'Nodejs',
// runtime: 'server',
// hostname: 'Eugenes-MBP.local',
// date: 2022-10-23T10:51:08.857Z,
// logLevelId: 3,
// logLevelName: 'INFO',
// path: {
// fullFilePath: 'file:///[...]/tslog/examples/nodejs/index.ts:113:23',
// fullFilePath: 'file:///[...]/tslog/examples/server/index.ts:113:23',
// fileName: 'index.ts',
// fileColumn: '23',
// fileLine: '113',
// filePath: '/examples/nodejs/index.ts',
// filePathWithLine: '/examples/nodejs/index.ts:113'
// filePath: '/examples/server/index.ts',
// filePathWithLine: '/examples/server/index.ts:113'
// }
// }
//}
Expand Down
Loading