Skip to content

feat(treaty): operation-first client with discriminated results#78

Merged
RawToast merged 11 commits into
masterfrom
cursor/treaty-client-redesign-e1d0
Apr 14, 2026
Merged

feat(treaty): operation-first client with discriminated results#78
RawToast merged 11 commits into
masterfrom
cursor/treaty-client-redesign-e1d0

Conversation

@RawToast

@RawToast RawToast commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the Treaty client redesign plan: operationId-first clients with a single request object (params, query, body, headers, init) and discriminated results (kind: success | http | transport | parse | unknown).

What changed

  • Metadata: errorStatusKeys maps OpenAPI response keys to errors field names so the runtime can pick the right Zod schema for HTTP error bodies. Emitted in operationMetadata alongside existing status maps.
  • Types: TreatyResult is now a discriminated union; added TreatyResultFor, TreatyOperationsClient, TreatyRequest, TreatyRouteTreeClient. Re-exported unwrap and orThrow (alias) from zenko/treaty.
  • Runtime: Operation-mode client validates success and error bodies with Zod when metadata + errors align; categorizes fetch failures, parse failures, and HTTP errors with specStatus.
  • Generator: Emits operations, full operationMetadata JSON, treatyRoutes, and createClient that returns the operation client plus $routes for legacy Eden-style chaining (documented as lighter / not metadata-aware).
  • Tests: Updated treaty runtime and type tests; CLI snapshots; example treaty tests assert the new API and kind narrowing.

Verification

  • bun check
  • bun zenko test
  • packages/examples: bun test (treaty tests run against generated *.gen.ts from bun run codegen locally; generated files are gitignored)

Follow-ups (non-blocking)

  • Narrow success status literals from successResponses without incorrect casts (now uses real HTTP status).
  • Optional: deepen TreatyResultFor HTTP branches or align petstore errorResponses with per-status OpenAPI entries for finer 404 vs default typing.
  • $routes could gain metadata-aware parsing in a later iteration.
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Operation-first Treaty HTTP client with operation-based call shape, discriminated result union (success | error | unexpectedError), and an ergonomic unwrap/orThrow helper.
  • Documentation

    • Added Treaty client docs and a migration/plan guide covering the new client surface and result shapes.
  • Tests

    • Added comprehensive runtime and type tests and updated examples to exercise the new Treaty client behavior.
  • Chores

    • Removed Bun audit CI step; package version bumped to 0.3.0-beta.3.

RawToast and others added 2 commits April 14, 2026 00:20
- Add errorStatusKeys to Operation and operationMetadata for runtime error Zod lookup
- Replace data/error envelope with kind: success | http | transport | parse | unknown
- Implement createTreatyClient({ operations, operationMetadata }) with Zod parsing
- Generate operations + operationMetadata; keep Eden-style chain as  (documented)
- Export unwrap/orThrow, TreatyOperationsClient, TreatyResultFor, TreatyRouteTreeClient
- Update treaty and CLI tests; refresh snapshots

Co-authored-by: RawToast <RawToast@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@RawToast has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 40 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 43 minutes and 40 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5f232e71-f1b0-4fa2-9108-80b4098b43c4

📥 Commits

Reviewing files that changed from the base of the PR and between c6c24eb and ffa76fc.

📒 Files selected for processing (1)
  • packages/zenko/src/treaty-types.ts
📝 Walkthrough

Walkthrough

The PR implements an operation-first Treaty HTTP client API, replaces shape-based results with a discriminated kind union (success | error | unexpectedError), extends operation metadata with status-key mappings (errorStatusKeys), centralizes operation execution (parsing/categorization), updates generator output to export operations/operationMetadata, and adds tests, docs, and examples.

Changes

