@tanstack/react-start-client 1.111.10

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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -0
  3. package/dist/cjs/Meta.cjs +14 -0
  4. package/dist/cjs/Meta.cjs.map +1 -0
  5. package/dist/cjs/Meta.d.cts +1 -0
  6. package/dist/cjs/Scripts.cjs +12 -0
  7. package/dist/cjs/Scripts.cjs.map +1 -0
  8. package/dist/cjs/Scripts.d.cts +1 -0
  9. package/dist/cjs/StartClient.cjs +24 -0
  10. package/dist/cjs/StartClient.cjs.map +1 -0
  11. package/dist/cjs/StartClient.d.cts +4 -0
  12. package/dist/cjs/createIsomorphicFn.cjs +7 -0
  13. package/dist/cjs/createIsomorphicFn.cjs.map +1 -0
  14. package/dist/cjs/createIsomorphicFn.d.cts +12 -0
  15. package/dist/cjs/createMiddleware.cjs +34 -0
  16. package/dist/cjs/createMiddleware.cjs.map +1 -0
  17. package/dist/cjs/createMiddleware.d.cts +129 -0
  18. package/dist/cjs/createServerFn.cjs +369 -0
  19. package/dist/cjs/createServerFn.cjs.map +1 -0
  20. package/dist/cjs/createServerFn.d.cts +137 -0
  21. package/dist/cjs/envOnly.cjs +7 -0
  22. package/dist/cjs/envOnly.cjs.map +1 -0
  23. package/dist/cjs/envOnly.d.cts +4 -0
  24. package/dist/cjs/headers.cjs +30 -0
  25. package/dist/cjs/headers.cjs.map +1 -0
  26. package/dist/cjs/headers.d.cts +5 -0
  27. package/dist/cjs/index.cjs +31 -0
  28. package/dist/cjs/index.cjs.map +1 -0
  29. package/dist/cjs/index.d.cts +14 -0
  30. package/dist/cjs/json.cjs +14 -0
  31. package/dist/cjs/json.cjs.map +1 -0
  32. package/dist/cjs/json.d.cts +2 -0
  33. package/dist/cjs/registerGlobalMiddleware.cjs +9 -0
  34. package/dist/cjs/registerGlobalMiddleware.cjs.map +1 -0
  35. package/dist/cjs/registerGlobalMiddleware.d.cts +5 -0
  36. package/dist/cjs/renderRSC.cjs +29 -0
  37. package/dist/cjs/renderRSC.cjs.map +1 -0
  38. package/dist/cjs/renderRSC.d.cts +2 -0
  39. package/dist/cjs/routesManifest.d.cts +0 -0
  40. package/dist/cjs/serializer.cjs +152 -0
  41. package/dist/cjs/serializer.cjs.map +1 -0
  42. package/dist/cjs/serializer.d.cts +2 -0
  43. package/dist/cjs/ssr-client.cjs +114 -0
  44. package/dist/cjs/ssr-client.cjs.map +1 -0
  45. package/dist/cjs/ssr-client.d.cts +65 -0
  46. package/dist/cjs/tests/createIsomorphicFn.test-d.d.cts +1 -0
  47. package/dist/cjs/tests/createServerFn.test-d.d.cts +1 -0
  48. package/dist/cjs/tests/createServerMiddleware.test-d.d.cts +1 -0
  49. package/dist/cjs/tests/envOnly.test-d.d.cts +1 -0
  50. package/dist/cjs/tests/json.test.d.cts +1 -0
  51. package/dist/cjs/tests/transformer.test.d.cts +1 -0
  52. package/dist/cjs/useServerFn.cjs +26 -0
  53. package/dist/cjs/useServerFn.cjs.map +1 -0
  54. package/dist/cjs/useServerFn.d.cts +1 -0
  55. package/dist/esm/Meta.d.ts +1 -0
  56. package/dist/esm/Meta.js +14 -0
  57. package/dist/esm/Meta.js.map +1 -0
  58. package/dist/esm/Scripts.d.ts +1 -0
  59. package/dist/esm/Scripts.js +12 -0
  60. package/dist/esm/Scripts.js.map +1 -0
  61. package/dist/esm/StartClient.d.ts +4 -0
  62. package/dist/esm/StartClient.js +24 -0
  63. package/dist/esm/StartClient.js.map +1 -0
  64. package/dist/esm/createIsomorphicFn.d.ts +12 -0
  65. package/dist/esm/createIsomorphicFn.js +7 -0
  66. package/dist/esm/createIsomorphicFn.js.map +1 -0
  67. package/dist/esm/createMiddleware.d.ts +129 -0
  68. package/dist/esm/createMiddleware.js +34 -0
  69. package/dist/esm/createMiddleware.js.map +1 -0
  70. package/dist/esm/createServerFn.d.ts +137 -0
  71. package/dist/esm/createServerFn.js +347 -0
  72. package/dist/esm/createServerFn.js.map +1 -0
  73. package/dist/esm/envOnly.d.ts +4 -0
  74. package/dist/esm/envOnly.js +7 -0
  75. package/dist/esm/envOnly.js.map +1 -0
  76. package/dist/esm/headers.d.ts +5 -0
  77. package/dist/esm/headers.js +30 -0
  78. package/dist/esm/headers.js.map +1 -0
  79. package/dist/esm/index.d.ts +14 -0
  80. package/dist/esm/index.js +31 -0
  81. package/dist/esm/index.js.map +1 -0
  82. package/dist/esm/json.d.ts +2 -0
  83. package/dist/esm/json.js +14 -0
  84. package/dist/esm/json.js.map +1 -0
  85. package/dist/esm/registerGlobalMiddleware.d.ts +5 -0
  86. package/dist/esm/registerGlobalMiddleware.js +9 -0
  87. package/dist/esm/registerGlobalMiddleware.js.map +1 -0
  88. package/dist/esm/renderRSC.d.ts +2 -0
  89. package/dist/esm/renderRSC.js +29 -0
  90. package/dist/esm/renderRSC.js.map +1 -0
  91. package/dist/esm/routesManifest.d.ts +0 -0
  92. package/dist/esm/serializer.d.ts +2 -0
  93. package/dist/esm/serializer.js +152 -0
  94. package/dist/esm/serializer.js.map +1 -0
  95. package/dist/esm/ssr-client.d.ts +65 -0
  96. package/dist/esm/ssr-client.js +114 -0
  97. package/dist/esm/ssr-client.js.map +1 -0
  98. package/dist/esm/tests/createIsomorphicFn.test-d.d.ts +1 -0
  99. package/dist/esm/tests/createServerFn.test-d.d.ts +1 -0
  100. package/dist/esm/tests/createServerMiddleware.test-d.d.ts +1 -0
  101. package/dist/esm/tests/envOnly.test-d.d.ts +1 -0
  102. package/dist/esm/tests/json.test.d.ts +1 -0
  103. package/dist/esm/tests/transformer.test.d.ts +1 -0
  104. package/dist/esm/useServerFn.d.ts +1 -0
  105. package/dist/esm/useServerFn.js +26 -0
  106. package/dist/esm/useServerFn.js.map +1 -0
  107. package/package.json +68 -0
  108. package/src/Meta.tsx +10 -0
  109. package/src/Scripts.tsx +8 -0
  110. package/src/StartClient.tsx +21 -0
  111. package/src/createIsomorphicFn.ts +36 -0
  112. package/src/createMiddleware.ts +517 -0
  113. package/src/createServerFn.ts +790 -0
  114. package/src/envOnly.ts +9 -0
  115. package/src/headers.ts +50 -0
  116. package/src/index.tsx +74 -0
  117. package/src/json.ts +15 -0
  118. package/src/registerGlobalMiddleware.ts +9 -0
  119. package/src/renderRSC.tsx +91 -0
  120. package/src/routesManifest.ts +0 -0
  121. package/src/serializer.ts +177 -0
  122. package/src/ssr-client.tsx +221 -0
  123. package/src/tests/createIsomorphicFn.test-d.ts +72 -0
  124. package/src/tests/createServerFn.test-d.tsx +390 -0
  125. package/src/tests/createServerMiddleware.test-d.ts +611 -0
  126. package/src/tests/envOnly.test-d.ts +34 -0
  127. package/src/tests/json.test.ts +37 -0
  128. package/src/tests/transformer.test.tsx +147 -0
  129. package/src/useServerFn.ts +30 -0
