Browse Source
- Move native fetcher configuration from HomeView.vue to App.vue mounted() hook - Single source of truth for configuration on app startup - Removed duplicate configuration logic from HomeView - Added diagnostic logging to trace configuration flow - Fix ES module compatibility issue with Capacitor CLI - Replace direct logger import with lazy async loading in test-user-zero.ts - Prevents 'exports is not defined' error when Capacitor CLI loads config - Update refreshToken() and setBaseUrl() methods to async for logger access - Add centralized logger utility (src/lib/logger.ts) - Single ESLint whitelist location for console usage - Structured logging with levels and emoji support - Updated router/index.ts and stores/app.ts to use logger - Enhance Android notification deduplication - Add within-batch duplicate detection in fetch workers - Improve storage deduplication with alarm cancellation - Cancel alarms for removed duplicate notifications - Update UserZeroView.vue to await async refreshToken() call Fixes: - npx cap sync android ES module error - Duplicate notification accumulation - Console statement lint warnings All changes maintain backward compatibility and improve debugging visibility.master
14 changed files with 462 additions and 80 deletions
@ -0,0 +1,152 @@ |
|||||
|
|
||||
|
/** |
||||
|
* Logger Utility |
||||
|
* |
||||
|
* Centralized logging utility that wraps console methods with ESLint suppression |
||||
|
* in a single location. Provides structured logging with log levels and optional |
||||
|
* emoji prefixes for visual distinction. |
||||
|
* |
||||
|
* This file is the single whitelisted location for console usage in the application. |
||||
|
* All console methods are allowed here as this is the designated logging utility. |
||||
|
* |
||||
|
* @author Matthew Raymer |
||||
|
* @version 1.0.0 |
||||
|
*/ |
||||
|
|
||||
|
export enum LogLevel { |
||||
|
DEBUG = 0, |
||||
|
INFO = 1, |
||||
|
WARN = 2, |
||||
|
ERROR = 3, |
||||
|
NONE = 4 |
||||
|
} |
||||
|
|
||||
|
interface LoggerConfig { |
||||
|
level: LogLevel |
||||
|
enableEmojis: boolean |
||||
|
prefix?: string |
||||
|
} |
||||
|
|
||||
|
class Logger { |
||||
|
private config: LoggerConfig |
||||
|
|
||||
|
constructor(config: Partial<LoggerConfig> = {}) { |
||||
|
this.config = { |
||||
|
level: config.level ?? LogLevel.DEBUG, |
||||
|
enableEmojis: config.enableEmojis ?? true, |
||||
|
prefix: config.prefix |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update logger configuration |
||||
|
*/ |
||||
|
configure(config: Partial<LoggerConfig>): void { |
||||
|
this.config = { ...this.config, ...config } |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log debug message |
||||
|
*/ |
||||
|
debug(...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.DEBUG) { |
||||
|
this.logInternal('🐛', 'DEBUG', args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log info message |
||||
|
*/ |
||||
|
info(...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.INFO) { |
||||
|
this.logInternal('ℹ️', 'INFO', args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log warning message |
||||
|
*/ |
||||
|
warn(...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.WARN) { |
||||
|
this.logInternal('⚠️', 'WARN', args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log error message |
||||
|
*/ |
||||
|
error(...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.ERROR) { |
||||
|
this.logInternal('❌', 'ERROR', args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log message without emoji (for custom formatting) |
||||
|
*/ |
||||
|
log(...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.INFO) { |
||||
|
console.log(...args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Internal logging method with emoji and level support |
||||
|
*/ |
||||
|
private logInternal(emoji: string, level: string, args: unknown[]): void { |
||||
|
const prefix = this.config.prefix ? `[${this.config.prefix}] ` : '' |
||||
|
const emojiPrefix = this.config.enableEmojis ? `${emoji} ` : '' |
||||
|
const levelPrefix = `[${level}] ` |
||||
|
|
||||
|
console.log(`${emojiPrefix}${prefix}${levelPrefix}`, ...args) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log with custom emoji (convenience method) |
||||
|
*/ |
||||
|
custom(emoji: string, ...args: unknown[]): void { |
||||
|
if (this.config.level <= LogLevel.INFO) { |
||||
|
const prefix = this.config.prefix ? `[${this.config.prefix}] ` : '' |
||||
|
const emojiPrefix = this.config.enableEmojis ? `${emoji} ` : '' |
||||
|
|
||||
|
console.log(`${emojiPrefix}${prefix}`, ...args) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log grouped message (uses console.group) |
||||
|
*/ |
||||
|
group(label: string): void { |
||||
|
if (this.config.level <= LogLevel.INFO) { |
||||
|
console.group(label) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* End log group |
||||
|
*/ |
||||
|
groupEnd(): void { |
||||
|
if (this.config.level <= LogLevel.INFO) { |
||||
|
console.groupEnd() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Log table (uses console.table) |
||||
|
*/ |
||||
|
table(data: unknown): void { |
||||
|
if (this.config.level <= LogLevel.DEBUG) { |
||||
|
console.table(data) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Export singleton instance
|
||||
|
export const logger = new Logger({ |
||||
|
level: import.meta.env.DEV ? LogLevel.DEBUG : LogLevel.INFO, |
||||
|
enableEmojis: true |
||||
|
}) |
||||
|
|
||||
|
// Export class for creating custom logger instances
|
||||
|
export { Logger } |
||||
|
|
||||
Loading…
Reference in new issue