feat: add transaction write builder and request API enhancements#3
feat: add transaction write builder and request API enhancements#3spiflicate wants to merge 1 commit intomainfrom
Conversation
📝 WalkthroughWalkthroughThis PR introduces transaction write support to the Yahoo Fantasy API client by adding a Changes
Sequence DiagramsequenceDiagram
actor Client
participant RequestBuilder
participant TransactionBuilder
participant XMLSerializer
participant HttpClient
participant YahooAPI
Client->>RequestBuilder: create(transactionBuilder)
RequestBuilder->>TransactionBuilder: toPayload()
TransactionBuilder-->>RequestBuilder: {transaction: {...}}
RequestBuilder->>XMLSerializer: serializeToYahooXml(payload)
XMLSerializer-->>RequestBuilder: <transaction>...</transaction>
RequestBuilder->>RequestBuilder: setPendingWriteRequest(POST, path, xml)
RequestBuilder->>HttpClient: execute()
HttpClient->>YahooAPI: POST /transactions (xml body)
YahooAPI-->>HttpClient: 200 OK
HttpClient-->>RequestBuilder: response
RequestBuilder->>RequestBuilder: clearPendingWriteRequest()
RequestBuilder-->>Client: result
Client->>RequestBuilder: transaction(key).edit(edits)
RequestBuilder->>XMLSerializer: serializeToYahooXml(edits)
XMLSerializer-->>RequestBuilder: <transaction>...</transaction>
RequestBuilder->>RequestBuilder: setPendingWriteRequest(PUT, dispatchPath, xml)
RequestBuilder->>HttpClient: execute()
HttpClient->>YahooAPI: PUT /transactions/key (xml body)
YahooAPI-->>HttpClient: 200 OK
HttpClient-->>RequestBuilder: response
RequestBuilder->>RequestBuilder: clearPendingWriteRequest()
RequestBuilder-->>Client: result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
There was a problem hiding this comment.
Pull request overview
Adds first-class support for composing and executing Yahoo transaction write requests (POST/PUT/DELETE) via the fluent request builder, including a dedicated TransactionBuilder for common transaction payloads.
Changes:
- Introduce
TransactionBuilderfor add/drop and pending trade payload construction. - Enhance
RequestBuilderwith transaction write helpers (create,edit,cancel) and automatic XML serialization for transaction write bodies. - Add games collection filter helpers (
isAvailable,gameTypes,gameCodes,seasons) and expand unit/integration test coverage + new transactions example.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/transaction-builder.test.ts | New unit tests covering TransactionBuilder payload construction and validation. |
| tests/unit/request-builder.test.ts | Adds coverage for games filter helpers, XML serialization, and transaction write flows (create/edit/cancel). |
| tests/unit/formatters.test.ts | Import reordering/formatting only. |
| tests/unit/errors.test.ts | Import reordering/formatting only. |
| tests/unit/client/RequestBuilderClient.test.ts | Type-level coverage for new request-builder methods + runtime guardrail tests for invalid write-stage usage. |
| tests/integration/workflows/e2e.test.ts | Formatting tweaks and a guard for optional userTeam.name comparison. |
| tests/integration/auth/oauth1.test.ts | Migrates some “advanced” usage to the request builder, and adjusts expectations for players responses. |
| src/types/responses/league.ts | Updates the doc comment for the renewed field. |
| src/request/transaction.ts | New TransactionBuilder implementation (add/drop + trade modes). |
| src/request/index.ts | Re-exports TransactionBuilder from the request module barrel. |
| src/request/builder.ts | Adds XML serialization for transaction writes, new write helpers (create/edit/cancel), dispatch-path support, and games collection filter helpers. |
| src/index.ts | Exposes TransactionBuilder from the package root. |
| examples/request-builder/02-transactions.ts | New end-to-end example demonstrating transaction read/write paths and payloads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return { | ||
| type: 'drop', | ||
| player: { | ||
| player_key: this.dropPlayerKey, | ||
| transaction_data: { | ||
| type: 'drop', | ||
| source_team_key: this.forTeamKey, | ||
| }, | ||
| }, | ||
| }; |
| .request() | ||
| .games() | ||
| // FIXME: verify what params should be available for the games collection | ||
| .param('is_available', 'true') |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
examples/request-builder/02-transactions.ts (1)
57-76: Consider logging parse errors in token loading.The
load()method silently swallows all errors including JSON parse failures. In path-only mode this is fine, but for live API usage, logging could help debug token file corruption.💡 Optional: Log parsing errors
async load(): Promise<OAuth2Tokens | null> { try { const data = await fs.readFile(tokenFile, 'utf-8'); return JSON.parse(data); - } catch { + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== 'ENOENT') { + console.warn('Failed to load tokens:', err); + } return null; } },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/request-builder/02-transactions.ts` around lines 57 - 76, The load() method on the storage object currently swallows all errors; update storage.load() to catch and log the error (including JSON parse failures) before returning null so tokenFile/JSON corruption is visible when debugging live API usage; reference the storage object and its load() method, include the caught error in a descriptive log message (e.g., mentioning tokenFile and OAuth2Tokens) and then return null as before.tests/integration/auth/oauth1.test.ts (1)
120-139: Replace.param('is_available', 'true')with.isAvailable(true)to ensure proper normalization.The test currently bypasses the
isAvailable()method which normalizes boolean values to the numeric format'1'or'0'that the Yahoo Fantasy API expects. Using.param('is_available', 'true')sends the string'true'directly, which does not match the API's numeric parameter format and will cause unexpected behavior.Use
.isAvailable(true)instead, which properly normalizes the value to'1'via the builder method.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/integration/auth/oauth1.test.ts` around lines 120 - 139, The test uses .param('is_available', 'true') which bypasses the request builder's normalization; replace that call with the builder method .isAvailable(true) so the value is converted to the API-expected numeric format ('1'/'0') — update the chain starting at .request().games() to call .isAvailable(true) instead of .param('is_available', 'true') (leave the surrounding .execute() and assertions unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@examples/request-builder/02-transactions.ts`:
- Around line 57-76: The load() method on the storage object currently swallows
all errors; update storage.load() to catch and log the error (including JSON
parse failures) before returning null so tokenFile/JSON corruption is visible
when debugging live API usage; reference the storage object and its load()
method, include the caught error in a descriptive log message (e.g., mentioning
tokenFile and OAuth2Tokens) and then return null as before.
In `@tests/integration/auth/oauth1.test.ts`:
- Around line 120-139: The test uses .param('is_available', 'true') which
bypasses the request builder's normalization; replace that call with the builder
method .isAvailable(true) so the value is converted to the API-expected numeric
format ('1'/'0') — update the chain starting at .request().games() to call
.isAvailable(true) instead of .param('is_available', 'true') (leave the
surrounding .execute() and assertions unchanged).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9ed55186-6fbc-47f7-a63c-f6f78530bb49
📒 Files selected for processing (13)
examples/request-builder/02-transactions.tssrc/index.tssrc/request/builder.tssrc/request/index.tssrc/request/transaction.tssrc/types/responses/league.tstests/integration/auth/oauth1.test.tstests/integration/workflows/e2e.test.tstests/unit/client/RequestBuilderClient.test.tstests/unit/errors.test.tstests/unit/formatters.test.tstests/unit/request-builder.test.tstests/unit/transaction-builder.test.ts
Greptile SummaryThis PR introduces a fluent transaction write API on top of the existing Key changes:
Notable issues found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant RequestBuilder
participant TransactionBuilder
participant XMLBuilder
participant HttpClient
Note over User,HttpClient: Fluent Write Flow (create / edit / cancel)
User->>RequestBuilder: .league(key).transactions()
User->>RequestBuilder: .create(new TransactionBuilder()...)
RequestBuilder->>TransactionBuilder: toPayload()
TransactionBuilder-->>RequestBuilder: Record<string,unknown>
RequestBuilder->>RequestBuilder: setPendingWriteRequest(POST, payload)
User->>RequestBuilder: .execute()
RequestBuilder->>RequestBuilder: state.method === 'POST'
RequestBuilder->>RequestBuilder: post(state.body, state.options)
RequestBuilder->>RequestBuilder: normalizeWriteBody(path, data)
RequestBuilder->>XMLBuilder: build(wrapped payload)
XMLBuilder-->>RequestBuilder: XML string
RequestBuilder->>HttpClient: post(path, xml, options)
HttpClient-->>RequestBuilder: response
RequestBuilder->>RequestBuilder: clearPendingWriteRequest()
RequestBuilder-->>User: response
Note over User,HttpClient: Direct write shortcut (post / put / delete)
User->>RequestBuilder: .transaction(key).put(xmlOrObject)
RequestBuilder->>RequestBuilder: normalizeWriteBody(path, data)
RequestBuilder->>HttpClient: put(path, xml, options)
HttpClient-->>RequestBuilder: response
RequestBuilder-->>User: response
|
Summary by CodeRabbit
Release Notes