add subDirectory option, move @ to # in relative paths, fix builder
All checks were successful
Code quality checks / biome (push) Successful in 12s

This commit is contained in:
creations 2025-06-13 20:21:45 -04:00
parent e0f4c50f20
commit 7b02602e86
Signed by: creations
GPG key ID: 8F553AA4320FC711
9 changed files with 73 additions and 47 deletions

View file

@ -7,7 +7,7 @@
},
"files": {
"ignoreUnknown": true,
"ignore": ["dist"]
"ignore": ["dist", "tsconfig.json"]
},
"formatter": {
"enabled": true,
@ -36,7 +36,7 @@
"noVar": "error"
}
},
"ignore": ["types"]
"ignore": ["types", "tsconfig.json"]
},
"javascript": {
"formatter": {

View file

@ -4,32 +4,24 @@
"description": "A minimal, flexible logger",
"private": false,
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"typesVersions": {
"*": {
"lib/char": ["./dist/lib/char.d.ts"],
"lib/config": ["./dist/lib/config.d.ts"]
}
},
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js"
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./lib/char": {
"import": "./dist/lib/char.js",
"require": "./dist/lib/char.js"
},
"./lib/config": {
"import": "./dist/lib/config.js",
"require": "./dist/lib/config.js"
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
}
}
},
"scripts": {
"dev": "bun run build --watch",
"build": "rm -rf dist && tsup src/index.ts --dts --out-dir dist --format esm,cjs",
"build": "rm -rf dist && tsup && rm -f dist/*.d.cts dist/**/*.d.cts",
"lint": "bunx biome check",
"lint:fix": "bunx biome check --fix",
"cleanup": "rm -rf logs node_modules bun.lock"
@ -38,8 +30,7 @@
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@types/bun": "^1.2.15",
"tsup": "^8.5.0",
"typescript": "^5.8.3"
"tsup": "latest"
},
"files": ["dist", "README.md", "LICENSE"],
"repository": {
@ -53,6 +44,6 @@
"url": "https://git.creations.works/atums/echo/issues"
},
"dependencies": {
"date-fns-tz": "^3.2.0"
"date-fns-tz": "latest"
}
}

View file

