Skip to content

Commit

Permalink
fix(server): dynamic params not work
Browse files Browse the repository at this point in the history
  • Loading branch information
unnoq committed Nov 19, 2024
1 parent 76179b3 commit d00f4e3
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 16 deletions.
59 changes: 59 additions & 0 deletions packages/server/src/adapters/fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,62 @@ describe('accept header', () => {
})
})
})

describe('dynamic params', () => {
const router = os.router({
deep: os
.route({
method: 'GET',
path: '/{id}/{id2}',
})
.input(
z.object({
id: z.number(),
id2: z.string(),
}),
)
.handler((input) => input),

find: os
.route({
method: 'GET',
path: '/{id}',
})
.input(
z.object({
id: z.number(),
}),
)
.handler((input) => input),
})

const handlers = [
createFetchHandler({
router,
}),
createFetchHandler({
router,
serverless: true,
}),
]

it.each(handlers)('should handle dynamic params', async (handler) => {
const response = await handler({
request: new Request('http://localhost/123'),
})

expect(response.status).toEqual(200)
expect(response.headers.get('Content-Type')).toEqual('application/json')
expect(await response.json()).toEqual({ id: 123 })
})

it.each(handlers)('should handle deep dynamic params', async (handler) => {
const response = await handler({
request: new Request('http://localhost/123/dfdsfds'),
})

expect(response.status).toEqual(200)
expect(response.headers.get('Content-Type')).toEqual('application/json')
expect(await response.json()).toEqual({ id: 123, id2: 'dfdsfds' })
})
})
57 changes: 42 additions & 15 deletions packages/server/src/adapters/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type PartialOnUndefinedDeep,
get,
isPlainObject,
mapValues,
trim,
} from '@orpc/shared'
import { ORPCError } from '@orpc/shared/error'
Expand All @@ -18,6 +19,7 @@ import {
ORPCSerializer,
OpenAPIDeserializer,
OpenAPISerializer,
zodCoerce,
} from '@orpc/transformer'
import { LinearRouter } from 'hono/router/linear-router'
import { RegExpRouter } from 'hono/router/reg-exp-router'
Expand Down Expand Up @@ -86,7 +88,7 @@ export function createFetchHandler<TRouter extends Router<any>>(

let path: string[] | undefined
let procedure: WELL_DEFINED_PROCEDURE | undefined
let params: Record<string, string | number> | undefined
let params: Record<string, string> | undefined

if (isORPCTransformer) {
path = trim(pathname, '/').split('/').map(decodeURIComponent)
Expand All @@ -96,13 +98,28 @@ export function createFetchHandler<TRouter extends Router<any>>(
procedure = val
}
} else {
const [[match]] = routing.match(
const [matches, params_] = routing.match(
requestOptions.request.method,
pathname,
)
path = match?.[0][0]
procedure = match?.[0][1]
params = match?.[1]

const [match] = matches.sort((a, b) => {
return Object.keys(a[1]).length - Object.keys(b[1]).length
})

if (match) {
path = match[0][0]
procedure = match[0][1]

if (params_) {
params = mapValues(
(match as any)[1]!,
(v) => params_[v as number]!,
)
} else {
params = match[1] as Record<string, string>
}
}

if (!path || !procedure) {
path = trim(pathname, '/').split('/').map(decodeURIComponent)
Expand Down Expand Up @@ -148,18 +165,28 @@ export function createFetchHandler<TRouter extends Router<any>>(
})()

const input = (() => {
if (
params &&
Object.keys(params).length > 0 &&
(input_ === undefined || isPlainObject(input_))
) {
return {
...params,
...input_,
}
if (!params || Object.keys(params).length === 0) {
return input_
}

return input_
const coercedParams = procedure.zz$p.contract.zz$cp.InputSchema
? (zodCoerce(
procedure.zz$p.contract.zz$cp.InputSchema,
{ ...params },
{
bracketNotation: true,
},
) as object)
: params

if (input_ !== undefined && !isPlainObject(input_)) {
return coercedParams
}

return {
...coercedParams,
...input_,
}
})()

const caller = createProcedureCaller({
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export * from './json'
export * from './object'

export { isPlainObject } from 'is-what'
export { guard, trim, mapEntries, omit } from 'radash'
export { guard, trim, mapEntries, omit, mapValues } from 'radash'
2 changes: 2 additions & 0 deletions packages/transformer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export * from './openapi/deserializer'
export * from './openapi/serializer'
export * from './orpc/deserializer'
export * from './orpc/serializer'

export { zodCoerce } from './openapi/zod-coerce'

0 comments on commit d00f4e3

Please sign in to comment.