@vue-skuilder/common 0.1.20 → 0.1.21
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/dist/logger.d.ts +52 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +201 -1
- package/dist/logger.js.map +1 -1
- package/dist/logger.mjs +163 -0
- package/package.json +2 -2
- package/src/logger.ts +184 -1
package/dist/logger.d.ts
CHANGED
|
@@ -27,4 +27,56 @@ export declare const consoleLogger: SkLogger;
|
|
|
27
27
|
* Appends logs to a file with timestamps
|
|
28
28
|
*/
|
|
29
29
|
export declare function createFileLogger(filePath: string): SkLogger;
|
|
30
|
+
/**
|
|
31
|
+
* Initialize TUI logging - redirect console logs to file in Node.js
|
|
32
|
+
*
|
|
33
|
+
* This function should be called once at the entry point of CLI applications
|
|
34
|
+
* to redirect all console output to a log file, preventing interference with
|
|
35
|
+
* interactive prompts (inquirer, etc).
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* import { initializeTuiLogging } from '@vue-skuilder/common';
|
|
39
|
+
* initializeTuiLogging();
|
|
40
|
+
*/
|
|
41
|
+
export declare function initializeTuiLogging(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get the current log file path (for debugging)
|
|
44
|
+
* @returns Path to current log file, or null if not initialized
|
|
45
|
+
*/
|
|
46
|
+
export declare function getLogFilePath(): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Show user-facing message (always visible in TUI)
|
|
49
|
+
*
|
|
50
|
+
* This bypasses log redirection to ensure the message appears in the terminal.
|
|
51
|
+
* Use this for important user-facing messages in CLI applications.
|
|
52
|
+
*
|
|
53
|
+
* @param message - Message to display to user
|
|
54
|
+
*/
|
|
55
|
+
export declare function showUserMessage(message: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Show user-facing error (always visible in TUI)
|
|
58
|
+
*
|
|
59
|
+
* This bypasses log redirection to ensure the error appears in the terminal.
|
|
60
|
+
* Use this for critical errors that users must see in CLI applications.
|
|
61
|
+
*
|
|
62
|
+
* @param message - Error message to display to user
|
|
63
|
+
*/
|
|
64
|
+
export declare function showUserError(message: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* TUI-aware logger instance
|
|
67
|
+
*
|
|
68
|
+
* This logger object respects TUI logging initialization. When initializeTuiLogging()
|
|
69
|
+
* has been called, log output is redirected to file. Otherwise, it outputs to console.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* import { initializeTuiLogging, tuiLogger } from '@vue-skuilder/common';
|
|
73
|
+
* initializeTuiLogging();
|
|
74
|
+
* tuiLogger.info('Application started');
|
|
75
|
+
*/
|
|
76
|
+
export declare const tuiLogger: {
|
|
77
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
78
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
79
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
80
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
81
|
+
};
|
|
30
82
|
//# sourceMappingURL=logger.d.ts.map
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,QAKxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,QAK3B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAkC3D"}
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,QAKxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,QAK3B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAkC3D;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CA0E3C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASrD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASnD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS;qBACH,MAAM,WAAW,OAAO,EAAE;oBAI3B,MAAM,WAAW,OAAO,EAAE;oBAI1B,MAAM,WAAW,OAAO,EAAE;qBAIzB,MAAM,WAAW,OAAO,EAAE;CAI5C,CAAC"}
|
package/dist/logger.js
CHANGED
|
@@ -1,7 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.consoleLogger = exports.noOpLogger = void 0;
|
|
36
|
+
exports.tuiLogger = exports.consoleLogger = exports.noOpLogger = void 0;
|
|
4
37
|
exports.createFileLogger = createFileLogger;
|
|
38
|
+
exports.initializeTuiLogging = initializeTuiLogging;
|
|
39
|
+
exports.getLogFilePath = getLogFilePath;
|
|
40
|
+
exports.showUserMessage = showUserMessage;
|
|
41
|
+
exports.showUserError = showUserError;
|
|
5
42
|
/**
|
|
6
43
|
* No-op logger implementation for contexts where logging is not needed
|
|
7
44
|
*/
|
|
@@ -56,4 +93,167 @@ function createFileLogger(filePath) {
|
|
|
56
93
|
error: (message, ...args) => writeLog('ERROR', message, ...args),
|
|
57
94
|
};
|
|
58
95
|
}
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// TUI-aware logging utilities - redirects console output to file in Node.js
|
|
98
|
+
// ============================================================================
|
|
99
|
+
const fs = __importStar(require("fs"));
|
|
100
|
+
const path = __importStar(require("path"));
|
|
101
|
+
const os = __importStar(require("os"));
|
|
102
|
+
// TUI-aware logging state
|
|
103
|
+
let tuiLogFile = null;
|
|
104
|
+
let tuiIsNodeEnvironment = false;
|
|
105
|
+
/**
|
|
106
|
+
* Get the application data directory for TUI logging
|
|
107
|
+
* Uses ~/.tuilder for cross-platform compatibility
|
|
108
|
+
*/
|
|
109
|
+
function getTuiLogDirectory() {
|
|
110
|
+
return path.join(os.homedir(), '.tuilder');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Initialize TUI logging - redirect console logs to file in Node.js
|
|
114
|
+
*
|
|
115
|
+
* This function should be called once at the entry point of CLI applications
|
|
116
|
+
* to redirect all console output to a log file, preventing interference with
|
|
117
|
+
* interactive prompts (inquirer, etc).
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* import { initializeTuiLogging } from '@vue-skuilder/common';
|
|
121
|
+
* initializeTuiLogging();
|
|
122
|
+
*/
|
|
123
|
+
function initializeTuiLogging() {
|
|
124
|
+
// Detect Node.js environment
|
|
125
|
+
tuiIsNodeEnvironment = typeof window === 'undefined' && typeof process !== 'undefined';
|
|
126
|
+
if (!tuiIsNodeEnvironment) {
|
|
127
|
+
return; // Browser environment - keep normal console logging
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
// Set up log file path
|
|
131
|
+
const logDir = getTuiLogDirectory();
|
|
132
|
+
// Ensure log directory exists
|
|
133
|
+
if (!fs.existsSync(logDir)) {
|
|
134
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
135
|
+
}
|
|
136
|
+
tuiLogFile = path.join(logDir, 'lastrun.log');
|
|
137
|
+
// Clear previous log file
|
|
138
|
+
if (fs.existsSync(tuiLogFile)) {
|
|
139
|
+
fs.unlinkSync(tuiLogFile);
|
|
140
|
+
}
|
|
141
|
+
// Create initial log entry
|
|
142
|
+
const startTime = new Date().toISOString();
|
|
143
|
+
fs.writeFileSync(tuiLogFile, `=== TUI Session Started: ${startTime} ===\n`);
|
|
144
|
+
// Redirect console methods to file
|
|
145
|
+
const originalConsole = {
|
|
146
|
+
// eslint-disable-next-line no-console
|
|
147
|
+
log: console.log,
|
|
148
|
+
// eslint-disable-next-line no-console
|
|
149
|
+
error: console.error,
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
warn: console.warn,
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
info: console.info
|
|
154
|
+
};
|
|
155
|
+
const writeToLog = (level, args) => {
|
|
156
|
+
const timestamp = new Date().toISOString();
|
|
157
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)).join(' ');
|
|
158
|
+
const logEntry = `[${timestamp}] ${level}: ${message}\n`;
|
|
159
|
+
try {
|
|
160
|
+
fs.appendFileSync(tuiLogFile, logEntry);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Fallback to original console if file write fails
|
|
164
|
+
originalConsole.error('Failed to write to log file:', err);
|
|
165
|
+
originalConsole[level.toLowerCase()](...args);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
// Override console methods
|
|
169
|
+
// eslint-disable-next-line no-console
|
|
170
|
+
console.log = (...args) => writeToLog('INFO', args);
|
|
171
|
+
// eslint-disable-next-line no-console
|
|
172
|
+
console.info = (...args) => writeToLog('INFO', args);
|
|
173
|
+
// eslint-disable-next-line no-console
|
|
174
|
+
console.warn = (...args) => writeToLog('WARN', args);
|
|
175
|
+
// eslint-disable-next-line no-console
|
|
176
|
+
console.error = (...args) => writeToLog('ERROR', args);
|
|
177
|
+
// eslint-disable-next-line no-console
|
|
178
|
+
console.log('TUI logging initialized - logs redirected to', tuiLogFile);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
// eslint-disable-next-line no-console
|
|
182
|
+
console.error('Failed to initialize TUI logging:', err);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get the current log file path (for debugging)
|
|
187
|
+
* @returns Path to current log file, or null if not initialized
|
|
188
|
+
*/
|
|
189
|
+
function getLogFilePath() {
|
|
190
|
+
return tuiLogFile;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Show user-facing message (always visible in TUI)
|
|
194
|
+
*
|
|
195
|
+
* This bypasses log redirection to ensure the message appears in the terminal.
|
|
196
|
+
* Use this for important user-facing messages in CLI applications.
|
|
197
|
+
*
|
|
198
|
+
* @param message - Message to display to user
|
|
199
|
+
*/
|
|
200
|
+
function showUserMessage(message) {
|
|
201
|
+
if (tuiIsNodeEnvironment) {
|
|
202
|
+
// In Node.js, write directly to stdout to bypass log redirection
|
|
203
|
+
process.stdout.write(message + '\n');
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// In browser, use normal console
|
|
207
|
+
// eslint-disable-next-line no-console
|
|
208
|
+
console.log(message);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Show user-facing error (always visible in TUI)
|
|
213
|
+
*
|
|
214
|
+
* This bypasses log redirection to ensure the error appears in the terminal.
|
|
215
|
+
* Use this for critical errors that users must see in CLI applications.
|
|
216
|
+
*
|
|
217
|
+
* @param message - Error message to display to user
|
|
218
|
+
*/
|
|
219
|
+
function showUserError(message) {
|
|
220
|
+
if (tuiIsNodeEnvironment) {
|
|
221
|
+
// In Node.js, write directly to stderr to bypass log redirection
|
|
222
|
+
process.stderr.write('Error: ' + message + '\n');
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// In browser, use normal console
|
|
226
|
+
// eslint-disable-next-line no-console
|
|
227
|
+
console.error(message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* TUI-aware logger instance
|
|
232
|
+
*
|
|
233
|
+
* This logger object respects TUI logging initialization. When initializeTuiLogging()
|
|
234
|
+
* has been called, log output is redirected to file. Otherwise, it outputs to console.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* import { initializeTuiLogging, tuiLogger } from '@vue-skuilder/common';
|
|
238
|
+
* initializeTuiLogging();
|
|
239
|
+
* tuiLogger.info('Application started');
|
|
240
|
+
*/
|
|
241
|
+
exports.tuiLogger = {
|
|
242
|
+
debug: (message, ...args) => {
|
|
243
|
+
// eslint-disable-next-line no-console
|
|
244
|
+
console.log(`[DEBUG] ${message}`, ...args);
|
|
245
|
+
},
|
|
246
|
+
info: (message, ...args) => {
|
|
247
|
+
// eslint-disable-next-line no-console
|
|
248
|
+
console.info(`[INFO] ${message}`, ...args);
|
|
249
|
+
},
|
|
250
|
+
warn: (message, ...args) => {
|
|
251
|
+
// eslint-disable-next-line no-console
|
|
252
|
+
console.warn(`[WARN] ${message}`, ...args);
|
|
253
|
+
},
|
|
254
|
+
error: (message, ...args) => {
|
|
255
|
+
// eslint-disable-next-line no-console
|
|
256
|
+
console.error(`[ERROR] ${message}`, ...args);
|
|
257
|
+
},
|
|
258
|
+
};
|
|
59
259
|
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAa;IACrC,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAClH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;CACnH,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,0CAA0C;IAG1C,IAAI,EAAE,GAAoB,IAAI,CAAC;IAE/B,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QACtE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC;gBACH,qGAAqG;gBACrG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAa,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,6CAA6C;gBAC7C,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,SAAS,MAAM,KAAK,KAAK,OAAO,GAAG,OAAO,IAAI,CAAC;QAEnE,IAAI,CAAC;YACH,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,8CAA8C;QAChD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACnF,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjF,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjF,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;KACpF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAa;IACrC,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAClH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;CACnH,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,0CAA0C;IAG1C,IAAI,EAAE,GAAoB,IAAI,CAAC;IAE/B,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QACtE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC;gBACH,qGAAqG;gBACrG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAa,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,6CAA6C;gBAC7C,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,SAAS,MAAM,KAAK,KAAK,OAAO,GAAG,OAAO,IAAI,CAAC;QAEnE,IAAI,CAAC;YACH,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,8CAA8C;QAChD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACnF,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjF,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjF,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;KACpF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAE/E,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,0BAA0B;AAC1B,IAAI,UAAU,GAAkB,IAAI,CAAC;AACrC,IAAI,oBAAoB,GAAG,KAAK,CAAC;AAEjC;;;GAGG;AACH,SAAS,kBAAkB;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB;IAClC,6BAA6B;IAC7B,oBAAoB,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,OAAO,KAAK,WAAW,CAAC;IAEvF,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,OAAO,CAAC,oDAAoD;IAC9D,CAAC;IAED,IAAI,CAAC;QACH,uBAAuB;QACvB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAEpC,8BAA8B;QAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAE9C,0BAA0B;QAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QAED,2BAA2B;QAC3B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,4BAA4B,SAAS,QAAQ,CAAC,CAAC;QAE5E,mCAAmC;QACnC,MAAM,eAAe,GAAG;YACtB,sCAAsC;YACtC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,sCAAsC;YACtC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,sCAAsC;YACtC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,sCAAsC;YACtC,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC;QAEF,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,IAAe,EAAE,EAAE;YACpD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAC7B,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACrE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEZ,MAAM,QAAQ,GAAG,IAAI,SAAS,KAAK,KAAK,KAAK,OAAO,IAAI,CAAC;YAEzD,IAAI,CAAC;gBACH,EAAE,CAAC,cAAc,CAAC,UAAW,EAAE,QAAQ,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,mDAAmD;gBACnD,eAAe,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;gBAC3D,eAAe,CAAC,KAAK,CAAC,WAAW,EAAkC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAChF,CAAC;QACH,CAAC,CAAC;QAEF,2BAA2B;QAC3B,sCAAsC;QACtC,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACpD,sCAAsC;QACtC,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrD,sCAAsC;QACtC,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrD,sCAAsC;QACtC,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAEvD,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,UAAU,CAAC,CAAC;IAE1E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,oBAAoB,EAAE,CAAC;QACzB,iEAAiE;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,iCAAiC;QACjC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,oBAAoB,EAAE,CAAC;QACzB,iEAAiE;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,iCAAiC;QACjC,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QAC7C,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QAC5C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,UAAU,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QAC5C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,UAAU,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QAC7C,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/C,CAAC;CACF,CAAC"}
|
package/dist/logger.mjs
CHANGED
|
@@ -52,4 +52,167 @@ export function createFileLogger(filePath) {
|
|
|
52
52
|
error: (message, ...args) => writeLog('ERROR', message, ...args),
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// TUI-aware logging utilities - redirects console output to file in Node.js
|
|
57
|
+
// ============================================================================
|
|
58
|
+
import * as fs from 'fs';
|
|
59
|
+
import * as path from 'path';
|
|
60
|
+
import * as os from 'os';
|
|
61
|
+
// TUI-aware logging state
|
|
62
|
+
let tuiLogFile = null;
|
|
63
|
+
let tuiIsNodeEnvironment = false;
|
|
64
|
+
/**
|
|
65
|
+
* Get the application data directory for TUI logging
|
|
66
|
+
* Uses ~/.tuilder for cross-platform compatibility
|
|
67
|
+
*/
|
|
68
|
+
function getTuiLogDirectory() {
|
|
69
|
+
return path.join(os.homedir(), '.tuilder');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Initialize TUI logging - redirect console logs to file in Node.js
|
|
73
|
+
*
|
|
74
|
+
* This function should be called once at the entry point of CLI applications
|
|
75
|
+
* to redirect all console output to a log file, preventing interference with
|
|
76
|
+
* interactive prompts (inquirer, etc).
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* import { initializeTuiLogging } from '@vue-skuilder/common';
|
|
80
|
+
* initializeTuiLogging();
|
|
81
|
+
*/
|
|
82
|
+
export function initializeTuiLogging() {
|
|
83
|
+
// Detect Node.js environment
|
|
84
|
+
tuiIsNodeEnvironment = typeof window === 'undefined' && typeof process !== 'undefined';
|
|
85
|
+
if (!tuiIsNodeEnvironment) {
|
|
86
|
+
return; // Browser environment - keep normal console logging
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Set up log file path
|
|
90
|
+
const logDir = getTuiLogDirectory();
|
|
91
|
+
// Ensure log directory exists
|
|
92
|
+
if (!fs.existsSync(logDir)) {
|
|
93
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
tuiLogFile = path.join(logDir, 'lastrun.log');
|
|
96
|
+
// Clear previous log file
|
|
97
|
+
if (fs.existsSync(tuiLogFile)) {
|
|
98
|
+
fs.unlinkSync(tuiLogFile);
|
|
99
|
+
}
|
|
100
|
+
// Create initial log entry
|
|
101
|
+
const startTime = new Date().toISOString();
|
|
102
|
+
fs.writeFileSync(tuiLogFile, `=== TUI Session Started: ${startTime} ===\n`);
|
|
103
|
+
// Redirect console methods to file
|
|
104
|
+
const originalConsole = {
|
|
105
|
+
// eslint-disable-next-line no-console
|
|
106
|
+
log: console.log,
|
|
107
|
+
// eslint-disable-next-line no-console
|
|
108
|
+
error: console.error,
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
warn: console.warn,
|
|
111
|
+
// eslint-disable-next-line no-console
|
|
112
|
+
info: console.info
|
|
113
|
+
};
|
|
114
|
+
const writeToLog = (level, args) => {
|
|
115
|
+
const timestamp = new Date().toISOString();
|
|
116
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)).join(' ');
|
|
117
|
+
const logEntry = `[${timestamp}] ${level}: ${message}\n`;
|
|
118
|
+
try {
|
|
119
|
+
fs.appendFileSync(tuiLogFile, logEntry);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
// Fallback to original console if file write fails
|
|
123
|
+
originalConsole.error('Failed to write to log file:', err);
|
|
124
|
+
originalConsole[level.toLowerCase()](...args);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
// Override console methods
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.log = (...args) => writeToLog('INFO', args);
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.info = (...args) => writeToLog('INFO', args);
|
|
132
|
+
// eslint-disable-next-line no-console
|
|
133
|
+
console.warn = (...args) => writeToLog('WARN', args);
|
|
134
|
+
// eslint-disable-next-line no-console
|
|
135
|
+
console.error = (...args) => writeToLog('ERROR', args);
|
|
136
|
+
// eslint-disable-next-line no-console
|
|
137
|
+
console.log('TUI logging initialized - logs redirected to', tuiLogFile);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
// eslint-disable-next-line no-console
|
|
141
|
+
console.error('Failed to initialize TUI logging:', err);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the current log file path (for debugging)
|
|
146
|
+
* @returns Path to current log file, or null if not initialized
|
|
147
|
+
*/
|
|
148
|
+
export function getLogFilePath() {
|
|
149
|
+
return tuiLogFile;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Show user-facing message (always visible in TUI)
|
|
153
|
+
*
|
|
154
|
+
* This bypasses log redirection to ensure the message appears in the terminal.
|
|
155
|
+
* Use this for important user-facing messages in CLI applications.
|
|
156
|
+
*
|
|
157
|
+
* @param message - Message to display to user
|
|
158
|
+
*/
|
|
159
|
+
export function showUserMessage(message) {
|
|
160
|
+
if (tuiIsNodeEnvironment) {
|
|
161
|
+
// In Node.js, write directly to stdout to bypass log redirection
|
|
162
|
+
process.stdout.write(message + '\n');
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// In browser, use normal console
|
|
166
|
+
// eslint-disable-next-line no-console
|
|
167
|
+
console.log(message);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Show user-facing error (always visible in TUI)
|
|
172
|
+
*
|
|
173
|
+
* This bypasses log redirection to ensure the error appears in the terminal.
|
|
174
|
+
* Use this for critical errors that users must see in CLI applications.
|
|
175
|
+
*
|
|
176
|
+
* @param message - Error message to display to user
|
|
177
|
+
*/
|
|
178
|
+
export function showUserError(message) {
|
|
179
|
+
if (tuiIsNodeEnvironment) {
|
|
180
|
+
// In Node.js, write directly to stderr to bypass log redirection
|
|
181
|
+
process.stderr.write('Error: ' + message + '\n');
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// In browser, use normal console
|
|
185
|
+
// eslint-disable-next-line no-console
|
|
186
|
+
console.error(message);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* TUI-aware logger instance
|
|
191
|
+
*
|
|
192
|
+
* This logger object respects TUI logging initialization. When initializeTuiLogging()
|
|
193
|
+
* has been called, log output is redirected to file. Otherwise, it outputs to console.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* import { initializeTuiLogging, tuiLogger } from '@vue-skuilder/common';
|
|
197
|
+
* initializeTuiLogging();
|
|
198
|
+
* tuiLogger.info('Application started');
|
|
199
|
+
*/
|
|
200
|
+
export const tuiLogger = {
|
|
201
|
+
debug: (message, ...args) => {
|
|
202
|
+
// eslint-disable-next-line no-console
|
|
203
|
+
console.log(`[DEBUG] ${message}`, ...args);
|
|
204
|
+
},
|
|
205
|
+
info: (message, ...args) => {
|
|
206
|
+
// eslint-disable-next-line no-console
|
|
207
|
+
console.info(`[INFO] ${message}`, ...args);
|
|
208
|
+
},
|
|
209
|
+
warn: (message, ...args) => {
|
|
210
|
+
// eslint-disable-next-line no-console
|
|
211
|
+
console.warn(`[WARN] ${message}`, ...args);
|
|
212
|
+
},
|
|
213
|
+
error: (message, ...args) => {
|
|
214
|
+
// eslint-disable-next-line no-console
|
|
215
|
+
console.error(`[ERROR] ${message}`, ...args);
|
|
216
|
+
},
|
|
217
|
+
};
|
|
55
218
|
//# sourceMappingURL=logger.js.map
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.21",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"module": "dist/index.mjs",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"zod": "^3.23.8",
|
|
37
37
|
"zod-to-json-schema": "^3.23.5"
|
|
38
38
|
},
|
|
39
|
-
"stableVersion": "0.1.
|
|
39
|
+
"stableVersion": "0.1.21"
|
|
40
40
|
}
|
package/src/logger.ts
CHANGED
|
@@ -41,7 +41,7 @@ export const consoleLogger: SkLogger = {
|
|
|
41
41
|
*/
|
|
42
42
|
export function createFileLogger(filePath: string): SkLogger {
|
|
43
43
|
// Lazy import fs to avoid bundling issues
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
type FsModule = typeof import('fs');
|
|
46
46
|
let fs: FsModule | null = null;
|
|
47
47
|
|
|
@@ -74,3 +74,186 @@ export function createFileLogger(filePath: string): SkLogger {
|
|
|
74
74
|
error: (message: string, ...args: unknown[]) => writeLog('ERROR', message, ...args),
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// TUI-aware logging utilities - redirects console output to file in Node.js
|
|
80
|
+
// ============================================================================
|
|
81
|
+
|
|
82
|
+
import * as fs from 'fs';
|
|
83
|
+
import * as path from 'path';
|
|
84
|
+
import * as os from 'os';
|
|
85
|
+
|
|
86
|
+
// TUI-aware logging state
|
|
87
|
+
let tuiLogFile: string | null = null;
|
|
88
|
+
let tuiIsNodeEnvironment = false;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get the application data directory for TUI logging
|
|
92
|
+
* Uses ~/.tuilder for cross-platform compatibility
|
|
93
|
+
*/
|
|
94
|
+
function getTuiLogDirectory(): string {
|
|
95
|
+
return path.join(os.homedir(), '.tuilder');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Initialize TUI logging - redirect console logs to file in Node.js
|
|
100
|
+
*
|
|
101
|
+
* This function should be called once at the entry point of CLI applications
|
|
102
|
+
* to redirect all console output to a log file, preventing interference with
|
|
103
|
+
* interactive prompts (inquirer, etc).
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* import { initializeTuiLogging } from '@vue-skuilder/common';
|
|
107
|
+
* initializeTuiLogging();
|
|
108
|
+
*/
|
|
109
|
+
export function initializeTuiLogging(): void {
|
|
110
|
+
// Detect Node.js environment
|
|
111
|
+
tuiIsNodeEnvironment = typeof window === 'undefined' && typeof process !== 'undefined';
|
|
112
|
+
|
|
113
|
+
if (!tuiIsNodeEnvironment) {
|
|
114
|
+
return; // Browser environment - keep normal console logging
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// Set up log file path
|
|
119
|
+
const logDir = getTuiLogDirectory();
|
|
120
|
+
|
|
121
|
+
// Ensure log directory exists
|
|
122
|
+
if (!fs.existsSync(logDir)) {
|
|
123
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
tuiLogFile = path.join(logDir, 'lastrun.log');
|
|
127
|
+
|
|
128
|
+
// Clear previous log file
|
|
129
|
+
if (fs.existsSync(tuiLogFile)) {
|
|
130
|
+
fs.unlinkSync(tuiLogFile);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Create initial log entry
|
|
134
|
+
const startTime = new Date().toISOString();
|
|
135
|
+
fs.writeFileSync(tuiLogFile, `=== TUI Session Started: ${startTime} ===\n`);
|
|
136
|
+
|
|
137
|
+
// Redirect console methods to file
|
|
138
|
+
const originalConsole = {
|
|
139
|
+
// eslint-disable-next-line no-console
|
|
140
|
+
log: console.log,
|
|
141
|
+
// eslint-disable-next-line no-console
|
|
142
|
+
error: console.error,
|
|
143
|
+
// eslint-disable-next-line no-console
|
|
144
|
+
warn: console.warn,
|
|
145
|
+
// eslint-disable-next-line no-console
|
|
146
|
+
info: console.info
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const writeToLog = (level: string, args: unknown[]) => {
|
|
150
|
+
const timestamp = new Date().toISOString();
|
|
151
|
+
const message = args.map(arg =>
|
|
152
|
+
typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
|
|
153
|
+
).join(' ');
|
|
154
|
+
|
|
155
|
+
const logEntry = `[${timestamp}] ${level}: ${message}\n`;
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
fs.appendFileSync(tuiLogFile!, logEntry);
|
|
159
|
+
} catch (err) {
|
|
160
|
+
// Fallback to original console if file write fails
|
|
161
|
+
originalConsole.error('Failed to write to log file:', err);
|
|
162
|
+
originalConsole[level.toLowerCase() as keyof typeof originalConsole](...args);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Override console methods
|
|
167
|
+
// eslint-disable-next-line no-console
|
|
168
|
+
console.log = (...args) => writeToLog('INFO', args);
|
|
169
|
+
// eslint-disable-next-line no-console
|
|
170
|
+
console.info = (...args) => writeToLog('INFO', args);
|
|
171
|
+
// eslint-disable-next-line no-console
|
|
172
|
+
console.warn = (...args) => writeToLog('WARN', args);
|
|
173
|
+
// eslint-disable-next-line no-console
|
|
174
|
+
console.error = (...args) => writeToLog('ERROR', args);
|
|
175
|
+
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.log('TUI logging initialized - logs redirected to', tuiLogFile);
|
|
178
|
+
|
|
179
|
+
} catch (err) {
|
|
180
|
+
// eslint-disable-next-line no-console
|
|
181
|
+
console.error('Failed to initialize TUI logging:', err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get the current log file path (for debugging)
|
|
187
|
+
* @returns Path to current log file, or null if not initialized
|
|
188
|
+
*/
|
|
189
|
+
export function getLogFilePath(): string | null {
|
|
190
|
+
return tuiLogFile;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Show user-facing message (always visible in TUI)
|
|
195
|
+
*
|
|
196
|
+
* This bypasses log redirection to ensure the message appears in the terminal.
|
|
197
|
+
* Use this for important user-facing messages in CLI applications.
|
|
198
|
+
*
|
|
199
|
+
* @param message - Message to display to user
|
|
200
|
+
*/
|
|
201
|
+
export function showUserMessage(message: string): void {
|
|
202
|
+
if (tuiIsNodeEnvironment) {
|
|
203
|
+
// In Node.js, write directly to stdout to bypass log redirection
|
|
204
|
+
process.stdout.write(message + '\n');
|
|
205
|
+
} else {
|
|
206
|
+
// In browser, use normal console
|
|
207
|
+
// eslint-disable-next-line no-console
|
|
208
|
+
console.log(message);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Show user-facing error (always visible in TUI)
|
|
214
|
+
*
|
|
215
|
+
* This bypasses log redirection to ensure the error appears in the terminal.
|
|
216
|
+
* Use this for critical errors that users must see in CLI applications.
|
|
217
|
+
*
|
|
218
|
+
* @param message - Error message to display to user
|
|
219
|
+
*/
|
|
220
|
+
export function showUserError(message: string): void {
|
|
221
|
+
if (tuiIsNodeEnvironment) {
|
|
222
|
+
// In Node.js, write directly to stderr to bypass log redirection
|
|
223
|
+
process.stderr.write('Error: ' + message + '\n');
|
|
224
|
+
} else {
|
|
225
|
+
// In browser, use normal console
|
|
226
|
+
// eslint-disable-next-line no-console
|
|
227
|
+
console.error(message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* TUI-aware logger instance
|
|
233
|
+
*
|
|
234
|
+
* This logger object respects TUI logging initialization. When initializeTuiLogging()
|
|
235
|
+
* has been called, log output is redirected to file. Otherwise, it outputs to console.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* import { initializeTuiLogging, tuiLogger } from '@vue-skuilder/common';
|
|
239
|
+
* initializeTuiLogging();
|
|
240
|
+
* tuiLogger.info('Application started');
|
|
241
|
+
*/
|
|
242
|
+
export const tuiLogger = {
|
|
243
|
+
debug: (message: string, ...args: unknown[]) => {
|
|
244
|
+
// eslint-disable-next-line no-console
|
|
245
|
+
console.log(`[DEBUG] ${message}`, ...args);
|
|
246
|
+
},
|
|
247
|
+
info: (message: string, ...args: unknown[]) => {
|
|
248
|
+
// eslint-disable-next-line no-console
|
|
249
|
+
console.info(`[INFO] ${message}`, ...args);
|
|
250
|
+
},
|
|
251
|
+
warn: (message: string, ...args: unknown[]) => {
|
|
252
|
+
// eslint-disable-next-line no-console
|
|
253
|
+
console.warn(`[WARN] ${message}`, ...args);
|
|
254
|
+
},
|
|
255
|
+
error: (message: string, ...args: unknown[]) => {
|
|
256
|
+
// eslint-disable-next-line no-console
|
|
257
|
+
console.error(`[ERROR] ${message}`, ...args);
|
|
258
|
+
},
|
|
259
|
+
};
|