From d0f24763e47a5e4df48cb256d7d2992e9668d3a8 Mon Sep 17 00:00:00 2001 From: Jacek Date: Fri, 22 Aug 2025 21:54:42 -0500 Subject: [PATCH 1/5] refactor(clerk-js): Remove unused functionality --- .../modules/debug/__tests__/logger.spec.ts | 284 +++--------------- .../clerk-js/src/core/modules/debug/index.ts | 30 +- .../clerk-js/src/core/modules/debug/logger.ts | 79 +---- .../transports/__tests__/telemetry.spec.ts | 1 - .../modules/debug/transports/composite.ts | 3 +- .../modules/debug/transports/telemetry.ts | 5 +- .../clerk-js/src/core/modules/debug/types.ts | 13 - packages/clerk-js/src/utils/debug.ts | 7 +- 8 files changed, 56 insertions(+), 366 deletions(-) diff --git a/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts b/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts index 76d1c315099..2d226d0b23c 100644 --- a/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts +++ b/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts @@ -1,9 +1,8 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { DebugLogger } from '../logger'; -import type { DebugLogEntry, DebugLogFilter } from '../types'; +import type { DebugLogEntry } from '../types'; -// Mock transport for testing class MockTransport { public sentEntries: DebugLogEntry[] = []; @@ -70,267 +69,64 @@ describe('DebugLogger', () => { }); }); - describe('filter functionality', () => { - describe('level filtering', () => { - it('should filter by specific log level', () => { - const filters: DebugLogFilter[] = [{ level: 'error' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); + describe('edge cases', () => { + it('should handle undefined context', () => { + logger.info('message with undefined context', undefined); - filteredLogger.info('info message'); - filteredLogger.warn('warn message'); - filteredLogger.error('error message'); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].level).toBe('error'); - }); - - it('should allow all levels when no level filter is specified', () => { - const filters: DebugLogFilter[] = [{}]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('info message'); - filteredLogger.warn('warn message'); - filteredLogger.error('error message'); - - expect(mockTransport.sentEntries).toHaveLength(3); - }); - }); - - describe('source filtering', () => { - it('should filter by exact string source', () => { - const filters: DebugLogFilter[] = [{ source: 'auth-module' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message 1', undefined, 'auth-module'); - filteredLogger.info('message 2', undefined, 'other-module'); - filteredLogger.info('message 3', undefined, 'auth-module'); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].source).toBe('auth-module'); - expect(mockTransport.sentEntries[1].source).toBe('auth-module'); - }); - - it('should filter by RegExp source pattern', () => { - const filters: DebugLogFilter[] = [{ source: /auth-.*/ }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message 1', undefined, 'auth-module'); - filteredLogger.info('message 2', undefined, 'auth-service'); - filteredLogger.info('message 3', undefined, 'other-module'); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].source).toBe('auth-module'); - expect(mockTransport.sentEntries[1].source).toBe('auth-service'); - }); - - it('should not log when source is undefined and filter expects a source', () => { - const filters: DebugLogFilter[] = [{ source: 'auth-module' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message without source'); - - expect(mockTransport.sentEntries).toHaveLength(0); - }); - }); - - describe('include pattern filtering', () => { - it('should include messages matching string patterns', () => { - const filters: DebugLogFilter[] = [{ includePatterns: ['user', 'auth'] }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('user login successful'); - filteredLogger.info('auth token refreshed'); - filteredLogger.info('database connection established'); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].message).toBe('user login successful'); - expect(mockTransport.sentEntries[1].message).toBe('auth token refreshed'); - }); - - it('should include messages matching RegExp patterns', () => { - const filters: DebugLogFilter[] = [{ includePatterns: [/user-.*/] }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('user-123 logged in'); - filteredLogger.info('user-456 logged out'); - filteredLogger.info('admin panel accessed'); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].message).toBe('user-123 logged in'); - expect(mockTransport.sentEntries[1].message).toBe('user-456 logged out'); - }); - }); - - describe('exclude pattern filtering', () => { - it('should exclude messages matching string patterns', () => { - const filters: DebugLogFilter[] = [{ excludePatterns: ['debug', 'test'] }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('user login successful'); - filteredLogger.info('debug information logged'); - filteredLogger.info('test data generated'); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].message).toBe('user login successful'); - }); - - it('should exclude messages matching RegExp patterns', () => { - const filters: DebugLogFilter[] = [{ excludePatterns: [/test-.*/] }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('user login successful'); - filteredLogger.info('test-123 created'); - filteredLogger.info('test-456 deleted'); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].message).toBe('user login successful'); - }); + expect(mockTransport.sentEntries).toHaveLength(1); + expect(mockTransport.sentEntries[0].context).toBeUndefined(); }); - // Note: userId and sessionId filtering are defined in types but not yet implemented - // These tests are commented out until the feature is implemented - /* - describe('userId filtering', () => { - it('should filter by specific userId', () => { - const filters: DebugLogFilter[] = [{ userId: 'user-123' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message 1', { userId: 'user-123' }); - filteredLogger.info('message 2', { userId: 'user-456' }); - filteredLogger.info('message 3', { userId: 'user-123' }); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].context?.userId).toBe('user-123'); - expect(mockTransport.sentEntries[1].context?.userId).toBe('user-123'); - }); + it('should handle undefined source', () => { + logger.info('message with undefined source', {}, undefined); - it('should not log when userId is undefined and filter expects a userId', () => { - const filters: DebugLogFilter[] = [{ userId: 'user-123' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message without userId'); - - expect(mockTransport.sentEntries).toHaveLength(0); - }); + expect(mockTransport.sentEntries).toHaveLength(1); + expect(mockTransport.sentEntries[0].source).toBeUndefined(); }); - describe('sessionId filtering', () => { - it('should filter by specific sessionId', () => { - const filters: DebugLogFilter[] = [{ sessionId: 'session-abc' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); + it('should handle empty context object', () => { + logger.info('message with empty context', {}); - filteredLogger.info('message 1', { sessionId: 'session-abc' }); - filteredLogger.info('message 2', { sessionId: 'session-xyz' }); - filteredLogger.info('message 3', { sessionId: 'session-abc' }); - - expect(mockTransport.sentEntries).toHaveLength(2); - expect(mockTransport.sentEntries[0].context?.sessionId).toBe('session-abc'); - expect(mockTransport.sentEntries[1].context?.sessionId).toBe('session-abc'); - }); - - it('should not log when sessionId is undefined and filter expects a sessionId', () => { - const filters: DebugLogFilter[] = [{ sessionId: 'session-abc' }]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message without sessionId'); - - expect(mockTransport.sentEntries).toHaveLength(0); - }); + expect(mockTransport.sentEntries).toHaveLength(1); + expect(mockTransport.sentEntries[0].context).toEqual({}); }); - */ - - describe('combined filtering', () => { - it('should apply multiple filters with AND logic', () => { - const filters: DebugLogFilter[] = [ - { level: 'error' }, - { source: 'auth-module' }, - { includePatterns: ['failed'] }, - ]; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.error('login failed', undefined, 'auth-module'); - filteredLogger.error('login successful', undefined, 'auth-module'); - filteredLogger.warn('login failed', undefined, 'auth-module'); - filteredLogger.error('login failed', undefined, 'other-module'); - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].message).toBe('login failed'); - expect(mockTransport.sentEntries[0].level).toBe('error'); - expect(mockTransport.sentEntries[0].source).toBe('auth-module'); - }); + it('should handle empty source string', () => { + logger.info('message with empty source', {}, ''); - it('should handle empty filters array', () => { - const filters: DebugLogFilter[] = []; - const filteredLogger = new DebugLogger(mockTransport, 'debug', filters); - - filteredLogger.info('message 1'); - filteredLogger.warn('message 2'); - filteredLogger.error('message 3'); - - expect(mockTransport.sentEntries).toHaveLength(3); - }); + expect(mockTransport.sentEntries).toHaveLength(1); + expect(mockTransport.sentEntries[0].source).toBe(''); }); + }); - describe('edge cases', () => { - it('should handle undefined context', () => { - logger.info('message with undefined context', undefined); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].context).toBeUndefined(); - }); - - it('should handle undefined source', () => { - logger.info('message with undefined source', {}, undefined); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].source).toBeUndefined(); - }); + describe('transport integration', () => { + it('should call transport.send for each log entry', async () => { + let sendCallCount = 0; + const countingTransport = { + async send(_entry: DebugLogEntry): Promise { + sendCallCount++; + }, + }; - it('should handle empty context object', () => { - logger.info('message with empty context', {}); + const testLogger = new DebugLogger(countingTransport, 'info'); - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].context).toEqual({}); - }); + testLogger.info('message 1'); + testLogger.warn('message 2'); + testLogger.error('message 3'); - it('should handle empty source string', () => { - logger.info('message with empty source', {}, ''); + await new Promise(resolve => setTimeout(resolve, 0)); - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].source).toBe(''); - }); + expect(sendCallCount).toBe(3); }); - describe('transport integration', () => { - it('should call transport.send for each log entry', async () => { - let sendCallCount = 0; - const countingTransport = { - async send(_entry: DebugLogEntry): Promise { - sendCallCount++; - }, - }; + it('should include timestamp in log entries', () => { + const beforeTime = Date.now(); + logger.info('test message'); + const afterTime = Date.now(); - const testLogger = new DebugLogger(countingTransport, 'info'); - - testLogger.info('message 1'); - testLogger.warn('message 2'); - testLogger.error('message 3'); - - // Allow async operations to complete - await new Promise(resolve => setTimeout(resolve, 0)); - - expect(sendCallCount).toBe(3); - }); - - it('should include timestamp in log entries', () => { - const beforeTime = Date.now(); - logger.info('test message'); - const afterTime = Date.now(); - - expect(mockTransport.sentEntries).toHaveLength(1); - expect(mockTransport.sentEntries[0].timestamp).toBeGreaterThanOrEqual(beforeTime); - expect(mockTransport.sentEntries[0].timestamp).toBeLessThanOrEqual(afterTime); - }); + expect(mockTransport.sentEntries).toHaveLength(1); + expect(mockTransport.sentEntries[0].timestamp).toBeGreaterThanOrEqual(beforeTime); + expect(mockTransport.sentEntries[0].timestamp).toBeLessThanOrEqual(afterTime); }); }); }); diff --git a/packages/clerk-js/src/core/modules/debug/index.ts b/packages/clerk-js/src/core/modules/debug/index.ts index 14a29f53846..a5725efe954 100644 --- a/packages/clerk-js/src/core/modules/debug/index.ts +++ b/packages/clerk-js/src/core/modules/debug/index.ts @@ -4,7 +4,7 @@ import { DebugLogger } from './logger'; import { CompositeTransport } from './transports/composite'; import { ConsoleTransport } from './transports/console'; import { TelemetryTransport } from './transports/telemetry'; -import type { DebugLogFilter, DebugLogLevel } from './types'; +import type { DebugLogLevel } from './types'; const DEFAULT_LOG_LEVEL: DebugLogLevel = 'info'; @@ -23,8 +23,6 @@ function validateLoggerOptions(options: T): vo export interface LoggerOptions { /** Optional URL to which telemetry logs will be sent. */ endpoint?: string; - /** Optional array of filters to control which logs are emitted. */ - filters?: DebugLogFilter[]; /** Minimum log level to capture. */ logLevel?: DebugLogLevel; /** Optional collector instance for custom telemetry handling. */ @@ -35,8 +33,6 @@ export interface LoggerOptions { * Options for console-only logger configuration. */ export interface ConsoleLoggerOptions { - /** Optional array of filters to control which logs are emitted. */ - filters?: DebugLogFilter[]; /** Minimum log level to capture. */ logLevel?: DebugLogLevel; } @@ -47,8 +43,6 @@ export interface ConsoleLoggerOptions { export interface TelemetryLoggerOptions { /** Optional URL to which telemetry logs will be sent. */ endpoint?: string; - /** Optional array of filters to control which logs are emitted. */ - filters?: DebugLogFilter[]; /** Minimum log level to capture. */ logLevel?: DebugLogLevel; /** Optional collector instance for custom telemetry handling. */ @@ -59,8 +53,6 @@ export interface TelemetryLoggerOptions { * Options for composite logger configuration. */ export interface CompositeLoggerOptions { - /** Optional array of filters to control which logs are emitted. */ - filters?: DebugLogFilter[]; /** Minimum log level to capture. */ logLevel?: DebugLogLevel; /** Collection of transports used by the composite logger. */ @@ -119,7 +111,7 @@ class DebugLoggerManager { private async performInitialization(options: LoggerOptions): Promise { try { validateLoggerOptions(options); - const { logLevel, filters, telemetryCollector } = options; + const { logLevel, telemetryCollector } = options; const finalLogLevel = logLevel ?? DEFAULT_LOG_LEVEL; const transports = [ @@ -129,7 +121,7 @@ class DebugLoggerManager { const transportInstances = transports.map(t => t.transport); const compositeTransport = new CompositeTransport(transportInstances); - const logger = new DebugLogger(compositeTransport, finalLogLevel, filters); + const logger = new DebugLogger(compositeTransport, finalLogLevel); this.logger = logger; this.initialized = true; @@ -184,18 +176,16 @@ export async function getDebugLogger(options: LoggerOptions = {}): Promise t.transport); const compositeTransport = new CompositeTransport(transportInstances); - const logger = new DebugLogger(compositeTransport, finalLogLevel, filters); + const logger = new DebugLogger(compositeTransport, finalLogLevel); return { logger, transport: compositeTransport }; } catch (error) { diff --git a/packages/clerk-js/src/core/modules/debug/logger.ts b/packages/clerk-js/src/core/modules/debug/logger.ts index 0e5834a1fb3..35e9c91c15d 100644 --- a/packages/clerk-js/src/core/modules/debug/logger.ts +++ b/packages/clerk-js/src/core/modules/debug/logger.ts @@ -1,4 +1,4 @@ -import type { DebugLogEntry, DebugLogFilter, DebugLogLevel, DebugTransport } from './types'; +import type { DebugLogEntry, DebugLogLevel, DebugTransport } from './types'; /** * Default log level for debug logging @@ -11,7 +11,6 @@ const DEFAULT_LOG_LEVEL: DebugLogLevel = 'debug'; * @public */ export class DebugLogger { - private readonly filters?: DebugLogFilter[]; private readonly logLevel: DebugLogLevel; private readonly transport: DebugTransport; @@ -20,12 +19,10 @@ export class DebugLogger { * * @param transport - Transport used to send log entries * @param logLevel - Minimum log level to record. Defaults to `'debug'` - * @param filters - Optional list of filters to include or exclude messages */ - constructor(transport: DebugTransport, logLevel?: DebugLogLevel, filters?: DebugLogFilter[]) { + constructor(transport: DebugTransport, logLevel?: DebugLogLevel) { this.transport = transport; this.logLevel = logLevel ?? DEFAULT_LOG_LEVEL; - this.filters = filters; } /** @@ -88,10 +85,6 @@ export class DebugLogger { return; } - if (!this.shouldLogFilters(level, message, source)) { - return; - } - const entry: DebugLogEntry = { timestamp: Date.now(), level, @@ -111,72 +104,4 @@ export class DebugLogger { const messageLevelIndex = levels.indexOf(level); return messageLevelIndex <= currentLevelIndex; } - - private shouldLogFilters(level: DebugLogLevel, message: string, source?: string): boolean { - if (!this.filters || this.filters.length === 0) { - return true; - } - - return this.filters.every(filter => { - if (filter.level && filter.level !== level) { - return false; - } - - if (filter.source && !this.matchesSource(filter.source, source)) { - return false; - } - - if ( - filter.includePatterns && - filter.includePatterns.length > 0 && - !this.shouldInclude(message, filter.includePatterns) - ) { - return false; - } - - if ( - filter.excludePatterns && - filter.excludePatterns.length > 0 && - this.shouldExclude(message, filter.excludePatterns) - ) { - return false; - } - - return true; - }); - } - - /** - * Checks if a source matches the given pattern (string or RegExp) - */ - private matchesSource(pattern: string | RegExp, source?: string): boolean { - if (typeof pattern === 'string') { - return source === pattern; - } - return source !== undefined && pattern.test(source); - } - - /** - * Checks if a message should be included based on the given patterns - */ - private shouldInclude(message: string, patterns: (string | RegExp)[]): boolean { - return patterns.some(pattern => this.matchesPattern(message, pattern)); - } - - /** - * Checks if a message should be excluded based on the given patterns - */ - private shouldExclude(message: string, patterns: (string | RegExp)[]): boolean { - return patterns.some(pattern => this.matchesPattern(message, pattern)); - } - - /** - * Checks if a message matches a given pattern (string or RegExp) - */ - private matchesPattern(message: string, pattern: string | RegExp): boolean { - if (typeof pattern === 'string') { - return message.includes(pattern); - } - return pattern.test(message); - } } diff --git a/packages/clerk-js/src/core/modules/debug/transports/__tests__/telemetry.spec.ts b/packages/clerk-js/src/core/modules/debug/transports/__tests__/telemetry.spec.ts index 4583f8abb92..f219d67e031 100644 --- a/packages/clerk-js/src/core/modules/debug/transports/__tests__/telemetry.spec.ts +++ b/packages/clerk-js/src/core/modules/debug/transports/__tests__/telemetry.spec.ts @@ -59,7 +59,6 @@ describe('TelemetryTransport', () => { timestamp: Date.now(), }; - // Should not throw when no collector is provided await expect(transportWithoutCollector.send(logEntry)).resolves.toBeUndefined(); }); }); diff --git a/packages/clerk-js/src/core/modules/debug/transports/composite.ts b/packages/clerk-js/src/core/modules/debug/transports/composite.ts index 6d155603246..b95c9495887 100644 --- a/packages/clerk-js/src/core/modules/debug/transports/composite.ts +++ b/packages/clerk-js/src/core/modules/debug/transports/composite.ts @@ -1,4 +1,4 @@ -import type { DebugLogEntry, DebugLogFilter, DebugTransport } from '../types'; +import type { DebugLogEntry, DebugTransport } from '../types'; /** * Options for configuring a composite debug transport that fans out logs @@ -7,7 +7,6 @@ import type { DebugLogEntry, DebugLogFilter, DebugTransport } from '../types'; * @public */ export interface CompositeLoggerOptions { - filters?: DebugLogFilter[]; logLevel?: 'error' | 'warn' | 'info' | 'debug' | 'trace'; transports: Array<{ options?: Record; diff --git a/packages/clerk-js/src/core/modules/debug/transports/telemetry.ts b/packages/clerk-js/src/core/modules/debug/transports/telemetry.ts index 4878397a1b7..487eb57e32b 100644 --- a/packages/clerk-js/src/core/modules/debug/transports/telemetry.ts +++ b/packages/clerk-js/src/core/modules/debug/transports/telemetry.ts @@ -1,6 +1,6 @@ -import type { TelemetryCollector } from '@clerk/shared/telemetry'; +import type { TelemetryCollector } from '@clerk/types'; -import type { DebugLogEntry, DebugLogFilter, DebugLogLevel, DebugTransport } from '../types'; +import type { DebugLogEntry, DebugLogLevel, DebugTransport } from '../types'; /** * Options for configuring a telemetry-backed transport. @@ -10,7 +10,6 @@ import type { DebugLogEntry, DebugLogFilter, DebugLogLevel, DebugTransport } fro export interface TelemetryLoggerOptions { endpoint?: string; logLevel?: DebugLogLevel; - filters?: DebugLogFilter[]; } /** diff --git a/packages/clerk-js/src/core/modules/debug/types.ts b/packages/clerk-js/src/core/modules/debug/types.ts index 7bd226b911e..2e64cdaf4f8 100644 --- a/packages/clerk-js/src/core/modules/debug/types.ts +++ b/packages/clerk-js/src/core/modules/debug/types.ts @@ -75,25 +75,12 @@ export interface ErrorDetails { */ export interface DebugLoggerConfig { readonly bufferSize: number; - readonly filters?: DebugLogFilter[]; readonly flushInterval: number; readonly logLevel: DebugLogLevel; readonly maxLogEntries: number; readonly transport?: DebugTransport; } -/** - * Filter configuration for debug logs - */ -export interface DebugLogFilter { - readonly excludePatterns?: (string | RegExp)[]; - readonly includePatterns?: (string | RegExp)[]; - readonly level?: DebugLogLevel; - readonly sessionId?: string; - readonly source?: string | RegExp; - readonly userId?: string; -} - /** * Validates if a value is a valid debug log level */ diff --git a/packages/clerk-js/src/utils/debug.ts b/packages/clerk-js/src/utils/debug.ts index 6b32525c7b1..03a1d201e87 100644 --- a/packages/clerk-js/src/utils/debug.ts +++ b/packages/clerk-js/src/utils/debug.ts @@ -1,6 +1,6 @@ import type { TelemetryCollector } from '@clerk/shared/telemetry'; -import type { DebugLogFilter, DebugLogLevel } from '@/core/modules/debug/types'; +import type { DebugLogLevel } from '@/core/modules/debug/types'; /** * Lightweight logger surface that callers can import as a singleton. @@ -16,7 +16,6 @@ export interface DebugLoggerInterface { type InitOptions = { enabled?: boolean; - filters?: DebugLogFilter[]; logLevel?: DebugLogLevel; telemetryCollector?: TelemetryCollector; }; @@ -84,7 +83,6 @@ async function ensureInitialized(): Promise { const { getDebugLogger } = await import('@/core/modules/debug'); const logger = await getDebugLogger({ - filters: lastOptions?.filters, logLevel: lastOptions?.logLevel ?? 'trace', telemetryCollector: lastOptions?.telemetryCollector, }); @@ -126,12 +124,10 @@ async function ensureInitialized(): Promise { * Options and defaults: * - options.enabled: defaults to true * - options.logLevel: defaults to 'trace' - * - options.filters: optional include/exclude filters and matching rules * - options.telemetryCollector: optional telemetry sink to forward logs * * @param options - Configuration options * @param options.enabled - Enables the logger; when false, logger is a no-op (default: true) - * @param options.filters - Filters applied to log entries (level, source, include/exclude patterns) * @param options.logLevel - Minimal level to log; lower-priority logs are ignored (default: 'trace') * @param options.telemetryCollector - Collector used by the debug transport for emitting telemetry * @@ -159,7 +155,6 @@ export function initDebugLogger(options: InitOptions = {}): void { const { __internal_resetDebugLogger, getDebugLogger } = await import('@/core/modules/debug'); __internal_resetDebugLogger(); const logger = await getDebugLogger({ - filters: lastOptions?.filters, logLevel: lastOptions?.logLevel ?? 'trace', telemetryCollector: lastOptions?.telemetryCollector, }); From e0d444d0406a8c99816bce9bb094d762ae774d7b Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 23 Aug 2025 08:44:43 -0500 Subject: [PATCH 2/5] additional removal --- packages/clerk-js/src/core/clerk.ts | 8 -- .../modules/debug/__tests__/logger.spec.ts | 7 +- .../clerk-js/src/core/modules/debug/index.ts | 42 +++----- .../clerk-js/src/core/modules/debug/logger.ts | 13 +-- .../modules/debug/transports/composite.ts | 2 +- .../core/modules/debug/transports/console.ts | 4 - .../clerk-js/src/core/modules/debug/types.ts | 4 +- packages/clerk-js/src/utils/debug.ts | 98 +++++-------------- 8 files changed, 41 insertions(+), 137 deletions(-) diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index bca3569f003..ce1b64d96ae 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -85,7 +85,6 @@ import type { Web3Provider, } from '@clerk/types'; -import type { DebugLoggerInterface } from '@/utils/debug'; import { debugLogger, initDebugLogger } from '@/utils/debug'; import type { MountComponentRenderer } from '../ui/Components'; @@ -163,11 +162,6 @@ type SetActiveHook = (intent?: 'sign-out') => void | Promise; export type ClerkCoreBroadcastChannelEvent = { type: 'signout' }; -/** - * Interface for the debug logger with all available logging methods - */ -// DebugLoggerInterface imported from '@/utils/debug' - declare global { interface Window { Clerk?: Clerk; @@ -219,8 +213,6 @@ export class Clerk implements ClerkInterface { public __internal_country?: string | null; public telemetry: TelemetryCollector | undefined; public readonly __internal_state: State = new State(); - // Deprecated: use global singleton from `@/utils/debug` - public debugLogger?: DebugLoggerInterface; protected internal_last_error: ClerkAPIError | null = null; // converted to protected environment to support `updateEnvironment` type assertion diff --git a/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts b/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts index 2d226d0b23c..f8c56fb9c6a 100644 --- a/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts +++ b/packages/clerk-js/src/core/modules/debug/__tests__/logger.spec.ts @@ -21,7 +21,7 @@ describe('DebugLogger', () => { beforeEach(() => { mockTransport = new MockTransport(); - logger = new DebugLogger(mockTransport, 'trace'); + logger = new DebugLogger(mockTransport, 'debug'); }); afterEach(() => { @@ -34,14 +34,12 @@ describe('DebugLogger', () => { logger.warn('warn message'); logger.info('info message'); logger.debug('debug message'); - logger.trace('trace message'); - expect(mockTransport.sentEntries).toHaveLength(5); + expect(mockTransport.sentEntries).toHaveLength(4); expect(mockTransport.sentEntries[0].level).toBe('error'); expect(mockTransport.sentEntries[1].level).toBe('warn'); expect(mockTransport.sentEntries[2].level).toBe('info'); expect(mockTransport.sentEntries[3].level).toBe('debug'); - expect(mockTransport.sentEntries[4].level).toBe('trace'); }); it('should include context and source in log entries', () => { @@ -58,7 +56,6 @@ describe('DebugLogger', () => { it('should respect log level filtering', () => { const infoLogger = new DebugLogger(mockTransport, 'info'); - infoLogger.trace('trace message'); infoLogger.debug('debug message'); infoLogger.info('info message'); infoLogger.warn('warn message'); diff --git a/packages/clerk-js/src/core/modules/debug/index.ts b/packages/clerk-js/src/core/modules/debug/index.ts index a5725efe954..cb7ec30695e 100644 --- a/packages/clerk-js/src/core/modules/debug/index.ts +++ b/packages/clerk-js/src/core/modules/debug/index.ts @@ -1,4 +1,5 @@ import type { TelemetryCollector } from '@clerk/shared/telemetry'; +import { isProductionEnvironment } from '@clerk/shared/utils'; import { DebugLogger } from './logger'; import { CompositeTransport } from './transports/composite'; @@ -53,17 +54,12 @@ export interface TelemetryLoggerOptions { * Options for composite logger configuration. */ export interface CompositeLoggerOptions { - /** Minimum log level to capture. */ logLevel?: DebugLogLevel; - /** Collection of transports used by the composite logger. */ transports: Array<{ transport: ConsoleTransport | TelemetryTransport }>; } /** * Manages a singleton instance of the debug logger. - * - * Ensures only one logger is initialized and provides access to it. - * Handles asynchronous initialization and configuration. */ class DebugLoggerManager { private static instance: DebugLoggerManager; @@ -73,9 +69,6 @@ class DebugLoggerManager { private constructor() {} - /** - * Get the singleton instance - */ static getInstance(): DebugLoggerManager { if (!DebugLoggerManager.instance) { DebugLoggerManager.instance = new DebugLoggerManager(); @@ -83,12 +76,6 @@ class DebugLoggerManager { return DebugLoggerManager.instance; } - /** - * Initialize the debug logger with the given options - * - * @param options - Configuration options for the logger - * @returns Promise resolving to the debug logger instance - */ async initialize(options: LoggerOptions = {}): Promise { if (this.initialized) { return this.logger; @@ -102,12 +89,6 @@ class DebugLoggerManager { return this.initializationPromise; } - /** - * Performs the actual initialization logic - * - * @param options - Configuration options for the logger - * @returns Promise resolving to the debug logger instance - */ private async performInitialization(options: LoggerOptions): Promise { try { validateLoggerOptions(options); @@ -116,7 +97,7 @@ class DebugLoggerManager { const transports = [ { transport: new ConsoleTransport() }, - { transport: new TelemetryTransport(telemetryCollector) }, + ...(telemetryCollector ? [{ transport: new TelemetryTransport(telemetryCollector) }] : []), ]; const transportInstances = transports.map(t => t.transport); @@ -133,23 +114,14 @@ class DebugLoggerManager { } } - /** - * Gets the current logger instance - */ getLogger(): DebugLogger | null { return this.logger; } - /** - * Checks if the debug logger is initialized - */ isInitialized(): boolean { return this.initialized; } - /** - * Resets the initialization state - */ reset(): void { this.initialized = false; this.logger = null; @@ -170,6 +142,7 @@ export async function getDebugLogger(options: LoggerOptions = {}): Promise, source?: string): void { - this.log('trace', message, context, source); - } + // trace level removed /** * Log a warning message. @@ -99,7 +90,7 @@ export class DebugLogger { } private shouldLogLevel(level: DebugLogLevel): boolean { - const levels: DebugLogLevel[] = ['error', 'warn', 'info', 'debug', 'trace']; + const levels: DebugLogLevel[] = ['error', 'warn', 'info', 'debug']; const currentLevelIndex = levels.indexOf(this.logLevel); const messageLevelIndex = levels.indexOf(level); return messageLevelIndex <= currentLevelIndex; diff --git a/packages/clerk-js/src/core/modules/debug/transports/composite.ts b/packages/clerk-js/src/core/modules/debug/transports/composite.ts index b95c9495887..0e243031c35 100644 --- a/packages/clerk-js/src/core/modules/debug/transports/composite.ts +++ b/packages/clerk-js/src/core/modules/debug/transports/composite.ts @@ -7,7 +7,7 @@ import type { DebugLogEntry, DebugTransport } from '../types'; * @public */ export interface CompositeLoggerOptions { - logLevel?: 'error' | 'warn' | 'info' | 'debug' | 'trace'; + logLevel?: 'error' | 'warn' | 'info' | 'debug'; transports: Array<{ options?: Record; transport: DebugTransport; diff --git a/packages/clerk-js/src/core/modules/debug/transports/console.ts b/packages/clerk-js/src/core/modules/debug/transports/console.ts index beca7099149..1b064e2a729 100644 --- a/packages/clerk-js/src/core/modules/debug/transports/console.ts +++ b/packages/clerk-js/src/core/modules/debug/transports/console.ts @@ -24,7 +24,6 @@ const LEVEL_COLORS = { debug: COLORS.green, error: COLORS.red, info: COLORS.blue, - trace: COLORS.magenta, warn: COLORS.yellow, } as const; @@ -71,9 +70,6 @@ export class ConsoleTransport implements DebugTransport { case 'debug': console.debug(message); break; - case 'trace': - console.trace(message); - break; default: console.log(message); } diff --git a/packages/clerk-js/src/core/modules/debug/types.ts b/packages/clerk-js/src/core/modules/debug/types.ts index 2e64cdaf4f8..9101a611a5c 100644 --- a/packages/clerk-js/src/core/modules/debug/types.ts +++ b/packages/clerk-js/src/core/modules/debug/types.ts @@ -1,12 +1,12 @@ /** * Debug logging levels for different types of information */ -export type DebugLogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace'; +export type DebugLogLevel = 'error' | 'warn' | 'info' | 'debug'; /** * Valid debug log levels */ -export const VALID_LOG_LEVELS: readonly DebugLogLevel[] = ['error', 'warn', 'info', 'debug', 'trace'] as const; +export const VALID_LOG_LEVELS: readonly DebugLogLevel[] = ['error', 'warn', 'info', 'debug'] as const; /** * Valid debug event types diff --git a/packages/clerk-js/src/utils/debug.ts b/packages/clerk-js/src/utils/debug.ts index 03a1d201e87..2008fee483c 100644 --- a/packages/clerk-js/src/utils/debug.ts +++ b/packages/clerk-js/src/utils/debug.ts @@ -6,11 +6,10 @@ import type { DebugLogLevel } from '@/core/modules/debug/types'; * Lightweight logger surface that callers can import as a singleton. * Methods are no-ops until initialized via `initDebugLogger`. */ -export interface DebugLoggerInterface { +export interface DebugLogger { debug(message: string, context?: Record, source?: string): void; error(message: string, context?: Record, source?: string): void; info(message: string, context?: Record, source?: string): void; - trace(message: string, context?: Record, source?: string): void; warn(message: string, context?: Record, source?: string): void; } @@ -21,8 +20,8 @@ type InitOptions = { }; let isEnabled = false; -let realLogger: DebugLoggerInterface | null = null; -let lastOptions: Omit | null = null; +let realLogger: DebugLogger | null = null; +let initializationAttempted = false; type BufferedLogEntry = { level: DebugLogLevel; @@ -36,6 +35,9 @@ const MAX_BUFFERED_LOGS = 200; const preInitBuffer: BufferedLogEntry[] = []; function pushBuffered(level: DebugLogLevel, message: string, context?: Record, source?: string): void { + if (!isEnabled) { + return; + } preInitBuffer.push({ level, message, context, source, ts: Date.now() }); if (preInitBuffer.length > MAX_BUFFERED_LOGS) { preInitBuffer.shift(); @@ -65,9 +67,6 @@ function flushBuffered(): void { case 'debug': realLogger.debug(entry.message, mergedContext, entry.source); break; - case 'trace': - realLogger.trace(entry.message, mergedContext, entry.source); - break; default: break; } @@ -75,7 +74,7 @@ function flushBuffered(): void { preInitBuffer.length = 0; } -async function ensureInitialized(): Promise { +async function ensureInitialized(options?: Omit): Promise { try { if (!isEnabled || realLogger) { return; @@ -83,8 +82,8 @@ async function ensureInitialized(): Promise { const { getDebugLogger } = await import('@/core/modules/debug'); const logger = await getDebugLogger({ - logLevel: lastOptions?.logLevel ?? 'trace', - telemetryCollector: lastOptions?.telemetryCollector, + logLevel: options?.logLevel ?? 'debug', + telemetryCollector: options?.telemetryCollector, }); if (logger) { @@ -92,42 +91,22 @@ async function ensureInitialized(): Promise { flushBuffered(); } } catch (error) { - const message = 'Debug logger initialization failed'; - if (isEnabled && realLogger) { - try { - realLogger.trace(message, { error }); - } catch { - // ignore secondary logging errors - } - } else { - try { - // Use a safe, minimal fallback to avoid noisy errors - console.debug?.(message, error); - } catch { - // ignore secondary logging errors - } + try { + console.debug?.('Debug logger initialization failed', error); + } catch { + void 0; } - // Silently return to avoid unhandled rejections and preserve behavior + return; } } /** * @public - * Initialize or update the global debug logger configuration. - * - * Behavior: - * - Safe to call multiple times; subsequent calls update options and re-initialize if needed - * - When disabled, the logger becomes a no-op and any existing real logger is cleared - * - Initialization happens asynchronously; errors are handled internally without throwing - * - * Options and defaults: - * - options.enabled: defaults to true - * - options.logLevel: defaults to 'trace' - * - options.telemetryCollector: optional telemetry sink to forward logs + * Initialize the global debug logger configuration once. * * @param options - Configuration options - * @param options.enabled - Enables the logger; when false, logger is a no-op (default: true) + * @param options.enabled - Enables the logger; when false, logger is a no-op (default: false) * @param options.logLevel - Minimal level to log; lower-priority logs are ignored (default: 'trace') * @param options.telemetryCollector - Collector used by the debug transport for emitting telemetry * @@ -140,40 +119,18 @@ async function ensureInitialized(): Promise { * ``` */ export function initDebugLogger(options: InitOptions = {}): void { - const { enabled = true, ...rest } = options; - lastOptions = rest; - isEnabled = Boolean(enabled); - - if (!isEnabled) { - realLogger = null; + if (initializationAttempted) { return; } - if (realLogger) { - void (async () => { - try { - const { __internal_resetDebugLogger, getDebugLogger } = await import('@/core/modules/debug'); - __internal_resetDebugLogger(); - const logger = await getDebugLogger({ - logLevel: lastOptions?.logLevel ?? 'trace', - telemetryCollector: lastOptions?.telemetryCollector, - }); - if (logger) { - realLogger = logger; - flushBuffered(); - } - } catch (error) { - try { - console.debug?.('Debug logger reconfiguration failed', error); - } catch { - // ignore secondary logging errors - } - } - })(); + const { enabled = false, ...rest } = options; + if (!enabled) { return; } - void ensureInitialized(); + isEnabled = true; + initializationAttempted = true; + void ensureInitialized(rest); } /** @@ -190,7 +147,7 @@ export function initDebugLogger(options: InitOptions = {}): void { * debugLogger.info('Loaded dashboard', { page: 'home' }, 'ui'); * ``` */ -const baseDebugLogger: DebugLoggerInterface = { +export const debugLogger: Readonly = { debug(message: string, context?: Record, source?: string): void { if (!realLogger) { pushBuffered('debug', message, context, source); @@ -212,13 +169,6 @@ const baseDebugLogger: DebugLoggerInterface = { } realLogger.info(message, context, source); }, - trace(message: string, context?: Record, source?: string): void { - if (!realLogger) { - pushBuffered('trace', message, context, source); - return; - } - realLogger.trace(message, context, source); - }, warn(message: string, context?: Record, source?: string): void { if (!realLogger) { pushBuffered('warn', message, context, source); @@ -227,5 +177,3 @@ const baseDebugLogger: DebugLoggerInterface = { realLogger.warn(message, context, source); }, }; - -export const debugLogger: Readonly = Object.freeze(baseDebugLogger); From 3bb114da89e9434510e9b390863ac1b8f0a478c7 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 23 Aug 2025 08:57:25 -0500 Subject: [PATCH 3/5] remove unused utility types --- .../clerk-js/src/core/modules/debug/types.ts | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/packages/clerk-js/src/core/modules/debug/types.ts b/packages/clerk-js/src/core/modules/debug/types.ts index 9101a611a5c..211bcd1b2b8 100644 --- a/packages/clerk-js/src/core/modules/debug/types.ts +++ b/packages/clerk-js/src/core/modules/debug/types.ts @@ -50,9 +50,6 @@ export interface DebugData { * Transport interface for sending debug log entries to different destinations */ export interface DebugTransport { - /** - * Send a single debug log entry - */ send(entry: DebugLogEntry): Promise; } @@ -128,22 +125,3 @@ export function isDebugData(obj: unknown): obj is DebugData { typeof (obj as DebugData).timestamp === 'number' ); } - -/** - * Utility type for creating partial debug logger configurations - */ -export type PartialDebugLoggerConfig = Partial; - -/** - * Utility type for creating debug log entries without readonly constraint - */ -export type MutableDebugLogEntry = { - -readonly [K in keyof DebugLogEntry]: DebugLogEntry[K]; -}; - -/** - * Utility type for creating debug data without readonly constraint - */ -export type MutableDebugData = { - -readonly [K in keyof DebugData]: DebugData[K]; -}; From 9b3e65769032e125d0c544c776951f8339ec04f9 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 23 Aug 2025 09:10:17 -0500 Subject: [PATCH 4/5] changeset --- .changeset/dull-rules-dance.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dull-rules-dance.md diff --git a/.changeset/dull-rules-dance.md b/.changeset/dull-rules-dance.md new file mode 100644 index 00000000000..22ace9b7b8d --- /dev/null +++ b/.changeset/dull-rules-dance.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Removing unused debugLogger functionality From 3c13778f232363e7f28e7e9049f2b88047fba157 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 23 Aug 2025 09:14:41 -0500 Subject: [PATCH 5/5] pr feedback --- packages/clerk-js/src/utils/debug.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/clerk-js/src/utils/debug.ts b/packages/clerk-js/src/utils/debug.ts index 2008fee483c..c52bc1f0486 100644 --- a/packages/clerk-js/src/utils/debug.ts +++ b/packages/clerk-js/src/utils/debug.ts @@ -82,7 +82,7 @@ async function ensureInitialized(options?: Omit): Promis const { getDebugLogger } = await import('@/core/modules/debug'); const logger = await getDebugLogger({ - logLevel: options?.logLevel ?? 'debug', + logLevel: options?.logLevel, telemetryCollector: options?.telemetryCollector, }); @@ -107,7 +107,7 @@ async function ensureInitialized(options?: Omit): Promis * * @param options - Configuration options * @param options.enabled - Enables the logger; when false, logger is a no-op (default: false) - * @param options.logLevel - Minimal level to log; lower-priority logs are ignored (default: 'trace') + * @param options.logLevel - Minimal level to log; lower-priority logs are ignored. Valid levels: 'error' | 'warn' | 'info' | 'debug'. * @param options.telemetryCollector - Collector used by the debug transport for emitting telemetry * * @example