Cohort / File(s) Summary
Build & Scan Config
\.bun-scan.config.json, turbo.json
Set bunReportWarnings: false; codegen task now depends on zenko#build and includes additional zenko sources in inputs.
CI Workflow
.github/workflows/ci.yml
Removed the bun audit --audit-level=moderate CI step conditioned on matrix.bun-version == 'latest'.
Docs & Plans
README.md, docs/plans/2026-04-14-treaty-client-redesign.md, docs/treaty-client.md
Added Treaty client docs and a multi-task redesign plan describing the operation-first API, discriminated result shape, migration guidance, and implementation/regeneration steps.
Package Exports & Version
packages/zenko/index.ts, packages/zenko/package.json
Re-exported new treaty runtime APIs/types (unwrap, orThrow, TreatyErrorResult, TreatyOperationsClient, etc.) and bumped package version to 0.3.0-beta.3.
Generator Output & Creation
packages/zenko/src/treaty-generator.ts, packages/zenko/src/zenko.ts
Generator now emits export const operations and operationMetadata; createClient returns an operations-aware client plus $routes route-tree client; operationMetadata emission includes optional errorStatusKeys.
Core Runtime & Types
packages/zenko/src/treaty.ts, packages/zenko/src/treaty-types.ts, packages/zenko/src/treaty-infer.ts
Introduced centralized executeOperation, overloaded createTreatyClient (operations vs routes), added TreatyClientOptions, unwrap/orThrow, and redesigned result/type system to discriminated TreatyResult union with TreatyErrorResult and TreatyUnexpectedError variants; added many new exported types (e.g., TreatyRequest, TreatyResultFor, TreatyOperationsClient).
Operation Metadata & Parser
packages/zenko/src/types/operation.ts, packages/zenko/src/core/operation-parser.ts, packages/zenko/src/utils/treaty-tree.ts
Added optional errorStatusKeys?: Record<string,string> to Operation/OperationMeta; parseOperations and getResponseTypes now compute/propagate errorStatusKeys.
Examples Generation
packages/examples/generate.js
Refactored to parameterized generateTreatyModuleForGen(...) and concurrently generate treaty modules for train-travel, auth-api, and petstore, failing if any generation fails.
Examples & Integration Tests
packages/examples/src/.../__tests__/*.test.ts
Added/updated treaty fetch tests (auth-api, petstore, train-travel) to exercise operation-first API (client.op({ ... })), mocked fetch, discriminated result.kind assertions, FormData/Blob handling, querystring behavior, and $routes compatibility.
Type & Runtime Tests
packages/zenko/src/__tests__/*
Expanded type-level and runtime tests for TreatyResultFor, discriminated branches, unwrap() behavior, operation execution flows (success/error/parse/transport), and updated generator/CLI assertions.

Sequence Diagram(s)

sequenceDiagram
    participant App as Client Code
    participant TC as TreatyClient
    participant EO as executeOperation
    participant Fetch as fetch API
    participant Parser as Response Parser
    participant Categorizer as Error Categorizer

    App->>TC: client.someOperation({params, query, body, headers, init})
    TC->>EO: executeOperation(operation, request, metadata, baseUrl)
    EO->>EO: Build URL, headers, body
    EO->>Fetch: fetch(url, init)
    
    alt Success Path
        Fetch-->>EO: Response (2xx)
        EO->>Parser: Read & parse body (JSON or text)
        Parser-->>EO: Parsed data / raw text
        EO-->>TC: {kind: "success", status, data, response, headers}
    else HTTP Error Path
        Fetch-->>EO: Response (4xx/5xx)
        EO->>Categorizer: Map status → specStatus via errorStatusKeys
        EO->>Parser: Parse error body
        EO-->>TC: {kind: "error", specStatus, error, status, response, headers}
    else Parse Error
        Parser-->>EO: parse fails
        EO-->>TC: {kind: "unexpectedError", subtype: "parse", error, rawBody}
    else Transport Error
        Fetch-->>EO: fetch rejects
        EO-->>TC: {kind: "unexpectedError", subtype: "transport", error}
    end

    TC-->>App: Promise<TreatyResult>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 I hopped through types and built a bridge,

from routes to ops across the ridge.
Now results all wear a little "kind",
success, error, or surprises you find.
Unwrap or throw — the client knows the way,
I nibble bugs and skip away! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: implementing an operation-first Treaty client API with discriminated union results (success | error | unexpectedError), which is the core objective across the entire changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/treaty-client-redesign-e1d0

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.51887% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.31%. Comparing base (aba335f) to head (ffa76fc).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
packages/zenko/src/treaty-types.ts 53.65% 19 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #78      +/-   ##
==========================================
+ Coverage   96.20%   97.31%   +1.11%     
==========================================
  Files          19       20       +1     
  Lines        2765     3130     +365     
==========================================
+ Hits         2660     3046     +386     
+ Misses        105       84      -21     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
packages/zenko/src/treaty-types.ts (1)

56-59: Enhance unwrap error message with more context.

The error message only includes result.kind, but for debugging it would be helpful to include the actual error details when available. Consider including result.error or result.status information.

♻️ Proposed enhancement for better debugging
 export function unwrap<T>(result: TreatyResult<T>): T {
   if (result.kind === "success") return result.data
-  throw new Error(`Treaty unwrap failed: ${result.kind}`)
+  if (result.kind === "error") {
+    throw new Error(`Treaty unwrap failed: HTTP ${result.status} (${result.specStatus})`)
+  }
+  const err = result.error instanceof Error ? result.error.message : String(result.error)
+  throw new Error(`Treaty unwrap failed: ${result.subtype} - ${err}`)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/zenko/src/treaty-types.ts` around lines 56 - 59, The unwrap function
throws a vague Error when TreatyResult is not a success; update unwrap (export
function unwrap<T>(result: TreatyResult<T>)) to include additional context from
the non-success result (e.g., result.error and/or result.status) in the thrown
error message so logs show the underlying error/details; construct a descriptive
message combining result.kind plus any available result.error and result.status
(safely handling undefined) before throwing.
packages/examples/generate.js (1)

149-170: Consider parallelizing treaty module generation.

The three treaty module generations are independent and could run in parallel using Promise.all for faster execution.

♻️ Optional: Parallelize treaty generation
-    const trainTravelTreatySuccess = await generateTreatyModuleForGen(
-      "train-travel.gen.ts",
-      "train-travel.treaty.gen.ts",
-      "train-travel"
-    )
-    const authApiTreatySuccess = await generateTreatyModuleForGen(
-      "auth-api.gen.ts",
-      "auth-api.treaty.gen.ts",
-      "auth-api"
-    )
-    const petstoreTreatySuccess = await generateTreatyModuleForGen(
-      "petstore.gen.ts",
-      "petstore.treaty.gen.ts",
-      "petstore"
-    )
-    if (
-      !trainTravelTreatySuccess ||
-      !authApiTreatySuccess ||
-      !petstoreTreatySuccess
-    ) {
+    const treatyResults = await Promise.all([
+      generateTreatyModuleForGen(
+        "train-travel.gen.ts",
+        "train-travel.treaty.gen.ts",
+        "train-travel"
+      ),
+      generateTreatyModuleForGen(
+        "auth-api.gen.ts",
+        "auth-api.treaty.gen.ts",
+        "auth-api"
+      ),
+      generateTreatyModuleForGen(
+        "petstore.gen.ts",
+        "petstore.treaty.gen.ts",
+        "petstore"
+      ),
+    ])
+    if (treatyResults.some((success) => !success)) {
       process.exit(1)
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/examples/generate.js` around lines 149 - 170, The three independent
calls to generateTreatyModuleForGen (for "train-travel", "auth-api", "petstore")
should be run in parallel instead of sequentially; replace the sequential awaits
that set trainTravelTreatySuccess, authApiTreatySuccess, and
petstoreTreatySuccess with a single Promise.all call that awaits all three
promises and then destructures or assigns the three results, and keep the
existing combined failure check (the if that calls process.exit(1)) unchanged to
handle any failures.
packages/examples/src/__tests__/petstore-treaty-fetch.test.ts (1)

206-208: Consider adding a comment explaining the unused client.

This module-level client instantiation appears to be for compile-time type checking of the generated client's API surface rather than runtime testing.

📝 Suggested clarification
+/** Type-check only: verify the generated client API compiles. */
 const _client = createClient("http://petstore.swagger.io/v1", {
   fetch: mock<typeof fetch>() as unknown as typeof fetch,
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/examples/src/__tests__/petstore-treaty-fetch.test.ts` around lines
206 - 208, The module-level const _client is instantiated only for compile-time
type checking of the generated client API and not used at runtime; add a brief
comment immediately above the createClient call (referencing _client and
createClient) that explains this intent (e.g., "instantiate only for
compile-time type checks of generated client surface; unused at runtime") and
keep the leading underscore to suppress unused-variable warnings so
linters/readers understand it's deliberate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/treaty-client.md`:
- Line 3: Update the opening sentence so it uses the correct indefinite article:
change "a Eden Treaty-style HTTP client" to "an Eden Treaty-style HTTP client"
in the phrase "Zenko can emit a Eden Treaty-style HTTP client" (look for the
exact string "Eden Treaty-style HTTP client" at the start of the document).

In `@packages/zenko/src/__tests__/treaty-generator.test.ts`:
- Around line 42-45: Replace the four permissive substring assertions in
treaty-generator.test.ts with a single snapshot assertion: remove the
expect(output).toContain(...) checks and call
expect(output).toMatchSnapshot("treaty-generated-module - full output") (or
another descriptive name) to capture the entire generated module; keep the test
harness that produces output and ensure the snapshot name references the
generated module so it is a descriptive, stable snapshot per the coding
guidelines.

---

Nitpick comments:
In `@packages/examples/generate.js`:
- Around line 149-170: The three independent calls to generateTreatyModuleForGen
(for "train-travel", "auth-api", "petstore") should be run in parallel instead
of sequentially; replace the sequential awaits that set
trainTravelTreatySuccess, authApiTreatySuccess, and petstoreTreatySuccess with a
single Promise.all call that awaits all three promises and then destructures or
assigns the three results, and keep the existing combined failure check (the if
that calls process.exit(1)) unchanged to handle any failures.

In `@packages/examples/src/__tests__/petstore-treaty-fetch.test.ts`:
- Around line 206-208: The module-level const _client is instantiated only for
compile-time type checking of the generated client API and not used at runtime;
add a brief comment immediately above the createClient call (referencing _client
and createClient) that explains this intent (e.g., "instantiate only for
compile-time type checks of generated client surface; unused at runtime") and
keep the leading underscore to suppress unused-variable warnings so
linters/readers understand it's deliberate.

In `@packages/zenko/src/treaty-types.ts`:
- Around line 56-59: The unwrap function throws a vague Error when TreatyResult
is not a success; update unwrap (export function unwrap<T>(result:
TreatyResult<T>)) to include additional context from the non-success result
(e.g., result.error and/or result.status) in the thrown error message so logs
show the underlying error/details; construct a descriptive message combining
result.kind plus any available result.error and result.status (safely handling
undefined) before throwing.
🪄 Autofix (Beta)

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

Run ID: be0aa5eb-6d6d-4200-8df2-f09d35e0e3d9

📥 Commits

Reviewing files that changed from the base of the PR and between aba335f and fdf5682.

⛔ Files ignored due to path filters (13)
  • packages/zenko/src/__tests__/__snapshots__/anyof-combinations.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/cli.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/date-enum.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/inline-response-array.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/no-response-content.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/non-json-responses.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/oneof-discriminator.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/petstore.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/security-schemes.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/selective-operations.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/tictactoe.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/train-travel.test.ts.snap is excluded by !**/*.snap
  • packages/zenko/src/__tests__/__snapshots__/zenko.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (24)
  • .bun-scan.config.json
  • .github/workflows/ci.yml
  • README.md
  • docs/plans/2026-04-14-treaty-client-redesign.md
  • docs/treaty-client.md
  • packages/examples/generate.js
  • packages/examples/src/__tests__/auth-api-treaty-fetch.test.ts
  • packages/examples/src/__tests__/petstore-treaty-fetch.test.ts
  • packages/examples/src/__tests__/train-travel-treaty-fetch.test.ts
  • packages/zenko/index.ts
  • packages/zenko/package.json
  • packages/zenko/src/__tests__/cli.test.ts
  • packages/zenko/src/__tests__/treaty-client-types.test.ts
  • packages/zenko/src/__tests__/treaty-generator.test.ts
  • packages/zenko/src/__tests__/treaty-runtime.test.ts
  • packages/zenko/src/core/operation-parser.ts
  • packages/zenko/src/treaty-generator.ts
  • packages/zenko/src/treaty-infer.ts
  • packages/zenko/src/treaty-types.ts
  • packages/zenko/src/treaty.ts
  • packages/zenko/src/types/operation.ts
  • packages/zenko/src/utils/treaty-tree.ts
  • packages/zenko/src/zenko.ts
  • turbo.json
💤 Files with no reviewable changes (1)
  • .github/workflows/ci.yml

Comment thread docs/treaty-client.md Outdated
Comment thread packages/zenko/src/__tests__/treaty-generator.test.ts Outdated
@RawToast RawToast marked this pull request as ready for review April 14, 2026 05:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/examples/src/__tests__/petstore-treaty-fetch.test.ts (2)

1-1: Stop patching global.fetch in this suite.

Every test already injects fetch via createClient(origin, { fetch }),
so the global override only adds shared state and potential bleed between
tests. Removing it also makes the afterEach reset unnecessary.

♻️ Small cleanup
-import { afterEach, describe, expect, it, mock } from "bun:test"
+import { describe, expect, it, mock } from "bun:test"
...
-  const originalFetch = global.fetch
-
-  afterEach(() => {
-    global.fetch = originalFetch
-  })
...
 function setupFetchMock() {
-  const fetchMock = mock<typeof fetch>()
-  global.fetch = fetchMock as unknown as typeof fetch
-  return fetchMock
+  return mock<typeof fetch>()
 }

Also applies to: 6-10, 200-203

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/examples/src/__tests__/petstore-treaty-fetch.test.ts` at line 1, The
test suite is patching global.fetch unnecessarily; remove the global.fetch
override and the related afterEach reset so each test uses the per-test injected
fetch via createClient(origin, { fetch }); specifically, delete the global.fetch
assignment and the afterEach cleanup in
packages/examples/src/__tests__/petstore-treaty-fetch.test.ts (and the similar
blocks at the other occurrences noted), and ensure tests construct clients with
createClient(origin, { fetch }) as intended so no global shared state remains.

206-210: Avoid the unused _client sentinel.

This call is fine, but the binding itself is intentionally unread and will
fight noUnusedLocals anywhere this file is included in a strict TS
project. A no-binding expression keeps the same type-check without the dead
local.

♻️ Minimal change
-const _client = createClient("http://petstore.swagger.io/v1", {
+void createClient("http://petstore.swagger.io/v1", {
   fetch: mock<typeof fetch>() as unknown as typeof fetch,
 })

As per coding guidelines: **/*.{ts,tsx}: Enable TypeScript strict mode with flags including noUncheckedIndexedAccess, noUnusedLocals, noUnusedParameters, and noFallthroughCasesInSwitch

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/examples/src/__tests__/petstore-treaty-fetch.test.ts` around lines
206 - 210, The test creates a compile-time-only sentinel `_client` which
triggers noUnusedLocals; replace the binding with an unassigned expression so
types still check but no dead local remains: remove `const _client =` and
instead call the `createClient("http://petstore.swagger.io/v1", { fetch:
mock<typeof fetch>() as unknown as typeof fetch })` expression without assigning
it (e.g., prefix with `void` or leave as a bare expression) so `createClient`
and the `mock<typeof fetch>()` cast are preserved for type-checking but no
unused local exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/zenko/src/treaty-types.ts`:
- Around line 85-88: The thrown error in the unwrap() path for result.kind ===
"error" currently interpolates the raw API payload via
unwrapErrorDetail(result.error); change the thrown message to only include
descriptive metadata (kind/status/specStatus) and remove the raw payload from
the message, and if you need to preserve the payload attach it to the Error
object (e.g., error.payload = result.error or error.details = safeSanitizedCopy)
instead of including it in the message; update the code paths referencing this
behavior in treaty-types.ts and the unwrap function to rely on the new
non-sensitive message while preserving the original payload on the Error
instance if needed.

---

Nitpick comments:
In `@packages/examples/src/__tests__/petstore-treaty-fetch.test.ts`:
- Line 1: The test suite is patching global.fetch unnecessarily; remove the
global.fetch override and the related afterEach reset so each test uses the
per-test injected fetch via createClient(origin, { fetch }); specifically,
delete the global.fetch assignment and the afterEach cleanup in
packages/examples/src/__tests__/petstore-treaty-fetch.test.ts (and the similar
blocks at the other occurrences noted), and ensure tests construct clients with
createClient(origin, { fetch }) as intended so no global shared state remains.
- Around line 206-210: The test creates a compile-time-only sentinel `_client`
which triggers noUnusedLocals; replace the binding with an unassigned expression
so types still check but no dead local remains: remove `const _client =` and
instead call the `createClient("http://petstore.swagger.io/v1", { fetch:
mock<typeof fetch>() as unknown as typeof fetch })` expression without assigning
it (e.g., prefix with `void` or leave as a bare expression) so `createClient`
and the `mock<typeof fetch>()` cast are preserved for type-checking but no
unused local exists.
🪄 Autofix (Beta)

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

Run ID: 7095f595-dbc4-4f30-82ce-654b320851d6

📥 Commits

Reviewing files that changed from the base of the PR and between fdf5682 and 2d80c9e.

⛔ Files ignored due to path filters (1)
  • packages/zenko/src/__tests__/__snapshots__/treaty-generator.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • docs/treaty-client.md
  • packages/examples/generate.js
  • packages/examples/src/__tests__/petstore-treaty-fetch.test.ts
  • packages/zenko/src/__tests__/treaty-generator.test.ts
  • packages/zenko/src/__tests__/treaty-runtime.test.ts
  • packages/zenko/src/treaty-types.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/treaty-client.md

Comment thread packages/zenko/src/treaty-types.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/zenko/src/treaty-types.ts`:
- Around line 82-105: The stray closing brace prematurely ends the
unwrap<T>(result: TreatyResult<T>) function causing the subsequent subtype
branches to be outside the function; remove that extra `}` so the function body
continues to handle the "unexpectedError" branches (checks on result.subtype
"transport", "parse", and default) and then close the function only once after
all branches are handled. Locate the unwrap function and its early returns for
result.kind ("success" and "error") and ensure the transport/parse/other error
throws are inside the same unwrap function before the single final closing
brace.
🪄 Autofix (Beta)

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

Run ID: 69b16080-7099-454d-9c1a-9fd779b8d5ba

📥 Commits

Reviewing files that changed from the base of the PR and between 2d80c9e and c6c24eb.

📒 Files selected for processing (1)
  • packages/zenko/src/treaty-types.ts

Comment thread packages/zenko/src/treaty-types.ts
@RawToast RawToast merged commit 48c0a29 into master Apr 14, 2026
6 checks passed
@RawToast RawToast deleted the cursor/treaty-client-redesign-e1d0 branch April 14, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants