@orpc/server 0.0.0-next.b15d206 → 0.0.0-next.b1b9914

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 (125) hide show
  1. package/README.md +131 -0
  2. package/dist/adapters/aws-lambda/index.d.mts +46 -0
  3. package/dist/adapters/aws-lambda/index.d.ts +46 -0
  4. package/dist/adapters/aws-lambda/index.mjs +42 -0
  5. package/dist/adapters/bun-ws/index.d.mts +36 -0
  6. package/dist/adapters/bun-ws/index.d.ts +36 -0
  7. package/dist/adapters/bun-ws/index.mjs +47 -0
  8. package/dist/adapters/crossws/index.d.mts +33 -0
  9. package/dist/adapters/crossws/index.d.ts +33 -0
  10. package/dist/adapters/crossws/index.mjs +45 -0
  11. package/dist/adapters/fastify/index.d.mts +53 -0
  12. package/dist/adapters/fastify/index.d.ts +53 -0
  13. package/dist/adapters/fastify/index.mjs +54 -0
  14. package/dist/adapters/fetch/index.d.mts +124 -0
  15. package/dist/adapters/fetch/index.d.ts +124 -0
  16. package/dist/adapters/fetch/index.mjs +180 -0
  17. package/dist/adapters/message-port/index.d.mts +57 -0
  18. package/dist/adapters/message-port/index.d.ts +57 -0
  19. package/dist/adapters/message-port/index.mjs +55 -0
  20. package/dist/adapters/node/index.d.mts +99 -0
  21. package/dist/adapters/node/index.d.ts +99 -0
  22. package/dist/adapters/node/index.mjs +152 -0
  23. package/dist/adapters/standard/index.d.mts +21 -0
  24. package/dist/adapters/standard/index.d.ts +21 -0
  25. package/dist/adapters/standard/index.mjs +8 -0
  26. package/dist/adapters/standard-peer/index.d.mts +18 -0
  27. package/dist/adapters/standard-peer/index.d.ts +18 -0
  28. package/dist/adapters/standard-peer/index.mjs +7 -0
  29. package/dist/adapters/websocket/index.d.mts +56 -0
  30. package/dist/adapters/websocket/index.d.ts +56 -0
  31. package/dist/adapters/websocket/index.mjs +67 -0
  32. package/dist/adapters/ws/index.d.mts +31 -0
  33. package/dist/adapters/ws/index.d.ts +31 -0
  34. package/dist/adapters/ws/index.mjs +37 -0
  35. package/dist/helpers/index.d.mts +149 -0
  36. package/dist/helpers/index.d.ts +149 -0
  37. package/dist/helpers/index.mjs +198 -0
  38. package/dist/hibernation/index.d.mts +44 -0
  39. package/dist/hibernation/index.d.ts +44 -0
  40. package/dist/hibernation/index.mjs +65 -0
  41. package/dist/index.d.mts +803 -0
  42. package/dist/index.d.ts +803 -0
  43. package/dist/index.mjs +492 -0
  44. package/dist/plugins/index.d.mts +172 -0
  45. package/dist/plugins/index.d.ts +172 -0
  46. package/dist/plugins/index.mjs +287 -0
  47. package/dist/shared/server.B4BGqy3Y.d.mts +193 -0
  48. package/dist/shared/server.B4BGqy3Y.d.ts +193 -0
  49. package/dist/shared/server.Bxx6tqNe.mjs +219 -0
  50. package/dist/shared/server.COL12UTb.d.ts +32 -0
  51. package/dist/shared/server.CVKCo60T.d.mts +12 -0
  52. package/dist/shared/server.Cb6yD7DZ.d.ts +42 -0
  53. package/dist/shared/server.Ck-gOLzq.d.mts +32 -0
  54. package/dist/shared/server.DBCUJijK.d.mts +74 -0
  55. package/dist/shared/server.DNtJ-p60.d.ts +12 -0
  56. package/dist/shared/server.DPIFWpxG.d.ts +74 -0
  57. package/dist/shared/server.DZ5BIITo.mjs +9 -0
  58. package/dist/shared/server.Ds4HPpvH.mjs +409 -0
  59. package/dist/shared/server.DzV1hr3z.d.mts +42 -0
  60. package/dist/shared/server.TEVCLCFC.mjs +39 -0
  61. package/dist/shared/server.UVMTOWrk.mjs +26 -0
  62. package/package.json +106 -26
  63. package/dist/chunk-TDFYNRZV.js +0 -190
  64. package/dist/chunk-TDFYNRZV.js.map +0 -1
  65. package/dist/fetch.js +0 -681
  66. package/dist/fetch.js.map +0 -1
  67. package/dist/index.js +0 -394
  68. package/dist/index.js.map +0 -1
  69. package/dist/src/adapters/fetch.d.ts +0 -42
  70. package/dist/src/adapters/fetch.d.ts.map +0 -1
  71. package/dist/src/builder.d.ts +0 -49
  72. package/dist/src/builder.d.ts.map +0 -1
  73. package/dist/src/index.d.ts +0 -15
  74. package/dist/src/index.d.ts.map +0 -1
  75. package/dist/src/middleware.d.ts +0 -26
  76. package/dist/src/middleware.d.ts.map +0 -1
  77. package/dist/src/procedure-builder.d.ts +0 -31
  78. package/dist/src/procedure-builder.d.ts.map +0 -1
  79. package/dist/src/procedure-caller.d.ts +0 -19
  80. package/dist/src/procedure-caller.d.ts.map +0 -1
  81. package/dist/src/procedure-implementer.d.ts +0 -18
  82. package/dist/src/procedure-implementer.d.ts.map +0 -1
  83. package/dist/src/procedure.d.ts +0 -29
  84. package/dist/src/procedure.d.ts.map +0 -1
  85. package/dist/src/router-builder.d.ts +0 -22
  86. package/dist/src/router-builder.d.ts.map +0 -1
  87. package/dist/src/router-caller.d.ts +0 -22
  88. package/dist/src/router-caller.d.ts.map +0 -1
  89. package/dist/src/router-implementer.d.ts +0 -20
  90. package/dist/src/router-implementer.d.ts.map +0 -1
  91. package/dist/src/router.d.ts +0 -20
  92. package/dist/src/router.d.ts.map +0 -1
  93. package/dist/src/types.d.ts +0 -8
  94. package/dist/src/types.d.ts.map +0 -1
  95. package/dist/src/utils.d.ts +0 -3
  96. package/dist/src/utils.d.ts.map +0 -1
  97. package/dist/tsconfig.tsbuildinfo +0 -1
  98. package/src/adapters/fetch.test.ts +0 -629
  99. package/src/adapters/fetch.ts +0 -290
  100. package/src/builder.test.ts +0 -371
  101. package/src/builder.ts +0 -238
  102. package/src/index.ts +0 -16
  103. package/src/middleware.test.ts +0 -260
  104. package/src/middleware.ts +0 -136
  105. package/src/procedure-builder.test.ts +0 -223
  106. package/src/procedure-builder.ts +0 -158
  107. package/src/procedure-caller.test.ts +0 -171
  108. package/src/procedure-caller.ts +0 -138
  109. package/src/procedure-implementer.test.ts +0 -220
  110. package/src/procedure-implementer.ts +0 -102
  111. package/src/procedure.test.ts +0 -317
  112. package/src/procedure.ts +0 -237
  113. package/src/router-builder.test.ts +0 -106
  114. package/src/router-builder.ts +0 -122
  115. package/src/router-caller.test.ts +0 -126
  116. package/src/router-caller.ts +0 -64
  117. package/src/router-implementer.test.ts +0 -116
  118. package/src/router-implementer.ts +0 -113
  119. package/src/router.test-d.ts +0 -48
  120. package/src/router.test.ts +0 -142
  121. package/src/router.ts +0 -91
  122. package/src/types.test.ts +0 -18
  123. package/src/types.ts +0 -13
  124. package/src/utils.test.ts +0 -16
  125. package/src/utils.ts +0 -16
