@reliverse/relinka 1.3.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -71
- package/bin/{core-impl/deprecated → deprecated}/components/levels/levels.d.ts +1 -1
- package/bin/{core-impl/deprecated → deprecated}/components/modes/basic.d.ts +1 -1
- package/bin/{core-impl/deprecated → deprecated}/components/modes/browser.d.ts +1 -1
- package/bin/deprecated/components/modes/shared.d.ts +2 -0
- package/bin/deprecated/components/modes/shared.js +1 -0
- package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/mod.d.ts +1 -1
- package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/relinka.d.ts +2 -2
- package/bin/{core-impl/deprecated → deprecated}/components/reporters/basic.d.ts +1 -1
- package/bin/{core-impl/deprecated → deprecated}/components/reporters/browser.d.ts +1 -1
- package/bin/{core-impl/deprecated → deprecated}/components/reporters/fancy.d.ts +2 -2
- package/bin/{core-impl/deprecated → deprecated}/components/reporters/fancy.js +1 -3
- package/bin/deprecated/impl-old.js +0 -0
- package/bin/{core-types.d.ts → deprecated/types.d.ts} +0 -32
- package/bin/deprecated/types.js +0 -0
- package/bin/impl.d.ts +149 -0
- package/bin/impl.js +606 -0
- package/bin/main.d.ts +24 -22
- package/bin/main.js +24 -21
- package/bin/types.d.ts +0 -0
- package/bin/types.js +0 -0
- package/package.json +41 -6
- package/bin/core-impl/deprecated/components/modes/shared.d.ts +0 -2
- package/bin/core-impl/deprecated/components/modes/shared.js +0 -4
- package/bin/core-impl/deprecated/components/relinka-deprecated/relinka.test.d.ts +0 -1
- package/bin/core-impl/deprecated/components/relinka-deprecated/relinka.test.js +0 -57
- package/bin/core-impl/impl-mod.d.ts +0 -19
- package/bin/core-impl/impl-mod.js +0 -321
- /package/bin/{core-impl/deprecated → deprecated}/components/levels/levels.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/modes/basic.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/modes/browser.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/logger.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/logger.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/mod.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/relinka-deprecated/relinka.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/reporters/basic.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/components/reporters/browser.js +0 -0
- /package/bin/{core-types.js → deprecated/impl-old.d.ts} +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/box.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/box.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/deprecatedColors.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/deprecatedColors.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/error.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/error.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/format.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/format.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/log.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/log.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/stream.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/stream.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/string.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/string.js +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/tree.d.ts +0 -0
- /package/bin/{core-impl/deprecated → deprecated}/utils/tree.js +0 -0
package/bin/main.js
CHANGED
|
@@ -1,58 +1,61 @@
|
|
|
1
|
+
export * from "./deprecated/types.js";
|
|
1
2
|
export {
|
|
2
3
|
LogLevelsDeprecated,
|
|
3
4
|
LogTypesDeprecated
|
|
4
|
-
} from "./
|
|
5
|
+
} from "./deprecated/components/levels/levels.js";
|
|
5
6
|
export {
|
|
6
7
|
createRelinkaBaseDeprecated,
|
|
7
8
|
relinkaBasicDeprecated
|
|
8
|
-
} from "./
|
|
9
|
+
} from "./deprecated/components/modes/basic.js";
|
|
9
10
|
export {
|
|
10
11
|
createRelinkaBrowserDeprecatedDeprecated,
|
|
11
12
|
relinkaBrowserDeprecated
|
|
12
|
-
} from "./
|
|
13
|
-
export { relinkaDeprecated } from "./
|
|
13
|
+
} from "./deprecated/components/modes/browser.js";
|
|
14
|
+
export { relinkaDeprecated } from "./deprecated/components/relinka-deprecated/logger.js";
|
|
14
15
|
export {
|
|
15
16
|
createRelinkaSharedDeprecated,
|
|
16
17
|
relinkaInstanceDeprecated
|
|
17
|
-
} from "./
|
|
18
|
+
} from "./deprecated/components/relinka-deprecated/mod.js";
|
|
18
19
|
export {
|
|
19
20
|
RelinkaInterface,
|
|
20
21
|
createRelinkaDeprecated
|
|
21
|
-
} from "./
|
|
22
|
-
export { BasicReporter } from "./
|
|
23
|
-
export { BrowserReporter } from "./
|
|
22
|
+
} from "./deprecated/components/relinka-deprecated/relinka.js";
|
|
23
|
+
export { BasicReporter } from "./deprecated/components/reporters/basic.js";
|
|
24
|
+
export { BrowserReporter } from "./deprecated/components/reporters/browser.js";
|
|
24
25
|
export {
|
|
25
26
|
TYPE_COLOR_MAP,
|
|
26
27
|
LEVEL_COLOR_MAP,
|
|
27
28
|
FancyReporter
|
|
28
|
-
} from "./
|
|
29
|
-
export { box } from "./
|
|
29
|
+
} from "./deprecated/components/reporters/fancy.js";
|
|
30
|
+
export { box } from "./deprecated/utils/box.js";
|
|
30
31
|
export {
|
|
31
32
|
colors,
|
|
32
33
|
getColor,
|
|
33
34
|
colorize
|
|
34
|
-
} from "./
|
|
35
|
-
export { parseStack } from "./
|
|
35
|
+
} from "./deprecated/utils/deprecatedColors.js";
|
|
36
|
+
export { parseStack } from "./deprecated/utils/error.js";
|
|
36
37
|
export {
|
|
37
38
|
compileFormat,
|
|
38
39
|
formatString
|
|
39
|
-
} from "./
|
|
40
|
-
export {
|
|
41
|
-
|
|
42
|
-
isLogObj
|
|
43
|
-
} from "./core-impl/deprecated/utils/log.js";
|
|
44
|
-
export { writeStream } from "./core-impl/deprecated/utils/stream.js";
|
|
40
|
+
} from "./deprecated/utils/format.js";
|
|
41
|
+
export { isPlainObject, isLogObj } from "./deprecated/utils/log.js";
|
|
42
|
+
export { writeStream } from "./deprecated/utils/stream.js";
|
|
45
43
|
export {
|
|
46
44
|
stripAnsi,
|
|
47
45
|
centerAlign,
|
|
48
46
|
rightAlign,
|
|
49
47
|
leftAlign,
|
|
50
48
|
align
|
|
51
|
-
} from "./
|
|
52
|
-
export { formatTree } from "./
|
|
49
|
+
} from "./deprecated/utils/string.js";
|
|
50
|
+
export { formatTree } from "./deprecated/utils/tree.js";
|
|
53
51
|
export {
|
|
54
52
|
relinkaConfig,
|
|
53
|
+
relinkaShutdown,
|
|
54
|
+
flushAllLogBuffers,
|
|
55
|
+
shouldNeverHappen,
|
|
56
|
+
truncateString,
|
|
57
|
+
casesHandled,
|
|
55
58
|
relinka,
|
|
56
59
|
relinkaAsync,
|
|
57
60
|
defineConfig
|
|
58
|
-
} from "./
|
|
61
|
+
} from "./impl.js";
|
package/bin/types.d.ts
ADDED
|
File without changes
|
package/bin/types.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "@reliverse/relinka is your next favorite logging library — built to make your terminal (and browser console — soon) output look good, stay clean, and be actually helpful. It’s styled, structured, and smart. Oh, and it works with configs, files, and colors out of the box.",
|
|
3
|
-
"license": "MIT",
|
|
4
|
-
"name": "@reliverse/relinka",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"version": "1.3.8",
|
|
7
2
|
"dependencies": {
|
|
8
3
|
"@reliverse/relico": "^1.1.0",
|
|
9
4
|
"@reliverse/runtime": "^1.0.3",
|
|
@@ -15,7 +10,47 @@
|
|
|
15
10
|
"std-env": "^3.9.0",
|
|
16
11
|
"string-width": "^7.2.0"
|
|
17
12
|
},
|
|
18
|
-
"
|
|
13
|
+
"description": "@reliverse/relinka is a modern, minimal logging library that actually feels right. It's not just pretty output — it's a system: smart formatting, file-safe logging, runtime config support, and a fatal mode built for developers who care about correctness.",
|
|
14
|
+
"homepage": "https://docs.reliverse.org",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"name": "@reliverse/relinka",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"version": "1.4.0",
|
|
19
|
+
"keywords": [
|
|
20
|
+
"logger",
|
|
21
|
+
"consola",
|
|
22
|
+
"console",
|
|
23
|
+
"elegant",
|
|
24
|
+
"clack",
|
|
25
|
+
"cli",
|
|
26
|
+
"error",
|
|
27
|
+
"format",
|
|
28
|
+
"prompt",
|
|
29
|
+
"reliverse",
|
|
30
|
+
"reporter",
|
|
31
|
+
"stacktrace",
|
|
32
|
+
"unified",
|
|
33
|
+
"universal"
|
|
34
|
+
],
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@biomejs/biome": "1.9.4",
|
|
37
|
+
"@eslint/js": "^9.24.0",
|
|
38
|
+
"@reliverse/relidler-cfg": "^1.1.3",
|
|
39
|
+
"@stylistic/eslint-plugin": "^4.2.0",
|
|
40
|
+
"@total-typescript/ts-reset": "^0.6.1",
|
|
41
|
+
"@types/bun": "^1.2.9",
|
|
42
|
+
"@types/fs-extra": "^11.0.4",
|
|
43
|
+
"@types/node": "^22.14.1",
|
|
44
|
+
"@types/sentencer": "^0.2.3",
|
|
45
|
+
"eslint": "^9.24.0",
|
|
46
|
+
"eslint-plugin-no-relative-import-paths": "^1.6.1",
|
|
47
|
+
"eslint-plugin-perfectionist": "^4.11.0",
|
|
48
|
+
"jiti": "^2.4.2",
|
|
49
|
+
"knip": "^5.50.2",
|
|
50
|
+
"sentencer": "^0.2.1",
|
|
51
|
+
"typescript": "^5.8.3",
|
|
52
|
+
"typescript-eslint": "^8.29.1"
|
|
53
|
+
},
|
|
19
54
|
"exports": {
|
|
20
55
|
".": "./bin/main.js"
|
|
21
56
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { createRelinkaDeprecated } from "./relinka.js";
|
|
3
|
-
import {
|
|
4
|
-
LogLevelsDeprecated
|
|
5
|
-
} from "./mod.js";
|
|
6
|
-
describe("relinka", () => {
|
|
7
|
-
test("can set level", () => {
|
|
8
|
-
const relinka = createRelinkaDeprecated();
|
|
9
|
-
expect(relinka.level).toBe(1);
|
|
10
|
-
for (let i = 0; i <= 5; i++) {
|
|
11
|
-
relinka.level = i;
|
|
12
|
-
expect(relinka.level).toBe(i);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
test("silent log level does't print logs", async () => {
|
|
16
|
-
const logs = [];
|
|
17
|
-
const TestReporter = {
|
|
18
|
-
log(logObj) {
|
|
19
|
-
logs.push(logObj);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const relinka = createRelinkaDeprecated({
|
|
23
|
-
throttle: 100,
|
|
24
|
-
level: LogLevelsDeprecated.silent,
|
|
25
|
-
reporters: [TestReporter]
|
|
26
|
-
});
|
|
27
|
-
for (let i = 0; i < 10; i++) {
|
|
28
|
-
relinka.log("SPAM");
|
|
29
|
-
}
|
|
30
|
-
await wait(200);
|
|
31
|
-
expect(logs.length).toBe(0);
|
|
32
|
-
});
|
|
33
|
-
test("can see spams without ending log", async () => {
|
|
34
|
-
const logs = [];
|
|
35
|
-
const TestReporter = {
|
|
36
|
-
log(logObj) {
|
|
37
|
-
logs.push(logObj);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
const relinka = createRelinkaDeprecated({
|
|
41
|
-
throttle: 100,
|
|
42
|
-
level: LogLevelsDeprecated.info,
|
|
43
|
-
reporters: [TestReporter]
|
|
44
|
-
});
|
|
45
|
-
for (let i = 0; i < 10; i++) {
|
|
46
|
-
relinka.log("SPAM");
|
|
47
|
-
}
|
|
48
|
-
await wait(300);
|
|
49
|
-
expect(logs.length).toBe(7);
|
|
50
|
-
expect(logs.at(-1).args).toEqual(["SPAM", "(repeated 4 times)"]);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
function wait(delay) {
|
|
54
|
-
return new Promise((resolve) => {
|
|
55
|
-
setTimeout(resolve, delay);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { RelinkaConfig, LogLevel } from "../core-types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Promise that resolves once c12 loads and merges the config.
|
|
4
|
-
*/
|
|
5
|
-
export declare const relinkaConfig: Promise<RelinkaConfig>;
|
|
6
|
-
/**
|
|
7
|
-
* Logs a message synchronously using the current config.
|
|
8
|
-
* Skips debug-level logs unless `debug` is true in the config.
|
|
9
|
-
*/
|
|
10
|
-
export declare function relinka(type: LogLevel | "clear", message: string, ...args: unknown[]): void;
|
|
11
|
-
/**
|
|
12
|
-
* Logs a message asynchronously, waiting for the config to be fully loaded.
|
|
13
|
-
* Also handles file writing and log cleanup if enabled.
|
|
14
|
-
*/
|
|
15
|
-
export declare function relinkaAsync(type: LogLevel, message: string, ...args: unknown[]): Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* Type helper for user config files.
|
|
18
|
-
*/
|
|
19
|
-
export declare function defineConfig(config: Partial<RelinkaConfig>): Partial<RelinkaConfig>;
|
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
import { re } from "@reliverse/relico";
|
|
2
|
-
import { loadConfig } from "c12";
|
|
3
|
-
import fs from "fs-extra";
|
|
4
|
-
import path from "pathe";
|
|
5
|
-
const DEV_VERBOSE = false;
|
|
6
|
-
const DEFAULT_RELINKA_CONFIG = {
|
|
7
|
-
debug: false,
|
|
8
|
-
dirs: {
|
|
9
|
-
dailyLogs: false,
|
|
10
|
-
logDir: ".reliverse/logs",
|
|
11
|
-
maxLogFiles: 0,
|
|
12
|
-
specialDirs: {
|
|
13
|
-
distDirNames: ["dist", "dist-jsr", "dist-npm", "dist-libs"],
|
|
14
|
-
useParentConfigInDist: true
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
disableColors: false,
|
|
18
|
-
logFilePath: "relinka.log",
|
|
19
|
-
saveLogsToFile: false,
|
|
20
|
-
withTimestamp: false
|
|
21
|
-
};
|
|
22
|
-
let currentConfig = { ...DEFAULT_RELINKA_CONFIG };
|
|
23
|
-
let isConfigInitialized = false;
|
|
24
|
-
let resolveRelinkaConfig;
|
|
25
|
-
export const relinkaConfig = new Promise((resolve) => {
|
|
26
|
-
resolveRelinkaConfig = resolve;
|
|
27
|
-
});
|
|
28
|
-
async function initializeConfig() {
|
|
29
|
-
try {
|
|
30
|
-
const result = await loadConfig({
|
|
31
|
-
name: "relinka",
|
|
32
|
-
// base name => tries relinka.config.*, .relinkarc, etc.
|
|
33
|
-
cwd: process.cwd(),
|
|
34
|
-
// working directory
|
|
35
|
-
dotenv: false,
|
|
36
|
-
packageJson: false,
|
|
37
|
-
rcFile: false,
|
|
38
|
-
globalRc: false,
|
|
39
|
-
defaults: DEFAULT_RELINKA_CONFIG
|
|
40
|
-
// lowest priority
|
|
41
|
-
// overrides: {}, // highest priority if we would need to forcibly override
|
|
42
|
-
});
|
|
43
|
-
currentConfig = result.config;
|
|
44
|
-
isConfigInitialized = true;
|
|
45
|
-
if (DEV_VERBOSE) {
|
|
46
|
-
console.log(
|
|
47
|
-
"[Relinka Config Debug] Config file used:",
|
|
48
|
-
result.configFile
|
|
49
|
-
);
|
|
50
|
-
console.log("[Relinka Config Debug] All merged layers:", result.layers);
|
|
51
|
-
console.log("[Relinka Config Debug] Final configuration:", currentConfig);
|
|
52
|
-
}
|
|
53
|
-
if (resolveRelinkaConfig) {
|
|
54
|
-
resolveRelinkaConfig(currentConfig);
|
|
55
|
-
}
|
|
56
|
-
} catch (err) {
|
|
57
|
-
console.error(
|
|
58
|
-
`[Relinka Config Error] Failed to load config: ${err instanceof Error ? err.message : String(err)}`
|
|
59
|
-
);
|
|
60
|
-
currentConfig = { ...DEFAULT_RELINKA_CONFIG };
|
|
61
|
-
isConfigInitialized = true;
|
|
62
|
-
if (resolveRelinkaConfig) {
|
|
63
|
-
resolveRelinkaConfig(currentConfig);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
initializeConfig().catch((err) => {
|
|
68
|
-
console.error(
|
|
69
|
-
`[Relinka Config Error] Unhandled error: ${err instanceof Error ? err.message : String(err)}`
|
|
70
|
-
);
|
|
71
|
-
if (!isConfigInitialized) {
|
|
72
|
-
currentConfig = { ...DEFAULT_RELINKA_CONFIG };
|
|
73
|
-
isConfigInitialized = true;
|
|
74
|
-
if (resolveRelinkaConfig) {
|
|
75
|
-
resolveRelinkaConfig(currentConfig);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
function isDebugEnabled(config) {
|
|
80
|
-
return config.debug ?? DEFAULT_RELINKA_CONFIG.debug;
|
|
81
|
-
}
|
|
82
|
-
function isColorEnabled(config) {
|
|
83
|
-
return !(config.disableColors ?? DEFAULT_RELINKA_CONFIG.disableColors);
|
|
84
|
-
}
|
|
85
|
-
function getLogDir(config) {
|
|
86
|
-
return config.dirs?.logDir ?? DEFAULT_RELINKA_CONFIG.dirs.logDir;
|
|
87
|
-
}
|
|
88
|
-
function isDailyLogsEnabled(config) {
|
|
89
|
-
return config.dirs?.dailyLogs ?? DEFAULT_RELINKA_CONFIG.dirs.dailyLogs;
|
|
90
|
-
}
|
|
91
|
-
function shouldSaveLogs(config) {
|
|
92
|
-
return config.saveLogsToFile ?? DEFAULT_RELINKA_CONFIG.saveLogsToFile;
|
|
93
|
-
}
|
|
94
|
-
function getMaxLogFiles(config) {
|
|
95
|
-
return config.dirs?.maxLogFiles ?? DEFAULT_RELINKA_CONFIG.dirs.maxLogFiles;
|
|
96
|
-
}
|
|
97
|
-
function getBaseLogName(config) {
|
|
98
|
-
return config.logFilePath ?? DEFAULT_RELINKA_CONFIG.logFilePath;
|
|
99
|
-
}
|
|
100
|
-
function getTimestamp(config) {
|
|
101
|
-
if (!config.withTimestamp) return "";
|
|
102
|
-
const now = /* @__PURE__ */ new Date();
|
|
103
|
-
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(
|
|
104
|
-
now.getMinutes()
|
|
105
|
-
).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}.${String(now.getMilliseconds()).padStart(3, "0")}`;
|
|
106
|
-
}
|
|
107
|
-
function getLogFilePath(config) {
|
|
108
|
-
const logDir = getLogDir(config);
|
|
109
|
-
const daily = isDailyLogsEnabled(config);
|
|
110
|
-
let finalLogName = getBaseLogName(config);
|
|
111
|
-
if (daily) {
|
|
112
|
-
const now = /* @__PURE__ */ new Date();
|
|
113
|
-
const datePrefix = `${now.getFullYear()}-${String(
|
|
114
|
-
now.getMonth() + 1
|
|
115
|
-
).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}-`;
|
|
116
|
-
finalLogName = datePrefix + finalLogName;
|
|
117
|
-
}
|
|
118
|
-
if (finalLogName && !finalLogName.endsWith(".log")) {
|
|
119
|
-
finalLogName += ".log";
|
|
120
|
-
}
|
|
121
|
-
const effectiveLogName = finalLogName || "relinka.log";
|
|
122
|
-
return path.resolve(process.cwd(), logDir, effectiveLogName);
|
|
123
|
-
}
|
|
124
|
-
function formatLogMessage(config, level, msg, details) {
|
|
125
|
-
const timestamp = getTimestamp(config);
|
|
126
|
-
let detailsStr = "";
|
|
127
|
-
if (details !== void 0) {
|
|
128
|
-
if (details instanceof Error) {
|
|
129
|
-
detailsStr = `
|
|
130
|
-
Stack Trace: ${details.stack || details.message}`;
|
|
131
|
-
} else if (typeof details === "object" && details !== null) {
|
|
132
|
-
try {
|
|
133
|
-
detailsStr = ` ${JSON.stringify(details)}`;
|
|
134
|
-
} catch {
|
|
135
|
-
detailsStr = " [object Object]";
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
detailsStr = ` ${String(details)}`;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const paddedLevel = level.padEnd(7, " ");
|
|
142
|
-
return timestamp ? `[${timestamp}] ${paddedLevel} ${msg}${detailsStr}` : `${paddedLevel} ${msg}${detailsStr}`;
|
|
143
|
-
}
|
|
144
|
-
function logToConsole(config, level, formattedMessage) {
|
|
145
|
-
const COLOR_RESET = "\x1B[0m";
|
|
146
|
-
if (!isColorEnabled(config)) {
|
|
147
|
-
if (level === "ERROR") {
|
|
148
|
-
console.error(formattedMessage);
|
|
149
|
-
} else {
|
|
150
|
-
console.log(formattedMessage);
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
153
|
-
switch (level) {
|
|
154
|
-
case "ERROR":
|
|
155
|
-
console.error(re.redBright(formattedMessage) + COLOR_RESET);
|
|
156
|
-
break;
|
|
157
|
-
case "WARN":
|
|
158
|
-
console.warn(re.yellowBright(formattedMessage) + COLOR_RESET);
|
|
159
|
-
break;
|
|
160
|
-
case "SUCCESS":
|
|
161
|
-
console.log(re.greenBright(formattedMessage) + COLOR_RESET);
|
|
162
|
-
break;
|
|
163
|
-
case "INFO":
|
|
164
|
-
console.log(re.cyanBright(formattedMessage) + COLOR_RESET);
|
|
165
|
-
break;
|
|
166
|
-
default:
|
|
167
|
-
console.log(re.dim(formattedMessage) + COLOR_RESET);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
async function getLogFilesSortedByDate(config) {
|
|
172
|
-
const logDirectoryPath = path.resolve(process.cwd(), getLogDir(config));
|
|
173
|
-
if (!await fs.pathExists(logDirectoryPath)) {
|
|
174
|
-
if (isDebugEnabled(config)) {
|
|
175
|
-
console.log(
|
|
176
|
-
`[Relinka FS Debug] Log directory not found: ${logDirectoryPath}`
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
try {
|
|
182
|
-
const files = await fs.readdir(logDirectoryPath);
|
|
183
|
-
const logFilesPromises = files.filter((f) => f.endsWith(".log")).map(async (f) => {
|
|
184
|
-
const filePath = path.join(logDirectoryPath, f);
|
|
185
|
-
try {
|
|
186
|
-
const stats = await fs.stat(filePath);
|
|
187
|
-
if (stats.isFile()) {
|
|
188
|
-
return { path: filePath, mtime: stats.mtime.getTime() };
|
|
189
|
-
}
|
|
190
|
-
return null;
|
|
191
|
-
} catch (err) {
|
|
192
|
-
if (isDebugEnabled(config)) {
|
|
193
|
-
console.error(
|
|
194
|
-
`[Relinka FS Debug] Error reading stats for ${filePath}: ${err instanceof Error ? err.message : String(err)}`
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
const logFiles = (await Promise.all(logFilesPromises)).filter(
|
|
201
|
-
(f) => Boolean(f)
|
|
202
|
-
);
|
|
203
|
-
return logFiles.sort((a, b) => b.mtime - a.mtime);
|
|
204
|
-
} catch (readErr) {
|
|
205
|
-
if (isDebugEnabled(config)) {
|
|
206
|
-
console.error(
|
|
207
|
-
`[Relinka FS Error] Failed reading log directory ${logDirectoryPath}: ${readErr instanceof Error ? readErr.message : String(readErr)}`
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
return [];
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
async function deleteFiles(filePaths, config) {
|
|
214
|
-
await Promise.all(
|
|
215
|
-
filePaths.map(async (filePath) => {
|
|
216
|
-
try {
|
|
217
|
-
await fs.unlink(filePath);
|
|
218
|
-
} catch (err) {
|
|
219
|
-
if (isDebugEnabled(config)) {
|
|
220
|
-
console.error(
|
|
221
|
-
`[Relinka FS Error] Failed to delete log file ${filePath}: ${err instanceof Error ? err.message : String(err)}`
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
async function cleanupOldLogFiles(config) {
|
|
229
|
-
if (!shouldSaveLogs(config) || getMaxLogFiles(config) <= 0) return;
|
|
230
|
-
try {
|
|
231
|
-
const sortedLogFiles = await getLogFilesSortedByDate(config);
|
|
232
|
-
const maxFiles = getMaxLogFiles(config);
|
|
233
|
-
if (sortedLogFiles.length > maxFiles) {
|
|
234
|
-
const filesToDelete = sortedLogFiles.slice(maxFiles).map((f) => f.path);
|
|
235
|
-
if (filesToDelete.length > 0) {
|
|
236
|
-
await deleteFiles(filesToDelete, config);
|
|
237
|
-
if (isDebugEnabled(config)) {
|
|
238
|
-
console.log(
|
|
239
|
-
`[Relinka Cleanup] Deleted ${filesToDelete.length} old log file(s). Kept ${maxFiles}.`
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
} catch (err) {
|
|
245
|
-
if (isDebugEnabled(config)) {
|
|
246
|
-
console.error(
|
|
247
|
-
`[Relinka Cleanup Error] Failed during log cleanup: ${err instanceof Error ? err.message : String(err)}`
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
async function appendToLogFile(config, absoluteLogFilePath, logMessage) {
|
|
253
|
-
try {
|
|
254
|
-
await fs.ensureDir(path.dirname(absoluteLogFilePath));
|
|
255
|
-
await fs.appendFile(absoluteLogFilePath, `${logMessage}
|
|
256
|
-
`);
|
|
257
|
-
} catch (err) {
|
|
258
|
-
if (isDebugEnabled(config)) {
|
|
259
|
-
console.error(
|
|
260
|
-
`[Relinka File Error] Failed to write to log file ${absoluteLogFilePath}: ${err instanceof Error ? err.message : String(err)}`
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
export function relinka(type, message, ...args) {
|
|
266
|
-
if (type === "clear") {
|
|
267
|
-
console.clear();
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
if (message === "") {
|
|
271
|
-
console.log();
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
const logLevelLabel = type === "verbose" ? "DEBUG" : type.toUpperCase();
|
|
275
|
-
if (logLevelLabel === "DEBUG" && !isDebugEnabled(currentConfig)) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
const details = args.length > 1 ? args : args[0];
|
|
279
|
-
const formatted = formatLogMessage(
|
|
280
|
-
currentConfig,
|
|
281
|
-
logLevelLabel,
|
|
282
|
-
message,
|
|
283
|
-
details
|
|
284
|
-
);
|
|
285
|
-
logToConsole(currentConfig, logLevelLabel, formatted);
|
|
286
|
-
}
|
|
287
|
-
export async function relinkaAsync(type, message, ...args) {
|
|
288
|
-
await relinkaConfig;
|
|
289
|
-
if (message === "") {
|
|
290
|
-
console.log();
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const logLevelLabel = type === "verbose" ? "DEBUG" : type.toUpperCase();
|
|
294
|
-
if (logLevelLabel === "DEBUG" && !isDebugEnabled(currentConfig)) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
const details = args.length > 1 ? args : args[0];
|
|
298
|
-
const formatted = formatLogMessage(
|
|
299
|
-
currentConfig,
|
|
300
|
-
logLevelLabel,
|
|
301
|
-
message,
|
|
302
|
-
details
|
|
303
|
-
);
|
|
304
|
-
logToConsole(currentConfig, logLevelLabel, formatted);
|
|
305
|
-
if (shouldSaveLogs(currentConfig)) {
|
|
306
|
-
const absoluteLogFilePath = getLogFilePath(currentConfig);
|
|
307
|
-
try {
|
|
308
|
-
await appendToLogFile(currentConfig, absoluteLogFilePath, formatted);
|
|
309
|
-
await cleanupOldLogFiles(currentConfig);
|
|
310
|
-
} catch (err) {
|
|
311
|
-
if (isDebugEnabled(currentConfig)) {
|
|
312
|
-
console.error(
|
|
313
|
-
`[Relinka File Async Error] Error during file logging/cleanup: ${err instanceof Error ? err.message : String(err)}`
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
export function defineConfig(config) {
|
|
320
|
-
return config;
|
|
321
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|