@orpc/server 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-26DTFWOI.js → chunk-YYGRQD4L.js} +26 -36
- package/dist/chunk-YYGRQD4L.js.map +1 -0
- package/dist/fetch.js +12 -12
- package/dist/fetch.js.map +1 -1
- package/dist/index.js +9 -15
- package/dist/index.js.map +1 -1
- package/dist/src/adapters/fetch.d.ts +2 -2
- package/dist/src/adapters/fetch.d.ts.map +1 -1
- package/dist/src/builder.d.ts +2 -2
- package/dist/src/builder.d.ts.map +1 -1
- package/dist/src/procedure-builder.d.ts +2 -2
- package/dist/src/procedure-builder.d.ts.map +1 -1
- package/dist/src/procedure-caller.d.ts +7 -16
- package/dist/src/procedure-caller.d.ts.map +1 -1
- package/dist/src/procedure-implementer.d.ts +2 -2
- package/dist/src/procedure-implementer.d.ts.map +1 -1
- package/dist/src/procedure.d.ts +11 -10
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/router-caller.d.ts +8 -17
- package/dist/src/router-caller.d.ts.map +1 -1
- package/dist/src/router.d.ts +2 -2
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/types.d.ts +0 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -6
- package/src/adapters/fetch.test.ts +18 -18
- package/src/adapters/fetch.ts +9 -5
- package/src/builder.test.ts +4 -4
- package/src/builder.ts +6 -6
- package/src/middleware.test.ts +1 -1
- package/src/procedure-builder.test.ts +2 -2
- package/src/procedure-builder.ts +6 -6
- package/src/procedure-caller.test.ts +27 -36
- package/src/procedure-caller.ts +36 -44
- package/src/procedure-implementer.test.ts +8 -8
- package/src/procedure-implementer.ts +6 -6
- package/src/procedure.test.ts +20 -20
- package/src/procedure.ts +30 -45
- package/src/router-builder.test.ts +4 -4
- package/src/router-caller.test.ts +5 -52
- package/src/router-caller.ts +11 -31
- package/src/router-implementer.test.ts +6 -6
- package/src/router.test-d.ts +2 -2
- package/src/router.test.ts +10 -10
- package/src/router.ts +4 -4
- package/src/types.ts +0 -1
- package/dist/chunk-26DTFWOI.js.map +0 -1
    
        package/src/procedure.test.ts
    CHANGED
    
    | @@ -18,7 +18,7 @@ it('isProcedure', () => { | |
| 18 18 | 
             
                        InputSchema: undefined,
         | 
| 19 19 | 
             
                        OutputSchema: undefined,
         | 
| 20 20 | 
             
                      }),
         | 
| 21 | 
            -
                       | 
| 21 | 
            +
                      func: () => {},
         | 
| 22 22 | 
             
                    }),
         | 
| 23 23 | 
             
                  ),
         | 
| 24 24 | 
             
                ),
         | 
| @@ -29,7 +29,7 @@ it('isProcedure', () => { | |
| 29 29 | 
             
                    InputSchema: undefined,
         | 
| 30 30 | 
             
                    OutputSchema: undefined,
         | 
| 31 31 | 
             
                  }),
         | 
| 32 | 
            -
                   | 
| 32 | 
            +
                  func: () => {},
         | 
| 33 33 | 
             
                },
         | 
| 34 34 | 
             
              }).toSatisfy(isProcedure)
         | 
