npm package: @onamfc/developer-log
Description: A lightweight console.log wrapper that suppresses output in production
Author: onamfc
Latest version: 1.2.4

# @onamfc/developer-log

A lightweight wrapper for all `console` methods that automatically suppresses output in production environments and supports optional tag-based filtering in development.

## Installation

```bash
npm install @onamfc/developer-log
```

## Usage

Import and use just like you would use the native `console` object:

```typescript
import { dev } from '@onamfc/developer-log';

// Basic logging
dev.log('Hello, world!');
dev.error('An error occurred');
dev.warn('This is a warning');
dev.info('Informational message');
dev.debug('Debug information');

// Logging with tags for filtering (optional)
dev.log('Database connected', { tag: 'database' });
dev.error('API request failed', error, { tag: 'api' });
dev.warn('Cache miss', cacheKey, { tag: 'cache' });

// Advanced methods
dev.table([{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }]);
dev.trace('Stack trace');
dev.dir({ foo: 'bar' });

// Grouping
dev.group('My Group');
dev.log('Inside group');
dev.groupEnd();

dev.groupCollapsed('Collapsed Group');
dev.log('Hidden by default');
dev.groupEnd();

// Timing
dev.time('operation');
// ... your code ...
dev.timeEnd('operation');
dev.timeLog('operation', 'Checkpoint');

// Counting
dev.count('clicks');
dev.count('clicks');
dev.countReset('clicks');

// Assertions
dev.assert(value === expected, 'Values do not match');

// Other methods
dev.clear();
dev.dirxml(document.body);
```

### Default Export

You can also use the default export:

```typescript
import dev from '@onamfc/developer-log';

dev.log('Using default export');
```

## How it Works
The package checks `process.env.NODE_ENV` and suppresses all output when it equals `'production'`. In all other environments (development, test, etc.), it behaves exactly like the native `console` methods.

## Tag-Based Filtering

Control which logs are displayed during development using optional tags. This is useful for filtering logs by category, feature, or component.

### Configuration

**Option 1: Auto-Load (Recommended)**

Simply create a config file in your project root with one of these names:
- `dev-log.config.json`
- `.devlogrc.json`
- `.devlogrc`

The config file will be automatically loaded when the module is imported (in non-production environments only).

```json
{
  "disabledTags": ["verbose", "debug", "trace"]
}
```

No additional code needed - just import and use:

```typescript
import { dev } from '@onamfc/developer-log';

// Config already loaded automatically!
// All tags show except those in disabledTags
dev.log('Query executed', { tag: 'database' }); // Shows
dev.log('Verbose details', { tag: 'verbose' }); // Hidden
```

**Option 2: Programmatic Configuration**

For dynamic configuration or when you need to set tags based on runtime conditions:

```typescript
import { dev } from '@onamfc/developer-log';

// Hide specific tags, show everything else
dev.configure({ disabledTags: ['verbose', 'debug', 'trace'] });
```

**Where to place `dev.configure()`:**
- In your main entry point (`index.ts`, `app.ts`, `server.ts`, `main.ts`)
- Before any code that uses tagged logs
- In framework initialization:
  - **Express/Node.js**: Top of your main server file
  - **Next.js**: In `_app.tsx` or `layout.tsx`
  - **React**: In `index.tsx` or `App.tsx`
  - **NestJS**: In `main.ts` before `app.listen()`

**Option 3: Explicit File Loading**

Load a config file from a specific path:

```typescript
import { dev } from '@onamfc/developer-log';

dev.loadConfig('./config/dev-log.config.json');
```

**Config File Format:**

```json
{
  "disabledTags": ["verbose", "debug", "trace"]
}
```

All tags are shown by default. Only tags in `disabledTags` will be hidden.

**Configuration Priority:**

If multiple configuration methods are used, the last one wins:
1. Auto-loaded config (happens first, at module import)
2. Programmatic `dev.configure()` (overrides auto-loaded config)
3. Explicit `dev.loadConfig()` (overrides everything)

### Using Tags

Add a tag by passing an options object as the last parameter:

```typescript
// Tagged logs - only show if tag is enabled
dev.log('Database query executed', result, { tag: 'database' });
dev.error('API request failed', error, { tag: 'api' });
dev.warn('Authentication timeout', { tag: 'auth' });

// Untagged logs - always show regardless of configuration
dev.log('Application started');
dev.error('Critical error occurred', error);
```

### Filtering Behavior

