npm package: @my-ul/eslint-plugin
Description: A set of custom eslint rules that make working with myUL projects easier.
Latest version: 19.0.0

# @my-ul/eslint-plugins

A set of custom eslint rules that make working with myUL projects
easier.

## Installation

If you are using Angular, make sure `angular-eslint` is installed
first.

```bash
npm install --save-dev @my-ul/eslint-plugin
```

## Rules

### `no-constructor-literal-initializers`

**has fixer**

This rule disallows initializing class properties in the constructor.

#### Disallowed

These are examples of incorrect code.

```ts
class MyClass {
  myProperty: number;
  constructor() {
    this.myProperty = 0;
  }
}
```

#### Allowed

These are examples of correct code.

```ts
class MyClass {
  myProperty = 0;
}
```

#### Configuration

```mjs
import myul from '@my-ul/eslint-plugin';
import tsParser from '@typescript-eslint/parser';

export default [
    {
        files: ['*.ts'],
        // this rules requires @typescript-eslint/parser for type checking
        languageOptions: {
            parser: tsParser,
            parserOptions: {
                project: './tsconfig.json'
            }
        },
        plugins: {
            myul
        }
        rules: {
            'myul/no-constructor-literal-initializers': ['error']
        }
    }
]
```

### `no-mismatched-fallback-labels`

**has fixer**

This rule will ensure that uses of `useTranslation` hooks are using
the correct fallback label.

#### Configuration

```mjs

import myul from '@my-ul/eslint-plugin';

/***
 * The path to the default dictionary file.
 **/
const defaultDictionaryPath = 'assets/i18n/en-US.json';

/***
 * The action to take when a mismatch is found.
 * 'fix' will automatically update the fallback label.
 * 'report' will only report the issue.
 **/
const action = 'fix';
export default [
    {
        files: ['**/*.ts'],
        plugins: {
            myul
        }
        rules: {
            'myul/no-mismatched-fallback-labels': ['error', {
                defaultDictionaryPath,
                action
            }]
        }
    }
]
```

#### Disallowed

These are examples of incorrect code.

```json
// assets/i18n/en-US.json
{
  "foo": "bar"
}
```

```ts
import { useTranslation } from '@my-ul/tod-angular-client';

@Component({
  selector: 'app-my-component',
  template: `
    @let i18n = translate();
    <div>{{ i18n.foo }}</div>
  `,
})
export class MyComponent {
  translate = useTranslationSignal({
    foo: 'baz', // eslint error: 'foo' does not match the fallback label 'bar'
  });
}
```

### `no-useless-rxjs-operators`

**has fixer**

This rule detects and removes useless RxJS operators, such as an empty
`.pipe()` or `map(x => x)` and `throwError(e => { throw e })`.

#### Disallowed

These are examples of incorrect code.

```ts
import { of, map, catchError } from 'rxjs';

export const myFunction = (number) =>
  of(number).pipe(
    map((x) => x),
    catchError((e) => {
      throw e;
    }),
  );
```

#### Allowed

These are examples of correct code.

```ts
import { of } from 'rxjs';

export const myFunction = (number) => of(number);
```

### `prefer-inject-function`

**has fixer**

This rule will migrate from constructor injection to the
`inject(token)` function.

#### Disallowed

These are examples of incorrect code.

```ts
import { Injectable, PLATFORM_ID } from '@angular/core';

@Injectable()
export class MyService {
  constructor(
    private dependency: Dependency,
    @Inject(PLATFORM_ID) private platformId,
  ) {}
}
```

#### Allowed

These are examples of correct code. (Note: the empty constructor
should be removed by a different rule).

```ts
import { Injectable, inject } from '@angular/core';

@Injectable()
export class MyService {
  constructor() {}
  private dependency = inject(Dependency);
  private platformId = inject(PLATFORM_ID);
}
```

#### Configuration

- `autoFix` (default: `true`): Automatically fix the code. When false,
  the rule will only report issues and suggest fixes.

```mjs
import myul from '@my-ul/eslint-plugin';

/**
 * Fix the code automatically.  False is useful for CI/CD pipeline checks.
 */
const autoFix = true;

export default [
    {
        files: ['**/*.ts'],
        plugins: {
            myul
        }
        rules: {
            'myul/prefer-inject-function': ['error', { autoFix: true }]
        }
    }
]
```

### `prefer-signal-primitives`

**has fixer**

This rule will automatically wrap primitive values in a signal. Most
accesses will also be updated.

#### Disallowed

These are examples of incorrect code.

```ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component',
  template: ` <div>{{ isOpen ? 'Close' : 'Open' }}</div> `,
})
export class MyComponent {
  isOpen = false;

  toggle() {
    this.isOpen = !this.isOpen;
  }
}
```

#### Allowed

These are examples of correct code.

```ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component',
  template: ` <div>{{ isOpen() ? 'Close' : 'Open' }}</div> `,
})
export class MyComponent {
  isOpen = signal(false);

  toggle() {
    this.isOpen.set(!this.isOpen());
  }
}
```

### `remove-restricted-syntax`

**has fixer**

This rule will remove restricted syntax from the codebase. This can be
used to perform production builds.

#### Configuration

Provide an array of objects of `{ remove: 'selector' }` or
`{ report: 'selector' }`. The `remove` option will remove the syntax
from the codebase, while the `report` option will only report the
syntax (suitable for CI/CI pre checks).

#### Example (HTML rule)

Automatically remove all `data-testid` attributes from the HTML at
build time.

```mjs
import myul from '@my-ul/eslint-plugin';
import templateParser from '@angular-eslint/template-parser';

export default [
  {
    files: ['*.html'],
    plugins: {
      myul,
    },
    parser: templateParser,
    rules: {
      // Remove all data-testid attributes
      'myul/remove-restricted-syntax': [
        'error',
        { report: 'Element$1 > TextAttribute[name=data-testid]' },
      ],
    },
  },
];
```

#### Example (TypeScript rule)

Automatically remove all `console.*` and `debugger` statements from
the TypeScript codebase at build time.

```mjs
import myul from '@my-ul/eslint-plugin';

export default [
  {
    files: ['*.ts'],
    plugins: {
      myul,
    },
    // requires @typescript-eslint/parser
    // parser: '@typescript-eslint/parser',
    rules: {
      'myul/remove-restricted-syntax': [
        'error',
        { remove: 'CallExpression[callee.name=console]' },
        { remove: 'DebuggerStatement' },
      ],
    },
  },
];
```