@@ -1,220 +0,0 @@
1
- import type { DecoratedProcedure, Meta, MiddlewareMeta } from '.'
2
- import { DecoratedContractProcedure } from '@orpc/contract'
3
- import { z } from 'zod'
4
- import { isProcedure, os } from '.'
5
- import { ProcedureImplementer } from './procedure-implementer'
6
-
7
- const p1 = new DecoratedContractProcedure({
8
- InputSchema: undefined,
9
- OutputSchema: undefined,
10
- method: undefined,
11
- path: undefined,
12
- })
13
- const implementer1 = new ProcedureImplementer<
14
- { auth: boolean },
15
- undefined,
16
- undefined,
17
- undefined
18
- >({ contract: p1 })
19
-
20
- const schema1 = z.object({ id: z.string() })
21
- const schema2 = z.object({ name: z.string() })
22
-
23
- const p2 = new DecoratedContractProcedure({
24
- InputSchema: schema1,
25
- OutputSchema: schema2,
26
- method: 'GET',
27
- path: '/test',
28
- })
29
-
30
- const implementer2 = new ProcedureImplementer<
31
- { auth: boolean },
32
- undefined,
33
- typeof schema1,
34
- typeof schema2
35
- >({ contract: p2 })
36
-
37
- describe('use middleware', () => {
38
- it('infer types', () => {
39
- const i = implementer1
40
- .use((input, context, meta) => {
41
- expectTypeOf(input).toEqualTypeOf<unknown>()
42
- expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
43
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
44
-
45
- return meta.next({
46
- context: {
47
- userId: '1',
48
- },
49
- })
50
- })
51
- .use((input, context, meta) => {
52
- expectTypeOf(input).toEqualTypeOf<unknown>()
53
- expectTypeOf(context).toEqualTypeOf<
54
- { userId: string } & { auth: boolean }
55
- >()
56
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<unknown>>()
57
-
58
- return meta.next({})
59
- })
60
-
61
- expectTypeOf(i).toEqualTypeOf<
62
- ProcedureImplementer<
63
- { auth: boolean },
64
- { userId: string },
65
- undefined,
66
- undefined
67
- >
68
- >()
69
- })
70
-
71
- it('map middleware input', () => {
72
- // @ts-expect-error mismatch input
73
- implementer2.use((input: { postId: string }) => {
74
- return { context: { a: 'a' } }
75
- })
76
-
77
- implementer2.use(
78
- (input: { postId: string }, _, meta) => {
79
- return meta.next({ context: { a: 'a' } })
80
- },
81
- // @ts-expect-error mismatch input
82
- input => ({ postId: 12455 }),
83
- )
84
-
85
- implementer2.use(
86
- (input: { postId: string }, context, meta) => meta.next({}),
87
- input => ({ postId: '12455' }),
88
- )
89
-
90
- const i = implementer2.use(
91
- (input: { id: number }, _, meta) => {
92
- return meta.next({
93
- context: {
94
- userIdd: '1',
95
- },
96
- })
97
- },
98
- input => ({ id: Number.parseInt(input.id) }),
99
- )
100
-
101
- expectTypeOf(i).toEqualTypeOf<
102
- ProcedureImplementer<
103
- { auth: boolean },
104
- { userIdd: string },
105
- typeof schema1,
106
- typeof schema2
107
- >
108
- >()
109
- })
110
- })
111
-
112
- describe('output schema', () => {
113
- it('auto infer output schema if output schema is not specified', async () => {
114
- const sr = os.func(() => ({ a: 1 }))
115
-
116
- const result = await sr.zz$p.func({}, undefined, {
117
- method: 'GET',
118
- path: '/',
119
- } as any)
120
-
121
- expectTypeOf(result).toEqualTypeOf<{ a: number }>()
122
- })
123
-
124
- it('not infer output schema if output schema is specified', async () => {
125
- const srb1 = new ProcedureImplementer({
126
- contract: new DecoratedContractProcedure({
127
- OutputSchema: z.unknown(),
128
- InputSchema: undefined,
129
- }),
130
- })
131
-
132
- const sr = srb1.func(() => ({ b: 1 }))
133
-
134
- const result = await sr.zz$p.func({}, {}, {
135
- method: 'GET',
136
- path: '/',
137
- } as any)
138
-
139
- expectTypeOf(result).toEqualTypeOf<unknown>()
140
- })
141
- })
142
-
143
- describe('handler', () => {
144
- it('infer types', () => {
145
- const handler = implementer1.func((input, context, meta) => {
146
- expectTypeOf(input).toEqualTypeOf<unknown>()
147
- expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
148
- expectTypeOf(meta).toEqualTypeOf<Meta>()
149
-
150
- return {
151
- name: 'unnoq',
152
- }
153
- })
154
-
155
- expectTypeOf(handler).toEqualTypeOf<
156
- DecoratedProcedure<
157
- { auth: boolean },
158
- undefined,
159
- undefined,
160
- undefined,
161
- { name: string }
162
- >
163
- >()
164
- expect(isProcedure(handler)).toBe(true)
165
-
166
- implementer2.func((input, context, meta) => {
167
- expectTypeOf(input).toEqualTypeOf<{ id: string }>()
168
- expectTypeOf(context).toEqualTypeOf<{ auth: boolean }>()
169
- expectTypeOf(meta).toEqualTypeOf<Meta>()
170
-
171
- return {
172
- name: 'unnoq',
173
- }
174
- })
175
-
176
- // @ts-expect-error mismatch output
177
- implementer2.func(() => {})
178
- })
179
-
180
- it('combine middlewares', () => {
181
- const mid1 = os.middleware((input, context, meta) => {
182
- return meta.next({
183
- context: {
184
- userId: '1',
185
- },
186
- })
187
- })
188
-
189
- const mid2 = os.middleware((input, context, meta) => {
190
- return meta.next({ })
191
- })
192
-
193
- const handler = implementer2
194
- .use(mid1)
195
- .use(mid2)
196
- .func((input, context, meta) => {
197
- expectTypeOf(input).toEqualTypeOf<{ id: string }>()
198
- expectTypeOf(context).toEqualTypeOf<
199
- { auth: boolean } & { userId: string }
200
- >()
201
- expectTypeOf(meta).toEqualTypeOf<Meta>()
202
-
203
- return {
204
- name: 'unnoq',
205
- }
206
- })
207
-
208
- expectTypeOf(handler).toEqualTypeOf<
209
- DecoratedProcedure<
210
- { auth: boolean },
211
- { userId: string },
212
- typeof schema1,
213
- typeof schema2,
214
- { name: string }
215
- >
216
- >()
217
-
218
- expect(handler.zz$p.middlewares).toEqual([mid1, mid2])
219
- })
220
- })
@@ -1,102 +0,0 @@
1
- import type { ContractProcedure, Schema, SchemaInput, SchemaOutput } from '@orpc/contract'
2
- import type { Context, MergeContext } from './types'
3
- import {
4
- decorateMiddleware,
5
- type MapInputMiddleware,
6
- type Middleware,
7
- } from './middleware'
8
- import {
9
- type DecoratedProcedure,
10
- decorateProcedure,
11
- type ProcedureFunc,
12
- } from './procedure'
13
-
14
- export class ProcedureImplementer<
15
- TContext extends Context,
16
- TExtraContext extends Context,
17
- TInputSchema extends Schema,
18
- TOutputSchema extends Schema,
19
- > {
20
- constructor(
21
- public zz$pi: {
22
- contract: ContractProcedure<TInputSchema, TOutputSchema>
23
- middlewares?: Middleware<any, any, any, any>[]
24
- },
25
- ) {}
26
-
27
- use<
28
- UExtraContext extends
29
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
30
- | undefined = undefined,
31
- >(
32
- middleware: Middleware<
33
- MergeContext<TContext, TExtraContext>,
34
- UExtraContext,
35
- SchemaOutput<TInputSchema>,
36
- SchemaInput<TOutputSchema>
37
- >,
38
- ): ProcedureImplementer<
39
- TContext,
40
- MergeContext<TExtraContext, UExtraContext>,
41
- TInputSchema,
42
- TOutputSchema
43
- >
44
-
45
- use<
46
- UExtraContext extends
47
- | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>
48
- | undefined = undefined,
49
- UMappedInput = unknown,
50
- >(
51
- middleware: Middleware<
52
- MergeContext<TContext, TExtraContext>,
53
- UExtraContext,
54
- UMappedInput,
55
- SchemaInput<TOutputSchema>
56
- >,
57
- mapInput: MapInputMiddleware<SchemaOutput<TInputSchema>, UMappedInput>,
58
- ): ProcedureImplementer<
59
- TContext,
60
- MergeContext<TExtraContext, UExtraContext>,
61
- TInputSchema,
62
- TOutputSchema
63
- >
64
-
65
- use(
66
- middleware: Middleware<any, any, any, any>,
67
- mapInput?: MapInputMiddleware<any, any>,
68
- ): ProcedureImplementer<any, any, any, any> {
69
- const middleware_ = mapInput
70
- ? decorateMiddleware(middleware).mapInput(mapInput)
71
- : middleware
72
-
73
- return new ProcedureImplementer({
74
- ...this.zz$pi,
75
- middlewares: [...(this.zz$pi.middlewares ?? []), middleware_],
76
- })
77
- }
78
-
79
- func<UFuncOutput extends SchemaOutput<TOutputSchema>>(
80
- func: ProcedureFunc<
81
- TContext,
82
- TExtraContext,
83
- TInputSchema,
84
- TOutputSchema,
85
- UFuncOutput
86
- >,
87
- ): DecoratedProcedure<
88
- TContext,
89
- TExtraContext,
90
- TInputSchema,
91
- TOutputSchema,
92
- UFuncOutput
93
- > {
94
- return decorateProcedure({
95
- zz$p: {
96
- middlewares: this.zz$pi.middlewares,
97
- contract: this.zz$pi.contract,
98
- func,
99
- },
100
- })
101
- }
102
- }
@@ -1,317 +0,0 @@
1
- import type { MiddlewareMeta } from '.'
2
- import { ContractProcedure, DecoratedContractProcedure } from '@orpc/contract'
3
- import { z } from 'zod'
4
- import { os } from '.'
5
- import {
6
- type DecoratedProcedure,
7
- decorateProcedure,
8
- isProcedure,
9
- Procedure,
10
- } from './procedure'
11
-
12
- it('isProcedure', () => {
13
- expect(
14
- isProcedure(
15
- decorateProcedure(
16
- new Procedure({
17
- contract: new ContractProcedure({
18
- InputSchema: undefined,
19
- OutputSchema: undefined,
20
- }),
21
- func: () => {},
22
- }),
23
- ),
24
- ),
25
- ).toBe(true)
26
- expect({
27
- zz$p: {
28
- contract: new DecoratedContractProcedure({
29
- InputSchema: undefined,
30
- OutputSchema: undefined,
31
- }),
32
- func: () => {},
33
- },
34
- }).toSatisfy(isProcedure)
35
-
36
- expect({
37
- zz$p: {
38
- contract: new DecoratedContractProcedure({
39
- InputSchema: undefined,
40
- OutputSchema: undefined,
41
- }),
42
- },
43
- }).not.toSatisfy(isProcedure)
44
-
45
- expect({
46
- zz$p: {
47
- handler: () => {},
48
- },
49
- }).not.toSatisfy(isProcedure)
50
-
51
- expect({}).not.toSatisfy(isProcedure)
52
- expect(12233).not.toSatisfy(isProcedure)
53
- expect('12233').not.toSatisfy(isProcedure)
54
- expect(undefined).not.toSatisfy(isProcedure)
55
- expect(null).not.toSatisfy(isProcedure)
56
- })
57
-
58
- describe('route method', () => {
59
- it('sets route options correctly', () => {
60
- const p = os.context<{ auth: boolean }>().func(() => {
61
- return 'test'
62
- })
63
-
64
- const p2 = p.route({ path: '/test', method: 'GET' })
65
-
66
- expect(p2.zz$p.contract.zz$cp.path).toBe('/test')
67
- expect(p2.zz$p.contract.zz$cp.method).toBe('GET')
68
- })
69
-
70
- it('preserves existing context and handler', () => {
71
- const handler = () => 'test'
72
- const p = os.context<{ auth: boolean }>().func(handler)
73
-
74
- const p2 = p.route({ path: '/test' })
75
-
76
- expect(p2.zz$p.func).toBe(handler)
77
- // Context type is preserved through the route method
78
- expectTypeOf(p2).toEqualTypeOf<
79
- DecoratedProcedure<
80
- { auth: boolean },
81
- undefined,
82
- undefined,
83
- undefined,
84
- string
85
- >
86
- >()
87
- })
88
-
89
- it('works with prefix method', () => {
90
- const p = os
91
- .context<{ auth: boolean }>()
92
- .route({ path: '/api', method: 'POST' })
93
- .func(() => 'test')
94
-
95
- const p2 = p.prefix('/v1')
96
-
97
- expect(p2.zz$p.contract.zz$cp.path).toBe('/v1/api')
98
- expect(p2.zz$p.contract.zz$cp.method).toBe('POST')
99
- })
100
-
101
- it('works with middleware', () => {
102
- const mid = os.middleware((_, __, meta) => meta.next({ context: { userId: '1' } }))
103
-
104
- const p = os
105
- .context<{ auth: boolean }>()
106
- .route({ path: '/test' })
107
- .use(mid)
108
- .func((input, context) => {
109
- expectTypeOf(context).toEqualTypeOf<
110
- { auth: boolean } & { userId: string }
111
- >()
112
- return 'test'
113
- })
114
-
115
- expect(p.zz$p.contract.zz$cp.path).toBe('/test')
116
- expect(p.zz$p.middlewares).toEqual([mid])
117
- })
118
-
119
- it('overrides existing route options', () => {
120
- const p = os
121
- .context<{ auth: boolean }>()
122
- .route({ path: '/test1', method: 'GET' })
123
- .func(() => 'test')
124
-
125
- const p2 = p.route({ path: '/test2', method: 'POST' })
126
-
127
- expect(p2.zz$p.contract.zz$cp.path).toBe('/test2')
128
- expect(p2.zz$p.contract.zz$cp.method).toBe('POST')
129
- })
130
-
131
- it('preserves input/output schemas', () => {
132
- const inputSchema = z.object({ id: z.number() })
133
- const outputSchema = z.string()
134
- const p = os
135
- .context<{ auth: boolean }>()
136
- .input(inputSchema)
137
- .output(outputSchema)
138
- .route({ path: '/test' })
139
- .func((input) => {
140
- expectTypeOf(input).toEqualTypeOf<{ id: number }>()
141
- return 'test'
142
- })
143
-
144
- const p2 = p.route({ path: '/test2' })
145
-
146
- // Type checking that schemas are preserved
147
- expectTypeOf(p2).toEqualTypeOf<
148
- DecoratedProcedure<
149
- { auth: boolean },
150
- undefined,
151
- typeof inputSchema,
152
- typeof outputSchema,
153
- string
154
- >
155
- >()
156
- })
157
- })
158
-
159
- it('prefix method', () => {
160
- const p = os.context<{ auth: boolean }>().func(() => {
161
- return 'unnoq'
162
- })
163
-
164
- const p2 = p.prefix('/test')
165
-
166
- expect(p2.zz$p.contract.zz$cp.path).toBe(undefined)
167
-
168
- const p3 = os
169
- .context<{ auth: boolean }>()
170
- .route({ path: '/test1' })
171
- .func(() => {
172
- return 'unnoq'
173
- })
174
-
175
- const p4 = p3.prefix('/test')
176
- expect(p4.zz$p.contract.zz$cp.path).toBe('/test/test1')
177
- })
178
-
179
- describe('use middleware', () => {
180
- it('infer types', () => {
181
- const p1 = os
182
- .context<{ auth: boolean }>()
183
- .use((_, __, meta) => {
184
- return meta.next({ context: { postId: 'string' } })
185
- })
186
- .func(() => {
187
- return 'unnoq'
188
- })
189
-
190
- const p2 = p1
191
- .use((input, context, meta) => {
192
- expectTypeOf(input).toEqualTypeOf<unknown>()
193
- expectTypeOf(context).toEqualTypeOf<
194
- { auth: boolean } & { postId: string }
195
- >()
196
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<string>>()
197
-
198
- return meta.next({
199
- context: {
200
- userId: '1',
201
- },
202
- })
203
- })
204
- .use((input, context, meta) => {
205
- expectTypeOf(input).toEqualTypeOf<unknown>()
206
- expectTypeOf(context).toEqualTypeOf<
207
- { userId: string } & { postId: string } & { auth: boolean }
208
- >()
209
- expectTypeOf(meta).toEqualTypeOf<MiddlewareMeta<string>>()
210
-
211
- return meta.next({})
212
- })
213
-
214
- expectTypeOf(p2).toEqualTypeOf<
215
- DecoratedProcedure<
216
- { auth: boolean },
217
- { postId: string } & { userId: string },
218
- undefined,
219
- undefined,
220
- string
221
- >
222
- >()
223
- })
224
-
225
- it('can map input', () => {
226
- const mid = os.middleware((input: { id: number }, __, meta) => {
227
- return meta.next({})
228
- })
229
-
230
- os.input(z.object({ postId: z.number() })).use(mid, (input) => {
231
- expectTypeOf(input).toEqualTypeOf<{ postId: number }>()
232
-
233
- return {
234
- id: input.postId,
235
- }
236
- })
237
-
238
- // @ts-expect-error mismatch input
239
- os.input(z.object({ postId: z.number() })).use(mid)
240
-
241
- // @ts-expect-error mismatch input
242
- os.input(z.object({ postId: z.number() })).use(mid, (input) => {
243
- return {
244
- wrong: input.postId,
245
- }
246
- })
247
- })
248
-
249
- it('add middlewares to beginning', () => {
250
- const mid1 = vi.fn()
251
- const mid2 = vi.fn()
252
- const mid3 = vi.fn()
253
-
254
- const p1 = os.use(mid1).func(() => 'unnoq')
255
- const p2 = p1.use(mid2).use(mid3)
256
-
257
- expect(p2.zz$p.middlewares).toEqual([mid3, mid2, mid1])
258
- })
259
- })
260
-
261
- describe('server action', () => {
262
- it('only accept undefined context', () => {
263
- expectTypeOf(os.func(() => {})).toMatchTypeOf<(...args: any[]) => any>()
264
- expectTypeOf(
265
- os.context<{ auth: boolean } | undefined>().func(() => {}),
266
- ).toMatchTypeOf<(...args: any[]) => any>()
267
- expectTypeOf(
268
- os.context<{ auth: boolean }>().func(() => {}),
269
- ).not.toMatchTypeOf<(...args: any[]) => any>()
270
- })
271
-
272
- it('infer types', () => {
273
- const p = os
274
- .input(z.object({ id: z.number() }))
275
- .output(z.string())
276
- .func(() => 'string')
277
-
278
- expectTypeOf(p).toMatchTypeOf<
279
- (input: { id: number } | FormData) => Promise<string>
280
- >()
281
-
282
- const p2 = os.input(z.object({ id: z.number() })).func(() => 12333)
283
-
284
- expectTypeOf(p2).toMatchTypeOf<
285
- (input: { id: number } | FormData) => Promise<number>
286
- >()
287
- })
288
-
289
- it('works with input', async () => {
290
- const p = os
291
- .input(z.object({ id: z.number(), date: z.date() }))
292
- .func(async (input, context) => {
293
- expect(context).toBe(undefined)
294
- return input
295
- })
296
-
297
- expect(await p({ id: 123, date: new Date('2022-01-01') })).toEqual({
298
- id: 123,
299
- date: new Date('2022-01-01'),
300
- })
301
- })
302
-
303
- it('can deserialize form data', async () => {
304
- const p = os
305
- .input(z.object({ id: z.number(), nested: z.object({ date: z.date() }) }))
306
- .func(async input => input)
307
-
308
- const form = new FormData()
309
- form.append('id', '123')
310
- form.append('nested[date]', '2022-01-01')
311
-
312
- expect(await p(form)).toEqual({
313
- id: 123,
314
- nested: { date: new Date('2022-01-01') },
315
- })
316
- })
317
- })