UNPKG

campeonato-brasileiro-api

Version:

API moderna para consultar classificação e rodada atual das Séries A, B, C e D do Brasileirão

577 lines (465 loc) 12.1 kB
# campeonato-brasileiro-api [![npm](https://img.shields.io/npm/v/campeonato-brasileiro-api.svg)](https://www.npmjs.com/package/campeonato-brasileiro-api) [![npm](https://img.shields.io/npm/dt/campeonato-brasileiro-api.svg)](https://www.npmjs.com/package/campeonato-brasileiro-api) API moderna para consultar classificação e rodada atual das Séries A, B, C e D do Brasileirão. ## Compatibilidade - Node.js `18+` - Sem dependências de runtime - Compatível com `require()` e `import` ## Instalação ```bash npm install campeonato-brasileiro-api ``` ## Métodos disponíveis | Método | Descrição | | --- | --- | | `listSeries()` | Lista as séries suportadas | | `getCompetition(serie, options?)` | Retorna o payload completo normalizado | | `getStandings(serie, options?)` | Retorna apenas classificação e legendas | | `getTable(serie, options?)` | Retorna uma tabela única | | `getGroups(serie, options?)` | Retorna os grupos da Série D | | `getRounds(serie, options?)` | Retorna a rodada atual normalizada | | `getCurrentRound(serie, options?)` | Alias de `getRounds()` | | `tabela(serie, options?)` | Helper legado de classificação | | `rodadaAtual(serie, rodada?, options?)` | Helper legado de jogos da rodada | ## Uso rápido ### CommonJS ```js const brasileirao = require('campeonato-brasileiro-api'); const data = await brasileirao.getCompetition('a'); console.log(data.competition.name); console.log(data.tables[0].entries[0].team.name); console.log(data.rounds[0].matches.length); ``` ### ESM ```js import { getStandings, getRounds } from 'campeonato-brasileiro-api'; const standings = await getStandings('b'); const rounds = await getRounds('b'); console.log(standings.tables[0].entries[0]); console.log(rounds.rounds[0].matches); ``` ## Exemplos completos ### `listSeries()` ```js const brasileirao = require('campeonato-brasileiro-api'); const series = brasileirao.listSeries(); console.log(series); ``` Saída esperada: ```js [ { code: 'a', slug: 'brasileirao-serie-a', name: 'Campeonato Brasileiro Série A', grouped: false, url: 'https://...' }, { code: 'd', slug: 'brasileirao-serie-d', name: 'Campeonato Brasileiro Série D', grouped: true, url: 'https://...' } ] ``` ### `getCompetition(serie, options?)` Retorna o contrato principal do pacote: - metadados da competição - legendas - tabelas - rodadas - jogos da rodada atual ```js const brasileirao = require('campeonato-brasileiro-api'); const competition = await brasileirao.getCompetition('a'); console.log(competition); ``` Exemplo de shape: ```js { competition: { code: 'a', slug: 'brasileirao-serie-a', name: 'Campeonato Brasileiro Série A 2026', season: 2026, sport: 'futebol', grouped: false, phase: { slug: 'fase-unica-campeonato-brasileiro-2026', disclaimer: '', description: 'Pontos Corridos', typeId: '1', grouped: false }, edition: { name: 'Campeonato Brasileiro Série A 2026', location: 'Brasil', startsAt: '2026-03-28', endsAt: '2026-12-06', regulation: '...' }, source: { provider: 'source', url: 'https://...', resourceId: '...', tUUID: '...' } }, grouped: false, legends: [ { id: 1, name: 'Libertadores', color: '#0000ff' } ], tables: [ { id: 'overall', name: 'Classificacao geral', round: { number: 13, total: 38, label: '13a rodada' }, entries: [ { position: 1, team: { id: 275, name: 'Palmeiras', shortName: 'PAL', badge: 'https://...' }, points: 32, matches: 13, wins: 10, draws: 2, losses: 1, goalsFor: 23, goalsAgainst: 10, goalDifference: 13, efficiency: 82, movement: 0, recentForm: ['W', 'W', 'D', 'W', 'W'], legend: { id: 1, name: 'Libertadores', color: '#0000ff' } } ] } ], rounds: [ { id: 'overall', groupId: null, groupName: null, number: 13, total: 38, label: '13a rodada', matches: [ { id: 346376, round: 13, totalRounds: 38, dateTime: '2026-04-25T18:30', date: '2026-04-25', time: '18:30', started: true, status: 'finished', statusCode: 'ENCERRADA', venue: 'Mané Garrincha', homeTeam: { id: 263, name: 'Botafogo', shortName: 'BOT', badge: 'https://...' }, awayTeam: { id: 285, name: 'Internacional', shortName: 'INT', badge: 'https://...' }, score: { home: 2, away: 2, penalties: null }, coverage: { label: 'saiba como foi', url: 'https://...', statusCode: 'ENCERRADA' } } ] } ], matches: [ { id: 346376, round: 13, status: 'finished' } ] } ``` ### `getStandings(serie, options?)` ```js const brasileirao = require('campeonato-brasileiro-api'); const standings = await brasileirao.getStandings('c'); console.log(standings); ``` Exemplo de retorno: ```js { competition: { code: 'c', name: 'Campeonato Brasileiro Série C 2026' }, grouped: false, legends: [ { id: 1, name: 'G8', color: '#0000ff' } ], tables: [ { id: 'overall', name: 'Classificacao geral', entries: [ { position: 1, team: { name: 'Amazonas', shortName: 'AMA' }, points: 12 } ] } ] } ``` ### `getTable(serie, options?)` #### Série A, B ou C ```js const brasileirao = require('campeonato-brasileiro-api'); const table = await brasileirao.getTable('a'); console.log(table.entries[0]); ``` #### Série D com grupo ```js const brasileirao = require('campeonato-brasileiro-api'); const table = await brasileirao.getTable('d', { group: 'A14' }); console.log(table.name); console.log(table.entries[0].team.name); ``` Exemplo de retorno: ```js { id: 6014, name: 'Grupo A14', round: { number: 4, total: 10, label: '4a rodada' }, entries: [ { position: 1, team: { id: 305, name: 'XV de Piracicaba', shortName: 'XVP', badge: 'https://...' }, points: 10 } ] } ``` ### `getGroups(serie, options?)` ```js const brasileirao = require('campeonato-brasileiro-api'); const groups = await brasileirao.getGroups('d'); for (const group of groups) { console.log(group.name, group.entries[0].team.name); } ``` Exemplo de retorno: ```js [ { id: 5988, name: 'Grupo A1', entries: [ { position: 1, team: { name: 'Nacional-AM' }, points: 9 } ] }, { id: 6014, name: 'Grupo A14', entries: [ { position: 1, team: { name: 'XV de Piracicaba' }, points: 10 } ] } ] ``` ### `getRounds(serie, options?)` #### Série A, B ou C ```js const brasileirao = require('campeonato-brasileiro-api'); const rounds = await brasileirao.getRounds('a'); console.log(rounds.rounds[0].matches); ``` #### Série D com grupo ```js const brasileirao = require('campeonato-brasileiro-api'); const rounds = await brasileirao.getRounds('d', { group: 'Grupo A1' }); console.log(rounds.rounds[0]); ``` Exemplo de retorno: ```js { competition: { code: 'd', name: 'Campeonato Brasileiro Série D 2026' }, grouped: true, rounds: [ { id: 5988, groupId: 5988, groupName: 'Grupo A1', number: 4, total: 10, label: '4a rodada', matches: [ { id: 351601, status: 'scheduled', venue: 'Ismael Benigno', homeTeam: { name: 'Manauara' }, awayTeam: { name: 'Monte Roraima' }, score: { home: 2, away: 0, penalties: null } } ] } ] } ``` ### `getCurrentRound(serie, options?)` É um alias de `getRounds()`: ```js const brasileirao = require('campeonato-brasileiro-api'); const currentRound = await brasileirao.getCurrentRound('b'); console.log(currentRound.rounds[0].number); ``` ### `tabela(serie, options?)` Helper legado com shape próximo ao pacote original. ```js const brasileirao = require('campeonato-brasileiro-api'); const table = await brasileirao.tabela('a'); console.log(table[0]); ``` Exemplo de retorno: ```js [ { nome: 'Palmeiras', sigla: 'PAL', escudo: 'https://...', posicao: 1, pontos: '32', jogos: '13', vitorias: '10', empates: '2', derrotas: '1', golsPro: '23', golsContra: '10', saldoGols: '13', percentual: '82' } ] ``` ### `rodadaAtual(serie, rodada?, options?)` Helper legado para jogos da rodada atual. ```js const brasileirao = require('campeonato-brasileiro-api'); const jogos = await brasileirao.rodadaAtual('a', 13); console.log(jogos); ``` Exemplo de retorno: ```js [ { mandante: 'Botafogo', placarMandante: 2, visitante: 'Internacional', placarVisitante: 2 }, { mandante: 'Athletico-PR', placarMandante: 3, visitante: 'Vitória', placarVisitante: 1 } ] ``` Na Série D: ```js const brasileirao = require('campeonato-brasileiro-api'); const jogos = await brasileirao.rodadaAtual('d', 4, { group: 'A1' }); console.log(jogos); ``` ## Série D A Série D é agrupada por design: - `getStandings('d')` retorna todas as tabelas dos grupos - `getGroups('d')` é o atalho mais direto para esses grupos - `getTable('d', { group })` exige um grupo - `getRounds('d', { group })` retorna a rodada atual do grupo selecionado O campo `group` aceita, por exemplo: - `A1` - `Grupo A1` - o `id` numérico do grupo ## Options Todos os métodos principais aceitam `options`. - `url`: sobrescreve a URL da competição - `html`: usa um HTML carregado, sem fazer fetch - `fetch`: injeta uma implementação customizada de fetch - `headers`: headers extras para a requisição - `signal`: `AbortSignal` - `group`: seleciona um grupo na Série D - `number`: valida a rodada esperada em `getRounds()` ### Exemplo com `html` ```js const fs = require('node:fs'); const brasileirao = require('campeonato-brasileiro-api'); const html = fs.readFileSync('./fixtures/serie-a.html', 'utf8'); const data = await brasileirao.getCompetition('a', { html }); ``` ### Exemplo com `fetch` customizado ```js import { getCompetition } from 'campeonato-brasileiro-api'; const data = await getCompetition('b', { fetch: globalThis.fetch, headers: { 'user-agent': 'my-app/1.0.0' } }); ``` ## Erros Os métodos podem lançar `BrasileiroApiError`. Principais códigos: - `INVALID_SERIE` - `FETCH_UNAVAILABLE` - `FETCH_FAILED` - `INVALID_RESPONSE` - `GROUP_REQUIRED` - `GROUP_NOT_FOUND` - `ROUND_NOT_AVAILABLE` Exemplo: ```js const brasileirao = require('campeonato-brasileiro-api'); try { await brasileirao.getTable('d'); } catch (error) { console.log(error.name); console.log(error.code); console.log(error.message); console.log(error.details); } ``` ## Especificação OpenAPI Este repositório agora inclui uma especificação OpenAPI 3.0 de referência em [docs/openapi.json](docs/openapi.json). Importante: - a biblioteca não expõe um servidor HTTP por conta própria - a spec descreve um contrato REST de referência para quem quiser criar um wrapper HTTP sobre o pacote - o arquivo é compatível com Swagger UI, Redoc e ferramentas OpenAPI em geral Rotas cobertas na spec: - `GET /series` - `GET /competitions/{serie}` - `GET /competitions/{serie}/standings` - `GET /competitions/{serie}/table` - `GET /competitions/{serie}/groups` - `GET /competitions/{serie}/rounds` - `GET /competitions/{serie}/current-round` - `GET /legacy/{serie}/tabela` - `GET /legacy/{serie}/rodada-atual` ## Limitações atuais da fonte A fonte atual expõe de forma estável a classificação e a rodada ativa da competição. O pacote valida `number`, mas não inventa histórico de rodadas que a página não entrega. ## Licença MIT ## Aviso Este projeto é fornecido apenas para fins educacionais.