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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,11 +3,10 @@
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
"@/*": ["src/*"], "@/*": ["src/*"],
"@types": ["types/index.ts"], "#types": ["types/index.ts"],
"@types/*": ["types/*"], "#lib/*": ["src/lib/*"]
"@lib/*": ["src/lib/*"]
}, },
"typeRoots": ["./types", "./node_modules/@types"], "typeRoots": ["./node_modules/@types"],
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"target": "ESNext", "target": "ESNext",
"module": "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 LogLevelValue = (typeof logLevelValues)[keyof typeof logLevelValues];
type LogLevel = keyof typeof logLevelValues; type LogLevel = keyof typeof logLevelValues;
@ -11,6 +11,7 @@ type LoggerConfig = {
rotate?: boolean; rotate?: boolean;
maxFiles?: number | null; maxFiles?: number | null;
fileNameFormat?: string; fileNameFormat?: string;
subDirectory?: string | null;
console?: boolean; console?: boolean;
consoleColor?: boolean; consoleColor?: boolean;