# Code Style

## Общие правила

+ Используйте краткие и описательные имена переменных, функций и классов.
+ Поддерживайте чистоту кода, избегая дублирования и излишней сложности.
+ Пишите комментарии только там, где это необходимо для пояснения сложного или нетривиального кода.

## Форматирование кода

+ Используйте 2 пробела в качестве отступа (для каждого уровня вложенности).
+ Используйте одинарные кавычки (') для строковых литералов.
+ Размещайте открывающую фигурную скобку на той же строке, что и соответствующая конструкция (функция, класс, условие и т.д.).
+ Используйте точку с запятой (;) в конце каждого выражения.

```typescript
// Пример форматирования кода

function greet(name: string): void {
  console.log('Hello, ' + name);
}

if (condition) {
  // ...
} else {
  // ...
}

class MyClass {
  // ...
}
```

## Объявление и наименование переменных

+ Используйте ключевое слово const для объявления переменных, значения которых не изменяются.
+ Используйте ключевое слово let для объявления переменных, значения которых могут изменяться.
+ Избегайте использования ключевого слова var для объявления переменных.
+ Используйте camelCase для имен переменных.
+ Используйте описательные имена переменных, чтобы обеспечить понятность их назначения.
+ Числовые и строковые константы должны быть названы в верхнем регистре.

```typescript
// Пример объявления переменных
const PI = 3.14;
let counter = 0;

// Избегайте использования var
var x = 5;

// Пример наименования переменных
const FIRST_NAME = 'John';
let age = 30;
```

## Функции

+ Используйте camelCase для имен функций.
+ Используйте описательные имена функций, отражающие их назначение и выполняемые действия.

```typescript
// Пример объявления функций

function calculateSum(a: number, b: number): number {
  return a + b;
}

function printMessage(message: string): void {
  console.log(message);
}
```

## Классы

+ Используйте PascalCase для имен классов.
+ Используйте описательные имена классов, отражающие их назначение и роль в системе.
+ Используйте интерфейсы для описания объектов

```typescript
// Пример объявления класса

class UserService {
  // ...
}
```

## Экспорт и импорт модулей

+ Используйте именованный экспорт (export) для экспорта функций, классов или переменных из модуля.
+ Не используйте дефолтный экспорт (export default) для экспорта функций, классов или переменных из модуля.
+ Импортируйте экспортируемые элементы с использованием фигурных скобок {}.

```typescript
// Пример экспорта и импорта модулей

// Файл moduleA.ts
export function greet(name: string): void {
  console.log('Hello, ' + name);
}

// Файл moduleB.ts
import { greet } from './moduleA';
```

## Условные конструкции

+ Используйте фигурные скобки для отделения блока кода, даже если он в одну строку
+ Не используйте вычисления внутри if
+ Не используйте длинные составные условия
+ Используйте явное сравнение с null или undefined
+ Избегайте использования вложенных условий
+ Используйте тернарный оператор для простых проверок

```typescript
// Плохо (без фигурных скобок)
if (condition) doSomething();
// Хорошо (легко понять область исполнения кода)
if (condition) {
  doSomething();
}

// Плохо (используется вычисление внутри if)
if (arr.includes(value)) {}
// Хорошо (используется константа с понятным названием)
const isValid = arr.includes(value);
if (isValid) {}

// Плохо (используется длинное составное условие)
if ((countryCode === 'RU' || countryCode === 'KZ') && phoneNumber.length > 12) {}
// Хорошо (используется константа с понятным названием)
const isValidPhone = (countryCode === 'RU' || countryCode === 'KZ') && phoneNumber.length > 12;
if (isValidPhone) {}

// Плохо (используется неявное преобразование типов)
if (value == null) {}
// Хорошо (используется явное сравнение)
if (value === null) {}

// Плохо (вложенные условия)
if (condition1) {
  if (condition2) {
    // ...
  }
}
// Хорошо (без вложенных условий)
if (condition1 && condition2) {}

// Плохо (используется if-else для простой проверки)
let result;
if (condition) {
  result = 'Condition is true';
} else {
  result = 'Condition is false';
}
// Хорошо (используется тернарный оператор)
const result = condition ? 'Condition is true' : 'Condition is false';
```

## Структура нового модуля

> Модули находятся в папке `src/{module_name}`.

Структура модуля:

```bash
modulename
  index.ts
  types.ts
  events.ts
  constants.ts
  moduleName.ts
```

+ moduleName.ts - основной файл, где находится код модуля
+ types.ts - файл с типами модуля
+ events.ts - события модуля, если они есть
+ constants.ts - константы, используемые в модуле
+ index.ts - файл для экспорта типов и самого модуля. На основе этого модуля  создается документация, поэтому все публичные типы для модуля должны быть экспортированы. [Пример](./src/auth/index.ts)

## Структура директории тестов

> Тесты находятся в папке `__tests__/{module_name}`

Файлы тестов должны иметь в названии `.tests.`. Пример:

```bash
__tests__/validator/validator.tests.ts
```

### `__tests__` - тут лежат файлы с jest тестами

+ `{module_name}`
  + {suite_name}.tests.ts
+ jest-global-mock.js - моки методов и переменных
+ utils.ts - полезные функции для использования в тестах

## Структура файлов Web SDK

### `src` - тут лежат файлы web sdk

+ `core` - классы и методы, которые используются при создании модулей
+ `{module_name}` - файлы модуля
+ `utils` - полезные функции для использования в проекте
+ constants.ts - общие константы для использования в проекте
+ index.ts - файл с публичными экспортами
