feat(client): adapter interceptor - #899
Conversation
LinkFetchClient, RPCLink, OpenAPILink, ... now support `adapterInterceptors` option for intercept fetch request/response
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds adapter interceptors and plugin support to the fetch link client API and types; constructor now accepts LinkFetchClientOptions (fetch, adapterInterceptors, plugins). Introduces LinkFetchPlugin and CompositeLinkFetchPlugin, updates call flow to build Requests via toFetchRequest, run interceptors with redirect: 'manual', and return StandardLazyResponse. Tests and type-tests added/updated. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant App as Caller
participant LFC as LinkFetchClient
participant CPL as CompositeLinkFetchPlugin
participant P as Plugin...
note over LFC,CPL: Initialization
App->>LFC: new LinkFetchClient(linkOptions)
LFC->>CPL: initRuntimeAdapter(linkOptions)
CPL->>P: initRuntimeAdapter(linkOptions) (ordered)
sequenceDiagram
autonumber
participant App as Caller
participant LFC as LinkFetchClient
participant INT as AdapterInterceptors
participant F as fetch
participant Conv as toStandardLazyResponse
App->>LFC: call(standardRequest, options, path, input)
note right of LFC: req = toFetchRequest(standardRequest, linkOptions)
LFC->>INT: intercept({request:req, init:{redirect:'manual'}, path, input, ...options})
INT-->>LFC: request/init (possibly modified)
LFC->>F: fetch(request, init)
F-->>LFC: Response
LFC->>Conv: toStandardLazyResponse(Response, { signal })
Conv-->>App: StandardLazyResponse
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a new adapterInterceptors option across various client-side link implementations, specifically enhancing the LinkFetchClient. This feature allows developers to intercept and modify fetch requests and responses, providing a powerful mechanism for custom request handling, logging, or authentication before the request is sent or after the response is received. It also lays the groundwork for a more robust plugin system for these adapters, enabling greater extensibility and modularity in client-side operations.
Highlights
- New
adapterInterceptorsOption: TheLinkFetchClientOptionsnow includes anadapterInterceptorsoption, allowing developers to define an array of functions that can intercept and modify fetch requests and responses. This provides a flexible way to implement cross-cutting concerns like logging, authentication, or caching. - Integrated Interception Logic: The core
LinkFetchClient.callmethod has been updated to integrate the new interception logic. It now uses a sharedinterceptutility to process theadapterInterceptorschain, ensuring that each interceptor can perform actions before or after the actual network request. - New Plugin System for Adapters: A new plugin system has been introduced for
LinkFetchClientthrough theLinkFetchPlugininterface andCompositeLinkFetchPluginclass. This system enables extensible runtime adapter initialization, allowing for more modular and configurable client behavior. - Expanded Test Coverage: Comprehensive test cases have been added and updated for
LinkFetchClientto validate the correct functionality of the newadapterInterceptorsand to ensure the proper initialization and execution of the new plugin system.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable feature: adapter-level interceptors for fetch-based clients, enhancing modularity and extensibility. The implementation is well-executed, employing a composite pattern for plugins and maintaining a clear separation of concerns. The accompanying tests are comprehensive, covering interceptor functionality, plugin initialization, and type compatibility. I have one suggestion for a minor refactoring in the LinkFetchClient constructor to further improve code clarity and maintainability.
More templates
@orpc/arktype
@orpc/client
@orpc/contract
@orpc/experimental-durable-event-iterator
@orpc/hey-api
@orpc/interop
@orpc/json-schema
@orpc/nest
@orpc/openapi
@orpc/openapi-client
@orpc/otel
@orpc/react
@orpc/react-query
@orpc/experimental-react-swr
@orpc/server
@orpc/shared
@orpc/solid-query
@orpc/standard-server
@orpc/standard-server-aws-lambda
@orpc/standard-server-fetch
@orpc/standard-server-node
@orpc/standard-server-peer
@orpc/svelte-query
@orpc/tanstack-query
@orpc/trpc
@orpc/valibot
@orpc/vue-colada
@orpc/vue-query
@orpc/zod
commit: |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
packages/client/src/adapters/fetch/plugin.test-d.ts (1)
6-7: Prefer toEqualTypeOf for concise bidirectional assignability checkYou can collapse the two mutual extends assertions into a single, clearer equality assertion.
- expectTypeOf<LinkFetchPlugin<{ a: string }>>().toExtend<StandardLinkPlugin<{ a: string }>>() - expectTypeOf<StandardLinkPlugin<{ a: string }>>().toExtend<LinkFetchPlugin<{ a: string }>>() + expectTypeOf<LinkFetchPlugin<{ a: string }>>().toEqualTypeOf<StandardLinkPlugin<{ a: string }>>()packages/client/src/adapters/fetch/plugin.test.ts (1)
34-35: Optionally assert stability when orders are equalConsider adding a case with two plugins having the same order to lock in stable ordering (insertion order) expectations.
Example (additive):
it('keeps insertion order when orders are equal', () => { const a = { order: 0, initRuntimeAdapter: vi.fn() } as const const b = { order: 0, initRuntimeAdapter: vi.fn() } as const const composite = new CompositeLinkFetchPlugin([a, b]) composite.initRuntimeAdapter({} as any) expect(a.initRuntimeAdapter).toHaveBeenCalledBefore(b.initRuntimeAdapter) })packages/client/src/adapters/fetch/plugin.ts (2)
6-8: Add a brief doc comment on initRuntimeAdapter’s purposeA short JSDoc helps clarify when this runs and what mutations are expected (e.g., mutating options to initialize runtime adapters).
-export interface LinkFetchPlugin<T extends ClientContext> extends StandardLinkPlugin<T> { - initRuntimeAdapter?(options: LinkFetchClientOptions<T>): void -} +export interface LinkFetchPlugin<T extends ClientContext> extends StandardLinkPlugin<T> { + /** + * Called during LinkFetchClient construction to initialize runtime fetch adapters. + * Implementations may safely mutate the provided options object to wire adapter behavior. + */ + initRuntimeAdapter?(options: LinkFetchClientOptions<T>): void +}
10-17: Consider extracting shared types to avoid a type-only circular referenceplugin.ts imports LinkFetchClientOptions from link-fetch-client.ts (type-only) while link-fetch-client.ts imports CompositeLinkFetchPlugin as a value. This is safe at runtime, but moving shared types (e.g., LinkFetchClientOptions) to a small types module can simplify layering and reduce future coupling.
packages/client/src/adapters/fetch/link-fetch-client.test.ts (1)
58-74: Optionally assert interceptor call orderYou already assert both are called. Adding an order assertion locks in sequencing guarantees.
expect(interceptor1).toBeCalledTimes(1) expect(interceptor2).toBeCalledTimes(1) + expect(interceptor1).toHaveBeenCalledBefore(interceptor2)packages/client/src/adapters/fetch/link-fetch-client.ts (2)
42-45: Normalize the fallback fetch to the extended signatureWhen options.fetch is not provided, this.fetch points to globalThis.fetch (2 params) while the declared type expects 5 params. JS ignores extra args, but wrapping improves clarity, avoids relying on parameter-count compatibility, and aligns with the declared type.
- this.fetch = options.fetch ?? globalThis.fetch.bind(globalThis) + this.fetch = options.fetch ?? ((request, init) => globalThis.fetch(request, init))Optionally, throw a helpful error if neither options.fetch nor globalThis.fetch exist.
11-16: Consider widening init to a narrowed RequestInit subset if neededIf adapters require more control (e.g., cache, credentials), you might evolve init from { redirect?: ... } to Pick<RequestInit, 'redirect' | 'cache' | 'credentials' | ...>. Current narrow shape is fine if redirect is the only supported knob.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
packages/client/src/adapters/fetch/link-fetch-client.test.ts(3 hunks)packages/client/src/adapters/fetch/link-fetch-client.ts(1 hunks)packages/client/src/adapters/fetch/plugin.test-d.ts(1 hunks)packages/client/src/adapters/fetch/plugin.test.ts(1 hunks)packages/client/src/adapters/fetch/plugin.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
packages/client/src/adapters/fetch/plugin.test.ts (1)
packages/client/src/adapters/fetch/plugin.ts (2)
LinkFetchPlugin(6-8)CompositeLinkFetchPlugin(10-17)
packages/client/src/adapters/fetch/plugin.test-d.ts (2)
packages/client/src/adapters/fetch/plugin.ts (1)
LinkFetchPlugin(6-8)packages/client/src/adapters/standard/plugin.ts (1)
StandardLinkPlugin(4-7)
packages/client/src/adapters/fetch/plugin.ts (2)
packages/client/src/adapters/standard/plugin.ts (2)
StandardLinkPlugin(4-7)CompositeStandardLinkPlugin(9-21)packages/client/src/adapters/fetch/link-fetch-client.ts (1)
LinkFetchClientOptions(18-30)
packages/client/src/adapters/fetch/link-fetch-client.test.ts (2)
packages/client/src/adapters/fetch/link-fetch-client.ts (1)
LinkFetchClient(32-60)packages/client/src/adapters/fetch/plugin.ts (1)
initRuntimeAdapter(12-16)
packages/client/src/adapters/fetch/link-fetch-client.ts (8)
packages/client/src/types.ts (2)
ClientContext(6-6)ClientOptions(8-12)packages/standard-server-fetch/src/request.ts (2)
ToFetchRequestOptions(24-24)toFetchRequest(26-36)packages/shared/src/interceptor.ts (1)
Interceptor(13-16)packages/client/src/adapters/fetch/plugin.ts (2)
LinkFetchPlugin(6-8)CompositeLinkFetchPlugin(10-17)packages/client/src/adapters/standard/types.ts (1)
StandardLinkClient(9-11)packages/shared/src/array.ts (1)
toArray(1-3)packages/standard-server/src/types.ts (2)
StandardRequest(13-24)StandardLazyResponse(43-49)packages/standard-server-fetch/src/response.ts (1)
toStandardLazyResponse(20-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: publish-commit
- GitHub Check: lint
- GitHub Check: test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
packages/client/src/adapters/fetch/plugin.test-d.ts (1)
4-9: Verify type-test environment provides globalsThis .test-d.ts uses describe/it/expectTypeOf as globals. Please ensure tsconfig includes vitest globals (or add a local reference) so editors and CI don’t flag missing types.
If needed, add this at the top:
/// <reference types="vitest/globals" />packages/client/src/adapters/fetch/plugin.test.ts (1)
6-36: LGTM: ordering and propagation behavior are well coveredGood coverage validating forward propagation, identical options object identity, and ordering based on order values (including the default 0).
packages/client/src/adapters/fetch/link-fetch-client.test.ts (2)
39-41: Good assertion: toFetchRequest called with full linkOptionsAsserting the second argument is linkOptions guards the API change to pass the entire options bag through.
76-91: LGTM: plugin initialization is invoked with the full optionsNice validation that initRuntimeAdapter receives the exact options object, which matches the mutation-based initialization design.
packages/client/src/adapters/fetch/link-fetch-client.ts (2)
37-45: Confirm whether Standard plugin init should also be invokedCompositeLinkFetchPlugin also supports the base init flow via CompositeStandardLinkPlugin. If any plugins rely on init (not just initRuntimeAdapter), you may want to call plugin.init(options as any) here or clarify that fetch adapters only use initRuntimeAdapter.
50-54: Interception flow looks correctThe intercept call correctly composes adapter interceptors, enforces redirect: 'manual' by default, and passes the normalized fetch signature through. Nice.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/server/src/adapters/fetch/rpc-handler.ts (1)
26-31: Avoid mutating caller-supplied options; build a new options object instead.Current code pushes into options.plugins, which can surprise callers (shared object, duplicate inserts if reused). Prefer an immutable merge and pass that downstream.
Apply:
- if (options.strictGetMethodPluginEnabled ?? true) { - options.plugins ??= [] - options.plugins.push(new StrictGetMethodPlugin()) - } - - super(new StandardRPCHandler(router, options), options) + const enableStrict = options.strictGetMethodPluginEnabled ?? true + const nextOptions: RPCHandlerOptions<T> = { + ...options, + plugins: enableStrict + ? [...(options.plugins ?? []), new StrictGetMethodPlugin()] + : options.plugins, + } + + super(new StandardRPCHandler(router, nextOptions), nextOptions)Optional follow-up: guard against duplicate StrictGetMethodPlugin if users also add it manually.
packages/server/src/adapters/node/rpc-handler.ts (2)
26-29: StrictGetMethodPlugin is likely the wrong plugin type target (pushed into Node plugins)NodeHttpHandlerOptions exposes
plugins?: NodeHttpHandlerPlugin<T>[], butStrictGetMethodPluginappears to be a Standard-layer plugin (imported from../../plugins) rather than a NodeHttpHandlerPlugin. Pushing it intooptions.pluginsrisks a type mismatch or a no-op at runtime.Refactor to inject the strict plugin into the StandardRPCHandler options instead, and avoid mutating the caller’s options object.
Apply this diff:
constructor(router: Router<any, T>, options: NoInfer<RPCHandlerOptions<T>> = {}) { - if (options.strictGetMethodPluginEnabled ?? true) { - options.plugins ??= [] - options.plugins.push(new StrictGetMethodPlugin()) - } - - super(new StandardRPCHandler(router, options), options) + // Build Standard options separately to attach Standard-level plugins. + const standardOptions: StandardRPCHandlerOptions<T> = { ...options } + if (options.strictGetMethodPluginEnabled ?? true) { + standardOptions.plugins ??= [] + standardOptions.plugins.push(new StrictGetMethodPlugin()) + } + + super(new StandardRPCHandler(router, standardOptions), options) }
25-25: Missing import forNoInferin Node RPC handler
TheRPCHandlerconstructor usesNoInfer<RPCHandlerOptions<T>>on line 25, but there’s noimport type { NoInfer } …at the top ofpackages/server/src/adapters/node/rpc-handler.ts. This will fail type-checking in isolated modules.• Add an import for
NoInferfrom wherever it’s defined, for example:import type { NoInfer } from '../../shared' // adjust path to your utility/types package• If
NoInferis intended as a global ambient type, ensure its.d.tsdeclaration is included in your TS config’stypeRoots.
🧹 Nitpick comments (6)
packages/client/src/adapters/fetch/rpc-link.ts (1)
7-9: Add documentation note clarifying plugin surface in RPCLinkOptionsPlease augment the public API docs on
RPCLinkOptionsto call out that only fetch-level plugins live here, and that standard RPC plugins have been removed from this surface. This will help users migrate any existing StandardRPCLink plugins to the new fetch-layer plugin model.• File needing update:
packages/client/src/adapters/fetch/rpc-link.ts
• Context: theRPCLinkOptionsinterface extendsLinkFetchClientOptions<T>(which still provides apluginsarray for fetch plugins) and omits the'plugins'field fromStandardRPCLinkOptions<T>(standard RPC plugins)Apply this diff:
export interface RPCLinkOptions<T extends ClientContext> extends LinkFetchClientOptions<T>, Omit<StandardRPCLinkOptions<T>, 'plugins'> {} + +/** + * Notes: + * - Standard RPC plugins (from `StandardRPCLinkOptions`) are intentionally omitted here. + * - To supply fetch-layer plugins, use the `plugins` array inherited from `LinkFetchClientOptions`. + * - For request/response interception on the fetch adapter, prefer `adapterInterceptors`. + */(optional) To double-check any client code still passing standard RPC plugins into the fetch adapter, you can run:
rg -nP -C2 'new\s+RPCLink\s*\(' rg -nP -C2 'RPCLinkOptions<' rg -nP -C2 '\bplugins\s*:'packages/openapi/src/adapters/fetch/openapi-handler.ts (1)
7-9: Public type surface now omits standard-layer plugins; ensure migration notes.OpenAPIHandlerOptions now composes FetchHandlerOptions with StandardOpenAPIHandlerOptions minus plugins. This is coherent with the new adapter interceptor/plugin model. Please add a short TsDoc note to signal the plugin relocation.
Apply:
-export interface OpenAPIHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> { -} +export interface OpenAPIHandlerOptions<T extends Context> + extends FetchHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> { + /** + * Standard-layer plugins are intentionally omitted. + * Use `FetchHandlerOptions.plugins` (fetch-layer plugins) and `adapterInterceptors` instead. + */ +}packages/openapi/src/adapters/node/openapi-handler.ts (1)
7-9: Mirror of fetch OpenAPI handler: omit standard-layer plugins and document it.Type change matches the fetch variant; suggest adding TsDoc to steer users toward NodeHttpHandlerOptions.plugins and adapterInterceptors.
Apply:
-export interface OpenAPIHandlerOptions<T extends Context> extends NodeHttpHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> { -} +export interface OpenAPIHandlerOptions<T extends Context> + extends NodeHttpHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> { + /** + * Standard-layer plugins are intentionally omitted. + * Use Node HTTP handler plugins (`NodeHttpHandlerOptions.plugins`) + * and `adapterInterceptors` for interception. + */ +}packages/server/src/adapters/node/rpc-handler.ts (3)
9-16: Interface now omits Standard plugins — confirm intended API change and migration impactBy extending NodeHttpHandlerOptions and Omit<StandardRPCHandlerOptions, 'plugins'>, callers can no longer pass Standard-level plugins through RPCHandlerOptions. If this is an intentional consolidation to the Node plugin surface, please confirm and document the migration (e.g., “pass NodeHttpHandlerPlugin via Node options; Standard plugins are injected internally only”). Otherwise, reintroduce a path for Standard plugins.
Would you like me to draft a short migration note for this API change?
25-32: Do not mutate caller-supplied optionsMutating
options.pluginsdirectly has surprising side effects for callers. The refactor above clones options for the Standard layer, preserving immutability and separation of concerns between Standard and Node handler options.
15-16: Add tests for strictGetMethodPluginEnabled on/off behaviorAdd integration tests for RPCHandler (Node adapter) that verify:
- Default (undefined/true) rejects GET with a body and/or enforces method semantics.
- When set to false, the strict behavior is not applied.
This guards the plugin wiring and future refactors.
I can draft the tests if you share the existing Node adapter test harness entry points.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
packages/client/src/adapters/fetch/rpc-link.ts(1 hunks)packages/openapi-client/src/adapters/fetch/openapi-link.ts(1 hunks)packages/openapi/src/adapters/fetch/openapi-handler.ts(1 hunks)packages/openapi/src/adapters/node/openapi-handler.ts(1 hunks)packages/server/src/adapters/fetch/rpc-handler.ts(1 hunks)packages/server/src/adapters/node/rpc-handler.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
packages/client/src/adapters/fetch/rpc-link.ts (2)
packages/client/src/adapters/fetch/link-fetch-client.ts (1)
LinkFetchClientOptions(18-30)packages/client/src/adapters/standard/rpc-link.ts (1)
StandardRPCLinkOptions(11-12)
packages/openapi-client/src/adapters/fetch/openapi-link.ts (2)
packages/client/src/adapters/fetch/link-fetch-client.ts (1)
LinkFetchClientOptions(18-30)packages/openapi-client/src/adapters/standard/openapi-link.ts (1)
StandardOpenAPILinkOptions(12-13)
packages/openapi/src/adapters/node/openapi-handler.ts (3)
packages/openapi/src/adapters/fetch/openapi-handler.ts (2)
OpenAPIHandlerOptions(7-8)OpenAPIHandler(16-20)packages/server/src/adapters/node/handler.ts (2)
NodeHttpHandlerOptions(20-24)NodeHttpHandler(26-70)packages/openapi/src/adapters/standard/openapi-handler.ts (1)
StandardOpenAPIHandlerOptions(10-12)
packages/openapi/src/adapters/fetch/openapi-handler.ts (4)
packages/openapi/src/adapters/node/openapi-handler.ts (2)
OpenAPIHandlerOptions(7-8)OpenAPIHandler(16-20)packages/server/src/context.ts (1)
Context(1-1)packages/server/src/adapters/fetch/handler.ts (2)
FetchHandlerOptions(19-23)FetchHandler(25-68)packages/openapi/src/adapters/standard/openapi-handler.ts (1)
StandardOpenAPIHandlerOptions(10-12)
packages/server/src/adapters/node/rpc-handler.ts (3)
packages/server/src/adapters/fetch/rpc-handler.ts (1)
RPCHandlerOptions(9-16)packages/server/src/adapters/node/handler.ts (1)
NodeHttpHandlerOptions(20-24)packages/server/src/adapters/standard/rpc-handler.ts (1)
StandardRPCHandlerOptions(11-13)
packages/server/src/adapters/fetch/rpc-handler.ts (3)
packages/server/src/adapters/node/rpc-handler.ts (1)
RPCHandlerOptions(9-16)packages/server/src/adapters/fetch/handler.ts (1)
FetchHandlerOptions(19-23)packages/server/src/adapters/standard/rpc-handler.ts (1)
StandardRPCHandlerOptions(11-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: publish-commit
- GitHub Check: test
- GitHub Check: lint
🔇 Additional comments (4)
packages/openapi-client/src/adapters/fetch/openapi-link.ts (1)
8-10: The above scripts will confirm whetherLinkFetchClientOptionstruly exposes apluginsfield (or onlyadapterInterceptors), and will locate the baseToFetchRequestOptionstype to see which fetch-layer hooks are available. Once we verify that, we can finalize the doc snippet accordingly.packages/openapi/src/adapters/fetch/openapi-handler.ts (1)
17-18: Constructor signature tightened to the new options type — LGTM.Type-only change; runtime remains the same. Consider adding a release note entry indicating that callers should migrate from the previous intersection type to OpenAPIHandlerOptions.
packages/server/src/adapters/fetch/rpc-handler.ts (1)
9-16: Type surface now drops standard-layer plugins; consistent with fetch-layer plugin model.Looks good and consistent with the Node variant. Ensure docs highlight that plugin injection now happens via FetchHandlerOptions.plugins, with strictGetMethodPlugin controlled by the new flag.
packages/openapi/src/adapters/node/openapi-handler.ts (1)
17-18: Constructor retyped to the new options — LGTM.No runtime impact; aligns with the fetch-side change. Add a brief migration note in the package CHANGELOG.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
apps/content/docs/advanced/superjson.md (3)
86-87: Confirm plugins property source or reintroduce it in SuperJSONHandlerOptionsYou’ve omitted
pluginsfromStandardHandlerOptions<T>but still mutateoptions.pluginsin the constructor. Please verify thatFetchHandlerOptions<T>definesplugins; otherwise this won’t type-check.If
FetchHandlerOptions<T>does not includeplugins, either:
- Reintroduce it explicitly on this options interface, or
- Stop mutating
options.pluginsand pass the plugin via the appropriate constructor option toStandardHandler.Proposed explicit reintroduction (if needed):
export interface SuperJSONHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, Omit<StandardHandlerOptions<T>, 'plugins'> { + // Required so SuperJSONHandler can inject StrictGetMethodPlugin + plugins?: StandardHandlerOptions<T>['plugins'] /** * Enable or disable the StrictGetMethodPlugin. * * @default true */ strictGetMethodPluginEnabled?: boolean }
97-97: NoInfer is used but not imported; consider importing or dropping for docs simplicityThe constructor’s
options: NoInfer<SuperJSONHandlerOptions<T>>will fail to type-check in the docs unlessNoInferis available in scope.Two options:
- Import it from your shared types module (verify the correct path in this repo):
// ---cut--- import type { StandardRPCSerializer } from '@orpc/client/standard' import type { Context, Router } from '@orpc/server' import type { FetchHandlerOptions } from '@orpc/server/fetch' +import type { NoInfer } from '@orpc/shared' // verify: correct source of NoInfer?
- Or, simplify the docs snippet by dropping
NoInfer:- constructor(router: Router<any, T>, options: NoInfer<SuperJSONHandlerOptions<T>> = {}) { + constructor(router: Router<any, T>, options: SuperJSONHandlerOptions<T> = {}) {
130-132: Link options composition looks correct; consider documenting adapterInterceptors usageExtending
LinkFetchClientOptions<T>and omitting'plugins'fromStandardLinkOptions<T>aligns with the PR’s client-side changes. To make the new capability discoverable, add a short example showingadapterInterceptorsusage withSuperJSONLink.Example to append below the code block:
import { SuperJSONLink } from './superjson-link' const link = new SuperJSONLink({ // from LinkFetchClientOptions<T>: fetch, // custom fetch if needed adapterInterceptors: [ { // runs before fetch request: async (req, ctx) => { req.headers.set('x-trace-id', ctx.requestId) return req }, // runs after fetch response: async (res) => { if (!res.ok) console.warn('request failed', res.status) return res }, }, ], // from StandardRPCLinkCodecOptions<T> / StandardLinkOptions<T> (minus 'plugins'): baseURL: 'https://api.example.com', })This will help users adopt the new
adapterInterceptorsoption introduced by this PR.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
apps/content/docs/advanced/superjson.md(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: lint
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: publish-commit
- GitHub Check: test
LinkFetchClient, RPCLink, OpenAPILink, ... now support
adapterInterceptorsoption for intercept fetch request/responseSummary by CodeRabbit
New Features
Refactor
Tests