Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@ecopages/logger

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ecopages/logger - npm Package Compare versions

Comparing version
0.2.2
to
0.2.3
+20
-5
dist/logger.d.ts

@@ -31,9 +31,15 @@ declare const Level: {

/**
* Format of the timestamp. Possible values:
* - 'full' = 'YYYY-MM-DD HH:mm:ss'
* - 'time' = 'HH:mm:ss'
* - 'short' = 'MM-DD HH:mm:ss'
* Format of the timestamp.
* Possible values:
* - 'full' = date + time
* - 'time' = time only
* - 'short' = short date + time
*/
timestampFormat?: 'full' | 'time' | 'short';
/**
* Locale used by timestamp formatting.
* Defaults to 'en-US' for deterministic output.
*/
locale?: string | string[];
/**
* Custom colors for different log levels.

@@ -74,5 +80,8 @@ * In browser: use CSS color values (e.g., '#00ff00', 'red', etc.)

* Logs an error message.
* Accepts unknown values (e.g. strict TypeScript catch variables).
* When an {@link Error} is provided, its stack (or name/message fallback)
* is logged so stack traces remain visible.
* @param args The arguments to be logged.
*/
error(...args: LogArgument[]): this;
error(...args: unknown[]): this;
/**

@@ -86,2 +95,5 @@ * Logs a debug message.

* Starts a timer with a label.
* Timer behavior is unified across color modes:
* - with `color: true`, output is colorized
* - with `color: false`, output is plain text
* @param label The label for the timer.

@@ -92,2 +104,3 @@ */

* Ends a timer with a label.
* Logs a warning if the timer label was not started.
* @param label The label for the timer.

@@ -99,2 +112,4 @@ */

private getFormatSpecifier;
private normalizeLogArgs;
private getConsoleMethod;
private logInternal;

@@ -101,0 +116,0 @@ /**

+1
-1

@@ -1,1 +0,1 @@

var q={INFO:"INFO",ERROR:"ERROR",WARN:"WARN",DEBUG:"DEBUG",TIMER:"TIMER"},V={level:q.INFO},X={level:q.ERROR},Y={level:q.WARN},Z={level:q.DEBUG},J=typeof window!=="undefined",_={INFO:"color: #00ff00",ERROR:"color: #ff0000",WARN:"color: #ffff00",DEBUG:"color: #00ffff",TIMER:"color: #ff00ff"},$={INFO:"\x1B[32m",ERROR:"\x1B[31m",WARN:"\x1B[33m",DEBUG:"\x1B[36m",TIMER:"\x1B[35m"};class A{prefix;colors;options={debug:!1,color:!0,timestampFormat:"time",verboseTimer:!1};timers=new Map;constructor(j,k){if(this.prefix=j,k)this.options={...this.options,...k};this.colors={...J?_:$,...k?.colors}}info(...j){return this.logInternal(V,...j),this}warn(...j){return this.logInternal(Y,...j),this}error(...j){return this.logInternal(X,...j),this}debug(...j){if(this.options.debug)this.logInternal(Z,...j);return this}time(j,k=q.TIMER){if(!this.options.color){console.time(`${this.prefix} ${j}`);return}if(this.timers.set(j,performance.now()),this.options.verboseTimer)if(J)console.log(`%c${this.prefix} ${j}: start`,this.getColor(k));else{let H=this.getColor(k);console.log(`${H}${this.prefix} ${j}: start\x1B[0m`)}}timeEnd(j,k=q.TIMER){if(!this.options.color){console.timeEnd(`${this.prefix} ${j}`);return}let H=this.timers.get(j);if(H===void 0){console.warn(`Timer '${this.prefix} ${j}' does not exist`);return}let z=performance.now()-H;if(this.timers.delete(j),J)console.log(`%c${this.prefix} ${j}: ${z.toFixed(2)}ms`,this.getColor(k));else{let K=this.getColor(k);console.log(`${K}${this.prefix} ${j}: ${z.toFixed(2)}ms\x1B[0m`)}}getTimestamp(){if(!this.options.timestamp)return"";let j=new Date,k;switch(this.options.timestampFormat){case"full":k={year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1};break;case"short":k={month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1};break;default:k={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}}return`[${j.toLocaleString("en-US",k)}] `}getColor(j){return this.colors[j]??""}getFormatSpecifier(j){if(j===null)return"%s";if(j===void 0)return"%s";switch(typeof j){case"object":return"%o";case"number":return"%d";case"boolean":return"%s";default:return"%s"}}logInternal(j,...k){let z=this.getTimestamp()+this.prefix;if(!this.options.color){console.log(z,...k);return}if(J){let P=j?this.getColor(j.level):"",Q=k.map((S)=>this.getFormatSpecifier(S));console.log(`%c${z} ${Q.join(" ")}`,P,...k);return}let K=j?this.getColor(j.level):"",M="\x1B[0m";console.log(`${K}${z}`,...k,M)}isDebugEnabled(){return!!this.options.debug}debugTime(j){if(this.isDebugEnabled())this.time(j,q.DEBUG)}debugTimeEnd(j){if(this.isDebugEnabled())this.timeEnd(j,q.DEBUG)}}export{A as Logger};
var H={INFO:"INFO",ERROR:"ERROR",WARN:"WARN",DEBUG:"DEBUG",TIMER:"TIMER"},_={level:H.INFO},$={level:H.ERROR},D={level:H.WARN},F={level:H.DEBUG},P=typeof window<"u",G={INFO:"color: #00ff00",ERROR:"color: #ff0000",WARN:"color: #ffff00",DEBUG:"color: #00ffff",TIMER:"color: #ff00ff"},I={INFO:"\x1B[32m",ERROR:"\x1B[31m",WARN:"\x1B[33m",DEBUG:"\x1B[36m",TIMER:"\x1B[35m"};class U{prefix;colors;options={debug:!1,color:!0,timestampFormat:"time",verboseTimer:!1};timers=new Map;constructor(j,k){if(this.prefix=j,k)this.options={...this.options,...k};this.colors={...P?G:I,...k?.colors}}info(...j){return this.logInternal(_,...j),this}warn(...j){return this.logInternal(D,...j),this}error(...j){return this.logInternal($,...j),this}debug(...j){if(this.options.debug)this.logInternal(F,...j);return this}time(j,k=H.TIMER){if(this.timers.set(j,performance.now()),this.options.verboseTimer)if(P)if(this.options.color)console.log(`%c${this.prefix} ${j}: start`,this.getColor(k));else console.log(`${this.prefix} ${j}: start`);else if(this.options.color){let q=this.getColor(k);console.log(`${q}${this.prefix} ${j}: start\x1B[0m`)}else console.log(`${this.prefix} ${j}: start`)}timeEnd(j,k=H.TIMER){let q=this.timers.get(j);if(q===void 0){console.warn(`Timer '${this.prefix} ${j}' does not exist`);return}let J=performance.now()-q;if(this.timers.delete(j),P)if(this.options.color)console.log(`%c${this.prefix} ${j}: ${J.toFixed(2)}ms`,this.getColor(k));else console.log(`${this.prefix} ${j}: ${J.toFixed(2)}ms`);else if(this.options.color){let K=this.getColor(k);console.log(`${K}${this.prefix} ${j}: ${J.toFixed(2)}ms\x1B[0m`)}else console.log(`${this.prefix} ${j}: ${J.toFixed(2)}ms`)}getTimestamp(){if(!this.options.timestamp)return"";let j=new Date,k;switch(this.options.timestampFormat){case"full":k={year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1};break;case"short":k={month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1};break;default:k={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}}let q=this.options.locale??"en-US";return`[${j.toLocaleString(q,k)}] `}getColor(j){return this.colors[j]??""}getFormatSpecifier(j){if(j===null)return"%s";if(j===void 0)return"%s";switch(typeof j){case"object":return"%o";case"number":return"%d";case"boolean":return"%s";default:return"%s"}}normalizeLogArgs(j,k){if(j!==H.ERROR)return k;return k.map((q)=>{if(q instanceof Error)return q.stack??`${q.name}: ${q.message}`;return q})}getConsoleMethod(j){switch(j){case H.ERROR:return console.error.bind(console);case H.WARN:return console.warn.bind(console);default:return console.log.bind(console)}}logInternal(j,...k){let J=this.getTimestamp()+this.prefix,K=this.normalizeLogArgs(j?.level,k),Q=this.getConsoleMethod(j?.level);if(!this.options.color){Q(J,...K);return}if(P){let X=j?this.getColor(j.level):"",Y=K.map((Z)=>this.getFormatSpecifier(Z));Q(`%c${J} ${Y.join(" ")}`,X,...K);return}let S=j?this.getColor(j.level):"",V="\x1B[0m";Q(`${S}${J}`,...K,V)}isDebugEnabled(){return!!this.options.debug}debugTime(j){if(this.isDebugEnabled())this.time(j,H.DEBUG)}debugTimeEnd(j){if(this.isDebugEnabled())this.timeEnd(j,H.DEBUG)}}export{U as Logger};
{
"name": "@ecopages/logger",
"version": "0.2.2",
"version": "0.2.3",
"license": "MIT",

@@ -17,4 +17,4 @@ "main": "./dist/logger.js",

"build:types": "tsc -p tsconfig.build.json",
"format": "bunx @biomejs/biome format --write .",
"lint": "bunx @biomejs/biome check --apply .",
"format": "biome format --write .",
"lint": "biome check --write .",
"lint-staged": "lint-staged",

@@ -29,2 +29,3 @@ "prepare": "husky",

"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@changesets/changelog-github": "^0.5.0",

@@ -31,0 +32,0 @@ "@changesets/cli": "^2.27.5",

@@ -51,2 +51,3 @@ # @ecopages/logger

timestampFormat: "full", // Configure timestamp format
locale: "de-DE", // Optional locale for timestamps
verboseTimer: true, // Show timer start messages

@@ -69,2 +70,3 @@ colors: {

| `timestampFormat` | "full" \| "time" \| "short" | "time" | Timestamp format |
| `locale` | string \| string[] | "en-US" | Locale used for timestamps |
| `verboseTimer` | boolean | `false` | Show timer start messages |

@@ -75,8 +77,35 @@ | `colors` | Partial<ColorConfig> | - | Custom colors for log levels |

- `full`: `YYYY-MM-DD HH:mm:ss`
- `time`: `HH:mm:ss`
- `short`: `MM-DD HH:mm:ss`
- `full`: full date and time
- `time`: time only
- `short`: short date and time
Timestamp output is generated via `toLocaleString(locale, ...)`.
By default, locale is `en-US`; set `locale` to customize it.
## Error Stack Traces
To keep stack traces, pass the actual `Error` object to `logger.error`:
```ts
try {
throw new Error("Something failed");
} catch (error: unknown) {
if (error instanceof Error) {
logger.error(error); // preserves stack output
} else {
logger.error(new Error(String(error)));
}
}
```
If you pass `error.message` (string) instead, the stack trace is not available.
## Timer Functionality
Timer behavior is consistent whether colors are enabled or disabled:
- `color: true` → colorized timer output
- `color: false` → plain timer output
- `verboseTimer: true` → logs `start` message before duration output
```ts

@@ -150,3 +179,3 @@ // Start a timer

logger.info("Application started");
// Output: [2024-02-16 15:30:45] [my-app] Application started
// Output: [02/16/2024, 15:30:45] [my-app] Application started
```

@@ -153,0 +182,0 @@