@orpc/server 0.10.0 → 0.11.0

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.
Files changed (64) hide show
  1. package/dist/{chunk-TDFYNRZV.js → chunk-CVLK2PBB.js} +0 -1
  2. package/dist/fetch.js +1 -2
  3. package/dist/index.js +1 -2
  4. package/dist/src/adapters/fetch.d.ts +0 -1
  5. package/dist/src/builder.d.ts +0 -1
  6. package/dist/src/index.d.ts +0 -1
  7. package/dist/src/middleware.d.ts +0 -1
  8. package/dist/src/procedure-builder.d.ts +0 -1
  9. package/dist/src/procedure-caller.d.ts +0 -1
  10. package/dist/src/procedure-implementer.d.ts +0 -1
  11. package/dist/src/procedure.d.ts +0 -1
  12. package/dist/src/router-builder.d.ts +0 -1
  13. package/dist/src/router-caller.d.ts +0 -1
  14. package/dist/src/router-implementer.d.ts +0 -1
  15. package/dist/src/router.d.ts +0 -1
  16. package/dist/src/types.d.ts +0 -1
  17. package/dist/src/utils.d.ts +0 -1
  18. package/package.json +12 -16
  19. package/dist/chunk-TDFYNRZV.js.map +0 -1
  20. package/dist/fetch.js.map +0 -1
  21. package/dist/index.js.map +0 -1
  22. package/dist/src/adapters/fetch.d.ts.map +0 -1
  23. package/dist/src/builder.d.ts.map +0 -1
  24. package/dist/src/index.d.ts.map +0 -1
  25. package/dist/src/middleware.d.ts.map +0 -1
  26. package/dist/src/procedure-builder.d.ts.map +0 -1
  27. package/dist/src/procedure-caller.d.ts.map +0 -1
  28. package/dist/src/procedure-implementer.d.ts.map +0 -1
  29. package/dist/src/procedure.d.ts.map +0 -1
  30. package/dist/src/router-builder.d.ts.map +0 -1
  31. package/dist/src/router-caller.d.ts.map +0 -1
  32. package/dist/src/router-implementer.d.ts.map +0 -1
  33. package/dist/src/router.d.ts.map +0 -1
  34. package/dist/src/types.d.ts.map +0 -1
  35. package/dist/src/utils.d.ts.map +0 -1
  36. package/dist/tsconfig.tsbuildinfo +0 -1
  37. package/src/adapters/fetch.test.ts +0 -629
  38. package/src/adapters/fetch.ts +0 -290
  39. package/src/builder.test.ts +0 -371
  40. package/src/builder.ts +0 -238
  41. package/src/index.ts +0 -16
  42. package/src/middleware.test.ts +0 -260
  43. package/src/middleware.ts +0 -136
  44. package/src/procedure-builder.test.ts +0 -223
  45. package/src/procedure-builder.ts +0 -158
  46. package/src/procedure-caller.test.ts +0 -171
  47. package/src/procedure-caller.ts +0 -138
  48. package/src/procedure-implementer.test.ts +0 -220
  49. package/src/procedure-implementer.ts +0 -102
  50. package/src/procedure.test.ts +0 -317
  51. package/src/procedure.ts +0 -237
  52. package/src/router-builder.test.ts +0 -106
  53. package/src/router-builder.ts +0 -122
  54. package/src/router-caller.test.ts +0 -126
  55. package/src/router-caller.ts +0 -64
  56. package/src/router-implementer.test.ts +0 -116
  57. package/src/router-implementer.ts +0 -113
  58. package/src/router.test-d.ts +0 -48
  59. package/src/router.test.ts +0 -142
  60. package/src/router.ts +0 -91
  61. package/src/types.test.ts +0 -18
  62. package/src/types.ts +0 -13
  63. package/src/utils.test.ts +0 -16
  64. package/src/utils.ts +0 -16
