Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/client/src/adapters/fetch/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './link-fetch-client'
export * from './rpc-link'
export * from './types'
13 changes: 6 additions & 7 deletions packages/client/src/adapters/fetch/rpc-link.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import type { ClientContext, ClientLink, ClientOptionsOut } from '../../types'
import type { StandardLinkOptions, StandardRPCLinkCodecOptions } from '../standard'
import type { LinkFetchClientOptions } from './link-fetch-client'
import { StandardLink, StandardRPCLinkCodec } from '../standard'
import { RPCSerializer, StandardLink, StandardRPCLinkCodec } from '../standard'
import { LinkFetchClient } from './link-fetch-client'

export interface RPCLinkOptions<T extends ClientContext>
extends StandardLinkOptions<T>, StandardRPCLinkCodecOptions<T>, LinkFetchClientOptions<T> {
linkCodec?: StandardRPCLinkCodec<T>
linkClient?: LinkFetchClient<T>
}
extends StandardLinkOptions<T>, StandardRPCLinkCodecOptions<T>, LinkFetchClientOptions<T> {}

export class RPCLink<T extends ClientContext> implements ClientLink<T> {
private readonly standardLink: StandardLink<T>

constructor(options: RPCLinkOptions<T>) {
const linkCodec = options.linkCodec ?? new StandardRPCLinkCodec(options)
const linkClient = options.linkClient ?? new LinkFetchClient(options)
const serializer = new RPCSerializer()
const linkCodec = new StandardRPCLinkCodec(serializer, options)
const linkClient = new LinkFetchClient(options)

this.standardLink = new StandardLink(linkCodec, linkClient, options)
}

Expand Down
9 changes: 3 additions & 6 deletions packages/client/src/adapters/standard/rpc-link-codec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ describe('standardRPCLinkCodec', () => {

describe('encode', () => {
const method = vi.fn()
const codec = new StandardRPCLinkCodec({
const codec = new StandardRPCLinkCodec(serializer, {
url: 'http://localhost:3000',
rpcSerializer: serializer,
method,
headers: () => ({ 'x-custom-header': 'custom-value' }),
})
Expand Down Expand Up @@ -78,9 +77,8 @@ describe('standardRPCLinkCodec', () => {
['blob inside', { blob: new Blob(['blob'], { type: 'text/plain' }) }],
['event-iterator', (async function* () { })()],
])('fallback method when method=GET: %s', async (_, input) => {
const codec = new StandardRPCLinkCodec({
const codec = new StandardRPCLinkCodec(serializer, {
url: 'http://localhost:3000',
rpcSerializer: serializer,
method: 'GET',
maxUrlLength: 100,
fallbackMethod: 'PATCH',
Expand All @@ -101,9 +99,8 @@ describe('standardRPCLinkCodec', () => {
})

describe('decode', () => {
const codec = new StandardRPCLinkCodec({
const codec = new StandardRPCLinkCodec(serializer, {
url: 'http://localhost:3000',
rpcSerializer: serializer,
})

it('should decode output', async () => {
Expand Down
15 changes: 7 additions & 8 deletions packages/client/src/adapters/standard/rpc-link-codec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { StandardHeaders, StandardLazyResponse, StandardRequest } from '@orpc/standard-server'
import type { ClientContext, ClientOptionsOut } from '../../types'
import type { RPCSerializer } from './rpc-serializer'
import type { StandardLinkCodec } from './types'
import { isAsyncIteratorObject, stringifyJSON, trim, value, type Value } from '@orpc/shared'
import { ORPCError } from '../../error'
import { RPCSerializer } from './rpc-serializer'

type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'

Expand Down Expand Up @@ -55,8 +55,6 @@ export interface StandardRPCLinkCodecOptions<T extends ClientContext> {
path: readonly string[],
input: unknown,
]>

rpcSerializer?: RPCSerializer
}

export class StandardRPCLinkCodec<T extends ClientContext> implements StandardLinkCodec<T> {
Expand All @@ -65,15 +63,16 @@ export class StandardRPCLinkCodec<T extends ClientContext> implements StandardLi
private readonly fallbackMethod: Exclude<StandardRPCLinkCodecOptions<T>['fallbackMethod'], undefined>
private readonly expectedMethod: Exclude<StandardRPCLinkCodecOptions<T>['method'], undefined>
private readonly headers: Exclude<StandardRPCLinkCodecOptions<T>['headers'], undefined>
private readonly rpcSerializer: Exclude<StandardRPCLinkCodecOptions<T>['rpcSerializer'], undefined>

constructor(options: StandardRPCLinkCodecOptions<T>) {
constructor(
private readonly serializer: RPCSerializer,
options: StandardRPCLinkCodecOptions<T>,
) {
this.baseUrl = options.url
this.maxUrlLength = options.maxUrlLength ?? 2083
this.fallbackMethod = options.fallbackMethod ?? 'POST'
this.expectedMethod = options.method ?? this.fallbackMethod
this.headers = options.headers ?? {}
this.rpcSerializer = options.rpcSerializer ?? new RPCSerializer()
}

async encode(path: readonly string[], input: unknown, options: ClientOptionsOut<any>): Promise<StandardRequest> {
Expand All @@ -82,7 +81,7 @@ export class StandardRPCLinkCodec<T extends ClientContext> implements StandardLi
const baseUrl = await value(this.baseUrl, options, path, input)
const url = new URL(`${trim(baseUrl.toString(), '/')}/${path.map(encodeURIComponent).join('/')}`)

const serialized = this.rpcSerializer.serialize(input)
const serialized = this.serializer.serialize(input)

if (
expectedMethod === 'GET'
Expand Down Expand Up @@ -126,7 +125,7 @@ export class StandardRPCLinkCodec<T extends ClientContext> implements StandardLi

isBodyOk = true

return this.rpcSerializer.deserialize(body)
return this.serializer.deserialize(body)
}
catch (error) {
if (!isBodyOk) {
Expand Down
19 changes: 0 additions & 19 deletions packages/openapi/src/adapters/fetch/openapi-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { StandardHandler } from '@orpc/server/standard'
import { toFetchResponse, toStandardLazyRequest } from '@orpc/standard-server-fetch'
import { describe, expect, it, vi } from 'vitest'
import { router } from '../../../../server/tests/shared'
import { OpenAPICodec, OpenAPIMatcher } from '../standard'
import { OpenAPIHandler } from './openapi-handler'

vi.mock('@orpc/server/standard', async origin => ({
Expand Down Expand Up @@ -93,22 +92,4 @@ describe('openAPIHandler', () => {

expect(vi.mocked(toFetchResponse)).not.toHaveBeenCalled()
})

it('standardHandler constructor', async () => {
const options = {
codec: new OpenAPICodec(),
matcher: new OpenAPIMatcher(),
interceptors: [vi.fn()],
}

const handler = new OpenAPIHandler(router, options)

expect(StandardHandler).toHaveBeenCalledOnce()
expect(StandardHandler).toHaveBeenCalledWith(
router,
options.matcher,
options.codec,
options,
)
})
})
11 changes: 6 additions & 5 deletions packages/openapi/src/adapters/fetch/openapi-handler.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import type { Context, Router } from '@orpc/server'
import type { FetchHandler, FetchHandleResult } from '@orpc/server/fetch'
import type { StandardHandleOptions } from '@orpc/server/standard'
import type { StandardHandleOptions, StandardHandlerOptions } from '@orpc/server/standard'
import type { MaybeOptionalOptions } from '@orpc/shared'
import type { ToFetchResponseOptions } from '@orpc/standard-server-fetch'
import type { OpenAPIHandlerOptions } from '../standard'
import { OpenAPISerializer } from '@orpc/openapi-client/standard'
import { StandardHandler } from '@orpc/server/standard'
import { toFetchResponse, toStandardLazyRequest } from '@orpc/standard-server-fetch'
import { OpenAPICodec, OpenAPIMatcher } from '../standard'

export class OpenAPIHandler<T extends Context> implements FetchHandler<T> {
private readonly standardHandler: StandardHandler<T>

constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>) {
const matcher = options?.matcher ?? new OpenAPIMatcher()
const codec = options?.codec ?? new OpenAPICodec()
constructor(router: Router<T, any>, options: NoInfer<StandardHandlerOptions<T>> = {}) {
const serializer = new OpenAPISerializer()
const matcher = new OpenAPIMatcher()
const codec = new OpenAPICodec(serializer)

this.standardHandler = new StandardHandler(router, matcher, codec, options)
}
Expand Down
19 changes: 0 additions & 19 deletions packages/openapi/src/adapters/node/openapi-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { StandardHandler } from '@orpc/server/standard'
import { sendStandardResponse, toStandardLazyRequest } from '@orpc/standard-server-node'
import inject from 'light-my-request'
import { router } from '../../../../server/tests/shared'
import { OpenAPICodec, OpenAPIMatcher } from '../standard'
import { OpenAPIHandler } from './openapi-handler'

vi.mock('@orpc/standard-server-node', () => ({
Expand Down Expand Up @@ -110,22 +109,4 @@ describe('openapiHandler', async () => {

expect(sendStandardResponse).not.toHaveBeenCalled()
})

it('standardHandler constructor', async () => {
const options = {
codec: new OpenAPICodec(),
matcher: new OpenAPIMatcher(),
interceptors: [vi.fn()],
}

const handler = new OpenAPIHandler(router, options)

expect(StandardHandler).toHaveBeenCalledOnce()
expect(StandardHandler).toHaveBeenCalledWith(
router,
options.matcher,
options.codec,
options,
)
})
})
13 changes: 7 additions & 6 deletions packages/openapi/src/adapters/node/openapi-handler.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type { Context, Router } from '@orpc/server'
import type { NodeHttpHandler, NodeHttpHandleResult, NodeHttpRequest, NodeHttpResponse } from '@orpc/server/node'
import type { StandardHandleOptions } from '@orpc/server/standard'
import type { StandardHandleOptions, StandardHandlerOptions } from '@orpc/server/standard'
import type { MaybeOptionalOptions } from '@orpc/shared'
import type { SendStandardResponseOptions } from '@orpc/standard-server-node'
import type { OpenAPIHandlerOptions } from '../standard'
import { OpenAPISerializer } from '@orpc/openapi-client/standard'
import { StandardHandler } from '@orpc/server/standard'
import { sendStandardResponse, toStandardLazyRequest } from '@orpc/standard-server-node'
import { OpenAPICodec, OpenAPIMatcher } from '../standard'

export class OpenAPIHandler<T extends Context> implements NodeHttpHandler<T> {
private readonly standardHandler: StandardHandler<T>

constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>) {
const matcher = options?.matcher ?? new OpenAPIMatcher()
const codec = options?.codec ?? new OpenAPICodec()
constructor(router: Router<T, any>, options: NoInfer<StandardHandlerOptions<T>> = {}) {
const serializer = new OpenAPISerializer()
const matcher = new OpenAPIMatcher()
const codec = new OpenAPICodec(serializer)

this.standardHandler = new StandardHandler(router, matcher, codec, { ...options })
this.standardHandler = new StandardHandler(router, matcher, codec, options)
}

async handle(
Expand Down
1 change: 0 additions & 1 deletion packages/openapi/src/adapters/standard/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './openapi-codec'
export * from './openapi-handler'
export * from './openapi-matcher'
4 changes: 0 additions & 4 deletions packages/openapi/src/adapters/standard/openapi-codec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,4 @@ describe('openAPICodec', () => {
expect(serializer.serialize).toHaveBeenCalledOnce()
expect(serializer.serialize).toHaveBeenCalledWith(error.toJSON())
})

it('work without arguments', async () => {
const codec = new OpenAPICodec()
})
})
4 changes: 2 additions & 2 deletions packages/openapi/src/adapters/standard/openapi-codec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { ORPCError } from '@orpc/client'
import type { OpenAPISerializer } from '@orpc/openapi-client/standard'
import type { AnyProcedure } from '@orpc/server'
import type { StandardCodec, StandardParams } from '@orpc/server/standard'
import type { StandardBody, StandardHeaders, StandardLazyRequest, StandardResponse } from '@orpc/standard-server'
import { fallbackContractConfig } from '@orpc/contract'
import { OpenAPISerializer } from '@orpc/openapi-client/standard'
import { isObject } from '@orpc/shared'

export class OpenAPICodec implements StandardCodec {
constructor(
private readonly serializer: OpenAPISerializer = new OpenAPISerializer(),
private readonly serializer: OpenAPISerializer,
) {
}

Expand Down
4 changes: 0 additions & 4 deletions packages/openapi/src/adapters/standard/openapi-handler.ts

This file was deleted.

3 changes: 2 additions & 1 deletion packages/server/src/adapters/fetch/rpc-handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RPCSerializer } from '@orpc/client/standard'
import { toFetchResponse, toStandardLazyRequest } from '@orpc/standard-server-fetch'
import { router } from '../../../tests/shared'
import { RPCCodec, RPCMatcher, StandardHandler } from '../standard'
Expand Down Expand Up @@ -91,7 +92,7 @@ describe('rpcHandler', () => {

it('standardHandler constructor', async () => {
const options = {
codec: new RPCCodec(),
codec: new RPCCodec(new RPCSerializer()),
matcher: new RPCMatcher(),
interceptors: [vi.fn()],
}
Expand Down
11 changes: 7 additions & 4 deletions packages/server/src/adapters/fetch/rpc-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import type { MaybeOptionalOptions } from '@orpc/shared'
import type { ToFetchResponseOptions } from '@orpc/standard-server-fetch'
import type { Context } from '../../context'
import type { Router } from '../../router'
import type { RPCHandlerOptions, StandardHandleOptions } from '../standard'
import type { StandardHandleOptions, StandardHandlerOptions } from '../standard'
import type { FetchHandler, FetchHandleResult } from './types'
import { RPCSerializer } from '@orpc/client/standard'
import { toFetchResponse, toStandardLazyRequest } from '@orpc/standard-server-fetch'
import { RPCCodec, RPCMatcher, StandardHandler } from '../standard'

export class RPCHandler<T extends Context> implements FetchHandler<T> {
private readonly standardHandler: StandardHandler<T>

constructor(router: Router<T, any>, options?: NoInfer<RPCHandlerOptions<T>>) {
const matcher = options?.matcher ?? new RPCMatcher()
const codec = options?.codec ?? new RPCCodec()
constructor(router: Router<T, any>, options: NoInfer<StandardHandlerOptions<T>> = {}) {
const serializer = new RPCSerializer()
const matcher = new RPCMatcher()
const codec = new RPCCodec(serializer)

this.standardHandler = new StandardHandler(router, matcher, codec, options)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/adapters/node/rpc-handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RPCSerializer } from '@orpc/client/standard'
import { sendStandardResponse, toStandardLazyRequest } from '@orpc/standard-server-node'
import inject from 'light-my-request'
import { router } from '../../../tests/shared'
Expand Down Expand Up @@ -112,7 +113,7 @@ describe('rpcHandler', async () => {

it('standardHandler constructor', async () => {
const options = {
codec: new RPCCodec(),
codec: new RPCCodec(new RPCSerializer()),
matcher: new RPCMatcher(),
interceptors: [vi.fn()],
}
Expand Down
10 changes: 6 additions & 4 deletions packages/server/src/adapters/node/rpc-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import type { MaybeOptionalOptions } from '@orpc/shared'
import type { SendStandardResponseOptions } from '@orpc/standard-server-node'
import type { Context } from '../../context'
import type { Router } from '../../router'
import type { RPCHandlerOptions, StandardHandleOptions } from '../standard'
import type { StandardHandleOptions, StandardHandlerOptions } from '../standard'
import type { NodeHttpHandler, NodeHttpHandleResult, NodeHttpRequest, NodeHttpResponse } from './types'
import { RPCSerializer } from '@orpc/client/standard'
import { sendStandardResponse, toStandardLazyRequest } from '@orpc/standard-server-node'
import { RPCCodec, RPCMatcher, StandardHandler } from '../standard'

export class RPCHandler<T extends Context> implements NodeHttpHandler<T> {
private readonly standardHandler: StandardHandler<T>

constructor(router: Router<T, any>, options?: NoInfer<RPCHandlerOptions<T>>) {
const codec = options?.codec ?? new RPCCodec()
const matcher = options?.matcher ?? new RPCMatcher()
constructor(router: Router<T, any>, options: NoInfer<StandardHandlerOptions<T>> = {}) {
const serializer = new RPCSerializer()
const matcher = new RPCMatcher()
const codec = new RPCCodec(serializer)

this.standardHandler = new StandardHandler(router, matcher, codec, options)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/adapters/standard/handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('standardHandler', () => {
}

it('should call matcher.init once', async () => {
const handler = new StandardHandler(router, matcher, codec)
const handler = new StandardHandler(router, matcher, codec, {})
expect(matcher.init).toHaveBeenCalledOnce()
expect(matcher.init).toHaveBeenCalledWith(router)
})
Expand Down Expand Up @@ -319,7 +319,7 @@ describe('standardHandler', () => {
params: { id: '__id__' },
})

const handler = new StandardHandler(router, matcher, codec)
const handler = new StandardHandler(router, matcher, codec, {})

expect(await handler.handle(request, { context: { db: 'postgres' } })).toEqual({
matched: true,
Expand All @@ -337,7 +337,7 @@ describe('standardHandler', () => {
params: { id: '__id__' },
})

const handler = new StandardHandler(router, matcher, codec)
const handler = new StandardHandler(router, matcher, codec, {})
const client = vi.fn().mockReturnValueOnce('__output__')
vi.mocked(createProcedureClient).mockReturnValueOnce(client)

Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/adapters/standard/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class StandardHandler<T extends Context> {
router: Router<T, any>,
private readonly matcher: StandardMatcher,
private readonly codec: StandardCodec,
private readonly options: NoInfer<StandardHandlerOptions<T>> = {},
private readonly options: NoInfer<StandardHandlerOptions<T>>,
) {
this.plugin = new CompositePlugin(options.plugins)

Expand Down
1 change: 0 additions & 1 deletion packages/server/src/adapters/standard/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './handler'
export * from './rpc-codec'
export * from './rpc-handler'
export * from './rpc-matcher'
export * from './types'
Loading