@@ -0,0 +1,72 @@
1
+ import { expectTypeOf, test } from 'vitest'
2
+ import { createIsomorphicFn } from '../createIsomorphicFn'
3
+
4
+ test('createIsomorphicFn with no implementations', () => {
5
+ const fn = createIsomorphicFn()
6
+
7
+ expectTypeOf(fn).toBeCallableWith()
8
+ expectTypeOf(fn).returns.toBeUndefined()
9
+
10
+ expectTypeOf(fn).toHaveProperty('server')
11
+ expectTypeOf(fn).toHaveProperty('client')
12
+ })
13
+
14
+ test('createIsomorphicFn with server implementation', () => {
15
+ const fn = createIsomorphicFn().server(() => 'data')
16
+
17
+ expectTypeOf(fn).toBeCallableWith()
18
+ expectTypeOf(fn).returns.toEqualTypeOf<string | undefined>()
19
+
20
+ expectTypeOf(fn).toHaveProperty('client')
21
+ expectTypeOf(fn).not.toHaveProperty('server')
22
+ })
23
+
24
+ test('createIsomorphicFn with client implementation', () => {
25
+ const fn = createIsomorphicFn().client(() => 'data')
26
+
27
+ expectTypeOf(fn).toBeCallableWith()
28
+ expectTypeOf(fn).returns.toEqualTypeOf<string | undefined>()
29
+
30
+ expectTypeOf(fn).toHaveProperty('server')
31
+ expectTypeOf(fn).not.toHaveProperty('client')
32
+ })
33
+
34
+ test('createIsomorphicFn with server and client implementation', () => {
35
+ const fn = createIsomorphicFn()
36
+ .server(() => 'data')
37
+ .client(() => 'data')
38
+
39
+ expectTypeOf(fn).toBeCallableWith()
40
+ expectTypeOf(fn).returns.toEqualTypeOf<string>()
41
+
42
+ expectTypeOf(fn).not.toHaveProperty('server')
43
+ expectTypeOf(fn).not.toHaveProperty('client')
44
+ })
45
+
46
+ test('createIsomorphicFn with varying returns', () => {
47
+ const fn = createIsomorphicFn()
48
+ .server(() => 'data')
49
+ .client(() => 1)
50
+ expectTypeOf(fn).toBeCallableWith()
51
+ expectTypeOf(fn).returns.toEqualTypeOf<string | number>()
52
+ })
53
+
54
+ test('createIsomorphicFn with arguments', () => {
55
+ const fn = createIsomorphicFn()
56
+ .server((a: number, b: string) => 'data')
57
+ .client((...args) => {
58
+ expectTypeOf(args).toEqualTypeOf<[number, string]>()
59
+ return 1
60
+ })
61
+ expectTypeOf(fn).toBeCallableWith(1, 'a')
62
+ expectTypeOf(fn).returns.toEqualTypeOf<string | number>()
63
+
64
+ const fn2 = createIsomorphicFn()
65
+ .client((a: number, b: string) => 'data')
66
+ .server((...args) => {
67
+ expectTypeOf(args).toEqualTypeOf<[number, string]>()
68
+ return 1
69
+ })
70
+ expectTypeOf(fn2).toBeCallableWith(1, 'a')
71
+ expectTypeOf(fn2).returns.toEqualTypeOf<string | number>()
72
+ })
@@ -0,0 +1,390 @@
1
+ import { expectTypeOf, test } from 'vitest'
2
+ import { createServerFn } from '../createServerFn'
3
+ import { createMiddleware } from '../createMiddleware'
4
+ import type { Constrain, Validator } from '@tanstack/router-core'
5
+
6
+ test('createServerFn method with autocomplete', () => {
7
+ createServerFn().handler((options) => {
8
+ expectTypeOf(options.method).toEqualTypeOf<'GET' | 'POST'>()
9
+ })
10
+ })
11
+
12
+ test('createServerFn without middleware', () => {
13
+ expectTypeOf(createServerFn()).toHaveProperty('handler')
14
+ expectTypeOf(createServerFn()).toHaveProperty('middleware')
15
+ expectTypeOf(createServerFn()).toHaveProperty('validator')
16
+
17
+ createServerFn({ method: 'GET' }).handler((options) => {
18
+ expectTypeOf(options).toEqualTypeOf<{
19
+ method: 'GET'
20
+ context: undefined
21
+ data: undefined
22
+ signal: AbortSignal
23
+ }>()
24
+ })
25
+ })
26
+
27
+ test('createServerFn with validator', () => {
28
+ const fnAfterValidator = createServerFn({ method: 'GET' }).validator(
29
+ (input: { input: string }) => ({
30
+ a: input.input,
31
+ }),
32
+ )
33
+
34
+ expectTypeOf(fnAfterValidator).toHaveProperty('handler')
35
+ expectTypeOf(fnAfterValidator).toHaveProperty('middleware')
36
+ expectTypeOf(fnAfterValidator).not.toHaveProperty('validator')
37
+
38
+ const fn = fnAfterValidator.handler((options) => {
39
+ expectTypeOf(options).toEqualTypeOf<{
40
+ method: 'GET'
41
+ context: undefined
42
+ data: {
43
+ a: string
44
+ }
45
+ signal: AbortSignal
46
+ }>()
47
+ })
48
+
49
+ expectTypeOf(fn).parameter(0).toEqualTypeOf<{
50
+ data: { input: string }
51
+ headers?: HeadersInit
52
+ type?: 'static' | 'dynamic'
53
+ fullResponse?: boolean
54
+ signal?: AbortSignal
55
+ }>()
56
+
57
+ expectTypeOf(fn).returns.resolves.toEqualTypeOf<void>()
58
+ })
59
+
60
+ test('createServerFn with middleware and context', () => {
61
+ const middleware1 = createMiddleware().server(({ next }) => {
62
+ return next({ context: { a: 'a' } as const })
63
+ })
64
+
65
+ const middleware2 = createMiddleware().server(({ next }) => {
66
+ return next({ context: { b: 'b' } as const })
67
+ })
68
+
69
+ const middleware3 = createMiddleware()
70
+ .middleware([middleware1, middleware2])
71
+ .client(({ next }) => {
72
+ return next({ context: { c: 'c' } as const })
73
+ })
74
+
75
+ const middleware4 = createMiddleware()
76
+ .middleware([middleware3])
77
+ .client(({ context, next }) => {
78
+ return next({ sendContext: context })
79
+ })
80
+ .server(({ context, next }) => {
81
+ expectTypeOf(context).toEqualTypeOf<{
82
+ readonly a: 'a'
83
+ readonly b: 'b'
84
+ readonly c: 'c'
85
+ }>()
86
+ return next({ context: { d: 'd' } as const })
87
+ })
88
+
89
+ const fnWithMiddleware = createServerFn({ method: 'GET' }).middleware([
90
+ middleware4,
91
+ ])
92
+
93
+ expectTypeOf(fnWithMiddleware).toHaveProperty('handler')
94
+ expectTypeOf(fnWithMiddleware).toHaveProperty('validator')
95
+ expectTypeOf(fnWithMiddleware).not.toHaveProperty('middleware')
96
+
97
+ fnWithMiddleware.handler((options) => {
98
+ expectTypeOf(options).toEqualTypeOf<{
99
+ method: 'GET'
100
+ context: {
101
+ readonly a: 'a'
102
+ readonly b: 'b'
103
+ readonly c: 'c'
104
+ readonly d: 'd'
105
+ }
106
+ data: undefined
107
+ signal: AbortSignal
108
+ }>()
109
+ })
110
+ })
111
+
112
+ test('createServerFn with middleware and validator', () => {
113
+ const middleware1 = createMiddleware().validator(
114
+ (input: { readonly inputA: 'inputA' }) =>
115
+ ({
116
+ outputA: 'outputA',
117
+ }) as const,
118
+ )
119
+
120
+ const middleware2 = createMiddleware().validator(
121
+ (input: { readonly inputB: 'inputB' }) =>
122
+ ({
123
+ outputB: 'outputB',
124
+ }) as const,
125
+ )
126
+
127
+ const middleware3 = createMiddleware().middleware([middleware1, middleware2])
128
+
129
+ const fn = createServerFn({ method: 'GET' })
130
+ .middleware([middleware3])
131
+ .validator(
132
+ (input: { readonly inputC: 'inputC' }) =>
133
+ ({
134
+ outputC: 'outputC',
135
+ }) as const,
136
+ )
137
+ .handler((options) => {
138
+ expectTypeOf(options).toEqualTypeOf<{
139
+ method: 'GET'
140
+ context: undefined
141
+ data: {
142
+ readonly outputA: 'outputA'
143
+ readonly outputB: 'outputB'
144
+ readonly outputC: 'outputC'
145
+ }
146
+ signal: AbortSignal
147
+ }>()
148
+
149
+ return 'data' as const
150
+ })
151
+
152
+ expectTypeOf(fn).parameter(0).toEqualTypeOf<{
153
+ data: {
154
+ readonly inputA: 'inputA'
155
+ readonly inputB: 'inputB'
156
+ readonly inputC: 'inputC'
157
+ }
158
+ headers?: HeadersInit
159
+ type?: 'static' | 'dynamic'
160
+ fullResponse?: boolean
161
+ signal?: AbortSignal
162
+ }>()
163
+
164
+ expectTypeOf(fn).returns.resolves.toEqualTypeOf<'data'>()
165
+
166
+ expectTypeOf(() =>
167
+ fn({
168
+ fullResponse: false,
169
+ data: { inputA: 'inputA', inputB: 'inputB', inputC: 'inputC' },
170
+ }),
171
+ ).returns.resolves.toEqualTypeOf<'data'>()
172
+
173
+ expectTypeOf(() =>
174
+ fn({
175
+ fullResponse: true,
176
+ data: { inputA: 'inputA', inputB: 'inputB', inputC: 'inputC' },
177
+ }),
178
+ ).returns.resolves.toEqualTypeOf<{
179
+ result: 'data'
180
+ context: undefined
181
+ error: unknown
182
+ }>()
183
+ })
184
+
185
+ test('createServerFn overrides properties', () => {
186
+ const middleware1 = createMiddleware()
187
+ .validator(
188
+ () =>
189
+ ({
190
+ input: 'a' as 'a' | 'b' | 'c',
191
+ }) as const,
192
+ )
193
+ .client(({ context, next }) => {
194
+ expectTypeOf(context).toEqualTypeOf<undefined>()
195
+
196
+ const newContext = { context: 'a' } as const
197
+ return next({ sendContext: newContext, context: newContext })
198
+ })
199
+ .server(({ data, context, next }) => {
200
+ expectTypeOf(data).toEqualTypeOf<{ readonly input: 'a' | 'b' | 'c' }>()
201
+
202
+ expectTypeOf(context).toEqualTypeOf<{
203
+ readonly context: 'a'
204
+ }>()
205
+
206
+ const newContext = { context: 'b' } as const
207
+ return next({ sendContext: newContext, context: newContext })
208
+ })
209
+
210
+ const middleware2 = createMiddleware()
211
+ .middleware([middleware1])
212
+ .validator(
213
+ () =>
214
+ ({
215
+ input: 'b' as 'b' | 'c',
216
+ }) as const,
217
+ )
218
+ .client(({ context, next }) => {
219
+ expectTypeOf(context).toEqualTypeOf<{ readonly context: 'a' }>()
220
+
221
+ const newContext = { context: 'aa' } as const
222
+
223
+ return next({ sendContext: newContext, context: newContext })
224
+ })
225
+ .server(({ context, next }) => {
226
+ expectTypeOf(context).toEqualTypeOf<{ readonly context: 'aa' }>()
227
+
228
+ const newContext = { context: 'bb' } as const
229
+
230
+ return next({ sendContext: newContext, context: newContext })
231
+ })
232
+
233
+ createServerFn()
234
+ .middleware([middleware2])
235
+ .validator(
236
+ () =>
237
+ ({
238
+ input: 'c',
239
+ }) as const,
240
+ )
241
+ .handler(({ data, context }) => {
242
+ expectTypeOf(data).toEqualTypeOf<{
243
+ readonly input: 'c'
244
+ }>()
245
+ expectTypeOf(context).toEqualTypeOf<{ readonly context: 'bb' }>()
246
+ })
247
+ })
248
+
249
+ test('createServerFn where validator is a primitive', () => {
250
+ createServerFn({ method: 'GET' })
251
+ .validator(() => 'c' as const)
252
+ .handler((options) => {
253
+ expectTypeOf(options).toEqualTypeOf<{
254
+ method: 'GET'
255
+ context: undefined
256
+ data: 'c'
257
+ signal: AbortSignal
258
+ }>()
259
+ })
260
+ })
261
+
262
+ test('createServerFn where validator is optional if object is optional', () => {
263
+ const fn = createServerFn({ method: 'GET' })
264
+ .validator((input: 'c' | undefined) => input)
265
+ .handler((options) => {
266
+ expectTypeOf(options).toEqualTypeOf<{
267
+ method: 'GET'
268
+ context: undefined
269
+ data: 'c' | undefined
270
+ signal: AbortSignal
271
+ }>()
272
+ })
273
+
274
+ expectTypeOf(fn).parameter(0).toEqualTypeOf<
275
+ | {
276
+ data?: 'c' | undefined
277
+ headers?: HeadersInit
278
+ type?: 'static' | 'dynamic'
279
+ fullResponse?: boolean
280
+ signal?: AbortSignal
281
+ }
282
+ | undefined
283
+ >()
284
+
285
+ expectTypeOf(fn).returns.resolves.toEqualTypeOf<void>()
286
+ })
287
+
288
+ test('createServerFn where data is optional if there is no validator', () => {
289
+ const fn = createServerFn({ method: 'GET' }).handler((options) => {
290
+ expectTypeOf(options).toEqualTypeOf<{
291
+ method: 'GET'
292
+ context: undefined
293
+ data: undefined
294
+ signal: AbortSignal
295
+ }>()
296
+ })
297
+
298
+ expectTypeOf(fn).parameter(0).toEqualTypeOf<
299
+ | {
300
+ data?: undefined
301
+ headers?: HeadersInit
302
+ type?: 'static' | 'dynamic'
303
+ fullResponse?: boolean
304
+ signal?: AbortSignal
305
+ }
306
+ | undefined
307
+ >()
308
+
309
+ expectTypeOf(fn).returns.resolves.toEqualTypeOf<void>()
310
+ })
311
+
312
+ test('createServerFn returns Date', () => {
313
+ const fn = createServerFn().handler(() => ({
314
+ dates: [new Date(), new Date()] as const,
315
+ }))
316
+
317
+ expectTypeOf(fn()).toEqualTypeOf<Promise<{ dates: readonly [Date, Date] }>>()
318
+ })
319
+
320
+ test('createServerFn returns RSC', () => {
321
+ const fn = createServerFn().handler(() => ({
322
+ rscs: [
323
+ <div key="0">I'm an RSC</div>,
324
+ <div key="1">I'm an RSC</div>,
325
+ ] as const,
326
+ }))
327
+
328
+ expectTypeOf(fn()).toEqualTypeOf<
329
+ Promise<{ rscs: readonly [ReadableStream, ReadableStream] }>
330
+ >()
331
+ })
332
+
333
+ test('createServerFn returns undefined', () => {
334
+ const fn = createServerFn().handler(() => ({
335
+ nothing: undefined,
336
+ }))
337
+
338
+ expectTypeOf(fn()).toEqualTypeOf<Promise<{ nothing: undefined }>>()
339
+ })
340
+
341
+ test('createServerFn cannot return function', () => {
342
+ expectTypeOf(createServerFn().handler<{ func: () => 'func' }>)
343
+ .parameter(0)
344
+ .returns.toEqualTypeOf<
345
+ | { func: 'Function is not serializable' }
346
+ | Promise<{ func: 'Function is not serializable' }>
347
+ >()
348
+ })
349
+
350
+ test('createServerFn cannot validate function', () => {
351
+ const validator = createServerFn().validator<
352
+ (input: { func: () => 'string' }) => { output: 'string' }
353
+ >
354
+
355
+ expectTypeOf(validator)
356
+ .parameter(0)
357
+ .toEqualTypeOf<
358
+ Constrain<
359
+ (input: { func: () => 'string' }) => { output: 'string' },
360
+ Validator<{ func: 'Function is not serializable' }, any>
361
+ >
362
+ >()
363
+ })
364
+
365
+ test('createServerFn can validate Date', () => {
366
+ const validator = createServerFn().validator<
367
+ (input: Date) => { output: 'string' }
368
+ >
369
+
370
+ expectTypeOf(validator)
371
+ .parameter(0)
372
+ .toEqualTypeOf<
373
+ Constrain<(input: Date) => { output: 'string' }, Validator<Date, any>>
374
+ >()
375
+ })
376
+
377
+ test('createServerFn can validate FormData', () => {
378
+ const validator = createServerFn().validator<
379
+ (input: FormData) => { output: 'string' }
380
+ >
381
+
382
+ expectTypeOf(validator)
383
+ .parameter(0)
384
+ .toEqualTypeOf<
385
+ Constrain<
386
+ (input: FormData) => { output: 'string' },
387
+ Validator<FormData, any>
388
+ >
389
+ >()
390
+ })