kailogger 1.0.1-dark.red → 1.0.2
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 +60 -48
- package/dist/core/Logger.d.ts +1 -1
- package/dist/core/Logger.js +36 -39
- package/dist/features/Chart.js +8 -9
- package/dist/features/Diff.js +4 -8
- package/dist/features/Encrypt.js +5 -5
- package/dist/features/Notify.js +40 -1
- package/dist/features/Screenshot.js +0 -3
- package/dist/features/Sound.d.ts +1 -0
- package/dist/features/Sound.js +37 -39
- package/dist/features/Timer.js +3 -7
- package/dist/features/Tree.js +5 -8
- package/dist/icon/logo.png +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -7
- package/dist/sounds/error.wav +0 -0
- package/dist/sounds/notification.wav +0 -0
- package/dist/sounds/success.wav +0 -0
- package/dist/sounds/warning.wav +0 -0
- package/dist/styles/KaiChroma.d.ts +85 -0
- package/dist/styles/KaiChroma.js +407 -0
- package/dist/styles/palettes.d.ts +21 -57
- package/dist/styles/palettes.js +160 -37
- package/dist/transports/ConsoleTransport.js +2 -2
- package/dist/utils/json.js +8 -11
- package/dist/utils/prettyError.js +16 -18
- package/dist/utils/progress.js +5 -7
- package/dist/utils/prompt.js +3 -3
- package/dist/utils/selection.js +14 -24
- package/dist/utils/spinner.d.ts +1 -1
- package/dist/utils/spinner.js +9 -13
- package/dist/utils/stripAnsi.js +2 -1
- package/dist/utils/table.js +4 -7
- package/examples/demo.js +134 -0
- package/package.json +4 -9
- package/scripts/copy-assets.js +37 -0
- package/src/core/Logger.ts +148 -31
- package/src/features/Chart.ts +25 -5
- package/src/features/Diff.ts +2 -2
- package/src/features/Encrypt.ts +13 -5
- package/src/features/Sound.ts +51 -25
- package/src/features/Timer.ts +3 -3
- package/src/features/Tree.ts +6 -5
- package/src/index.ts +1 -1
- package/src/styles/KaiChroma.ts +370 -0
- package/src/styles/palettes.ts +190 -38
- package/src/transports/ConsoleTransport.ts +2 -2
- package/src/utils/json.ts +14 -6
- package/src/utils/prettyError.ts +26 -13
- package/src/utils/progress.ts +19 -5
- package/src/utils/prompt.ts +6 -2
- package/src/utils/selection.ts +40 -17
- package/src/utils/spinner.ts +11 -7
- package/src/utils/stripAnsi.ts +4 -1
- package/src/utils/table.ts +10 -3
- package/src/styles/gradients.ts +0 -22
package/examples/demo.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var src_1 = require("../src");
|
|
40
|
+
var path = require("path");
|
|
41
|
+
function runDemo() {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
43
|
+
return __generator(this, function (_a) {
|
|
44
|
+
switch (_a.label) {
|
|
45
|
+
case 0:
|
|
46
|
+
console.clear();
|
|
47
|
+
src_1.kai.setSoundsDir(path.join(__dirname, '../src/sounds'));
|
|
48
|
+
src_1.kai.box('KaiLogger v1.0.1', 'Now with Charts, Notifications, Screenshots & More!');
|
|
49
|
+
console.log('\n');
|
|
50
|
+
src_1.kai.info('📋 Basic Logging');
|
|
51
|
+
src_1.kai.success('Operation completed');
|
|
52
|
+
src_1.kai.warning('Low memory');
|
|
53
|
+
src_1.kai.error('Connection failed');
|
|
54
|
+
console.log('\n');
|
|
55
|
+
src_1.kai.info('📊 Charts Demo');
|
|
56
|
+
src_1.kai.chart([
|
|
57
|
+
{ label: 'Users', value: 1500 },
|
|
58
|
+
{ label: 'Sales', value: 890 },
|
|
59
|
+
{ label: 'Orders', value: 450 },
|
|
60
|
+
{ label: 'Returns', value: 32 }
|
|
61
|
+
]);
|
|
62
|
+
// Sparkline
|
|
63
|
+
src_1.kai.info('📈 Sparkline (CPU usage over time)');
|
|
64
|
+
src_1.kai.sparkline([10, 25, 30, 15, 45, 60, 55, 70, 85, 60, 40, 30]);
|
|
65
|
+
// Gauge
|
|
66
|
+
console.log('');
|
|
67
|
+
src_1.kai.gauge(75, 100, 'Memory');
|
|
68
|
+
src_1.kai.gauge(45, 100, 'CPU');
|
|
69
|
+
src_1.kai.gauge(95, 100, 'Disk');
|
|
70
|
+
// ===== ENCRYPTION =====
|
|
71
|
+
console.log('\n');
|
|
72
|
+
src_1.kai.info('🔐 Encryption Demo');
|
|
73
|
+
src_1.kai.masked('API Key', 'sk-1234567890abcdef', 4);
|
|
74
|
+
src_1.kai.masked('Password', 'superSecretPassword123', 3);
|
|
75
|
+
src_1.kai.encrypted('This is a secret message!', 'my-secret-key');
|
|
76
|
+
// ===== TREE =====
|
|
77
|
+
console.log('\n');
|
|
78
|
+
src_1.kai.info('🌳 Tree View');
|
|
79
|
+
src_1.kai.tree({
|
|
80
|
+
src: {
|
|
81
|
+
core: { 'Logger.ts': null },
|
|
82
|
+
features: { 'Chart.ts': null, 'Sound.ts': null },
|
|
83
|
+
sounds: { 'success.wav': null, 'error.wav': null }
|
|
84
|
+
},
|
|
85
|
+
'package.json': null
|
|
86
|
+
});
|
|
87
|
+
// ===== TABLE =====
|
|
88
|
+
console.log('\n');
|
|
89
|
+
src_1.kai.info('📉 Table');
|
|
90
|
+
src_1.kai.table([
|
|
91
|
+
{ name: 'Kai', role: 'Admin', status: '🟢' },
|
|
92
|
+
{ name: 'Neo', role: 'User', status: '🟡' },
|
|
93
|
+
{ name: 'Trinity', role: 'Mod', status: '🔴' }
|
|
94
|
+
]);
|
|
95
|
+
// ===== SOUNDS =====
|
|
96
|
+
console.log('\n');
|
|
97
|
+
src_1.kai.info('🔊 Sound Demo');
|
|
98
|
+
src_1.kai.info('Playing success sound...');
|
|
99
|
+
return [4 /*yield*/, src_1.kai.soundSuccess()];
|
|
100
|
+
case 1:
|
|
101
|
+
_a.sent();
|
|
102
|
+
return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, 500); })];
|
|
103
|
+
case 2:
|
|
104
|
+
_a.sent();
|
|
105
|
+
src_1.kai.warning('Playing warning sound...');
|
|
106
|
+
return [4 /*yield*/, src_1.kai.soundWarning()];
|
|
107
|
+
case 3:
|
|
108
|
+
_a.sent();
|
|
109
|
+
return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, 500); })];
|
|
110
|
+
case 4:
|
|
111
|
+
_a.sent();
|
|
112
|
+
src_1.kai.error('Playing error sound...');
|
|
113
|
+
return [4 /*yield*/, src_1.kai.soundError()];
|
|
114
|
+
case 5:
|
|
115
|
+
_a.sent();
|
|
116
|
+
return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, 500); })];
|
|
117
|
+
case 6:
|
|
118
|
+
_a.sent();
|
|
119
|
+
// ===== NOTIFICATION =====
|
|
120
|
+
console.log('\n');
|
|
121
|
+
src_1.kai.info('💬 Sending Desktop Notification...');
|
|
122
|
+
src_1.kai.notify('KaiLogger demo finished!', '✅ Success');
|
|
123
|
+
return [4 /*yield*/, src_1.kai.soundNotification()];
|
|
124
|
+
case 7:
|
|
125
|
+
_a.sent();
|
|
126
|
+
// ===== DONE =====
|
|
127
|
+
console.log('\n');
|
|
128
|
+
src_1.kai.success('✨ Demo complete! KaiLogger v2.1.0 is ready.');
|
|
129
|
+
return [2 /*return*/];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
runDemo();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kailogger",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"main": "dist/index.js",
|
|
14
14
|
"types": "dist/index.d.ts",
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc && node scripts/copy-assets.js",
|
|
17
17
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [],
|
|
20
|
-
"author": "",
|
|
20
|
+
"author": "Soblend Development",
|
|
21
21
|
"license": "ISC",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/crypto-js": "^4.2.2",
|
|
@@ -28,13 +28,8 @@
|
|
|
28
28
|
"typescript": "^5.9.3"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"chalk": "^4.1.2",
|
|
32
|
-
"cli-highlight": "^2.1.11",
|
|
33
31
|
"crypto-js": "^4.2.0",
|
|
34
|
-
"gradient-string": "^3.0.0",
|
|
35
32
|
"node-notifier": "^10.0.1",
|
|
36
|
-
"
|
|
37
|
-
"stack-trace": "^1.0.0-pre2",
|
|
38
|
-
"syntax-error": "^1.4.0"
|
|
33
|
+
"stack-trace": "^1.0.0-pre2"
|
|
39
34
|
}
|
|
40
35
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
6
|
+
const srcDir = path.join(rootDir, 'src');
|
|
7
|
+
const distDir = path.join(rootDir, 'dist');
|
|
8
|
+
|
|
9
|
+
console.log('📦 Copying assets...');
|
|
10
|
+
|
|
11
|
+
// Copy sounds
|
|
12
|
+
const soundsSrc = path.join(srcDir, 'sounds');
|
|
13
|
+
const soundsDist = path.join(distDir, 'sounds');
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(soundsSrc)) {
|
|
16
|
+
if (!fs.existsSync(soundsDist)) fs.mkdirSync(soundsDist, { recursive: true });
|
|
17
|
+
fs.readdirSync(soundsSrc).forEach(file => {
|
|
18
|
+
if (file.endsWith('.wav') || file.endsWith('.mp3')) {
|
|
19
|
+
fs.copyFileSync(path.join(soundsSrc, file), path.join(soundsDist, file));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
console.log(' ✔ Sounds copied');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Copy icon
|
|
26
|
+
const iconSrc = path.join(srcDir, 'icon');
|
|
27
|
+
const iconDist = path.join(distDir, 'icon');
|
|
28
|
+
|
|
29
|
+
if (fs.existsSync(iconSrc)) {
|
|
30
|
+
if (!fs.existsSync(iconDist)) fs.mkdirSync(iconDist, { recursive: true });
|
|
31
|
+
fs.readdirSync(iconSrc).forEach(file => {
|
|
32
|
+
fs.copyFileSync(path.join(iconSrc, file), path.join(iconDist, file));
|
|
33
|
+
});
|
|
34
|
+
console.log(' ✔ Icon copied');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log('✨ Build assets complete');
|
package/src/core/Logger.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
-
import { paint } from '../styles/
|
|
3
|
+
import { paint, palettes, ThemeName } from '../styles/palettes';
|
|
4
|
+
import { KaiChroma } from '../styles/KaiChroma';
|
|
4
5
|
import { KaiSpinner } from '../utils/spinner';
|
|
5
6
|
import { KaiProgress } from '../utils/progress';
|
|
6
7
|
import { KaiTable } from '../utils/table';
|
|
@@ -9,7 +10,6 @@ import { KaiSelection } from '../utils/selection';
|
|
|
9
10
|
import { KaiJson } from '../utils/json';
|
|
10
11
|
import { PrettyError } from '../utils/prettyError';
|
|
11
12
|
import { stripAnsi } from '../utils/stripAnsi';
|
|
12
|
-
import { ThemeName, palettes } from '../styles/palettes';
|
|
13
13
|
import { config } from './Config';
|
|
14
14
|
import { ScopedLogger } from './Scope';
|
|
15
15
|
import { KaiTimer } from '../features/Timer';
|
|
@@ -31,16 +31,19 @@ interface LoggerOptions {
|
|
|
31
31
|
silent?: boolean;
|
|
32
32
|
timestamp?: 'ISO' | 'locale' | 'relative' | 'none';
|
|
33
33
|
}
|
|
34
|
+
|
|
34
35
|
export class KaiLogger {
|
|
35
36
|
private spinner = new KaiSpinner();
|
|
36
37
|
private timer = new KaiTimer();
|
|
37
38
|
private logFilePath?: string;
|
|
38
39
|
private buffer: string[] = [];
|
|
39
40
|
private startTime: number = Date.now();
|
|
41
|
+
|
|
40
42
|
public theme: ThemeName;
|
|
41
43
|
public level: LogLevel;
|
|
42
44
|
public silent: boolean;
|
|
43
45
|
public timestampFormat: 'ISO' | 'locale' | 'relative' | 'none';
|
|
46
|
+
|
|
44
47
|
constructor(options: LoggerOptions | ThemeName = 'zen') {
|
|
45
48
|
if (typeof options === 'string') {
|
|
46
49
|
this.theme = options;
|
|
@@ -56,6 +59,9 @@ export class KaiLogger {
|
|
|
56
59
|
}
|
|
57
60
|
paint.setTheme(this.theme);
|
|
58
61
|
}
|
|
62
|
+
|
|
63
|
+
// ========== CONFIGURATION ==========
|
|
64
|
+
|
|
59
65
|
public configure(options: Partial<LoggerOptions>): void {
|
|
60
66
|
if (options.theme) this.setTheme(options.theme);
|
|
61
67
|
if (options.level) this.level = options.level;
|
|
@@ -63,31 +69,47 @@ export class KaiLogger {
|
|
|
63
69
|
if (options.silent !== undefined) this.silent = options.silent;
|
|
64
70
|
if (options.timestamp) this.timestampFormat = options.timestamp;
|
|
65
71
|
}
|
|
72
|
+
|
|
66
73
|
public setTheme(theme: ThemeName): void {
|
|
67
74
|
this.theme = theme;
|
|
68
75
|
paint.setTheme(theme);
|
|
69
76
|
}
|
|
77
|
+
|
|
70
78
|
public setLevel(level: LogLevel): void {
|
|
71
79
|
this.level = level;
|
|
72
80
|
}
|
|
81
|
+
|
|
73
82
|
public setSilent(silent: boolean): void {
|
|
74
83
|
this.silent = silent;
|
|
75
84
|
}
|
|
85
|
+
|
|
86
|
+
// ========== TRANSPORTS ==========
|
|
87
|
+
|
|
76
88
|
public addFileTransport(options: FileTransportOptions): void {
|
|
77
89
|
config.addTransport(new FileTransport(options));
|
|
78
90
|
}
|
|
91
|
+
|
|
79
92
|
public addWebhookTransport(options: WebhookTransportOptions): void {
|
|
80
93
|
config.addTransport(new WebhookTransport(options));
|
|
81
94
|
}
|
|
95
|
+
|
|
82
96
|
public removeTransport(name: string): void {
|
|
83
97
|
config.removeTransport(name);
|
|
84
98
|
}
|
|
99
|
+
|
|
100
|
+
// ========== SCOPED LOGGERS ==========
|
|
101
|
+
|
|
85
102
|
public scope(name: string): ScopedLogger {
|
|
86
103
|
return new ScopedLogger(this, name);
|
|
87
104
|
}
|
|
105
|
+
|
|
106
|
+
// ========== TIMESTAMPS ==========
|
|
107
|
+
|
|
88
108
|
private getTime(): string {
|
|
89
109
|
if (this.timestampFormat === 'none') return '';
|
|
110
|
+
|
|
90
111
|
const now = new Date();
|
|
112
|
+
|
|
91
113
|
switch (this.timestampFormat) {
|
|
92
114
|
case 'ISO':
|
|
93
115
|
return `[${now.toISOString()}]`;
|
|
@@ -100,238 +122,333 @@ export class KaiLogger {
|
|
|
100
122
|
return `[${now.toLocaleTimeString()}]`;
|
|
101
123
|
}
|
|
102
124
|
}
|
|
125
|
+
|
|
126
|
+
// ========== LEVEL CHECKING ==========
|
|
127
|
+
|
|
103
128
|
private shouldLog(level: LogLevel): boolean {
|
|
104
129
|
if (this.silent) return false;
|
|
105
130
|
return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.level];
|
|
106
131
|
}
|
|
132
|
+
|
|
133
|
+
// ========== FILE & TRANSPORT LOGGING ==========
|
|
134
|
+
|
|
107
135
|
private logToFile(level: string, message: string): void {
|
|
108
136
|
if (this.logFilePath) {
|
|
109
137
|
const cleanMsg = stripAnsi(message);
|
|
110
138
|
const logLine = `${this.getTime()} [${level.toUpperCase()}] ${cleanMsg}\n`;
|
|
111
139
|
fs.appendFileSync(this.logFilePath, logLine);
|
|
112
140
|
}
|
|
141
|
+
|
|
113
142
|
const transports = config.get('transports') || [];
|
|
114
143
|
transports.forEach(t => t.log(level as LogLevel, message));
|
|
115
144
|
}
|
|
145
|
+
|
|
116
146
|
private addToBuffer(level: string, message: string): void {
|
|
117
147
|
this.buffer.push(`${this.getTime()} [${level.toUpperCase()}] ${message}`);
|
|
118
148
|
}
|
|
149
|
+
|
|
119
150
|
public getBuffer(): string[] {
|
|
120
151
|
return [...this.buffer];
|
|
121
152
|
}
|
|
153
|
+
|
|
122
154
|
public clearBuffer(): void {
|
|
123
155
|
this.buffer = [];
|
|
124
156
|
}
|
|
157
|
+
|
|
158
|
+
// ========== CORE LOGGING ==========
|
|
159
|
+
|
|
125
160
|
private print(level: LogLevel, label: string, message: string, ...args: any[]): void {
|
|
126
161
|
if (!this.shouldLog(level)) {
|
|
127
162
|
this.addToBuffer(level, message);
|
|
128
163
|
return;
|
|
129
164
|
}
|
|
165
|
+
|
|
130
166
|
this.stopSpinner();
|
|
131
|
-
|
|
132
|
-
const
|
|
167
|
+
// Accedemos safe a paint.colors[level]
|
|
168
|
+
const colors = (paint.colors as any)[level] as string[];
|
|
169
|
+
const time = this.timestampFormat !== 'none' ? KaiChroma.hex('#666666', this.getTime()) + ' ' : '';
|
|
133
170
|
const badge = paint.apply(` ${label.padEnd(7)} `, colors);
|
|
134
171
|
const output = `${time}${badge} ${message}`;
|
|
172
|
+
|
|
135
173
|
console.log(output, ...args);
|
|
174
|
+
|
|
136
175
|
const fileMsg = [message, ...args.map(a => typeof a === 'object' ? JSON.stringify(a) : a)].join(' ');
|
|
137
176
|
this.logToFile(level, fileMsg);
|
|
138
177
|
this.addToBuffer(level, fileMsg);
|
|
139
178
|
}
|
|
179
|
+
|
|
140
180
|
public success(message: string, ...args: any[]): void {
|
|
141
181
|
this.print('success', '✔ SUCCESS', message, ...args);
|
|
142
182
|
}
|
|
183
|
+
|
|
143
184
|
public error(message: string | Error, ...args: any[]): void {
|
|
144
185
|
if (!this.shouldLog('error')) return;
|
|
186
|
+
|
|
145
187
|
if (message instanceof Error) {
|
|
146
188
|
this.stopSpinner();
|
|
147
|
-
PrettyError.handle(message,
|
|
189
|
+
PrettyError.handle(message, paint.colors);
|
|
148
190
|
this.logToFile('error', message.toString());
|
|
149
191
|
this.addToBuffer('error', message.toString());
|
|
150
192
|
} else {
|
|
151
193
|
this.print('error', '✖ ERROR', message, ...args);
|
|
152
194
|
}
|
|
153
195
|
}
|
|
196
|
+
|
|
154
197
|
public warning(message: string, ...args: any[]): void {
|
|
155
198
|
this.print('warning', '⚠ WARN', message, ...args);
|
|
156
199
|
}
|
|
200
|
+
|
|
157
201
|
public info(message: string, ...args: any[]): void {
|
|
158
202
|
this.print('info', 'ℹ INFO', message, ...args);
|
|
159
203
|
}
|
|
204
|
+
|
|
160
205
|
public debug(message: string, ...args: any[]): void {
|
|
161
206
|
this.print('debug', '⚙ DEBUG', message, ...args);
|
|
162
207
|
}
|
|
208
|
+
|
|
163
209
|
public log(message: string): void {
|
|
164
210
|
if (this.silent) return;
|
|
165
211
|
this.stopSpinner();
|
|
166
|
-
const time = this.timestampFormat !== 'none' ?
|
|
212
|
+
const time = this.timestampFormat !== 'none' ? KaiChroma.hex('#666666', this.getTime()) + ' ' : '';
|
|
167
213
|
console.log(`${time}${message}`);
|
|
168
214
|
this.logToFile('log', message);
|
|
169
215
|
}
|
|
216
|
+
|
|
217
|
+
// ========== CUSTOM BADGE ==========
|
|
218
|
+
|
|
170
219
|
public custom(badge: string, color: string, message: string, ...args: any[]): void {
|
|
171
220
|
if (this.silent) return;
|
|
172
221
|
this.stopSpinner();
|
|
173
|
-
const time = this.timestampFormat !== 'none' ?
|
|
174
|
-
const styledBadge =
|
|
222
|
+
const time = this.timestampFormat !== 'none' ? KaiChroma.hex('#666666', this.getTime()) + ' ' : '';
|
|
223
|
+
const styledBadge = KaiChroma.bgHex(color, ` ${badge.toUpperCase().padEnd(7)} `);
|
|
175
224
|
console.log(`${time}${styledBadge} ${message}`, ...args);
|
|
176
225
|
this.logToFile(badge, message);
|
|
177
226
|
}
|
|
227
|
+
|
|
228
|
+
// ========== BOX ==========
|
|
229
|
+
|
|
178
230
|
public box(title: string, message: string): void {
|
|
179
231
|
if (this.silent) return;
|
|
180
232
|
this.stopSpinner();
|
|
181
233
|
const width = Math.max(message.length, title.length) + 4;
|
|
182
|
-
const border = paint.apply('─'.repeat(width), paint.
|
|
183
|
-
const topLeft = paint.apply('╭', paint.
|
|
184
|
-
const topRight = paint.apply('╮', paint.
|
|
185
|
-
const bottomLeft = paint.apply('╰', paint.
|
|
186
|
-
const bottomRight = paint.apply('╯', paint.
|
|
187
|
-
const side = paint.apply('│', paint.
|
|
234
|
+
const border = paint.apply('─'.repeat(width), paint.colors.info);
|
|
235
|
+
const topLeft = paint.apply('╭', paint.colors.info);
|
|
236
|
+
const topRight = paint.apply('╮', paint.colors.info);
|
|
237
|
+
const bottomLeft = paint.apply('╰', paint.colors.info);
|
|
238
|
+
const bottomRight = paint.apply('╯', paint.colors.info);
|
|
239
|
+
const side = paint.apply('│', paint.colors.info);
|
|
240
|
+
|
|
188
241
|
console.log(`${topLeft}${border}${topRight}`);
|
|
189
|
-
console.log(`${side} ${paint.apply(title.padEnd(width - 2), paint.
|
|
190
|
-
console.log(`${side}${paint.apply('─'.repeat(width), paint.
|
|
242
|
+
console.log(`${side} ${paint.apply(title.padEnd(width - 2), paint.colors.success)} ${side}`);
|
|
243
|
+
console.log(`${side}${paint.apply('─'.repeat(width), paint.colors.debug)}${side}`);
|
|
191
244
|
console.log(`${side} ${message.padEnd(width - 2)} ${side}`);
|
|
192
245
|
console.log(`${bottomLeft}${border}${bottomRight}`);
|
|
246
|
+
|
|
193
247
|
this.logToFile('box', `${title}: ${message}`);
|
|
194
248
|
}
|
|
249
|
+
|
|
250
|
+
// ========== SPINNER ==========
|
|
251
|
+
|
|
195
252
|
public await(message: string): void {
|
|
196
253
|
if (this.silent) return;
|
|
197
|
-
this.spinner.start(message, paint.
|
|
254
|
+
this.spinner.start(message, paint.colors.info[0]);
|
|
198
255
|
}
|
|
256
|
+
|
|
199
257
|
public stop(message?: string): void {
|
|
200
|
-
this.spinner.stop('✔', message, paint.
|
|
258
|
+
this.spinner.stop('✔', message, paint.colors.success[1]);
|
|
201
259
|
if (message) this.logToFile('stop', message);
|
|
202
260
|
}
|
|
261
|
+
|
|
203
262
|
private stopSpinner(): void {
|
|
263
|
+
this.spinner.stop();
|
|
204
264
|
}
|
|
265
|
+
|
|
266
|
+
// ========== PROGRESS ==========
|
|
267
|
+
|
|
205
268
|
public createProgress(total: number, width?: number): KaiProgress {
|
|
206
269
|
return new KaiProgress(total, width, this.theme);
|
|
207
270
|
}
|
|
271
|
+
|
|
272
|
+
// ========== TABLE ==========
|
|
273
|
+
|
|
208
274
|
public table(data: any[]): void {
|
|
209
275
|
if (this.silent) return;
|
|
210
276
|
this.stopSpinner();
|
|
211
|
-
KaiTable.print(data,
|
|
277
|
+
KaiTable.print(data, paint.colors);
|
|
212
278
|
this.logToFile('table', JSON.stringify(data));
|
|
213
279
|
}
|
|
280
|
+
|
|
281
|
+
// ========== JSON ==========
|
|
282
|
+
|
|
214
283
|
public json(data: any): void {
|
|
215
284
|
if (this.silent) return;
|
|
216
285
|
this.stopSpinner();
|
|
217
|
-
KaiJson.print(data,
|
|
286
|
+
KaiJson.print(data, paint.colors);
|
|
218
287
|
this.logToFile('json', JSON.stringify(data));
|
|
219
288
|
}
|
|
289
|
+
|
|
290
|
+
// ========== TREE ==========
|
|
291
|
+
|
|
220
292
|
public tree(data: any): void {
|
|
221
293
|
if (this.silent) return;
|
|
222
294
|
this.stopSpinner();
|
|
223
|
-
KaiTree.print(data,
|
|
295
|
+
KaiTree.print(data, paint.colors);
|
|
224
296
|
this.logToFile('tree', JSON.stringify(data));
|
|
225
297
|
}
|
|
298
|
+
|
|
299
|
+
// ========== DIFF ==========
|
|
300
|
+
|
|
226
301
|
public diff(before: any, after: any): void {
|
|
227
302
|
if (this.silent) return;
|
|
228
303
|
this.stopSpinner();
|
|
229
|
-
KaiDiff.print(before, after,
|
|
304
|
+
KaiDiff.print(before, after, paint.colors);
|
|
230
305
|
this.logToFile('diff', JSON.stringify({ before, after }));
|
|
231
306
|
}
|
|
307
|
+
|
|
308
|
+
// ========== TIMER ==========
|
|
309
|
+
|
|
232
310
|
public time(label: string): void {
|
|
233
311
|
this.timer.time(label);
|
|
234
312
|
}
|
|
313
|
+
|
|
235
314
|
public timeEnd(label: string): number | null {
|
|
236
315
|
if (this.silent) return null;
|
|
237
|
-
return this.timer.timeEnd(label,
|
|
316
|
+
return this.timer.timeEnd(label, paint.colors);
|
|
238
317
|
}
|
|
318
|
+
|
|
319
|
+
// ========== PROMPTS ==========
|
|
320
|
+
|
|
239
321
|
public async ask(question: string): Promise<string> {
|
|
240
322
|
this.stopSpinner();
|
|
241
|
-
|
|
323
|
+
// Pasamos theme.info colors, asumimos que prompt maneja esto
|
|
324
|
+
const answer = await KaiPrompt.ask(question, paint.colors);
|
|
242
325
|
this.logToFile('ask', `${question} -> ${answer}`);
|
|
243
326
|
return answer;
|
|
244
327
|
}
|
|
328
|
+
|
|
245
329
|
public async confirm(question: string): Promise<boolean> {
|
|
246
330
|
this.stopSpinner();
|
|
247
|
-
const answer = await KaiPrompt.confirm(question,
|
|
331
|
+
const answer = await KaiPrompt.confirm(question, paint.colors);
|
|
248
332
|
this.logToFile('confirm', `${question} -> ${answer}`);
|
|
249
333
|
return answer;
|
|
250
334
|
}
|
|
335
|
+
|
|
251
336
|
public async select(question: string, options: string[]): Promise<string> {
|
|
252
337
|
this.stopSpinner();
|
|
253
|
-
const answer = await KaiSelection.select(question, options,
|
|
338
|
+
const answer = await KaiSelection.select(question, options, paint.colors);
|
|
254
339
|
this.logToFile('select', `${question} -> ${answer}`);
|
|
255
340
|
return answer;
|
|
256
341
|
}
|
|
342
|
+
|
|
257
343
|
public async multiselect(question: string, options: string[]): Promise<string[]> {
|
|
258
344
|
this.stopSpinner();
|
|
259
|
-
const answer = await KaiSelection.multiselect(question, options,
|
|
345
|
+
const answer = await KaiSelection.multiselect(question, options, paint.colors);
|
|
260
346
|
this.logToFile('multiselect', `${question} -> ${answer.join(', ')}`);
|
|
261
347
|
return answer;
|
|
262
348
|
}
|
|
349
|
+
|
|
350
|
+
// ========== CHARTS ==========
|
|
351
|
+
|
|
263
352
|
public chart(data: { label: string; value: number }[], options?: { width?: number; showValues?: boolean }): void {
|
|
264
353
|
if (this.silent) return;
|
|
265
354
|
this.stopSpinner();
|
|
266
|
-
KaiChart.bar(data,
|
|
355
|
+
KaiChart.bar(data, paint.colors, options);
|
|
267
356
|
}
|
|
357
|
+
|
|
268
358
|
public sparkline(values: number[]): void {
|
|
269
359
|
if (this.silent) return;
|
|
270
360
|
this.stopSpinner();
|
|
271
|
-
KaiChart.sparkline(values,
|
|
361
|
+
KaiChart.sparkline(values, paint.colors);
|
|
272
362
|
}
|
|
363
|
+
|
|
273
364
|
public gauge(value: number, max: number, label?: string): void {
|
|
274
365
|
if (this.silent) return;
|
|
275
366
|
this.stopSpinner();
|
|
276
|
-
KaiChart.gauge(value, max,
|
|
367
|
+
KaiChart.gauge(value, max, paint.colors, label);
|
|
277
368
|
}
|
|
369
|
+
|
|
370
|
+
// ========== NOTIFICATIONS ==========
|
|
371
|
+
|
|
278
372
|
public notify(message: string, title?: string): void {
|
|
279
373
|
KaiNotify.send({ message, title });
|
|
280
374
|
}
|
|
375
|
+
|
|
281
376
|
public notifySuccess(message: string): void {
|
|
282
377
|
KaiNotify.success(message);
|
|
283
378
|
}
|
|
379
|
+
|
|
284
380
|
public notifyError(message: string): void {
|
|
285
381
|
KaiNotify.error(message);
|
|
286
382
|
}
|
|
383
|
+
|
|
384
|
+
// ========== SCREENSHOT ==========
|
|
385
|
+
|
|
287
386
|
public startCapture(): void {
|
|
288
387
|
KaiScreenshot.startCapture();
|
|
289
388
|
}
|
|
389
|
+
|
|
290
390
|
public stopCapture(): string[] {
|
|
291
391
|
return KaiScreenshot.stopCapture();
|
|
292
392
|
}
|
|
393
|
+
|
|
293
394
|
public saveScreenshot(filename: string): void {
|
|
294
395
|
KaiScreenshot.save(filename);
|
|
295
396
|
}
|
|
397
|
+
|
|
296
398
|
public saveScreenshotHtml(filename: string): void {
|
|
297
399
|
KaiScreenshot.saveHtml(filename);
|
|
298
400
|
}
|
|
401
|
+
|
|
402
|
+
// ========== ENCRYPTION ==========
|
|
403
|
+
|
|
299
404
|
public setEncryptionKey(key: string): void {
|
|
300
405
|
KaiEncrypt.setDefaultKey(key);
|
|
301
406
|
}
|
|
407
|
+
|
|
302
408
|
public encrypted(message: string, key?: string): void {
|
|
303
409
|
if (this.silent) return;
|
|
304
410
|
this.stopSpinner();
|
|
305
411
|
KaiEncrypt.printEncrypted(message, key);
|
|
306
412
|
}
|
|
413
|
+
|
|
307
414
|
public decrypted(encryptedMessage: string, key?: string): void {
|
|
308
415
|
if (this.silent) return;
|
|
309
416
|
this.stopSpinner();
|
|
310
417
|
KaiEncrypt.printDecrypted(encryptedMessage, key);
|
|
311
418
|
}
|
|
419
|
+
|
|
312
420
|
public masked(label: string, value: string, showLast?: number): void {
|
|
313
421
|
if (this.silent) return;
|
|
314
422
|
this.stopSpinner();
|
|
315
423
|
KaiEncrypt.printMasked(label, value, showLast);
|
|
316
424
|
}
|
|
425
|
+
|
|
426
|
+
// ========== SOUNDS ==========
|
|
427
|
+
|
|
317
428
|
public setSoundsDir(dir: string): void {
|
|
318
429
|
KaiSound.setSoundsDir(dir);
|
|
319
430
|
}
|
|
431
|
+
|
|
320
432
|
public beep(): void {
|
|
321
433
|
KaiSound.beep();
|
|
322
434
|
}
|
|
435
|
+
|
|
323
436
|
public async soundSuccess(): Promise<void> {
|
|
324
437
|
await KaiSound.success();
|
|
325
438
|
}
|
|
439
|
+
|
|
326
440
|
public async soundError(): Promise<void> {
|
|
327
441
|
await KaiSound.error();
|
|
328
442
|
}
|
|
443
|
+
|
|
329
444
|
public async soundWarning(): Promise<void> {
|
|
330
445
|
await KaiSound.warning();
|
|
331
446
|
}
|
|
447
|
+
|
|
332
448
|
public async soundNotification(): Promise<void> {
|
|
333
449
|
await KaiSound.notification();
|
|
334
450
|
}
|
|
451
|
+
|
|
335
452
|
public async playSound(filename: string): Promise<void> {
|
|
336
453
|
await KaiSound.play(filename);
|
|
337
454
|
}
|