npm package: @mjfwebb/enforce-logger-snake-case
Description: An ESLint plugin that enforces snake_case naming convention for object keys passed to Logger methods.
Latest version: 1.0.0

# @mjfwebb/enforce-logger-snake-case

An ESLint plugin that enforces snake_case naming convention for object keys passed to Logger methods, ensuring consistent and predictable logging throughout your codebase.

## Installation

```bash
npm install --save-dev @mjfwebb/enforce-logger-snake-case
```

## Usage

Register the plugin in your ESLint configuration.

### ESLint Flat Config (`eslint.config.js`)

```js
import enforceLoggerSnakeCase from "@mjfwebb/enforce-logger-snake-case";

export default [
  {
    plugins: {
      "enforce-logger-snake-case": enforceLoggerSnakeCase,
    },
    rules: {
      // Enforce snake_case keys in Logger method calls
      "enforce-logger-snake-case/enforce-logger-snake-case": "error",
    },
  },
];
```

### Legacy config (`.eslintrc.cjs`)

```js
module.exports = {
  plugins: ["enforce-logger-snake-case"],
  rules: {
    "enforce-logger-snake-case/enforce-logger-snake-case": "error",
  },
};
```

## Rule: enforce-logger-snake-case/enforce-logger-snake-case

**Enforces snake_case naming convention for object keys when passing objects to Logger methods.**

This rule applies to the following Logger methods:

- `Logger.trace()`
- `Logger.debug()`
- `Logger.info()`
- `Logger.warn()`
- `Logger.error()`

### Examples

#### ❌ Incorrect

```js
// camelCase and PascalCase keys
Logger.info({ userId: 123 });

Logger.debug({ requestCount: 5 });

Logger.error({ errorMessage: "failed", ErrorCode: 500 });

Logger.warn({ connectionTimeout: 30 });

Logger.trace({ APIResponseTime: 100 });

// Mixed naming conventions
Logger.info({
  user_id: 1,
  userName: "test", // camelCase not allowed
  userEmail: "test@example.com", // camelCase not allowed
});

// Shorthand properties with camelCase variable names
const userId = 123;
Logger.info({ userId }); // will be converted to { user_id: userId }

// Quoted identifiers (even if already snake_case)
Logger.info({ "user_id": 123 }); // quotes should be removed for consistency

// Spread properties (cannot be validated)
Logger.info({ ...otherObject });
Logger.info({ user_id: 1, ...otherObject });

// Computed properties (cannot be validated)
const key = "user_id";
Logger.info({ [key]: 123 });
Logger.info({ [getUserIdKey()]: 123 });
```

#### ✅ Correct

```js
// Unquoted snake_case identifiers
Logger.info({ user_id: 123 });

Logger.debug({ request_count: 5 });

Logger.error({ error_message: "failed", error_code: 500 });

Logger.warn({ connection_timeout: 30 });

Logger.trace({ api_response_time: 100 });

// Single word keys are valid
Logger.info({ message: "test" });
Logger.debug({ status: "ok" });

// Multiple snake_case keys
Logger.info({
  user_id: 1,
  user_name: "test",
  user_email: "test@example.com",
});

// Shorthand properties with snake_case variable names
const user_id = 123;
Logger.info({ user_id });

// String literals with special characters (allowed since they can't be identifiers)
Logger.info({ "user-id": 123 });
Logger.info({ "Content-Type": "application/json" });

// Other loggers are not affected
console.log({ userId: 123 });
someOtherLogger.info({ userId: 123 });

// Non-object arguments are allowed
Logger.info("simple message");
Logger.info(123);
Logger.info();
```

### Auto-fix

This rule includes an automatic fix that converts camelCase and PascalCase keys to snake_case:

```js
// Before (auto-fix)
Logger.info({ userId: 123, requestCount: 5 });

// After (auto-fix applied)
Logger.info({ user_id: 123, request_count: 5 });
```

Shorthand properties are expanded when needed:

```js
// Before (auto-fix)
const userId = 123;
Logger.info({ userId });

// After (auto-fix applied)
const userId = 123;
Logger.info({ user_id: userId });
```

Quoted identifiers are unquoted:

```js
// Before (auto-fix)
Logger.info({ "user_id": 123 });
Logger.info({ "userId": 456 });

// After (auto-fix applied)
Logger.info({ user_id: 123 });
Logger.info({ user_id: 456 });
```

Run ESLint with the `--fix` flag to automatically convert all keys to snake_case:

```bash
eslint --fix .
```

### Rule Details

This rule enforces several constraints for consistent logging:

1. **snake_case required**: All property names must use snake_case (lowercase with underscores)
2. **No quoted identifiers**: Property names that could be valid identifiers must not be quoted
3. **No spread properties**: Spread syntax (`...object`) is not allowed as properties cannot be validated
4. **No computed properties**: Computed property names (`[key]`) are not allowed as they cannot be validated at lint time

### Notes

- Only applies to objects passed directly as the first argument to Logger methods
- Does not affect other logging libraries or console methods
- Snake_case format: lowercase letters and numbers, with underscores separating words
- Single word keys (all lowercase) are valid
- Valid pattern: `^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$`
- Auto-fix converts camelCase and PascalCase to snake_case (e.g., `userId` → `user_id`, `APIResponseTime` → `api_response_time`)
- String literals with special characters (hyphens, spaces, etc.) are allowed since they require quotes

## License

MIT