package/src/procedure.ts DELETED
@@ -1,237 +0,0 @@
1
- import type { Promisable } from '@orpc/shared'
2
- import type { ProcedureCaller } from './procedure-caller'
3
- import type { Context, MergeContext, Meta } from './types'
4
- import {
5
- type ContractProcedure,
6
- DecoratedContractProcedure,
7
- type HTTPPath,
8
- isContractProcedure,
9
- type RouteOptions,
10
- type Schema,
11
- type SchemaInput,
12
- type SchemaOutput,
13
- } from '@orpc/contract'
14
- import {
15
- decorateMiddleware,
16
- type MapInputMiddleware,
17
- type Middleware,
18
- } from './middleware'
19
- import { createProcedureCaller } from './procedure-caller'
20
-
21
- export class Procedure<
22
- TContext extends Context,
23
- TExtraContext extends Context,
24
- TInputSchema extends Schema,
25
- TOutputSchema extends Schema,
26
- TFuncOutput extends SchemaOutput<TOutputSchema>,
27
- > {
28
- constructor(
29
- public zz$p: {
30
- middlewares?: Middleware<any, any, any, any>[]
31
- contract: ContractProcedure<TInputSchema, TOutputSchema>
32
- func: ProcedureFunc<
33
- TContext,
34
- TExtraContext,
35
- TInputSchema,
36
- TOutputSchema,
37
- TFuncOutput
38
- >
39
- },
40
- ) {}
41
- }
42
-
43
- export type DecoratedProcedure<
44
- TContext extends Context,
45
- TExtraContext extends Context,
46
- TInputSchema extends Schema,
47
- TOutputSchema extends Schema,
48
- TFuncOutput extends SchemaOutput<TOutputSchema>,
49
- > = Procedure<
50
- TContext,
51
- TExtraContext,
52
- TInputSchema,
53
- TOutputSchema,
54
- TFuncOutput
55
- > & {
56
- prefix: (
57
- prefix: HTTPPath,
58
- ) => DecoratedProcedure<
59
- TContext,
60
- TExtraContext,
61
- TInputSchema,
62
- TOutputSchema,
63
- TFuncOutput
64
- >
65
-
66
- route: (
67
- opts: RouteOptions,
68
- ) => DecoratedProcedure<
69
- TContext,
70
- TExtraContext,
71
- TInputSchema,
72
- TOutputSchema,
73
- TFuncOutput
74
- >
75
-
76
- use: (<
77
- UExtraContext extends
78
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
79
- | undefined = undefined,
80
- >(
81
- middleware: Middleware<
82
- MergeContext<TContext, TExtraContext>,
83
- UExtraContext,
84
- SchemaOutput<TInputSchema>,
85
- SchemaInput<TOutputSchema, TFuncOutput>
86
- >,
87
- ) => DecoratedProcedure<
88
- TContext,
89
- MergeContext<TExtraContext, UExtraContext>,
90
- TInputSchema,
91
- TOutputSchema,
92
- TFuncOutput
93
- >) & (<
94
- UExtraContext extends
95
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
96
- | undefined = undefined,
97
- UMappedInput = unknown,
98
- >(
99
- middleware: Middleware<
100
- MergeContext<TContext, TExtraContext>,
101
- UExtraContext,
102
- UMappedInput,
103
- SchemaInput<TOutputSchema, TFuncOutput>
104
- >,
105
- mapInput: MapInputMiddleware<
106
- SchemaOutput<TInputSchema, TFuncOutput>,
107
- UMappedInput
108
- >,
109
- ) => DecoratedProcedure<
110
- TContext,
111
- MergeContext<TExtraContext, UExtraContext>,
112
- TInputSchema,
113
- TOutputSchema,
114
- TFuncOutput
115
- >)
116
- } & (undefined extends TContext
117
- ? ProcedureCaller<Procedure<
118
- TContext,
119
- TExtraContext,
120
- TInputSchema,
121
- TOutputSchema,
122
- TFuncOutput
123
- >>
124
- : unknown)
125
-
126
- export interface ProcedureFunc<
127
- TContext extends Context,
128
- TExtraContext extends Context,
129
- TInputSchema extends Schema,
130
- TOutputSchema extends Schema,
131
- TOutput extends SchemaOutput<TOutputSchema>,
132
- > {
133
- (
134
- input: SchemaOutput<TInputSchema>,
135
- context: MergeContext<TContext, TExtraContext>,
136
- meta: Meta,
137
- ): Promisable<SchemaInput<TOutputSchema, TOutput>>
138
- }
139
-
140
- const DECORATED_PROCEDURE_SYMBOL = Symbol('DECORATED_PROCEDURE')
141
-
142
- export function decorateProcedure<
143
- TContext extends Context,
144
- TExtraContext extends Context,
145
- TInputSchema extends Schema,
146
- TOutputSchema extends Schema,
147
- TFuncOutput extends SchemaOutput<TOutputSchema>,
148
- >(
149
- procedure: Procedure<
150
- TContext,
151
- TExtraContext,
152
- TInputSchema,
153
- TOutputSchema,
154
- TFuncOutput
155
- >,
156
- ): DecoratedProcedure<
157
- TContext,
158
- TExtraContext,
159
- TInputSchema,
160
- TOutputSchema,
161
- TFuncOutput
162
- > {
163
- if (DECORATED_PROCEDURE_SYMBOL in procedure) {
164
- return procedure as any
165
- }
166
-
167
- return Object.assign(createProcedureCaller({
168
- procedure,
169
- context: undefined as any,
170
- }), {
171
- [DECORATED_PROCEDURE_SYMBOL]: true,
172
- zz$p: procedure.zz$p,
173
-
174
- prefix(prefix: HTTPPath) {
175
- return decorateProcedure({
176
- zz$p: {
177
- ...procedure.zz$p,
178
- contract: DecoratedContractProcedure.decorate(
179
- procedure.zz$p.contract,
180
- ).prefix(prefix),
181
- },
182
- })
183
- },
184
-
185
- route(opts: RouteOptions) {
186
- return decorateProcedure({
187
- zz$p: {
188
- ...procedure.zz$p,
189
- contract: DecoratedContractProcedure.decorate(
190
- procedure.zz$p.contract,
191
- ).route(opts),
192
- },
193
- })
194
- },
195
-
196
- use(
197
- middleware: Middleware<any, any, any, any>,
198
- mapInput?: MapInputMiddleware<any, any>,
199
- ) {
200
- const middleware_ = mapInput
201
- ? decorateMiddleware(middleware).mapInput(mapInput)
202
- : middleware
203
-
204
- return decorateProcedure({
205
- zz$p: {
206
- ...procedure.zz$p,
207
- middlewares: [middleware_, ...(procedure.zz$p.middlewares ?? [])],
208
- },
209
- })
210
- },
211
- }) as any
212
- }
213
-
214
- export type WELL_DEFINED_PROCEDURE = Procedure<
215
- Context,
216
- Context,
217
- Schema,
218
- Schema,
219
- unknown
220
- >
221
-
222
- export function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {
223
- if (item instanceof Procedure)
224
- return true
225
-
226
- return (
227
- (typeof item === 'object' || typeof item === 'function')
228
- && item !== null
229
- && 'zz$p' in item
230
- && typeof item.zz$p === 'object'
231
- && item.zz$p !== null
232
- && 'contract' in item.zz$p
233
- && isContractProcedure(item.zz$p.contract)
234
- && 'func' in item.zz$p
235
- && typeof item.zz$p.func === 'function'
236
- )
237
- }
@@ -1,106 +0,0 @@
1
- import { ContractProcedure } from '@orpc/contract'
2
- import { z } from 'zod'
3
- import { decorateProcedure, isProcedure, os, Procedure } from '.'
4
- import { RouterBuilder } from './router-builder'
5
-
6
- const builder = new RouterBuilder<undefined, undefined>({})
7
- const ping = os
8
- .route({ method: 'GET', path: '/ping', tags: ['ping'] })
9
- .func(() => 'ping')
10
- const pong = os
11
- .output(z.object({ id: z.string() }))
12
- .func(() => ({ id: '123' }))
13
-
14
- describe('prefix', () => {
15
- it('chainable prefix', () => {
16
- expect(builder.prefix('/1').prefix('/2').prefix('/3').zz$rb.prefix).toEqual(
17
- '/1/2/3',
18
- )
19
- })
20
-
21
- it('router', () => {
22
- const router = builder
23
- .prefix('/api')
24
- .prefix('/users')
25
- .router({ ping, pong })
26
-
27
- expect(router.ping.zz$p.contract.zz$cp.path).toEqual('/api/users/ping')
28
- expect(router.pong.zz$p.contract.zz$cp.path).toEqual(undefined)
29
- })
30
- })
31
-
32
- describe('tags', () => {
33
- it('chainable tags', () => {
34
- expect(builder.tags('1', '2').tags('3').tags('4').zz$rb.tags).toEqual([
35
- '1',
36
- '2',
37
- '3',
38
- '4',
39
- ])
40
- })
41
-
42
- it('router', () => {
43
- const router = builder
44
- .tags('api')
45
- .tags('users')
46
- .router({ ping, pong })
47
-
48
- expect(router.ping.zz$p.contract.zz$cp.tags).toEqual([
49
- 'ping',
50
- 'api',
51
- 'users',
52
- ])
53
- expect(router.pong.zz$p.contract.zz$cp.tags).toEqual(['api', 'users'])
54
- })
55
- })
56
-
57
- describe('middleware', () => {
58
- const mid1 = vi.fn()
59
- const mid2 = vi.fn()
60
- const mid3 = vi.fn()
61
-
62
- it('chainable middleware', () => {
63
- expect(builder.use(mid1).use(mid2).use(mid3).zz$rb.middlewares).toEqual([
64
- mid1,
65
- mid2,
66
- mid3,
67
- ])
68
- })
69
-
70
- it('router', () => {
71
- const router = builder.use(mid1).use(mid2).router({ ping, pong })
72
-
73
- expect(router.ping.zz$p.middlewares).toEqual([mid1, mid2])
74
- expect(router.pong.zz$p.middlewares).toEqual([mid1, mid2])
75
- })
76
-
77
- it('decorate items', () => {
78
- const ping = new Procedure({
79
- contract: new ContractProcedure({
80
- InputSchema: undefined,
81
- OutputSchema: undefined,
82
- }),
83
- func: () => {},
84
- })
85
-
86
- const decorated = decorateProcedure({
87
- zz$p: {
88
- contract: new ContractProcedure({
89
- InputSchema: undefined,
90
- OutputSchema: undefined,
91
- }),
92
- func: () => {},
93
- },
94
- })
95
-
96
- const router = builder.router({ ping, nested: { ping } })
97
-
98
- expectTypeOf(router).toEqualTypeOf<{
99
- ping: typeof decorated
100
- nested: { ping: typeof decorated }
101
- }>()
102
-
103
- expect(router.ping).satisfies(isProcedure)
104
- expect(router.nested.ping).satisfies(isProcedure)
105
- })
106
- })
@@ -1,122 +0,0 @@
1
- import type { HandledRouter, Router } from './router'
2
- import type { Context, MergeContext } from './types'
3
- import { DecoratedContractProcedure, type HTTPPath } from '@orpc/contract'
4
- import {
5
- decorateMiddleware,
6
- type MapInputMiddleware,
7
- type Middleware,
8
- } from './middleware'
9
- import { decorateProcedure, isProcedure } from './procedure'
10
-
11
- export class RouterBuilder<
12
- TContext extends Context,
13
- TExtraContext extends Context,
14
- > {
15
- constructor(
16
- public zz$rb: {
17
- prefix?: HTTPPath
18
- tags?: string[]
19
- middlewares?: Middleware<any, any, any, any>[]
20
- },
21
- ) {}
22
-
23
- prefix(prefix: HTTPPath): RouterBuilder<TContext, TExtraContext> {
24
- return new RouterBuilder({
25
- ...this.zz$rb,
26
- prefix: `${this.zz$rb.prefix ?? ''}${prefix}`,
27
- })
28
- }
29
-
30
- tags(...tags: string[]): RouterBuilder<TContext, TExtraContext> {
31
- if (!tags.length)
32
- return this
33
-
34
- return new RouterBuilder({
35
- ...this.zz$rb,
36
- tags: [...(this.zz$rb.tags ?? []), ...tags],
37
- })
38
- }
39
-
40
- use<
41
- UExtraContext extends
42
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
43
- | undefined = undefined,
44
- >(
45
- middleware: Middleware<
46
- MergeContext<TContext, TExtraContext>,
47
- UExtraContext,
48
- unknown,
49
- unknown
50
- >,
51
- ): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>
52
-
53
- use<
54
- UExtraContext extends
55
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
56
- | undefined = undefined,
57
- UMappedInput = unknown,
58
- >(
59
- middleware: Middleware<
60
- MergeContext<TContext, TExtraContext>,
61
- UExtraContext,
62
- UMappedInput,
63
- unknown
64
- >,
65
- mapInput: MapInputMiddleware<unknown, UMappedInput>,
66
- ): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>
67
-
68
- use(
69
- middleware: Middleware<any, any, any, any>,
70
- mapInput?: MapInputMiddleware<any, any>,
71
- ): RouterBuilder<any, any> {
72
- const middleware_ = mapInput
73
- ? decorateMiddleware(middleware).mapInput(mapInput)
74
- : middleware
75
-
76
- return new RouterBuilder({
77
- ...this.zz$rb,
78
- middlewares: [...(this.zz$rb.middlewares || []), middleware_],
79
- })
80
- }
81
-
82
- router<URouter extends Router<TContext>>(
83
- router: URouter,
84
- ): HandledRouter<URouter> {
85
- const handled: Router<TContext> = {}
86
-
87
- for (const key in router) {
88
- const item = router[key]
89
-
90
- if (isProcedure(item)) {
91
- const builderMiddlewares = this.zz$rb.middlewares ?? []
92
- const itemMiddlewares = item.zz$p.middlewares ?? []
93
-
94
- const middlewares = [
95
- ...builderMiddlewares,
96
- ...itemMiddlewares.filter(
97
- item => !builderMiddlewares.includes(item),
98
- ),
99
- ]
100
-
101
- const contract = DecoratedContractProcedure.decorate(
102
- item.zz$p.contract,
103
- ).addTags(...(this.zz$rb.tags ?? []))
104
-
105
- handled[key] = decorateProcedure({
106
- zz$p: {
107
- ...item.zz$p,
108
- contract: this.zz$rb.prefix
109
- ? contract.prefix(this.zz$rb.prefix)
110
- : contract,
111
- middlewares,
112
- },
113
- })
114
- }
115
- else {
116
- handled[key] = this.router(item as any)
117
- }
118
- }
119
-
120
- return handled as HandledRouter<URouter>
121
- }
122
- }
@@ -1,126 +0,0 @@
1
- import { z } from 'zod'
2
- import { createRouterCaller, os } from '.'
3
-
4
- describe('createRouterCaller', () => {
5
- const internal = false
6
- const context = { auth: true }
7
-
8
- const osw = os.context<{ auth?: boolean }>()
9
-
10
- const ping = osw
11
- .input(z.object({ value: z.string().transform(v => Number(v)) }))
12
- .output(z.object({ value: z.number().transform(v => v.toString()) }))
13
- .func((input, context, meta) => {
14
- expect(context).toEqual(context)
15
-
16
- return input
17
- })
18
-
19
- const pong = osw.func((_, context, meta) => {
20
- expect(context).toEqual(context)
21
-
22
- return { value: true }
23
- })
24
-
25
- const router = osw.router({
26
- ping,
27
- pong,
28
- nested: {
29
- ping,
30
- pong,
31
- },
32
- })
33
-
34
- it('infer context', () => {
35
- createRouterCaller({
36
- router,
37
- // @ts-expect-error invalid context
38
- context: { auth: 123 },
39
- })
40
-
41
- createRouterCaller({
42
- router,
43
- context,
44
- })
45
- })
46
-
47
- it('with validate', () => {
48
- const caller = createRouterCaller({
49
- router,
50
- context,
51
- })
52
-
53
- expectTypeOf(caller.ping).toMatchTypeOf<
54
- (input: { value: string }) => Promise<{
55
- value: string
56
- }>
57
- >()
58
-
59
- expectTypeOf(caller.pong).toMatchTypeOf<
60
- (input: unknown) => Promise<{
61
- value: boolean
62
- }>
63
- >()
64
-
65
- expectTypeOf(caller.nested.ping).toMatchTypeOf<
66
- (input: { value: string }) => Promise<{
67
- value: string
68
- }>
69
- >()
70
-
71
- expectTypeOf(caller.nested.pong).toMatchTypeOf<
72
- (input: unknown) => Promise<{
73
- value: boolean
74
- }>
75
- >()
76
-
77
- expect(caller.ping({ value: '123' })).resolves.toEqual({ value: '123' })
78
- expect(caller.pong({ value: '123' })).resolves.toEqual({ value: true })
79
-
80
- expect(caller.nested.ping({ value: '123' })).resolves.toEqual({
81
- value: '123',
82
- })
83
- expect(caller.nested.pong({ value: '123' })).resolves.toEqual({
84
- value: true,
85
- })
86
-
87
- // @ts-expect-error - invalid input
88
- expect(caller.ping({ value: new Date('2023-01-01') })).rejects.toThrowError(
89
- 'Validation input failed',
90
- )
91
-
92
- // @ts-expect-error - invalid input
93
- expect(caller.nested.ping({ value: true })).rejects.toThrowError(
94
- 'Validation input failed',
95
- )
96
- })
97
-
98
- it('path', () => {
99
- const ping = osw.func((_, __, { path }) => {
100
- return path
101
- })
102
-
103
- const router = osw.router({
104
- ping,
105
- nested: {
106
- ping,
107
- child: {
108
- ping,
109
- },
110
- },
111
- })
112
-
113
- const caller = createRouterCaller({
114
- router,
115
- context,
116
- })
117
-
118
- expect(caller.ping('')).resolves.toEqual(['ping'])
119
- expect(caller.nested.ping('')).resolves.toEqual(['nested', 'ping'])
120
- expect(caller.nested.child.ping('')).resolves.toEqual([
121
- 'nested',
122
- 'child',
123
- 'ping',
124
- ])
125
- })
126
- })
@@ -1,64 +0,0 @@
1
- import type { Value } from '@orpc/shared'
2
- import type { Router } from './router'
3
- import { isProcedure, type Procedure } from './procedure'
4
- import { createProcedureCaller, type ProcedureCaller } from './procedure-caller'
5
-
6
- export interface CreateRouterCallerOptions<
7
- TRouter extends Router<any>,
8
- > {
9
- router: TRouter
10
-
11
- /**
12
- * The context used when calling the procedure.
13
- */
14
- context: Value<
15
- TRouter extends Router<infer UContext> ? UContext : never
16
- >
17
-
18
- /**
19
- * This is helpful for logging and analytics.
20
- *
21
- * @internal
22
- */
23
- basePath?: string[]
24
- }
25
-
26
- export type RouterCaller<
27
- TRouter extends Router<any>,
28
- > = {
29
- [K in keyof TRouter]: TRouter[K] extends Procedure<any, any, any, any, any>
30
- ? ProcedureCaller<TRouter[K]>
31
- : TRouter[K] extends Router<any>
32
- ? RouterCaller<TRouter[K]>
33
- : never
34
- }
35
-
36
- export function createRouterCaller<
37
- TRouter extends Router<any>,
38
- >(
39
- options: CreateRouterCallerOptions<TRouter>,
40
- ): RouterCaller<TRouter> {
41
- const caller: Record<string, unknown> = {}
42
-
43
- for (const key in options.router) {
44
- const path = [...(options.basePath ?? []), key]
45
- const item = options.router[key]
46
-
47
- if (isProcedure(item)) {
48
- caller[key] = createProcedureCaller({
49
- procedure: item,
50
- context: options.context as any,
51
- path,
52
- })
53
- }
54
- else {
55
- caller[key] = createRouterCaller({
56
- router: item as any,
57
- context: options.context,
58
- basePath: path,
59
- })
60
- }
61
- }
62
-
63
- return caller as RouterCaller<TRouter>
64
- }