# @nitra/eslint-config

Спільна конфігурація ESLint 10 (flat config) для проєктів на Vue та Node.js.

## Вимоги

- **ESLint 10+** (тільки flat config, eslintrc більше не підтримується)
- **Node.js 20.19.0+**

## Встановлення

```sh
bun add @nitra/eslint-config -D
```

_Це лише спільна конфігурація. ESLint та плагіни потрібно встановлювати окремо або вони підтягнуться як залежності (форматування коду — окремо, наприклад oxfmt)._

## Використання

У корені проєкту створіть **`eslint.config.js`** (або `eslint.config.mjs`):

```js
import { getConfig } from '@nitra/eslint-config'

export default getConfig({
  node: ['src/server', 'scripts'], // шляхи до Node.js коду
  vue: ['src/frontend'], // шляхи до Vue 3
  vue2: [] // шляхи до Vue 2 (якщо є)
})
```

- **Тільки Node.js** — передайте лише `node`:

  ```js
  import { getConfig } from '@nitra/eslint-config'

  export default getConfig({ node: ['.'] })
  ```

- **Тільки Vue** — передайте лише `vue` або `vue2`:

  ```js
  import { getConfig } from '@nitra/eslint-config'

  export default getConfig({ vue: ['src'] })
  ```

- **Monorepo** — укажіть відповідні директорії:

  ```js
  import { getConfig } from '@nitra/eslint-config'

  export default getConfig({
    node: ['apps/api', 'packages/cli'],
    vue: ['apps/web'],
    vue2: ['apps/legacy']
  })
  ```

### Додаткові глобали (опційно)

Якщо потрібні додаткові глобальні змінні (наприклад, для Vue), їх можна додати окремим блоком у вашому `eslint.config.js` після виклику `getConfig()`:

```js
import { getConfig } from '@nitra/eslint-config'

export default [
  ...getConfig({ vue: ['src'] }),
  {
    files: ['src/**/*.{js,vue}'],
    languageOptions: {
      globals: {
        localStorage: 'readonly'
      }
    }
  }
]
```

## Що входить у конфіг

- Базові правила JS (recommended), JSDoc, **eslint-plugin-import-x** (префікс `import-x/`), Unicorn
- YAML і Markdown
- Для **Node**: eslint-plugin-n
- Для **Vue**: eslint-plugin-vue з правилами атрибутів та порядку
- Oxlint (recommended)

## Стиль коду

### `for...in` заборонено — рефакторити на `for...of`

`no-restricted-syntax` із селектором `ForInStatement` забороняє `for...in` у всіх JS-подібних файлах (`.js`, `.mjs`, `.cjs`, `.vue`). Разом із цим зникає потреба в `Object.hasOwn`-guard — він має зникнути з кодом одночасно з `for...in`.

<!-- eslint-skip -->

```js
// ❌ погано
for (const k in obj) {
  if (!Object.hasOwn(obj, k)) continue
  use(k, obj[k])
}
for (const i in arr) {
  use(arr[i])
}

// ✅ добре
for (const [k, v] of Object.entries(obj)) {
  use(k, v)
}
for (const item of arr) {
  use(item)
}
```

Альтернативи залежно від потреби: `Object.keys(obj)`, `Object.values(obj)`, `Object.entries(obj)` — або пряма ітерація масиву через `for...of`.