- **No configuration**: All logs (tagged and untagged) are displayed
- **With `disabledTags`**: All logs except those with disabled tags are displayed
- **Untagged logs**: Always displayed regardless of configuration
- **Production environment**: All logs are suppressed (tags have no effect)

### Practical Examples

**Scenario 1: Hiding noisy logs**

```typescript
// You have lots of verbose logs that clutter your console
dev.log('Verbose cache details', data, { tag: 'verbose' });
dev.log('Debug information', { tag: 'debug' });
dev.log('Trace data', { tag: 'trace' });
dev.log('User logged in', { tag: 'auth' }); // Important log

// Hide the noisy tags, but keep everything else
dev.configure({ disabledTags: ['verbose', 'debug', 'trace'] });
// Now: auth and all other logs show, but verbose/debug/trace are hidden
```

**Scenario 2: Production-like logging in development**

```typescript
// Disable development-only debug logs
dev.log('SQL Query: SELECT * FROM users', { tag: 'sql-debug' });
dev.log('Cache hit ratio: 85%', { tag: 'performance-debug' });
dev.error('Payment failed', error, { tag: 'payment' }); // Important

// Simulate production logging
dev.configure({ disabledTags: ['sql-debug', 'performance-debug'] });
// Only important logs show, like production
```

**Scenario 3: Dynamic configuration via environment**

```typescript
// In your main app entry point
if (process.env.DISABLE_TAGS) {
  dev.configure({
    disabledTags: process.env.DISABLE_TAGS.split(',')
  });
}

// Run with: DISABLE_TAGS=verbose,debug npm start
// All logs show except verbose and debug
```

### Supported Methods

All standard console methods are supported:

- `log` - General logging
- `error` - Error messages
- `warn` - Warning messages
- `info` - Informational messages
- `debug` - Debug messages
- `trace` - Stack trace
- `table` - Tabular data
- `dir` - Object inspection
- `dirxml` - XML/HTML element inspection
- `group` - Create a message group
- `groupCollapsed` - Create a collapsed message group
- `groupEnd` - End a message group
- `clear` - Clear the console
- `count` - Count occurrences
- `countReset` - Reset counter
- `assert` - Assertion testing
- `time` - Start a timer
- `timeEnd` - End a timer
- `timeLog` - Log elapsed time

## Why Use This?

- **Clean production builds**: No need to manually remove debug statements
- **Granular log control**: Filter logs by category/feature using tags during development
- **Reduce noise**: Focus on relevant logs without commenting out code
- **Type-safe**: Full TypeScript support
- **Zero dependencies**: Lightweight and efficient
- **Drop-in replacement**: Works exactly like `console` in development
- **Performance**: No overhead in production (all methods are no-ops)
- **Flexible filtering**: Configure via code or config file

## Migration from console

Simply replace `console` with `dev`:

```typescript
// Before
console.log('Debug message');
console.error('Error message');
console.table(data);

// After
import { dev } from '@onamfc/developer-log';

dev.log('Debug message');
dev.error('Error message');
dev.table(data);
```

**Optional: Add tags for better log organization**

```typescript
// After migration, optionally add tags
dev.log('User authenticated', user, { tag: 'auth' });
dev.log('Verbose trace data', data, { tag: 'verbose' });
dev.warn('Debug information', { tag: 'debug' });

// Hide noisy tags to clean up your console
dev.configure({ disabledTags: ['verbose', 'debug'] });
// Now 'verbose' and 'debug' logs are hidden, everything else shows
```

## Platform Support

### Node.js
Full support for all features including:
- ✅ Tag-based filtering
- ✅ Auto-load config from files
- ✅ Programmatic configuration
- ✅ File-based configuration with `loadConfig()`

### React Native / Browser
Basic logging works perfectly, with some limitations:
- ✅ All console methods work (log, error, warn, etc.)
- ✅ Tag-based filtering with programmatic configuration
- ✅ Production environment suppression
- ❌ Auto-load config files (Node.js file system not available)
- ❌ `dev.loadConfig()` (Node.js file system not available)

**React Native Usage:**

```typescript
import { dev } from '@onamfc/developer-log';

// Use programmatic configuration instead of file-based
dev.configure({ disabledTags: ['verbose', 'debug'] });

// Everything else works the same
dev.log('User logged in', { tag: 'auth' }); // Shows
dev.log('Verbose details', { tag: 'verbose' }); // Hidden
dev.error('API error', error, { tag: 'api' }); // Shows
```

## TypeScript

This package is written in TypeScript and includes type definitions out of the box.

## License

MIT