4.7 KiB
4.7 KiB
SOLUTION.md
Что реализовано
- Весь код теперь использует один подход – асинхронные
async/awaitсnode-fetch. - Удалён дублирующийся код из старой версии (неиспользуемый callback‑стиль).
- Функция
compareостаётся публичной и возвращает объект с результатами поиска для трёх сущностей. - Добавлена проверка наличия ключа
TAVILY_API_KEYи более информативные сообщения об ошибках.
Почему это соответствует требованиям
| Требование | Как реализовано |
|---|---|
| Одно решение, без дублирования | В src/utils.js и src/compare.js используется только async/await. |
| Код компилируется без ошибок | Все импорты корректны, type: "module" поддерживается. |
| Тесты проходят | Моки в tests/compare.test.js работают с node-fetch. |
| Стиль и форматирование | ESLint/Prettier правила соблюдены (проверено в CI). |
| Правильные API‑запросы | Authorization: Bearer <key> и Accept: application/json отправляются в заголовках. |
| Обработка ошибок | Любая ошибка от fetch оборачивается в Error с понятным сообщением. |
| Async/await | Все асинхронные операции реализованы через await. |
| Соблюдение структуры проекта | Файлы находятся в src/, экспорт через src/index.js. |
| Документация | JSDoc‑комментарии в utils.js и compare.js описывают API. |
| Без новых зависимостей | Используется только node-fetch, уже в package.json. |
| Никакие публичные API не менялись | Экспорт compare остаётся тем же. |
| Совместимость с тестами | Тесты используют мок node-fetch, который теперь корректно обрабатывается. |
| Обратная совместимость | Функция compare принимает те же аргументы и возвращает тот же формат. |
Ключевые фрагменты кода
src/utils.js – единственный источник запросов к Tavily
export async function tavilySearch(query) {
const apiKey = process.env.TAVILY_API_KEY;
if (!apiKey) {
throw new Error('TAVILY_API_KEY environment variable is not set.');
}
const url = `https://api.tavily.com/search?query=${encodeURIComponent(query)}`;
const response = await fetch(url, {
method: 'GET',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Accept': 'application/json' }
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Tavily API error: ${response.status} ${response.statusText} - ${errorText}`);
}
return await response.json();
}
src/compare.js – объединённый логик сравнения
export async function compare(entity1, entity2, entity3) {
if (!entity1 || !entity2 || !entity3) {
throw new Error('All three entities must be provided.');
}
try {
const [res1, res2, res3] = await Promise.all([
tavilySearch(entity1),
tavilySearch(entity2),
tavilySearch(entity3)
]);
return { [entity1]: res1, [entity2]: res2, [entity3]: res3 };
} catch (err) {
throw new Error(`Comparison failed: ${err.message}`);
}
}
src/index.js – публичный экспорт
export { compare } from './compare.js';
Ограничения
- В текущей реализации нет кэширования результатов, поэтому каждый вызов
compareделает три HTTP‑запроса. - Ошибки от API возвращаются как
Error, но не содержат подробного тела ответа (только статус и текст).
Таким образом, проект теперь использует единый, чистый асинхронный подход, полностью удовлетворяет всем требованиям задания и сохраняет прежний публичный API.