# Custom ESLint Rules

This directory contains custom ESLint rules for the orchardgo project.

## Available Rules

### `no-nested-i18n-calls`

**Type:** Problem
**Recommended:** Yes

This rule ensures translations happen during rendering by preventing `formatMessage` and `formatUpperCase` calls outside of React components, custom hooks, and JSX.

#### Problem

Calling `formatMessage()` outside of rendering contexts (in utility functions, at module level, etc.) causes translation bugs where the translated text cannot be properly localized. Translations must happen at the point of use (during rendering) to work correctly.

#### What This Rule Catches

1. **formatMessage/formatUpperCase in utility functions**
2. **formatMessage/formatUpperCase at module/file level**
3. **Nested i18n calls** (double translation)

#### What This Rule Allows

- ✅ formatMessage in React components (functions starting with uppercase)
- ✅ formatMessage in custom hooks (functions starting with 'use')
- ✅ formatMessage inside JSX expressions

#### Examples

❌ **Incorrect:**

```javascript
// ❌ Utility function - translation happens outside rendering
const getDisplayName = () => {
    return formatMessage('user.name');
};

// ❌ Module level - translation happens at import time
const TITLE = formatMessage('page.title');

// ❌ Nested calls - double translation
const text = formatUpperCase(formatMessage('some.key'));

// ❌ Any function that's not a Component or Hook
const formatTitle = (key) => {
    return formatMessage(key);
};
```

✅ **Correct:**

```javascript
// ✅ Return the key, translate at point of use
const getDisplayNameKey = () => {
    return 'user.name';
};

// ✅ React Component - translation during rendering
const MyComponent = () => {
    const name = formatMessage('user.name');
    return <div>{name}</div>;
};

// ✅ Custom Hook - part of rendering flow
const useTitle = () => {
    return formatMessage('page.title');
};

// ✅ Inside JSX - direct rendering
const Header = () => {
    return <h1>{formatMessage('header.title')}</h1>;
};

// ✅ Single translation at point of use
const text = formatUpperCase('some.key');
```

#### Why This Matters

- **Correct localization:** Translations happen when the component renders with the user's current language
- **Prevents caching issues:** Translation keys can be reused across different contexts
- **Better performance:** Translation happens only when needed during render
- **Avoids double-translation bugs:** Prevents passing already-translated strings to translation functions

## Usage

The custom rules are automatically loaded when running the lint command:

```bash
yarn lint
```

This is configured in `package.json` with the `--rulesdir eslint-rules` flag.

To enable the rule in your `.eslintrc.js`, add:

```javascript
rules: {
    'no-nested-i18n-calls': 'error'
}
```

## Development

To add new custom rules:

1. Create a new `.js` file in this directory
2. Export an ESLint rule object with `meta` and `create` properties
3. Add the rule to `index.js`
4. Update this README with documentation

## Related Issues

-   GO-4217: Total Streams translation bug