| 35 35 |  | 
| @@ -57,7 +57,7 @@ it('isProcedure', () => { | |
| 57 57 |  | 
| 58 58 | 
             
            describe('route method', () => {
         | 
| 59 59 | 
             
              it('sets route options correctly', () => {
         | 
| 60 | 
            -
                const p = os.context<{ auth: boolean }>(). | 
| 60 | 
            +
                const p = os.context<{ auth: boolean }>().func(() => {
         | 
| 61 61 | 
             
                  return 'test'
         | 
| 62 62 | 
             
                })
         | 
| 63 63 |  | 
| @@ -69,11 +69,11 @@ describe('route method', () => { | |
| 69 69 |  | 
| 70 70 | 
             
              it('preserves existing context and handler', () => {
         | 
| 71 71 | 
             
                const handler = () => 'test'
         | 
| 72 | 
            -
                const p = os.context<{ auth: boolean }>(). | 
| 72 | 
            +
                const p = os.context<{ auth: boolean }>().func(handler)
         | 
| 73 73 |  | 
| 74 74 | 
             
                const p2 = p.route({ path: '/test' })
         | 
| 75 75 |  | 
| 76 | 
            -
                expect(p2.zz$p. | 
| 76 | 
            +
                expect(p2.zz$p.func).toBe(handler)
         | 
| 77 77 | 
             
                // Context type is preserved through the route method
         | 
| 78 78 | 
             
                expectTypeOf(p2).toEqualTypeOf<
         | 
| 79 79 | 
             
                  DecoratedProcedure<
         | 
| @@ -90,7 +90,7 @@ describe('route method', () => { | |
| 90 90 | 
             
                const p = os
         | 
| 91 91 | 
             
                  .context<{ auth: boolean }>()
         | 
| 92 92 | 
             
                  .route({ path: '/api', method: 'POST' })
         | 
| 93 | 
            -
                  . | 
| 93 | 
            +
                  .func(() => 'test')
         | 
| 94 94 |  | 
| 95 95 | 
             
                const p2 = p.prefix('/v1')
         | 
| 96 96 |  | 
| @@ -105,7 +105,7 @@ describe('route method', () => { | |
| 105 105 | 
             
                  .context<{ auth: boolean }>()
         | 
| 106 106 | 
             
                  .route({ path: '/test' })
         | 
| 107 107 | 
             
                  .use(mid)
         | 
| 108 | 
            -
                  . | 
| 108 | 
            +
                  .func((input, context) => {
         | 
| 109 109 | 
             
                    expectTypeOf(context).toEqualTypeOf<
         | 
| 110 110 | 
             
                      { auth: boolean } & { userId: string }
         | 
| 111 111 | 
             
                    >()
         | 
| @@ -120,7 +120,7 @@ describe('route method', () => { | |
| 120 120 | 
             
                const p = os
         | 
| 121 121 | 
             
                  .context<{ auth: boolean }>()
         | 
| 122 122 | 
             
                  .route({ path: '/test1', method: 'GET' })
         | 
| 123 | 
            -
                  . | 
| 123 | 
            +
                  .func(() => 'test')
         | 
| 124 124 |  | 
| 125 125 | 
             
                const p2 = p.route({ path: '/test2', method: 'POST' })
         | 
| 126 126 |  | 
| @@ -136,7 +136,7 @@ describe('route method', () => { | |
| 136 136 | 
             
                  .input(inputSchema)
         | 
| 137 137 | 
             
                  .output(outputSchema)
         | 
| 138 138 | 
             
                  .route({ path: '/test' })
         | 
| 139 | 
            -
                  . | 
| 139 | 
            +
                  .func((input) => {
         | 
| 140 140 | 
             
                    expectTypeOf(input).toEqualTypeOf<{ id: number }>()
         | 
| 141 141 | 
             
                    return 'test'
         | 
| 142 142 | 
             
                  })
         | 
| @@ -157,7 +157,7 @@ describe('route method', () => { | |
| 157 157 | 
             
            })
         | 
| 158 158 |  | 
| 159 159 | 
             
            it('prefix method', () => {
         | 
| 160 | 
            -
              const p = os.context<{ auth: boolean }>(). | 
| 160 | 
            +
              const p = os.context<{ auth: boolean }>().func(() => {
         | 
| 161 161 | 
             
                return 'unnoq'
         | 
| 162 162 | 
             
              })
         | 
| 163 163 |  | 
| @@ -168,7 +168,7 @@ it('prefix method', () => { | |
| 168 168 | 
             
              const p3 = os
         | 
| 169 169 | 
             
                .context<{ auth: boolean }>()
         | 
| 170 170 | 
             
                .route({ path: '/test1' })
         | 
| 171 | 
            -
                . | 
| 171 | 
            +
                .func(() => {
         | 
| 172 172 | 
             
                  return 'unnoq'
         | 
| 173 173 | 
             
                })
         | 
| 174 174 |  | 
| @@ -183,7 +183,7 @@ describe('use middleware', () => { | |
| 183 183 | 
             
                  .use((_, __, meta) => {
         | 
| 184 184 | 
             
                    return meta.next({ context: { postId: 'string' } })
         | 
| 185 185 | 
             
                  })
         | 
| 186 | 
            -
                  . | 
| 186 | 
            +
                  .func(() => {
         | 
| 187 187 | 
             
                    return 'unnoq'
         | 
| 188 188 | 
             
                  })
         | 
| 189 189 |  | 
| @@ -251,7 +251,7 @@ describe('use middleware', () => { | |
| 251 251 | 
             
                const mid2 = vi.fn()
         | 
| 252 252 | 
             
                const mid3 = vi.fn()
         | 
| 253 253 |  | 
| 254 | 
            -
                const p1 = os.use(mid1). | 
| 254 | 
            +
                const p1 = os.use(mid1).func(() => 'unnoq')
         | 
| 255 255 | 
             
                const p2 = p1.use(mid2).use(mid3)
         | 
| 256 256 |  | 
| 257 257 | 
             
                expect(p2.zz$p.middlewares).toEqual([mid3, mid2, mid1])
         | 
| @@ -260,12 +260,12 @@ describe('use middleware', () => { | |
| 260 260 |  | 
| 261 261 | 
             
            describe('server action', () => {
         | 
| 262 262 | 
             
              it('only accept undefined context', () => {
         | 
| 263 | 
            -
                expectTypeOf(os. | 
| 263 | 
            +
                expectTypeOf(os.func(() => {})).toMatchTypeOf<(...args: any[]) => any>()
         | 
| 264 264 | 
             
                expectTypeOf(
         | 
| 265 | 
            -
                  os.context<{ auth: boolean } | undefined>(). | 
| 265 | 
            +
                  os.context<{ auth: boolean } | undefined>().func(() => {}),
         | 
| 266 266 | 
             
                ).toMatchTypeOf<(...args: any[]) => any>()
         | 
| 267 267 | 
             
                expectTypeOf(
         | 
| 268 | 
            -
                  os.context<{ auth: boolean }>(). | 
| 268 | 
            +
                  os.context<{ auth: boolean }>().func(() => {}),
         | 
| 269 269 | 
             
                ).not.toMatchTypeOf<(...args: any[]) => any>()
         | 
| 270 270 | 
             
              })
         | 
| 271 271 |  | 
| @@ -273,13 +273,13 @@ describe('server action', () => { | |
| 273 273 | 
             
                const p = os
         | 
| 274 274 | 
             
                  .input(z.object({ id: z.number() }))
         | 
| 275 275 | 
             
                  .output(z.string())
         | 
| 276 | 
            -
                  . | 
| 276 | 
            +
                  .func(() => 'string')
         | 
| 277 277 |  | 
| 278 278 | 
             
                expectTypeOf(p).toMatchTypeOf<
         | 
| 279 279 | 
             
                  (input: { id: number } | FormData) => Promise<string>
         | 
| 280 280 | 
             
                >()
         | 
| 281 281 |  | 
| 282 | 
            -
                const p2 = os.input(z.object({ id: z.number() })). | 
| 282 | 
            +
                const p2 = os.input(z.object({ id: z.number() })).func(() => 12333)
         | 
| 283 283 |  | 
| 284 284 | 
             
                expectTypeOf(p2).toMatchTypeOf<
         | 
| 285 285 | 
             
                  (input: { id: number } | FormData) => Promise<number>
         | 
| @@ -289,7 +289,7 @@ describe('server action', () => { | |
| 289 289 | 
             
              it('works with input', async () => {
         | 
| 290 290 | 
             
                const p = os
         | 
| 291 291 | 
             
                  .input(z.object({ id: z.number(), date: z.date() }))
         | 
| 292 | 
            -
                  . | 
| 292 | 
            +
                  .func(async (input, context) => {
         | 
| 293 293 | 
             
                    expect(context).toBe(undefined)
         | 
| 294 294 | 
             
                    return input
         | 
| 295 295 | 
             
                  })
         | 
| @@ -303,7 +303,7 @@ describe('server action', () => { | |
| 303 303 | 
             
              it('can deserialize form data', async () => {
         | 
| 304 304 | 
             
                const p = os
         | 
| 305 305 | 
             
                  .input(z.object({ id: z.number(), nested: z.object({ date: z.date() }) }))
         | 
| 306 | 
            -
                  . | 
| 306 | 
            +
                  .func(async input => input)
         | 
| 307 307 |  | 
| 308 308 | 
             
                const form = new FormData()
         | 
| 309 309 | 
             
                form.append('id', '123')
         | 
    
        package/src/procedure.ts
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            import type { Promisable } from '@orpc/shared'
         | 
| 2 | 
            +
            import type { ProcedureCaller } from './procedure-caller'
         | 
| 2 3 | 
             
            import type { Context, MergeContext, Meta } from './types'
         | 
| 3 4 | 
             
            import {
         | 
| 4 5 | 
             
              type ContractProcedure,
         | 
| @@ -10,7 +11,6 @@ import { | |
| 10 11 | 
             
              type SchemaInput,
         | 
| 11 12 | 
             
              type SchemaOutput,
         | 
| 12 13 | 
             
            } from '@orpc/contract'
         | 
| 13 | 
            -
            import { OpenAPIDeserializer } from '@orpc/transformer'
         | 
| 14 14 | 
             
            import {
         | 
| 15 15 | 
             
              decorateMiddleware,
         | 
| 16 16 | 
             
              type MapInputMiddleware,
         | 
| @@ -23,18 +23,18 @@ export class Procedure< | |
| 23 23 | 
             
              TExtraContext extends Context,
         | 
| 24 24 | 
             
              TInputSchema extends Schema,
         | 
| 25 25 | 
             
              TOutputSchema extends Schema,
         | 
| 26 | 
            -
               | 
| 26 | 
            +
              TFuncOutput extends SchemaOutput<TOutputSchema>,
         | 
| 27 27 | 
             
            > {
         | 
| 28 28 | 
             
              constructor(
         | 
| 29 29 | 
             
                public zz$p: {
         | 
| 30 30 | 
             
                  middlewares?: Middleware<any, any, any, any>[]
         | 
| 31 31 | 
             
                  contract: ContractProcedure<TInputSchema, TOutputSchema>
         | 
| 32 | 
            -
                   | 
| 32 | 
            +
                  func: ProcedureFunc<
         | 
| 33 33 | 
             
                    TContext,
         | 
| 34 34 | 
             
                    TExtraContext,
         | 
| 35 35 | 
             
                    TInputSchema,
         | 
| 36 36 | 
             
                    TOutputSchema,
         | 
| 37 | 
            -
                     | 
| 37 | 
            +
                    TFuncOutput
         | 
| 38 38 | 
             
                  >
         | 
| 39 39 | 
             
                },
         | 
| 40 40 | 
             
              ) {}
         | 
| @@ -45,13 +45,13 @@ export type DecoratedProcedure< | |
| 45 45 | 
             
              TExtraContext extends Context,
         | 
| 46 46 | 
             
              TInputSchema extends Schema,
         | 
| 47 47 | 
             
              TOutputSchema extends Schema,
         | 
| 48 | 
            -
               | 
| 48 | 
            +
              TFuncOutput extends SchemaOutput<TOutputSchema>,
         | 
| 49 49 | 
             
            > = Procedure<
         | 
| 50 50 | 
             
              TContext,
         | 
| 51 51 | 
             
              TExtraContext,
         | 
| 52 52 | 
             
              TInputSchema,
         | 
| 53 53 | 
             
              TOutputSchema,
         | 
| 54 | 
            -
               | 
| 54 | 
            +
              TFuncOutput
         | 
| 55 55 | 
             
            > & {
         | 
| 56 56 | 
             
              prefix: (
         | 
| 57 57 | 
             
                prefix: HTTPPath,
         | 
| @@ -60,7 +60,7 @@ export type DecoratedProcedure< | |
| 60 60 | 
             
                TExtraContext,
         | 
| 61 61 | 
             
                TInputSchema,
         | 
| 62 62 | 
             
                TOutputSchema,
         | 
| 63 | 
            -
                 | 
| 63 | 
            +
                TFuncOutput
         | 
| 64 64 | 
             
              >
         | 
| 65 65 |  | 
| 66 66 | 
             
              route: (
         | 
| @@ -70,7 +70,7 @@ export type DecoratedProcedure< | |
| 70 70 | 
             
                TExtraContext,
         | 
| 71 71 | 
             
                TInputSchema,
         | 
| 72 72 | 
             
                TOutputSchema,
         | 
| 73 | 
            -
                 | 
| 73 | 
            +
                TFuncOutput
         | 
| 74 74 | 
             
              >
         | 
| 75 75 |  | 
| 76 76 | 
             
              use: (<
         | 
| @@ -82,14 +82,14 @@ export type DecoratedProcedure< | |
| 82 82 | 
             
                  MergeContext<TContext, TExtraContext>,
         | 
| 83 83 | 
             
                  UExtraContext,
         | 
| 84 84 | 
             
                  SchemaOutput<TInputSchema>,
         | 
| 85 | 
            -
                  SchemaInput<TOutputSchema,  | 
| 85 | 
            +
                  SchemaInput<TOutputSchema, TFuncOutput>
         | 
| 86 86 | 
             
                >,
         | 
| 87 87 | 
             
              ) => DecoratedProcedure<
         | 
| 88 88 | 
             
                TContext,
         | 
| 89 89 | 
             
                MergeContext<TExtraContext, UExtraContext>,
         | 
| 90 90 | 
             
                TInputSchema,
         | 
| 91 91 | 
             
                TOutputSchema,
         | 
| 92 | 
            -
                 | 
| 92 | 
            +
                TFuncOutput
         | 
| 93 93 | 
             
              >) & (<
         | 
| 94 94 | 
             
                UExtraContext extends
         | 
| 95 95 | 
             
                | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
         | 
| @@ -100,10 +100,10 @@ export type DecoratedProcedure< | |
| 100 100 | 
             
                  MergeContext<TContext, TExtraContext>,
         | 
| 101 101 | 
             
                  UExtraContext,
         | 
| 102 102 | 
             
                  UMappedInput,
         | 
| 103 | 
            -
                  SchemaInput<TOutputSchema,  | 
| 103 | 
            +
                  SchemaInput<TOutputSchema, TFuncOutput>
         | 
| 104 104 | 
             
                >,
         | 
| 105 105 | 
             
                mapInput: MapInputMiddleware<
         | 
| 106 | 
            -
                  SchemaOutput<TInputSchema,  | 
| 106 | 
            +
                  SchemaOutput<TInputSchema, TFuncOutput>,
         | 
| 107 107 | 
             
                  UMappedInput
         | 
| 108 108 | 
             
                >,
         | 
| 109 109 | 
             
              ) => DecoratedProcedure<
         | 
| @@ -111,15 +111,19 @@ export type DecoratedProcedure< | |
| 111 111 | 
             
                MergeContext<TExtraContext, UExtraContext>,
         | 
| 112 112 | 
             
                TInputSchema,
         | 
| 113 113 | 
             
                TOutputSchema,
         | 
| 114 | 
            -
                 | 
| 114 | 
            +
                TFuncOutput
         | 
| 115 115 | 
             
              >)
         | 
| 116 116 | 
             
            } & (undefined extends TContext
         | 
| 117 | 
            -
              ?  | 
| 118 | 
            -
             | 
| 119 | 
            -
                 | 
| 117 | 
            +
              ? ProcedureCaller<Procedure<
         | 
| 118 | 
            +
                TContext,
         | 
| 119 | 
            +
                TExtraContext,
         | 
| 120 | 
            +
                TInputSchema,
         | 
| 121 | 
            +
                TOutputSchema,
         | 
| 122 | 
            +
                TFuncOutput
         | 
| 123 | 
            +
              >>
         | 
| 120 124 | 
             
              : unknown)
         | 
| 121 125 |  | 
| 122 | 
            -
            export interface  | 
| 126 | 
            +
            export interface ProcedureFunc<
         | 
| 123 127 | 
             
              TContext extends Context,
         | 
| 124 128 | 
             
              TExtraContext extends Context,
         | 
| 125 129 | 
             
              TInputSchema extends Schema,
         | 
| @@ -140,49 +144,30 @@ export function decorateProcedure< | |
| 140 144 | 
             
              TExtraContext extends Context,
         | 
| 141 145 | 
             
              TInputSchema extends Schema,
         | 
| 142 146 | 
             
              TOutputSchema extends Schema,
         | 
| 143 | 
            -
               | 
| 147 | 
            +
              TFuncOutput extends SchemaOutput<TOutputSchema>,
         | 
| 144 148 | 
             
            >(
         | 
| 145 149 | 
             
              procedure: Procedure<
         | 
| 146 150 | 
             
                TContext,
         | 
| 147 151 | 
             
                TExtraContext,
         | 
| 148 152 | 
             
                TInputSchema,
         | 
| 149 153 | 
             
                TOutputSchema,
         | 
| 150 | 
            -
                 | 
| 154 | 
            +
                TFuncOutput
         | 
| 151 155 | 
             
              >,
         | 
| 152 156 | 
             
            ): DecoratedProcedure<
         | 
| 153 157 | 
             
                TContext,
         | 
| 154 158 | 
             
                TExtraContext,
         | 
| 155 159 | 
             
                TInputSchema,
         | 
| 156 160 | 
             
                TOutputSchema,
         | 
| 157 | 
            -
                 | 
| 161 | 
            +
                TFuncOutput
         | 
| 158 162 | 
             
              > {
         | 
| 159 163 | 
             
              if (DECORATED_PROCEDURE_SYMBOL in procedure) {
         | 
| 160 164 | 
             
                return procedure as any
         | 
| 161 165 | 
             
              }
         | 
| 162 166 |  | 
| 163 | 
            -
               | 
| 164 | 
            -
                 | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
                  const transformer = new OpenAPIDeserializer({
         | 
| 169 | 
            -
                    schema: procedure.zz$p.contract.zz$cp.InputSchema,
         | 
| 170 | 
            -
                  })
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                  return transformer.deserializeAsFormData(input)
         | 
| 173 | 
            -
                })()
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                const procedureCaller = createProcedureCaller({
         | 
| 176 | 
            -
                  procedure,
         | 
| 177 | 
            -
                  context: undefined as any,
         | 
| 178 | 
            -
                  internal: false,
         | 
| 179 | 
            -
                  validate: true,
         | 
| 180 | 
            -
                })
         | 
| 181 | 
            -
             | 
| 182 | 
            -
                return await procedureCaller(input_ as any)
         | 
| 183 | 
            -
              }
         | 
| 184 | 
            -
             | 
| 185 | 
            -
              return Object.assign(serverAction, {
         | 
| 167 | 
            +
              return Object.assign(createProcedureCaller({
         | 
| 168 | 
            +
                procedure,
         | 
| 169 | 
            +
                context: undefined as any,
         | 
| 170 | 
            +
              }), {
         | 
| 186 171 | 
             
                [DECORATED_PROCEDURE_SYMBOL]: true,
         | 
| 187 172 | 
             
                zz$p: procedure.zz$p,
         | 
| 188 173 |  | 
| @@ -246,7 +231,7 @@ export function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE { | |
| 246 231 | 
             
                && item.zz$p !== null
         | 
| 247 232 | 
             
                && 'contract' in item.zz$p
         | 
| 248 233 | 
             
                && isContractProcedure(item.zz$p.contract)
         | 
| 249 | 
            -
                && ' | 
| 250 | 
            -
                && typeof item.zz$p. | 
| 234 | 
            +
                && 'func' in item.zz$p
         | 
| 235 | 
            +
                && typeof item.zz$p.func === 'function'
         | 
| 251 236 | 
             
              )
         | 
| 252 237 | 
             
            }
         | 
| @@ -6,10 +6,10 @@ import { RouterBuilder } from './router-builder' | |
| 6 6 | 
             
            const builder = new RouterBuilder<undefined, undefined>({})
         | 
| 7 7 | 
             
            const ping = os
         | 
| 8 8 | 
             
              .route({ method: 'GET', path: '/ping', tags: ['ping'] })
         | 
| 9 | 
            -
              . | 
| 9 | 
            +
              .func(() => 'ping')
         | 
| 10 10 | 
             
            const pong = os
         | 
| 11 11 | 
             
              .output(z.object({ id: z.string() }))
         | 
| 12 | 
            -
              . | 
| 12 | 
            +
              .func(() => ({ id: '123' }))
         | 
| 13 13 |  | 
| 14 14 | 
             
            describe('prefix', () => {
         | 
| 15 15 | 
             
              it('chainable prefix', () => {
         | 
| @@ -80,7 +80,7 @@ describe('middleware', () => { | |
| 80 80 | 
             
                    InputSchema: undefined,
         | 
| 81 81 | 
             
                    OutputSchema: undefined,
         | 
| 82 82 | 
             
                  }),
         | 
| 83 | 
            -
                   | 
| 83 | 
            +
                  func: () => {},
         | 
| 84 84 | 
             
                })
         | 
| 85 85 |  | 
| 86 86 | 
             
                const decorated = decorateProcedure({
         | 
| @@ -89,7 +89,7 @@ describe('middleware', () => { | |
| 89 89 | 
             
                      InputSchema: undefined,
         | 
| 90 90 | 
             
                      OutputSchema: undefined,
         | 
| 91 91 | 
             
                    }),
         | 
| 92 | 
            -
                     | 
| 92 | 
            +
                    func: () => {},
         | 
| 93 93 | 
             
                  },
         | 
| 94 94 | 
             
                })
         | 
| 95 95 |  | 
| @@ -2,24 +2,22 @@ import { z } from 'zod' | |
| 2 2 | 
             
            import { createRouterCaller, os } from '.'
         | 
| 3 3 |  | 
| 4 4 | 
             
            describe('createRouterCaller', () => {
         | 
| 5 | 
            -
               | 
| 6 | 
            -
               | 
| 5 | 
            +
              const internal = false
         | 
| 6 | 
            +
              const context = { auth: true }
         | 
| 7 7 |  | 
| 8 8 | 
             
              const osw = os.context<{ auth?: boolean }>()
         | 
| 9 9 |  | 
| 10 10 | 
             
              const ping = osw
         | 
| 11 11 | 
             
                .input(z.object({ value: z.string().transform(v => Number(v)) }))
         | 
| 12 12 | 
             
                .output(z.object({ value: z.number().transform(v => v.toString()) }))
         | 
| 13 | 
            -
                . | 
| 13 | 
            +
                .func((input, context, meta) => {
         | 
| 14 14 | 
             
                  expect(context).toEqual(context)
         | 
| 15 | 
            -
                  expect(meta.internal).toEqual(internal)
         | 
| 16 15 |  | 
| 17 16 | 
             
                  return input
         | 
| 18 17 | 
             
                })
         | 
| 19 18 |  | 
| 20 | 
            -
              const pong = osw. | 
| 19 | 
            +
              const pong = osw.func((_, context, meta) => {
         | 
| 21 20 | 
             
                expect(context).toEqual(context)
         | 
| 22 | 
            -
                expect(meta.internal).toBe(internal)
         | 
| 23 21 |  | 
| 24 22 | 
             
                return { value: true }
         | 
| 25 23 | 
             
              })
         | 
| @@ -50,7 +48,6 @@ describe('createRouterCaller', () => { | |
| 50 48 | 
             
                const caller = createRouterCaller({
         | 
| 51 49 | 
             
                  router,
         | 
| 52 50 | 
             
                  context,
         | 
| 53 | 
            -
                  internal,
         | 
| 54 51 | 
             
                })
         | 
| 55 52 |  | 
| 56 53 | 
             
                expectTypeOf(caller.ping).toMatchTypeOf<
         | 
| @@ -98,52 +95,8 @@ describe('createRouterCaller', () => { | |
| 98 95 | 
             
                )
         | 
| 99 96 | 
             
              })
         | 
| 100 97 |  | 
| 101 | 
            -
              it('without validate', () => {
         | 
| 102 | 
            -
                internal = true
         | 
| 103 | 
            -
                context = { auth: false }
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                const caller = createRouterCaller({
         | 
| 106 | 
            -
                  router,
         | 
| 107 | 
            -
                  context,
         | 
| 108 | 
            -
                  internal,
         | 
| 109 | 
            -
                  validate: false,
         | 
| 110 | 
            -
                })
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                expectTypeOf(caller.ping).toMatchTypeOf<
         | 
| 113 | 
            -
                  (input: { value: number }) => Promise<{
         | 
| 114 | 
            -
                    value: number
         | 
| 115 | 
            -
                  }>
         | 
| 116 | 
            -
                >()
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                expectTypeOf(caller.pong).toMatchTypeOf<
         | 
| 119 | 
            -
                  (input: unknown) => Promise<{
         | 
| 120 | 
            -
                    value: boolean
         | 
| 121 | 
            -
                  }>
         | 
| 122 | 
            -
                >()
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                expectTypeOf(caller.nested.ping).toMatchTypeOf<
         | 
| 125 | 
            -
                  (input: { value: number }) => Promise<{
         | 
| 126 | 
            -
                    value: number
         | 
| 127 | 
            -
                  }>
         | 
| 128 | 
            -
                >()
         | 
| 129 | 
            -
             | 
| 130 | 
            -
                expectTypeOf(caller.nested.pong).toMatchTypeOf<
         | 
| 131 | 
            -
                  (input: unknown) => Promise<{
         | 
| 132 | 
            -
                    value: boolean
         | 
| 133 | 
            -
                  }>
         | 
| 134 | 
            -
                >()
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                expect(caller.ping({ value: 123 })).resolves.toEqual({ value: 123 })
         | 
| 137 | 
            -
                expect(caller.pong({ value: 123 })).resolves.toEqual({ value: true })
         | 
| 138 | 
            -
                expect(caller.nested.ping({ value: 123 })).resolves.toEqual({ value: 123 })
         | 
| 139 | 
            -
                expect(caller.nested.pong({ value: 123 })).resolves.toEqual({ value: true })
         | 
| 140 | 
            -
             | 
| 141 | 
            -
                // @ts-expect-error it's not validate so bellow still works
         | 
| 142 | 
            -
                expect(caller.ping({ value: '123' })).resolves.toEqual({ value: '123' })
         | 
| 143 | 
            -
              })
         | 
| 144 | 
            -
             | 
| 145 98 | 
             
              it('path', () => {
         | 
| 146 | 
            -
                const ping = osw. | 
| 99 | 
            +
                const ping = osw.func((_, __, { path }) => {
         | 
| 147 100 | 
             
                  return path
         | 
| 148 101 | 
             
                })
         | 
| 149 102 |  | 
    
        package/src/router-caller.ts
    CHANGED
    
    | @@ -1,59 +1,43 @@ | |
| 1 | 
            -
            import type {} from '@orpc/ | 
| 1 | 
            +
            import type { Value } from '@orpc/shared'
         | 
| 2 2 | 
             
            import type { Router } from './router'
         | 
| 3 3 | 
             
            import { isProcedure, type Procedure } from './procedure'
         | 
| 4 4 | 
             
            import { createProcedureCaller, type ProcedureCaller } from './procedure-caller'
         | 
| 5 5 |  | 
| 6 6 | 
             
            export interface CreateRouterCallerOptions<
         | 
| 7 7 | 
             
              TRouter extends Router<any>,
         | 
| 8 | 
            -
              TValidate extends boolean,
         | 
| 9 8 | 
             
            > {
         | 
| 10 9 | 
             
              router: TRouter
         | 
| 11 10 |  | 
| 12 11 | 
             
              /**
         | 
| 13 12 | 
             
               * The context used when calling the procedure.
         | 
| 14 13 | 
             
               */
         | 
| 15 | 
            -
              context:  | 
| 14 | 
            +
              context: Value<
         | 
| 15 | 
            +
                TRouter extends Router<infer UContext> ? UContext : never
         | 
| 16 | 
            +
              >
         | 
| 16 17 |  | 
| 17 18 | 
             
              /**
         | 
| 18 19 | 
             
               * This is helpful for logging and analytics.
         | 
| 19 | 
            -
               */
         | 
| 20 | 
            -
              basePath?: string[]
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              /**
         | 
| 23 | 
            -
               * This flag helpful when you want bypass some logics not necessary to internal server calls.
         | 
| 24 | 
            -
               *
         | 
| 25 | 
            -
               * @default true
         | 
| 26 | 
            -
               */
         | 
| 27 | 
            -
              internal?: boolean
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              /**
         | 
| 30 | 
            -
               * Indicate whether validate input and output.
         | 
| 31 20 | 
             
               *
         | 
| 32 | 
            -
               * @ | 
| 21 | 
            +
               * @internal
         | 
| 33 22 | 
             
               */
         | 
| 34 | 
            -
               | 
| 23 | 
            +
              basePath?: string[]
         | 
| 35 24 | 
             
            }
         | 
| 36 25 |  | 
| 37 26 | 
             
            export type RouterCaller<
         | 
| 38 27 | 
             
              TRouter extends Router<any>,
         | 
| 39 | 
            -
              TValidate extends boolean,
         | 
| 40 28 | 
             
            > = {
         | 
| 41 29 | 
             
              [K in keyof TRouter]: TRouter[K] extends Procedure<any, any, any, any, any>
         | 
| 42 | 
            -
                ? ProcedureCaller<TRouter[K] | 
| 30 | 
            +
                ? ProcedureCaller<TRouter[K]>
         | 
| 43 31 | 
             
                : TRouter[K] extends Router<any>
         | 
| 44 | 
            -
                  ? RouterCaller<TRouter[K] | 
| 32 | 
            +
                  ? RouterCaller<TRouter[K]>
         | 
| 45 33 | 
             
                  : never
         | 
| 46 34 | 
             
            }
         | 
| 47 35 |  | 
| 48 36 | 
             
            export function createRouterCaller<
         | 
| 49 37 | 
             
              TRouter extends Router<any>,
         | 
| 50 | 
            -
              TValidate extends boolean = true,
         | 
| 51 38 | 
             
            >(
         | 
| 52 | 
            -
              options: CreateRouterCallerOptions<TRouter | 
| 53 | 
            -
            ): RouterCaller<TRouter | 
| 54 | 
            -
              const internal = options.internal ?? true
         | 
| 55 | 
            -
              const validate = options.validate ?? true
         | 
| 56 | 
            -
             | 
| 39 | 
            +
              options: CreateRouterCallerOptions<TRouter>,
         | 
| 40 | 
            +
            ): RouterCaller<TRouter> {
         | 
| 57 41 | 
             
              const caller: Record<string, unknown> = {}
         | 
| 58 42 |  | 
| 59 43 | 
             
              for (const key in options.router) {
         | 
| @@ -65,8 +49,6 @@ export function createRouterCaller< | |
| 65 49 | 
             
                    procedure: item,
         | 
| 66 50 | 
             
                    context: options.context as any,
         | 
| 67 51 | 
             
                    path,
         | 
| 68 | 
            -
                    internal,
         | 
| 69 | 
            -
                    validate,
         | 
| 70 52 | 
             
                  })
         | 
| 71 53 | 
             
                }
         | 
| 72 54 | 
             
                else {
         | 
| @@ -74,11 +56,9 @@ export function createRouterCaller< | |
| 74 56 | 
             
                    router: item as any,
         | 
| 75 57 | 
             
                    context: options.context,
         | 
| 76 58 | 
             
                    basePath: path,
         | 
| 77 | 
            -
                    internal,
         | 
| 78 | 
            -
                    validate,
         | 
| 79 59 | 
             
                  })
         | 
| 80 60 | 
             
                }
         | 
| 81 61 | 
             
              }
         | 
| 82 62 |  | 
| 83 | 
            -
              return caller as RouterCaller<TRouter | 
| 63 | 
            +
              return caller as RouterCaller<TRouter>
         | 
| 84 64 | 
             
            }
         | 
| @@ -17,15 +17,15 @@ const cr = oc.router({ | |
| 17 17 |  | 
| 18 18 | 
             
            const osw = os.context<{ auth: boolean }>().contract(cr)
         | 
| 19 19 |  | 
| 20 | 
            -
            const p1 = osw.p1. | 
| 20 | 
            +
            const p1 = osw.p1.func(() => {
         | 
| 21 21 | 
             
              return 'unnoq'
         | 
| 22 22 | 
             
            })
         | 
| 23 23 |  | 
| 24 | 
            -
            const p2 = osw.nested.p2. | 
| 24 | 
            +
            const p2 = osw.nested.p2.func(() => {
         | 
| 25 25 | 
             
              return 'unnoq'
         | 
| 26 26 | 
             
            })
         | 
| 27 27 |  | 
| 28 | 
            -
            const p3 = osw.nested2.p3. | 
| 28 | 
            +
            const p3 = osw.nested2.p3.func(() => {
         | 
| 29 29 | 
             
              return 'unnoq'
         | 
| 30 30 | 
             
            })
         | 
| 31 31 |  | 
| @@ -37,7 +37,7 @@ it('required all procedure match', () => { | |
| 37 37 | 
             
              implementer.router({
         | 
| 38 38 | 
             
                p1,
         | 
| 39 39 | 
             
                nested: {
         | 
| 40 | 
            -
                  p2: os.contract(cp2). | 
| 40 | 
            +
                  p2: os.contract(cp2).func(() => ''),
         | 
| 41 41 | 
             
                },
         | 
| 42 42 | 
             
                nested2: {
         | 
| 43 43 | 
             
                  p3,
         | 
| @@ -47,7 +47,7 @@ it('required all procedure match', () => { | |
| 47 47 | 
             
              expect(() => {
         | 
| 48 48 | 
             
                implementer.router({
         | 
| 49 49 | 
             
                  // @ts-expect-error p1 is mismatch
         | 
| 50 | 
            -
                  p1: os. | 
| 50 | 
            +
                  p1: os.func(() => {}),
         | 
| 51 51 | 
             
                  nested: {
         | 
| 52 52 | 
             
                    p2,
         | 
| 53 53 | 
             
                  },
         | 
| @@ -76,7 +76,7 @@ it('required all procedure match', () => { | |
| 76 76 | 
             
                  p1: os
         | 
| 77 77 | 
             
                    .input(z.string())
         | 
| 78 78 | 
             
                    .output(z.string())
         | 
| 79 | 
            -
                    . | 
| 79 | 
            +
                    .func(() => 'unnoq'),
         | 
| 80 80 | 
             
                  nested: {
         | 
| 81 81 | 
             
                    p2,
         | 
| 82 82 | 
             
                  },
         | 
    
        package/src/router.test-d.ts
    CHANGED
    
    | @@ -6,11 +6,11 @@ const router = os.router({ | |
| 6 6 | 
             
              ping: os
         | 
| 7 7 | 
             
                .input(z.object({ ping: z.string().transform(() => 1) }))
         | 
| 8 8 | 
             
                .output(z.object({ pong: z.number().transform(() => '1') }))
         | 
| 9 | 
            -
                . | 
| 9 | 
            +
                .func(() => ({ pong: 1 })),
         | 
| 10 10 | 
             
              user: {
         | 
| 11 11 | 
             
                find: os
         | 
| 12 12 | 
             
                  .input(z.object({ find: z.number().transform(() => '1') }))
         | 
| 13 | 
            -
                  . | 
| 13 | 
            +
                  .func(() => ({ user: { id: 1 } }))
         | 
| 14 14 | 
             
                ,
         | 
| 15 15 | 
             
              },
         | 
| 16 16 | 
             
            })
         | 
    
        package/src/router.test.ts
    CHANGED
    
    | @@ -6,22 +6,22 @@ it('require procedure match context', () => { | |
| 6 6 | 
             
              const osw = os.context<{ auth: boolean, userId: string }>()
         | 
| 7 7 |  | 
| 8 8 | 
             
              osw.router({
         | 
| 9 | 
            -
                ping: osw.context<{ auth: boolean }>(). | 
| 9 | 
            +
                ping: osw.context<{ auth: boolean }>().func(() => {
         | 
| 10 10 | 
             
                  return { pong: 'ping' }
         | 
| 11 11 | 
             
                }),
         | 
| 12 12 |  | 
| 13 13 | 
             
                // @ts-expect-error userId is not match
         | 
| 14 | 
            -
                ping2: osw.context<{ userId: number }>(). | 
| 14 | 
            +
                ping2: osw.context<{ userId: number }>().func(() => {
         | 
| 15 15 | 
             
                  return { name: 'unnoq' }
         | 
| 16 16 | 
             
                }),
         | 
| 17 17 |  | 
| 18 18 | 
             
                nested: {
         | 
| 19 | 
            -
                  ping: osw.context<{ auth: boolean }>(). | 
| 19 | 
            +
                  ping: osw.context<{ auth: boolean }>().func(() => {
         | 
| 20 20 | 
             
                    return { pong: 'ping' }
         | 
| 21 21 | 
             
                  }),
         | 
| 22 22 |  | 
| 23 23 | 
             
                  // @ts-expect-error userId is not match
         | 
| 24 | 
            -
                  ping2: osw.context<{ userId: number }>(). | 
| 24 | 
            +
                  ping2: osw.context<{ userId: number }>().func(() => {
         | 
| 25 25 | 
             
                    return { name: 'unnoq' }
         | 
| 26 26 | 
             
                  }),
         | 
| 27 27 | 
             
                },
         | 
| @@ -31,10 +31,10 @@ it('require procedure match context', () => { | |
| 31 31 | 
             
            it('require match contract', () => {
         | 
| 32 32 | 
             
              const pingContract = oc.route({ method: 'GET', path: '/ping' })
         | 
| 33 33 | 
             
              const pongContract = oc.input(z.string()).output(z.string())
         | 
| 34 | 
            -
              const ping = os.contract(pingContract). | 
| 34 | 
            +
              const ping = os.contract(pingContract).func(() => {
         | 
| 35 35 | 
             
                return 'ping'
         | 
| 36 36 | 
             
              })
         | 
| 37 | 
            -
              const pong = os.contract(pongContract). | 
| 37 | 
            +
              const pong = os.contract(pongContract).func(() => {
         | 
| 38 38 | 
             
                return 'pong'
         | 
| 39 39 | 
             
              })
         | 
| 40 40 |  | 
| @@ -85,7 +85,7 @@ it('require match contract', () => { | |
| 85 85 | 
             
                nested: {
         | 
| 86 86 | 
             
                  ping,
         | 
| 87 87 | 
             
                  // @ts-expect-error nested.pong is mismatch
         | 
| 88 | 
            -
                  pong: os. | 
| 88 | 
            +
                  pong: os.func(() => 'ping'),
         | 
| 89 89 | 
             
                },
         | 
| 90 90 | 
             
              }
         | 
| 91 91 |  | 
| @@ -120,18 +120,18 @@ it('toContractRouter', () => { | |
| 120 120 | 
             
              const osw = os.contract(contract)
         | 
| 121 121 |  | 
| 122 122 | 
             
              const router = osw.router({
         | 
| 123 | 
            -
                p1: osw.p1. | 
| 123 | 
            +
                p1: osw.p1.func(() => {
         | 
| 124 124 | 
             
                  return 'unnoq'
         | 
| 125 125 | 
             
                }),
         | 
| 126 126 |  | 
| 127 127 | 
             
                nested: osw.nested.router({
         | 
| 128 | 
            -
                  p2: osw.nested.p2. | 
| 128 | 
            +
                  p2: osw.nested.p2.func(() => {
         | 
| 129 129 | 
             
                    return 'unnoq'
         | 
| 130 130 | 
             
                  }),
         | 
| 131 131 | 
             
                }),
         | 
| 132 132 |  | 
| 133 133 | 
             
                nested2: {
         | 
| 134 | 
            -
                  p3: osw.nested2.p3. | 
| 134 | 
            +
                  p3: osw.nested2.p3.func(() => {
         | 
| 135 135 | 
             
                    return 'unnoq'
         | 
| 136 136 | 
             
                  }),
         | 
| 137 137 | 
             
                },
         |