feat(api_sports): add API-Sports plugin - #359
Conversation
Implement Corsair OSS plugin for API-Sports across football, NBA, basketball, AFL, baseball, F1, MMA, and NFL APIs with x-apisports-key auth, sport-specific base URLs, live-tested endpoints, and demo registration. Closes corsairdev#358
|
@Ayush7614 is attempting to deploy a commit to the corsair Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThe PR adds the API-Sports plugin with typed operations spanning eight sports, sport-specific request routing, API-key authentication, response-error normalization, and package registration.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; all three previously reported issues are fixed at the current head. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Caller["Corsair endpoint caller"] --> KeyBuilder["API-Sports keyBuilder"]
KeyBuilder --> Endpoint["Typed endpoint implementation"]
Endpoint --> Router["Sport-specific route lookup"]
Router --> Client["Shared API-Sports HTTP client"]
Client --> Provider["Selected API-Sports host"]
Provider --> Errors{"HTTP or body errors?"}
Errors -->|No| Response["Typed response"]
Errors -->|Yes| Handler["API-Sports error handling"]
Reviews (6): Last reviewed commit: "fix(apisports): rename package to drop u..." | Re-trigger Greptile |
Route getGameStatisticsByTeams to basketball /games/statistics/teams, throw AuthMissingError when API key is absent, and use console.error for auth failures.
Cache sport/path/query lookups via ctx.db.queries upserts following the Slack plugin pattern; remove generator script from PR.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughChangesAPI-Sports provider
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant ApiSportsPlugin
participant EndpointHandler
participant executeApiSportsRequest
participant makeApiSportsRequest
participant ApiSportsAPI
participant QueryStorage
ApiSportsPlugin->>EndpointHandler: invoke typed endpoint
EndpointHandler->>executeApiSportsRequest: pass route, API key, and query
executeApiSportsRequest->>makeApiSportsRequest: execute authenticated GET request
makeApiSportsRequest->>ApiSportsAPI: send normalized query
ApiSportsAPI-->>makeApiSportsRequest: return response or API error
executeApiSportsRequest->>QueryStorage: upsert query metadata
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@greptile review |
Plugin PR scorecard —
|
| Check | Status | Notes |
|---|---|---|
| R1 — Scope: plugin files only | ✅ | |
| R2 — Tests with assertions | ✅ | |
| R3 — Description complete | ✅ | |
| R3 — Linked issue / claim | ✅ | |
| R4 — Demo video / recording | ✅ |
Rules: PLUGIN_PR_RULES.md · re-runs on every push
|
Hey @Ayush7614, thanks for the contribution! 🏴☠️ Before a maintainer reviews, please fix the items below — the review re-runs automatically on your next push. Must fix
Optional improvements (P2)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! If anything remains after your next push, a bot commit will clean it up; a maintainer always does the final review and merge. |
|
@greptile Review |
|
Remaining findings are being fixed by a bot commit — it will be re-reviewed automatically. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/apisports/endpoints/types.ts (1)
41-319: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffThe 67-operation list is hand-copied into five places.
packages/apisports/endpoints/routes.tsalready holds every route key and itsdescription, but the key list is re-typed in four maps intypes.tsand again inapiSportsEndpointMetainindex.ts. Adding one route requires five coordinated edits, and adescriptionedit inroutes.tsdoes not reachindex.ts. Thesatisfiesconstraints catch missing keys at compile time, so this is a maintenance cost rather than a correctness defect.
packages/apisports/endpoints/types.ts#L41-L319: deriveApiSportsEndpointInputs,ApiSportsEndpointOutputs,ApiSportsEndpointInputSchemas, andApiSportsEndpointOutputSchemasfromApiSportsRouteKeyandAPI_SPORTS_ROUTES.packages/apisports/index.ts#L497-L766: build eachapiSportsEndpointMetaentry from the matchingAPI_SPORTS_ROUTES[op].descriptioninstead of a repeated literal string.Keep the explicit literal maps if
RequiredPluginEndpointSchemasandRequiredPluginEndpointMetarequire literal key inference to type-check.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apisports/endpoints/types.ts` around lines 41 - 319, The 67-operation key and description lists are duplicated across endpoint types and metadata. In packages/apisports/endpoints/types.ts#L41-319, derive ApiSportsEndpointInputs, ApiSportsEndpointOutputs, ApiSportsEndpointInputSchemas, and ApiSportsEndpointOutputSchemas from ApiSportsRouteKey and API_SPORTS_ROUTES while preserving explicit literal maps if required for RequiredPluginEndpointSchemas inference; in packages/apisports/index.ts#L497-766, source each apiSportsEndpointMeta description from API_SPORTS_ROUTES[op].description instead of repeating string literals.packages/apisports/endpoints/routes.ts (1)
229-234: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider renaming
getGamesEventsto reflect the NFL host.The route targets the
nflsport, butindex.tsregistersgetGamesEventsunder thebasketballgroup. A caller readsbasketball.getGamesEventsand expects NBA data. The same applies tostandings.getStandingsDivisionsandstandings.getNflStandingsConferences, which also targetnfl.A name such as
getNflGamesEventsplus annflgroup would remove the ambiguity. The code comment documents the current intent, so this is a naming preference only.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apisports/endpoints/routes.ts` around lines 229 - 234, Rename the NFL-specific route key getGamesEvents to getNflGamesEvents in the route definitions and update its registration in index.ts to use the nfl group instead of basketball. Apply the same naming/grouping clarification to standings.getStandingsDivisions and standings.getNflStandingsConferences, preserving their existing NFL paths and behavior.packages/apisports/api.test.ts (1)
101-109: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueVerify that the
nba/games/eventsrequest fails for the expected reason.The test asserts that the call rejects with
ApiSportsAPIError. The route table comment atpackages/apisports/endpoints/routes.tsline 229 states that NBA has no/games/events. A rejection can also come from a rate limit, a plan restriction, or a network timeout. The assertion then passes for the wrong reason.Assert on the error message content, as the test at line 116 does.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apisports/api.test.ts` around lines 101 - 109, Strengthen the `throws on API-Sports body errors` test by asserting that the rejected `ApiSportsAPIError` also contains the expected missing-route message for NBA `/games/events`, following the message-content assertion pattern used by the nearby test. Keep the existing API-key guard and request unchanged.
🔇 Additional comments (28)
packages/apisports/endpoints/routes.ts (1)
1-228: LGTM!Also applies to: 235-333
packages/apisports/endpoints/types.ts (1)
1-39: LGTM!packages/apisports/schema/database.ts (1)
3-7: 🗄️ Data Integrity & Integration
⚠️ Unverified finding
Sandbox verification was unavailable.Verify that all-optional fields are correct for a persisted entity.
sport,path, andqueriedAtare each optional, so{}parses successfully. The plugin registers this schema as thequeriesentity. Ifclient.tsusessportandpathas the cache lookup key, an undefined value produces an unusable row. Most Corsair plugin entities also declare anidfield.Confirm the writer always supplies
sportandpath, or make those fields required.packages/apisports/schema/index.ts (1)
1-8: LGTM!packages/apisports/package.json (2)
25-34: 📐 Maintainability & Code Quality
⚠️ Unverified finding
Sandbox verification was unavailable.Verify the devDependency version style matches sibling plugin packages.
typescriptusescatalog:, butjest,ts-jest,tsup,dotenv, andzoduse explicit ranges. If the workspace catalog already pins these tools, the explicit ranges can drift from the rest of the monorepo. The PR screenshot also shows pnpm warnings aboutpnpm.overridesandpnpm.onlyBuiltDependenciesbeing ignored outside the workspace root; confirm this package does not declare those fields.
1-24: LGTM!Also applies to: 35-45
packages/apisports/jest.config.cjs (2)
22-25: 📐 Maintainability & Code Quality | 💤 Low value
⚠️ Unverified finding
Sandbox verification was unavailable.Add a
corsair/coremapping tomoduleNameMapper.
moduleNameMappermaps onlycorsair/http. The plugin entrypackages/apisports/index.tsimports fromcorsair/core. The current test file does not importindex.ts, so tests pass today. A future test that imports the plugin factoryapisports()would fail to resolvecorsair/core.♻️ Proposed mapping
moduleNameMapper: { + '^corsair/core$': '<rootDir>/../corsair/core/index.ts', '^corsair/http$': '<rootDir>/../corsair/http.ts', '^(\\.\\.?/.*)\\.js$': '$1', },Confirm the
corsair/coreentry path before you apply the change.
1-21: LGTM!Also applies to: 26-29
packages/apisports/index.ts (2)
814-826: LGTM!
1-496: LGTM!Also applies to: 767-813, 830-842
packages/corsair/core/constants.ts (1)
32-32: LGTM!Also applies to: 144-144, 263-263
packages/apisports/api.test.ts (1)
55-99: LGTM!packages/apisports/tsconfig.json (1)
1-20: LGTM!packages/apisports/tsup.config.ts (1)
1-15: LGTM!packages/apisports/client.ts (1)
1-165: LGTM!packages/apisports/endpoints/shared.ts (1)
1-61: LGTM!packages/apisports/endpoints/baseball.ts (1)
1-21: LGTM!packages/apisports/endpoints/formula1.ts (1)
1-137: LGTM!packages/apisports/endpoints/mma.ts (1)
1-107: LGTM!packages/apisports/endpoints/index.ts (1)
1-12: LGTM!packages/apisports/error-handlers.ts (1)
1-68: LGTM!packages/apisports/endpoints/core.ts (1)
1-252: LGTM!packages/apisports/endpoints/fixtures.ts (1)
1-119: LGTM!packages/apisports/endpoints/standings.ts (1)
1-69: LGTM!packages/apisports/endpoints/players.ts (1)
1-155: LGTM!packages/apisports/endpoints/odds.ts (1)
1-108: LGTM!packages/apisports/endpoints/basketball.ts (1)
1-119: LGTM!packages/apisports/endpoints/afl.ts (1)
1-91: LGTM!
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apisports/api.test.ts`:
- Around line 119-135: Replace the network-dependent “joins array query params
with hyphens” test in api.test.ts with a unit test for the query serialization
helper from client.ts. Assert the exact serialized output for an ids array,
ensuring values are joined with hyphens rather than commas or repeated keys;
remove the API-key guard, network request, response-schema parsing, and
catch-based assertions.
- Around line 10-17: Replace per-test early returns based on TEST_API_KEY with a
conditional describe block so API-dependent tests are reported as skipped when
API_SPORTS_API_KEY is unset; preserve their existing assertions and warning
behavior as appropriate. Move the “throws auth body errors for invalid key” test
into a separate describe block that always runs without requiring TEST_API_KEY.
---
Nitpick comments:
In `@packages/apisports/api.test.ts`:
- Around line 101-109: Strengthen the `throws on API-Sports body errors` test by
asserting that the rejected `ApiSportsAPIError` also contains the expected
missing-route message for NBA `/games/events`, following the message-content
assertion pattern used by the nearby test. Keep the existing API-key guard and
request unchanged.
In `@packages/apisports/endpoints/routes.ts`:
- Around line 229-234: Rename the NFL-specific route key getGamesEvents to
getNflGamesEvents in the route definitions and update its registration in
index.ts to use the nfl group instead of basketball. Apply the same
naming/grouping clarification to standings.getStandingsDivisions and
standings.getNflStandingsConferences, preserving their existing NFL paths and
behavior.
In `@packages/apisports/endpoints/types.ts`:
- Around line 41-319: The 67-operation key and description lists are duplicated
across endpoint types and metadata. In
packages/apisports/endpoints/types.ts#L41-319, derive ApiSportsEndpointInputs,
ApiSportsEndpointOutputs, ApiSportsEndpointInputSchemas, and
ApiSportsEndpointOutputSchemas from ApiSportsRouteKey and API_SPORTS_ROUTES
while preserving explicit literal maps if required for
RequiredPluginEndpointSchemas inference; in
packages/apisports/index.ts#L497-766, source each apiSportsEndpointMeta
description from API_SPORTS_ROUTES[op].description instead of repeating string
literals.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 26ddebbc-1041-4660-8738-559c3e946d73
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (25)
packages/apisports/api.test.tspackages/apisports/client.tspackages/apisports/endpoints/afl.tspackages/apisports/endpoints/baseball.tspackages/apisports/endpoints/basketball.tspackages/apisports/endpoints/core.tspackages/apisports/endpoints/fixtures.tspackages/apisports/endpoints/formula1.tspackages/apisports/endpoints/index.tspackages/apisports/endpoints/mma.tspackages/apisports/endpoints/odds.tspackages/apisports/endpoints/players.tspackages/apisports/endpoints/routes.tspackages/apisports/endpoints/shared.tspackages/apisports/endpoints/standings.tspackages/apisports/endpoints/types.tspackages/apisports/error-handlers.tspackages/apisports/index.tspackages/apisports/jest.config.cjspackages/apisports/package.jsonpackages/apisports/schema/database.tspackages/apisports/schema/index.tspackages/apisports/tsconfig.jsonpackages/apisports/tsup.config.tspackages/corsair/core/constants.ts
Description
Adds `@corsair-dev/api_sports` — a Corsair plugin for the API-Sports REST APIs (football, basketball, NBA, AFL, baseball, Formula 1, MMA, NFL).
Closes #358
Claim: https://corsair.dev/oss/api_sports
Checklist
Before submitting your PR, please verify the following:
Screenshots / Demos (if applicable)
Summary by CodeRabbit