npm package: @kitsuneislife/nyaa
Description: Robust unofficial API/scraper for nyaa.si with retry, cache, and advanced features
Author: kitsuneislife
Latest version: 1.1.0

# Nyaa.si Scraper/API Wrapper

[![CI](https://github.com/kitsuneislife/nyaa-scraper/workflows/CI%2FCD/badge.svg)](https://github.com/kitsuneislife/nyaa-scraper/actions)
[![npm version](https://badge.fury.io/js/%40kitsuneislife%2Fnyaa.svg)](https://badge.fury.io/js/%40kitsuneislife%2Fnyaa)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
[![codecov](https://codecov.io/gh/kitsuneislife/nyaa-scraper/branch/main/graph/badge.svg)](https://codecov.io/gh/kitsuneislife/nyaa-scraper)

Um wrapper/scraper robusto e não-oficial para o site nyaa.si, desenvolvido em TypeScript.

## � Documentação

- [🚀 Getting Started](docs/GETTING_STARTED.md) - Comece aqui!
- [📚 API Reference](docs/API.md) - Documentação completa da API
- [⚡ Quick Start](docs/QUICKSTART.md) - Guia rápido de uso
- [🧪 Testing Guide](docs/TESTING.md) - Como testar
- [🤝 Contributing](docs/CONTRIBUTING.md) - Como contribuir
- [📝 Changelog](docs/CHANGELOG.md) - Histórico de mudanças
- [🔒 Security](docs/SECURITY.md) - Política de segurança
- [📊 Summary](docs/SUMMARY.md) - Resumo do projeto

## �🚀 Funcionalidades

### Core Features
- ✅ Busca de torrents com filtros avançados
- ✅ Obtenção de detalhes completos de torrents
- ✅ Busca por usuário
- ✅ Listagem de torrents mais recentes
- ✅ Suporte a paginação
- ✅ Parsing robusto de HTML com Cheerio
- ✅ Tratamento de erros completo
- ✅ TypeScript com tipagem completa
- ✅ Suporte a categorias do Nyaa
- ✅ Identificação de uploads confiáveis (trusted)
- ✅ Links de torrent e magnet

### 🆕 Advanced Features
- ✨ **Retry automático** com exponential backoff
- ✨ **Cache em memória** para reduzir requisições
- ✨ **Download de arquivos .torrent**
- ✨ **Paginação automática** (buscar todas as páginas)
- ✨ **Validação de parâmetros** de entrada
- ✨ **Estatísticas de requisições** (total, cache hit rate, retries, etc.)
- ✨ **Configuração flexível** (timeout, retry, cache TTL)

## � Getting Started

Para começar rapidamente, consulte o [Guia de Início](docs/GETTING_STARTED.md).

## �📦 Instalação

```bash
npm install
```

## 🔧 Uso

### Inicialização Básica

```typescript
import { NyaaScraper, NyaaCategory } from '@kitsuneislife/nyaa';

// Uso básico
const scraper = new NyaaScraper();

// Com configuração avançada
const scraper = new NyaaScraper({
  timeout: 30000,
  retry: {
    maxRetries: 5,
    initialDelay: 1000,
    maxDelay: 10000,
    backoffMultiplier: 2
  },
  enableCache: true,
  cacheTTL: 300000  // 5 minutos
});
```

### Busca Básica

```typescript
// Buscar torrents
const results = await scraper.search({
  query: 'one piece',
  category: NyaaCategory.ANIME_ENGLISH,
  filter: 'trusted-only',
  page: 1,
});

console.log(results.torrents);
console.log(results.hasNextPage);
```

### Busca Avançada

```typescript
// Busca com todos os filtros
const results = await scraper.search({
  query: 'anime',
  category: NyaaCategory.ANIME_ENGLISH,
  filter: 'trusted-only', // 'no-filter' | 'no-remakes' | 'trusted-only'
  page: 1,
  sortBy: 'seeders', // 'id' | 'size' | 'seeders' | 'leechers' | 'downloads'
  order: 'desc', // 'asc' | 'desc'
});
```

### 🆕 Buscar Todas as Páginas

```typescript
// Buscar automaticamente múltiplas páginas
const allTorrents = await scraper.searchAllPages({
  query: 'one piece',
  filter: 'trusted-only'
}, 5); // Máximo de 5 páginas

console.log(`Encontrados ${allTorrents.length} torrents`);
```

### 🆕 Download de Arquivo .torrent

```typescript
import fs from 'fs/promises';

// Baixar arquivo .torrent
const torrentData = await scraper.downloadTorrent('1234567');
await fs.writeFile('myfile.torrent', torrentData);
console.log('Arquivo .torrent salvo!');
```

### 🆕 Estatísticas de Uso

```typescript
// Fazer algumas requisições
await scraper.search({ query: 'test' });
await scraper.search({ query: 'test' }); // Virá do cache

// Obter estatísticas
const stats = scraper.getStats();
console.log(`Total de requisições: ${stats.totalRequests}`);
console.log(`Respostas cacheadas: ${stats.cachedResponses}`);
console.log(`Taxa de cache: ${(stats.cachedResponses / (stats.totalRequests + stats.cachedResponses) * 100).toFixed(2)}%`);

// Limpar cache e estatísticas
scraper.clearCache();
scraper.resetStats();
```

### Obter Detalhes de um Torrent

```typescript
const details = await scraper.getTorrent('1234567');

console.log(details.title);
console.log(details.description);
console.log(details.files); // Lista de arquivos
console.log(details.infoHash);
console.log(details.magnetLink);
```

### Buscar por Usuário

```typescript
const userTorrents = await scraper.searchByUser('subsplease', {
  page: 1,
  sortBy: 'id',
  order: 'desc',
});
```

### Obter Torrents Mais Recentes

```typescript
const latest = await scraper.getLatest(1);
```

## 📋 API

### `NyaaScraper`

#### Métodos

- **`search(options: SearchOptions): Promise<SearchResult>`**
  - Busca torrents com filtros opcionais

- **`getTorrent(id: string): Promise<NyaaTorrentDetails>`**
  - Obtém informações detalhadas de um torrent específico

- **`getLatest(page?: number): Promise<SearchResult>`**
  - Obtém os torrents mais recentes

- **`searchByUser(username: string, options?: SearchOptions): Promise<SearchResult>`**
  - Busca torrents de um usuário específico

### Tipos

#### `SearchOptions`

```typescript
interface SearchOptions {
  query?: string;
  category?: string;
  filter?: 'no-filter' | 'no-remakes' | 'trusted-only';
  page?: number;
  sortBy?: 'id' | 'size' | 'comments' | 'seeders' | 'leechers' | 'downloads';
  order?: 'asc' | 'desc';
  user?: string;
}
```

#### `NyaaTorrent`

```typescript
interface NyaaTorrent {
  id: string;
  title: string;
  category: string;
  torrentLink: string;
  magnetLink: string;
  size: string;
  date: string;
  seeders: number;
  leechers: number;
  downloads: number;
  link: string;
  uploader?: string;
  isTrusted?: boolean;
  isRemake?: boolean;
}
```

#### `NyaaCategory`

```typescript
enum NyaaCategory {
  ALL = '0_0',
  ANIME = '1_0',
  ANIME_AMV = '1_1',
  ANIME_ENGLISH = '1_2',
  ANIME_NON_ENGLISH = '1_3',
  ANIME_RAW = '1_4',
  AUDIO = '2_0',
  AUDIO_LOSSLESS = '2_1',
  AUDIO_LOSSY = '2_2',
  LITERATURE = '3_0',
  // ... e mais
}
```

## 🧪 Testes

### Executar Testes

```bash
# Executar todos os testes
npm test

# Executar testes com coverage
npm run test:coverage

# Executar testes em watch mode
npm run test:watch

# Executar testes de integração (cuidado com rate limiting!)
INTEGRATION_TESTS=true npm test
```

### Cobertura de Testes

Este projeto mantém alta cobertura de testes:
- ✅ Testes unitários para todas as funções principais
- ✅ Testes de integração (opcionais)
- ✅ Testes de parsing HTML
- ✅ Testes de tratamento de erros

## 🧪 Executar Exemplos

```bash
npm run example
```

## 🏗️ Build

```bash
npm run build
```

## 🤝 Contribuindo

Contribuições são bem-vindas! Por favor, leia [CONTRIBUTING.md](docs/CONTRIBUTING.md) para detalhes sobre nosso código de conduta e processo de submissão de pull requests.

### Desenvolvimento

```bash
# Instalar dependências
npm install

# Rodar em modo dev
npm run dev

# Lint
npm run lint

# Format
npm run format
```

## ⚠️ Aviso Legal

Este é um projeto não-oficial e não tem afiliação com nyaa.si. Use de forma responsável e respeite os termos de serviço do site.

## 📄 Licença

MIT

## 🛠️ Tecnologias

- TypeScript
- Axios (HTTP client)
- Cheerio (HTML parsing)
- Node.js