@ -14,17 +14,17 @@ import {
getTimestamp,
parsePattern,
processPattern,
} from "@lib/char";
} from "#lib/char";
import {
defaultConfig,
loadEnvConfig,
loadLoggerConfig,
logLevelValues,
validateAndSanitizeConfig,
} from "@lib/config";
import { FileLogger } from "@lib/file";
} from "#lib/config";
import { FileLogger } from "#lib/file";
import type { LogLevel, LoggerConfig, PatternTokens } from "@types";
import type { LogLevel, LoggerConfig, PatternTokens } from "#types";
class Echo {
private readonly directory: string;
@ -160,4 +160,3 @@ function createLogger(config?: string | LoggerConfig): Echo {
const echo = new Echo();
export { echo, Echo, createLogger };
export type { LoggerConfig, LogLevel } from "@types";

View file

@ -1,7 +1,7 @@
import { basename } from "node:path";
import { format, inspect } from "node:util";
import { ansiColors, defaultLevelColor, logLevelValues } from "@lib/config";
import { format as formatDate } from "date-fns-tz";
import { ansiColors, defaultLevelColor, logLevelValues } from "#lib/config";
import type {
LogLevel,
@ -9,7 +9,7 @@ import type {
LoggerConfig,
PatternContext,
PatternTokens,
} from "@types";
} from "#types";
function getTimestamp(config: Required<LoggerConfig>): {
prettyTimestamp: string;

View file

@ -1,7 +1,7 @@
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import type { LogLevel, LoggerConfig } from "@types";
import type { LogLevel, LoggerConfig } from "#types";
const logLevelValues = {
trace: 10,
@ -51,6 +51,7 @@ const defaultConfig: Required<LoggerConfig> = {
rotate: true,
maxFiles: null,
fileNameFormat: "yyyy-MM-dd",
subDirectory: null,
console: true,
consoleColor: true,
@ -233,6 +234,10 @@ function loadEnvConfig(): LoggerConfig {
config.fileNameFormat = process.env.LOG_FILE_NAME_FORMAT;
}
if (process.env.LOG_SUB_DIRECTORY) {
config.subDirectory = process.env.LOG_SUB_DIRECTORY;
}
if (process.env.LOG_DATE_FORMAT) {
config.dateFormat = process.env.LOG_DATE_FORMAT;
}

View file

@ -1,27 +1,29 @@
import {
type WriteStream,
createWriteStream,
existsSync,
mkdirSync,
readdirSync,
unlinkSync,
} from "node:fs";
import { join } from "node:path";
import { serializeLogData } from "@lib/char";
import { format } from "date-fns-tz";
import { serializeLogData } from "#lib/char";
import type { LogLevel, LoggerConfig } from "@types";
import type { LogLevel, LoggerConfig } from "#types";
class FileLogger {
private stream: WriteStream | null = null;
private filePath = "";
private date = "";
private fileNameFormat = "yyyy-MM-dd";
private logDirectory: string;
constructor(private readonly config: Required<LoggerConfig>) {
if (!existsSync(this.config.directory)) {
mkdirSync(this.config.directory, { recursive: true });
}
this.logDirectory = this.config.subDirectory
? join(this.config.directory, this.config.subDirectory)
: this.config.directory;
mkdirSync(this.logDirectory, { recursive: true });
if (this.config.fileNameFormat) {
try {
@ -39,7 +41,7 @@ class FileLogger {
private getLogFilePath(dateStr: string): string {
const fileName = `${dateStr}.jsonl`;
return join(this.config.directory, fileName);
return join(this.logDirectory, fileName);
}
private resetStream(path: string): void {
@ -72,7 +74,7 @@ class FileLogger {
}
const fileRegex = this.generateFileRegex();
const files = readdirSync(this.config.directory)
const files = readdirSync(this.logDirectory)
.filter((file) => fileRegex.test(file))
.sort();
@ -83,7 +85,7 @@ class FileLogger {
for (const file of excess) {
try {
unlinkSync(join(this.config.directory, file));
unlinkSync(join(this.logDirectory, file));
} catch {}
}
}
@ -92,7 +94,7 @@ class FileLogger {
if (this.config.rotate && dateStr) {
return this.getLogFilePath(dateStr);
}
return join(this.config.directory, "log.jsonl");
return join(this.logDirectory, "log.jsonl");
}
public write(

View file

@ -3,11 +3,10 @@
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@types": ["types/index.ts"],
"@types/*": ["types/*"],
"@lib/*": ["src/lib/*"]
"#types": ["types/index.ts"],
"#lib/*": ["src/lib/*"]
},
"typeRoots": ["./types", "./node_modules/@types"],
"typeRoots": ["./node_modules/@types"],
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ESNext",

29
tsup.config.ts Normal file
View file

@ -0,0 +1,29 @@
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: {
resolve: true,
compilerOptions: {
module: "ESNext",
moduleResolution: "bundler",
},
},
outDir: "dist",
minify: true,
splitting: false,
sourcemap: false,
clean: true,
treeshake: true,
target: "es2024",
define: {
"process.env.NODE_ENV": '"production"',
},
outExtension({ format }) {
return {
js: format === "cjs" ? ".cjs" : ".js",
dts: ".d.ts",
};
},
});

View file

@ -1,4 +1,4 @@
import type { ansiColors, logLevelValues } from "@lib/config";
import type { ansiColors, logLevelValues } from "#lib/config";
type LogLevelValue = (typeof logLevelValues)[keyof typeof logLevelValues];
type LogLevel = keyof typeof logLevelValues;
@ -11,6 +11,7 @@ type LoggerConfig = {
rotate?: boolean;
maxFiles?: number | null;
fileNameFormat?: string;
subDirectory?: string | null;
console?: boolean;
consoleColor?: boolean;