diff --git a/README.md b/README.md index 89c70f1..6f81fa2 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,39 @@ -# API CodeGen +# @gromlab/api-codegen CLI утилита для генерации TypeScript API клиента из OpenAPI спецификации. -## Установка - -```bash -bun install -``` - ## Использование ```bash -api-codegen -u -i -o [-n ] +npx @gromlab/api-codegen -i -o [-n ] [--swr] ``` **Аргументы:** -- `-u, --url ` - Базовый URL API -- `-i, --input ` - Путь к OpenAPI файлу (локальный или URL) +- `-i, --input ` - Путь к OpenAPI файлу (локальный файл или URL) - `-o, --output ` - Директория для сохранения файлов -- `-n, --name ` - Имя сгенерированного файла (опционально) +- `-n, --name ` - Имя сгенерированного файла (опционально, по умолчанию из `spec.info.title`) +- `--swr` - Генерировать SWR хуки для React **Примеры:** ```bash # Локальный файл -api-codegen -u https://api.example.com -i ./openapi.json -o ./src/api +npx @gromlab/api-codegen -i ./openapi.json -o ./src/api # URL на спецификацию -api-codegen -u https://api.example.com -i https://petstore.swagger.io/v2/swagger.json -o ./src/api +npx @gromlab/api-codegen -i https://httpbin.org/spec.json -o ./src/api # С кастомным именем файла -api-codegen -u https://api.example.com -i ./openapi.json -o ./src/api -n MyApiClient +npx @gromlab/api-codegen -i ./openapi.json -o ./src/api -n MyApi + +# С генерацией SWR хуков +npx @gromlab/api-codegen -i ./openapi.json -o ./src/api --swr ``` -## Пример использования +## Пример использования сгенерированного кода ```typescript -import { Api, HttpClient } from './src/api/Api'; +import { Api, HttpClient } from './src/api/MyApi'; const httpClient = new HttpClient(); httpClient.setSecurityData({ token: 'jwt-token' }); @@ -48,12 +45,6 @@ const user = await api.auth.getProfile(); // POST запрос const result = await api.auth.login({ email, password }); - -// React + SWR -function Profile() { - const { data } = useSWR('/auth/me', () => api.auth.getProfile()); - return
{data?.email}
; -} ``` ## Разработка @@ -65,49 +56,24 @@ bun run build ### Тестирование -Проект использует комплексную систему тестирования с максимальным покрытием (~72 тестовых кейса). - -**Запуск всех тестов:** ```bash +# Все тесты bun test + +# Юнит тесты +bun run test:unit + +# Интеграционные тесты +bun run test:integration + +# Watch режим +bun run test:watch + +# С coverage +bun run test:coverage ``` -**Только юнит тесты:** -```bash -bun test:unit -``` - -**Только интеграционные тесты:** -```bash -bun test:integration -``` - -**Watch режим:** -```bash -bun test:watch -``` - -**С coverage:** -```bash -bun test:coverage -``` - -Подробная документация по тестированию доступна в [`tests/README.md`](tests/README.md). - -### Структура тестов - -- **Юнит тесты** - CLI, генератор, утилиты, валидация -- **Интеграционные тесты** - E2E генерация, сгенерированный клиент -- **Тестовые фикстуры** - 7 OpenAPI спецификаций для различных сценариев -- **Mock сервер** - для тестирования HTTP запросов - -**Покрываемые сценарии:** -- ✅ CLI команды и обработка ошибок -- ✅ Генерация TypeScript кода -- ✅ Компиляция сгенерированного кода -- ✅ HTTP запросы с mock сервером -- ✅ Аутентификация (Bearer tokens) -- ✅ Edge cases (Unicode, большие спецификации) +Подробная документация по тестированию в [`tests/README.md`](tests/README.md). ## Лицензия diff --git a/package.json b/package.json index 6ffd4c5..89b0f2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gromlab/api-codegen", - "version": "1.0.5", + "version": "1.0.7", "description": "CLI tool to generate TypeScript API client from OpenAPI specification", "type": "module", "bin": { diff --git a/src/generator.ts b/src/generator.ts index 864daf5..19e3fd0 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -33,7 +33,20 @@ export async function generate(config: GeneratorConfig): Promise { url = config.inputPath; // Загружаем спецификацию для получения info.title const response = await fetch(url); - spec = await response.json(); + if (!response.ok) { + throw new Error( + `Failed to fetch OpenAPI spec from ${url}: ${response.status} ${response.statusText}` + ); + } + const text = await response.text(); + try { + spec = JSON.parse(text); + } catch { + throw new Error( + `Failed to parse OpenAPI spec from ${url} as JSON. ` + + `Response starts with: "${text.slice(0, 50)}..."` + ); + } } else { inputPath = resolve(config.inputPath); spec = await readJsonFile(inputPath);