@tanstack/react-start-client 1.114.3 → 1.114.5

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 (97) hide show
  1. package/dist/cjs/StartClient.cjs +2 -2
  2. package/dist/cjs/StartClient.cjs.map +1 -1
  3. package/dist/cjs/StartClient.d.cts +1 -1
  4. package/dist/cjs/createServerFn.cjs +13 -230
  5. package/dist/cjs/createServerFn.cjs.map +1 -1
  6. package/dist/cjs/createServerFn.d.cts +1 -141
  7. package/dist/cjs/index.cjs +37 -16
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/index.d.cts +11 -9
  10. package/dist/cjs/tests/setupTests.d.cts +0 -0
  11. package/dist/esm/StartClient.d.ts +1 -1
  12. package/dist/esm/StartClient.js +1 -1
  13. package/dist/esm/StartClient.js.map +1 -1
  14. package/dist/esm/createServerFn.d.ts +1 -141
  15. package/dist/esm/createServerFn.js +6 -201
  16. package/dist/esm/createServerFn.js.map +1 -1
  17. package/dist/esm/index.d.ts +11 -9
  18. package/dist/esm/index.js +1 -7
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/tests/setupTests.d.ts +0 -0
  21. package/package.json +4 -3
  22. package/src/StartClient.tsx +2 -2
  23. package/src/createServerFn.ts +29 -692
  24. package/src/index.tsx +20 -20
  25. package/src/tests/createServerFn.test-d.tsx +1 -1
  26. package/src/tests/setupTests.tsx +1 -0
  27. package/dist/cjs/createIsomorphicFn.cjs +0 -7
  28. package/dist/cjs/createIsomorphicFn.cjs.map +0 -1
  29. package/dist/cjs/createIsomorphicFn.d.cts +0 -12
  30. package/dist/cjs/createMiddleware.cjs +0 -34
  31. package/dist/cjs/createMiddleware.cjs.map +0 -1
  32. package/dist/cjs/createMiddleware.d.cts +0 -131
  33. package/dist/cjs/envOnly.cjs +0 -7
  34. package/dist/cjs/envOnly.cjs.map +0 -1
  35. package/dist/cjs/envOnly.d.cts +0 -4
  36. package/dist/cjs/headers.cjs +0 -30
  37. package/dist/cjs/headers.cjs.map +0 -1
  38. package/dist/cjs/headers.d.cts +0 -5
  39. package/dist/cjs/json.cjs +0 -14
  40. package/dist/cjs/json.cjs.map +0 -1
  41. package/dist/cjs/json.d.cts +0 -2
  42. package/dist/cjs/registerGlobalMiddleware.cjs +0 -9
  43. package/dist/cjs/registerGlobalMiddleware.cjs.map +0 -1
  44. package/dist/cjs/registerGlobalMiddleware.d.cts +0 -5
  45. package/dist/cjs/serializer.cjs +0 -152
  46. package/dist/cjs/serializer.cjs.map +0 -1
  47. package/dist/cjs/serializer.d.cts +0 -2
  48. package/dist/cjs/ssr-client.cjs +0 -130
  49. package/dist/cjs/ssr-client.cjs.map +0 -1
  50. package/dist/cjs/ssr-client.d.cts +0 -65
  51. package/dist/cjs/tests/createIsomorphicFn.test-d.d.cts +0 -1
  52. package/dist/cjs/tests/createServerMiddleware.test-d.d.cts +0 -1
  53. package/dist/cjs/tests/envOnly.test-d.d.cts +0 -1
  54. package/dist/cjs/tests/json.test.d.cts +0 -1
  55. package/dist/cjs/tests/transformer.test.d.cts +0 -1
  56. package/dist/esm/createIsomorphicFn.d.ts +0 -12
  57. package/dist/esm/createIsomorphicFn.js +0 -7
  58. package/dist/esm/createIsomorphicFn.js.map +0 -1
  59. package/dist/esm/createMiddleware.d.ts +0 -131
  60. package/dist/esm/createMiddleware.js +0 -34
  61. package/dist/esm/createMiddleware.js.map +0 -1
  62. package/dist/esm/envOnly.d.ts +0 -4
  63. package/dist/esm/envOnly.js +0 -7
  64. package/dist/esm/envOnly.js.map +0 -1
  65. package/dist/esm/headers.d.ts +0 -5
  66. package/dist/esm/headers.js +0 -30
  67. package/dist/esm/headers.js.map +0 -1
  68. package/dist/esm/json.d.ts +0 -2
  69. package/dist/esm/json.js +0 -14
  70. package/dist/esm/json.js.map +0 -1
  71. package/dist/esm/registerGlobalMiddleware.d.ts +0 -5
  72. package/dist/esm/registerGlobalMiddleware.js +0 -9
  73. package/dist/esm/registerGlobalMiddleware.js.map +0 -1
  74. package/dist/esm/serializer.d.ts +0 -2
  75. package/dist/esm/serializer.js +0 -152
  76. package/dist/esm/serializer.js.map +0 -1
  77. package/dist/esm/ssr-client.d.ts +0 -65
  78. package/dist/esm/ssr-client.js +0 -130
  79. package/dist/esm/ssr-client.js.map +0 -1
  80. package/dist/esm/tests/createIsomorphicFn.test-d.d.ts +0 -1
  81. package/dist/esm/tests/createServerMiddleware.test-d.d.ts +0 -1
  82. package/dist/esm/tests/envOnly.test-d.d.ts +0 -1
  83. package/dist/esm/tests/json.test.d.ts +0 -1
  84. package/dist/esm/tests/transformer.test.d.ts +0 -1
  85. package/src/createIsomorphicFn.ts +0 -36
  86. package/src/createMiddleware.ts +0 -595
  87. package/src/envOnly.ts +0 -9
  88. package/src/headers.ts +0 -50
  89. package/src/json.ts +0 -15
  90. package/src/registerGlobalMiddleware.ts +0 -9
  91. package/src/serializer.ts +0 -177
  92. package/src/ssr-client.tsx +0 -246
  93. package/src/tests/createIsomorphicFn.test-d.ts +0 -72
  94. package/src/tests/createServerMiddleware.test-d.ts +0 -611
  95. package/src/tests/envOnly.test-d.ts +0 -34
  96. package/src/tests/json.test.ts +0 -37
  97. package/src/tests/transformer.test.tsx +0 -147
@@ -1,501 +1,30 @@
1
- import { default as invariant } from 'tiny-invariant'
2
- import { default as warning } from 'tiny-warning'
3
1
  import { isNotFound, isRedirect } from '@tanstack/react-router'
4
- import { mergeHeaders } from './headers'
5
- import { globalMiddleware } from './registerGlobalMiddleware'
6
- import { startSerializer } from './serializer'
7
- import type { Readable } from 'node:stream'
8
- import type {
9
- AnyValidator,
10
- Constrain,
11
- Expand,
12
- ResolveValidatorInput,
13
- SerializerParse,
14
- SerializerStringify,
15
- SerializerStringifyBy,
16
- Validator,
17
- } from '@tanstack/router-core'
2
+ import {
3
+ applyMiddleware,
4
+ execValidator,
5
+ extractFormDataContext,
6
+ flattenMiddlewares,
7
+ globalMiddleware,
8
+ serverFnBaseToMiddleware,
9
+ serverFnStaticCache,
10
+ } from '@tanstack/start-client-core'
11
+ import invariant from 'tiny-invariant'
18
12
  import type {
19
13
  AnyMiddleware,
20
- AssignAllClientSendContext,
21
- AssignAllServerContext,
22
- IntersectAllValidatorInputs,
23
- IntersectAllValidatorOutputs,
24
- MiddlewareClientFnResult,
25
- MiddlewareServerFnResult,
26
- } from './createMiddleware'
27
-
28
- export interface JsonResponse<TData> extends Response {
29
- json: () => Promise<TData>
30
- }
31
-
32
- export type CompiledFetcherFnOptions = {
33
- method: Method
34
- data: unknown
35
- response?: ServerFnResponseType
36
- headers?: HeadersInit
37
- signal?: AbortSignal
38
- context?: any
39
- }
40
-
41
- export type Fetcher<
42
- TMiddlewares,
43
- TValidator,
44
- TResponse,
45
- TServerFnResponseType extends ServerFnResponseType,
46
- > =
47
- undefined extends IntersectAllValidatorInputs<TMiddlewares, TValidator>
48
- ? OptionalFetcher<
49
- TMiddlewares,
50
- TValidator,
51
- TResponse,
52
- TServerFnResponseType
53
- >
54
- : RequiredFetcher<
55
- TMiddlewares,
56
- TValidator,
57
- TResponse,
58
- TServerFnResponseType
59
- >
60
-
61
- export interface FetcherBase {
62
- url: string
63
- __executeServer: (opts: {
64
- method: Method
65
- response?: ServerFnResponseType
66
- data: unknown
67
- headers?: HeadersInit
68
- context?: any
69
- signal: AbortSignal
70
- }) => Promise<unknown>
71
- }
72
-
73
- export type FetchResult<
74
- TMiddlewares,
75
- TResponse,
76
- TServerFnResponseType extends ServerFnResponseType,
77
- > = TServerFnResponseType extends 'raw'
78
- ? Promise<Response>
79
- : TServerFnResponseType extends 'full'
80
- ? Promise<FullFetcherData<TMiddlewares, TResponse>>
81
- : Promise<FetcherData<TResponse>>
82
-
83
- export interface OptionalFetcher<
84
- TMiddlewares,
85
- TValidator,
86
- TResponse,
87
- TServerFnResponseType extends ServerFnResponseType,
88
- > extends FetcherBase {
89
- (
90
- options?: OptionalFetcherDataOptions<TMiddlewares, TValidator>,
91
- ): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>
92
- }
93
-
94
- export interface RequiredFetcher<
95
- TMiddlewares,
96
- TValidator,
97
- TResponse,
98
- TServerFnResponseType extends ServerFnResponseType,
99
- > extends FetcherBase {
100
- (
101
- opts: RequiredFetcherDataOptions<TMiddlewares, TValidator>,
102
- ): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>
103
- }
104
-
105
- export type FetcherBaseOptions = {
106
- headers?: HeadersInit
107
- type?: ServerFnType
108
- signal?: AbortSignal
109
- }
110
-
111
- export type ServerFnType = 'static' | 'dynamic'
112
-
113
- export interface OptionalFetcherDataOptions<TMiddlewares, TValidator>
114
- extends FetcherBaseOptions {
115
- data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>
116
- }
117
-
118
- export interface RequiredFetcherDataOptions<TMiddlewares, TValidator>
119
- extends FetcherBaseOptions {
120
- data: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>
121
- }
122
-
123
- export interface FullFetcherData<TMiddlewares, TResponse> {
124
- error: unknown
125
- result: FetcherData<TResponse>
126
- context: AssignAllClientSendContext<TMiddlewares>
127
- }
128
-
129
- export type FetcherData<TResponse> =
130
- TResponse extends JsonResponse<any>
131
- ? SerializerParse<ReturnType<TResponse['json']>>
132
- : SerializerParse<TResponse>
133
-
134
- export type RscStream<T> = {
135
- __cacheState: T
136
- }
137
-
138
- export type Method = 'GET' | 'POST'
139
- export type ServerFnResponseType = 'data' | 'full' | 'raw'
140
-
141
- // see https://h3.unjs.io/guide/event-handler#responses-types
142
- export type RawResponse = Response | ReadableStream | Readable | null | string
143
-
144
- export type ServerFnReturnType<
145
- TServerFnResponseType extends ServerFnResponseType,
146
- TResponse,
147
- > = TServerFnResponseType extends 'raw'
148
- ? RawResponse | Promise<RawResponse>
149
- : Promise<SerializerStringify<TResponse>> | SerializerStringify<TResponse>
150
- export type ServerFn<
151
- TMethod,
152
- TServerFnResponseType extends ServerFnResponseType,
153
- TMiddlewares,
154
- TValidator,
155
- TResponse,
156
- > = (
157
- ctx: ServerFnCtx<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
158
- ) => ServerFnReturnType<TServerFnResponseType, TResponse>
159
-
160
- export interface ServerFnCtx<
161
- TMethod,
162
- TServerFnResponseType extends ServerFnResponseType,
163
- TMiddlewares,
164
- TValidator,
165
- > {
166
- method: TMethod
167
- response: TServerFnResponseType
168
- data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TValidator>>
169
- context: Expand<AssignAllServerContext<TMiddlewares>>
170
- signal: AbortSignal
171
- }
172
-
173
- export type CompiledFetcherFn<
174
- TResponse,
175
- TServerFnResponseType extends ServerFnResponseType,
176
- > = {
177
- (
178
- opts: CompiledFetcherFnOptions &
179
- ServerFnBaseOptions<Method, TServerFnResponseType>,
180
- ): Promise<TResponse>
181
- url: string
182
- }
183
-
184
- type ServerFnBaseOptions<
185
- TMethod extends Method = 'GET',
186
- TServerFnResponseType extends ServerFnResponseType = 'data',
187
- TResponse = unknown,
188
- TMiddlewares = unknown,
189
- TInput = unknown,
190
- > = {
191
- method: TMethod
192
- response?: TServerFnResponseType
193
- validateClient?: boolean
194
- middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyMiddleware>>
195
- validator?: ConstrainValidator<TInput>
196
- extractedFn?: CompiledFetcherFn<TResponse, TServerFnResponseType>
197
- serverFn?: ServerFn<
198
- TMethod,
199
- TServerFnResponseType,
200
- TMiddlewares,
201
- TInput,
202
- TResponse
203
- >
204
- functionId: string
205
- type: ServerFnTypeOrTypeFn<
206
- TMethod,
207
- TServerFnResponseType,
208
- TMiddlewares,
209
- AnyValidator
210
- >
211
- }
212
-
213
- export type ValidatorSerializerStringify<TValidator> = Validator<
214
- SerializerStringifyBy<
215
- ResolveValidatorInput<TValidator>,
216
- Date | undefined | FormData
217
- >,
218
- any
219
- >
220
-
221
- export type ConstrainValidator<TValidator> = unknown extends TValidator
222
- ? TValidator
223
- : Constrain<TValidator, ValidatorSerializerStringify<TValidator>>
224
-
225
- export interface ServerFnMiddleware<
226
- TMethod extends Method,
227
- TServerFnResponseType extends ServerFnResponseType,
228
- TValidator,
229
- > {
230
- middleware: <const TNewMiddlewares = undefined>(
231
- middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyMiddleware>>,
232
- ) => ServerFnAfterMiddleware<
233
- TMethod,
234
- TServerFnResponseType,
235
- TNewMiddlewares,
236
- TValidator
237
- >
238
- }
239
-
240
- export interface ServerFnAfterMiddleware<
241
- TMethod extends Method,
242
- TServerFnResponseType extends ServerFnResponseType,
243
- TMiddlewares,
244
- TValidator,
245
- > extends ServerFnValidator<TMethod, TServerFnResponseType, TMiddlewares>,
246
- ServerFnTyper<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
247
- ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}
248
-
249
- export type ValidatorFn<
250
- TMethod extends Method,
251
- TServerFnResponseType extends ServerFnResponseType,
252
- TMiddlewares,
253
- > = <TValidator>(
254
- validator: ConstrainValidator<TValidator>,
255
- ) => ServerFnAfterValidator<
256
- TMethod,
257
- TServerFnResponseType,
258
- TMiddlewares,
259
- TValidator
260
- >
261
-
262
- export interface ServerFnValidator<
263
- TMethod extends Method,
264
- TServerFnResponseType extends ServerFnResponseType,
265
- TMiddlewares,
266
- > {
267
- validator: ValidatorFn<TMethod, TServerFnResponseType, TMiddlewares>
268
- }
269
-
270
- export interface ServerFnAfterValidator<
271
- TMethod extends Method,
272
- TServerFnResponseType extends ServerFnResponseType,
273
- TMiddlewares,
274
- TValidator,
275
- > extends ServerFnMiddleware<TMethod, TServerFnResponseType, TValidator>,
276
- ServerFnTyper<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
277
- ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}
278
-
279
- // Typer
280
- export interface ServerFnTyper<
281
- TMethod extends Method,
282
- TServerFnResponseType extends ServerFnResponseType,
283
- TMiddlewares,
284
- TValidator,
285
- > {
286
- type: (
287
- typer: ServerFnTypeOrTypeFn<
288
- TMethod,
289
- TServerFnResponseType,
290
- TMiddlewares,
291
- TValidator
292
- >,
293
- ) => ServerFnAfterTyper<
294
- TMethod,
295
- TServerFnResponseType,
296
- TMiddlewares,
297
- TValidator
298
- >
299
- }
300
-
301
- export type ServerFnTypeOrTypeFn<
302
- TMethod extends Method,
303
- TServerFnResponseType extends ServerFnResponseType,
304
- TMiddlewares,
305
- TValidator,
306
- > =
307
- | ServerFnType
308
- | ((
309
- ctx: ServerFnCtx<
310
- TMethod,
311
- TServerFnResponseType,
312
- TMiddlewares,
313
- TValidator
314
- >,
315
- ) => ServerFnType)
316
-
317
- export interface ServerFnAfterTyper<
318
- TMethod extends Method,
319
- TServerFnResponseType extends ServerFnResponseType,
320
- TMiddlewares,
321
- TValidator,
322
- > extends ServerFnHandler<
323
- TMethod,
324
- TServerFnResponseType,
325
- TMiddlewares,
326
- TValidator
327
- > {}
328
-
329
- // Handler
330
- export interface ServerFnHandler<
331
- TMethod extends Method,
332
- TServerFnResponseType extends ServerFnResponseType,
333
- TMiddlewares,
334
- TValidator,
335
- > {
336
- handler: <TNewResponse>(
337
- fn?: ServerFn<
338
- TMethod,
339
- TServerFnResponseType,
340
- TMiddlewares,
341
- TValidator,
342
- TNewResponse
343
- >,
344
- ) => Fetcher<TMiddlewares, TValidator, TNewResponse, TServerFnResponseType>
345
- }
346
-
347
- export interface ServerFnBuilder<
348
- TMethod extends Method = 'GET',
349
- TServerFnResponseType extends ServerFnResponseType = 'data',
350
- > extends ServerFnMiddleware<TMethod, TServerFnResponseType, undefined>,
351
- ServerFnValidator<TMethod, TServerFnResponseType, undefined>,
352
- ServerFnTyper<TMethod, TServerFnResponseType, undefined, undefined>,
353
- ServerFnHandler<TMethod, TServerFnResponseType, undefined, undefined> {
354
- options: ServerFnBaseOptions<
355
- TMethod,
356
- TServerFnResponseType,
357
- unknown,
358
- undefined,
359
- undefined
360
- >
361
- }
362
-
363
- type StaticCachedResult = {
364
- ctx?: {
365
- result: any
366
- context: any
367
- }
368
- error?: any
369
- }
370
-
371
- export type ServerFnStaticCache = {
372
- getItem: (
373
- ctx: MiddlewareResult,
374
- ) => StaticCachedResult | Promise<StaticCachedResult | undefined>
375
- setItem: (
376
- ctx: MiddlewareResult,
377
- response: StaticCachedResult,
378
- ) => Promise<void>
379
- fetchItem: (
380
- ctx: MiddlewareResult,
381
- ) => StaticCachedResult | Promise<StaticCachedResult | undefined>
382
- }
383
-
384
- let serverFnStaticCache: ServerFnStaticCache | undefined
385
-
386
- export function setServerFnStaticCache(
387
- cache?: ServerFnStaticCache | (() => ServerFnStaticCache | undefined),
388
- ) {
389
- const previousCache = serverFnStaticCache
390
- serverFnStaticCache = typeof cache === 'function' ? cache() : cache
391
-
392
- return () => {
393
- serverFnStaticCache = previousCache
394
- }
395
- }
396
-
397
- export function createServerFnStaticCache(
398
- serverFnStaticCache: ServerFnStaticCache,
399
- ) {
400
- return serverFnStaticCache
401
- }
402
-
403
- setServerFnStaticCache(() => {
404
- const getStaticCacheUrl = (options: MiddlewareResult, hash: string) => {
405
- return `/__tsr/staticServerFnCache/${options.functionId}__${hash}.json`
406
- }
407
-
408
- const jsonToFilenameSafeString = (json: any) => {
409
- // Custom replacer to sort keys
410
- const sortedKeysReplacer = (key: string, value: any) =>
411
- value && typeof value === 'object' && !Array.isArray(value)
412
- ? Object.keys(value)
413
- .sort()
414
- .reduce((acc: any, curr: string) => {
415
- acc[curr] = value[curr]
416
- return acc
417
- }, {})
418
- : value
419
-
420
- // Convert JSON to string with sorted keys
421
- const jsonString = JSON.stringify(json ?? '', sortedKeysReplacer)
422
-
423
- // Replace characters invalid in filenames
424
- return jsonString
425
- .replace(/[/\\?%*:|"<>]/g, '-') // Replace invalid characters with a dash
426
- .replace(/\s+/g, '_') // Optionally replace whitespace with underscores
427
- }
428
-
429
- const staticClientCache =
430
- typeof document !== 'undefined' ? new Map<string, any>() : null
431
-
432
- return createServerFnStaticCache({
433
- getItem: async (ctx) => {
434
- if (typeof document === 'undefined') {
435
- const hash = jsonToFilenameSafeString(ctx.data)
436
- const url = getStaticCacheUrl(ctx, hash)
437
- const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!
438
-
439
- // Use fs instead of fetch to read from filesystem
440
- const { promises: fs } = await import('node:fs')
441
- const path = await import('node:path')
442
- const filePath = path.join(publicUrl, url)
443
-
444
- const [cachedResult, readError] = await fs
445
- .readFile(filePath, 'utf-8')
446
- .then((c) => [
447
- startSerializer.parse(c) as {
448
- ctx: unknown
449
- error: any
450
- },
451
- null,
452
- ])
453
- .catch((e) => [null, e])
454
-
455
- if (readError && readError.code !== 'ENOENT') {
456
- throw readError
457
- }
458
-
459
- return cachedResult as StaticCachedResult
460
- }
461
-
462
- return undefined
463
- },
464
- setItem: async (ctx, response) => {
465
- const { promises: fs } = await import('node:fs')
466
- const path = await import('node:path')
467
-
468
- const hash = jsonToFilenameSafeString(ctx.data)
469
- const url = getStaticCacheUrl(ctx, hash)
470
- const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!
471
- const filePath = path.join(publicUrl, url)
472
-
473
- // Ensure the directory exists
474
- await fs.mkdir(path.dirname(filePath), { recursive: true })
475
-
476
- // Store the result with fs
477
- await fs.writeFile(filePath, startSerializer.stringify(response))
478
- },
479
- fetchItem: async (ctx) => {
480
- const hash = jsonToFilenameSafeString(ctx.data)
481
- const url = getStaticCacheUrl(ctx, hash)
482
-
483
- let result: any = staticClientCache?.get(url)
484
-
485
- if (!result) {
486
- result = await fetch(url, {
487
- method: 'GET',
488
- })
489
- .then((r) => r.text())
490
- .then((d) => startSerializer.parse(d))
491
-
492
- staticClientCache?.set(url, result)
493
- }
494
-
495
- return result
496
- },
497
- })
498
- })
14
+ CompiledFetcherFn,
15
+ CompiledFetcherFnOptions,
16
+ Method,
17
+ MiddlewareFn,
18
+ NextFn,
19
+ ServerFn,
20
+ ServerFnBaseOptions,
21
+ ServerFnBuilder,
22
+ ServerFnMiddlewareOptions,
23
+ ServerFnMiddlewareResult,
24
+ ServerFnResponseType,
25
+ ServerFnType,
26
+ StaticCachedResult,
27
+ } from '@tanstack/start-client-core'
499
28
 
500
29
  export function createServerFn<
501
30
  TMethod extends Method,
@@ -588,6 +117,7 @@ export function createServerFn<
588
117
 
589
118
  // We want to make sure the new function has the same
590
119
  // properties as the original function
120
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
591
121
  return Object.assign(
592
122
  async (opts?: CompiledFetcherFnOptions) => {
593
123
  // Start by executing the client-side middleware chain
@@ -686,144 +216,11 @@ export function createServerFn<
686
216
  }
687
217
  }
688
218
 
689
- function extractFormDataContext(formData: FormData) {
690
- const serializedContext = formData.get('__TSR_CONTEXT')
691
- formData.delete('__TSR_CONTEXT')
692
-
693
- if (typeof serializedContext !== 'string') {
694
- return {
695
- context: {},
696
- data: formData,
697
- }
698
- }
699
-
700
- try {
701
- const context = startSerializer.parse(serializedContext)
702
- return {
703
- context,
704
- data: formData,
705
- }
706
- } catch {
707
- return {
708
- data: formData,
709
- }
710
- }
711
- }
712
-
713
- function flattenMiddlewares(
714
- middlewares: Array<AnyMiddleware>,
715
- ): Array<AnyMiddleware> {
716
- const seen = new Set<AnyMiddleware>()
717
- const flattened: Array<AnyMiddleware> = []
718
-
719
- const recurse = (middleware: Array<AnyMiddleware>) => {
720
- middleware.forEach((m) => {
721
- if (m.options.middleware) {
722
- recurse(m.options.middleware)
723
- }
724
-
725
- if (!seen.has(m)) {
726
- seen.add(m)
727
- flattened.push(m)
728
- }
729
- })
730
- }
731
-
732
- recurse(middlewares)
733
-
734
- return flattened
735
- }
736
-
737
- export type MiddlewareOptions = {
738
- method: Method
739
- response?: ServerFnResponseType
740
- data: any
741
- headers?: HeadersInit
742
- signal?: AbortSignal
743
- sendContext?: any
744
- context?: any
745
- type: ServerFnTypeOrTypeFn<any, any, any, any>
746
- functionId: string
747
- }
748
-
749
- export type MiddlewareResult = MiddlewareOptions & {
750
- result?: unknown
751
- error?: unknown
752
- type: ServerFnTypeOrTypeFn<any, any, any, any>
753
- }
754
-
755
- export type NextFn = (ctx: MiddlewareResult) => Promise<MiddlewareResult>
756
-
757
- export type MiddlewareFn = (
758
- ctx: MiddlewareOptions & {
759
- next: NextFn
760
- },
761
- ) => Promise<MiddlewareResult>
762
-
763
- const applyMiddleware = async (
764
- middlewareFn: MiddlewareFn,
765
- ctx: MiddlewareOptions,
766
- nextFn: NextFn,
767
- ) => {
768
- return middlewareFn({
769
- ...ctx,
770
- next: (async (userCtx: MiddlewareResult | undefined = {} as any) => {
771
- // Return the next middleware
772
- return nextFn({
773
- ...ctx,
774
- ...userCtx,
775
- context: {
776
- ...ctx.context,
777
- ...userCtx.context,
778
- },
779
- sendContext: {
780
- ...ctx.sendContext,
781
- ...(userCtx.sendContext ?? {}),
782
- },
783
- headers: mergeHeaders(ctx.headers, userCtx.headers),
784
- result:
785
- userCtx.result !== undefined
786
- ? userCtx.result
787
- : ctx.response === 'raw'
788
- ? userCtx
789
- : (ctx as any).result,
790
- error: userCtx.error ?? (ctx as any).error,
791
- })
792
- }) as any,
793
- } as any)
794
- }
795
-
796
- function execValidator(validator: AnyValidator, input: unknown): unknown {
797
- if (validator == null) return {}
798
-
799
- if ('~standard' in validator) {
800
- const result = validator['~standard'].validate(input)
801
-
802
- if (result instanceof Promise)
803
- throw new Error('Async validation not supported')
804
-
805
- if (result.issues)
806
- throw new Error(JSON.stringify(result.issues, undefined, 2))
807
-
808
- return result.value
809
- }
810
-
811
- if ('parse' in validator) {
812
- return validator.parse(input)
813
- }
814
-
815
- if (typeof validator === 'function') {
816
- return validator(input)
817
- }
818
-
819
- throw new Error('Invalid validator type!')
820
- }
821
-
822
219
  async function executeMiddleware(
823
220
  middlewares: Array<AnyMiddleware>,
824
221
  env: 'client' | 'server',
825
- opts: MiddlewareOptions,
826
- ): Promise<MiddlewareResult> {
222
+ opts: ServerFnMiddlewareOptions,
223
+ ): Promise<ServerFnMiddlewareResult> {
827
224
  const flattenedMiddlewares = flattenMiddlewares([
828
225
  ...globalMiddleware,
829
226
  ...middlewares,
@@ -846,6 +243,7 @@ async function executeMiddleware(
846
243
  ctx.data = await execValidator(nextMiddleware.options.validator, ctx.data)
847
244
  }
848
245
 
246
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
849
247
  const middlewareFn = (
850
248
  env === 'client'
851
249
  ? nextMiddleware.options.client
@@ -855,7 +253,7 @@ async function executeMiddleware(
855
253
  if (middlewareFn) {
856
254
  // Execute the middleware
857
255
  return applyMiddleware(middlewareFn, ctx, async (newCtx) => {
858
- return next(newCtx).catch((error) => {
256
+ return next(newCtx).catch((error: any) => {
859
257
  if (isRedirect(error) || isNotFound(error)) {
860
258
  return {
861
259
  ...newCtx,
@@ -879,64 +277,3 @@ async function executeMiddleware(
879
277
  context: opts.context || {},
880
278
  })
881
279
  }
882
-
883
- function serverFnBaseToMiddleware(
884
- options: ServerFnBaseOptions<any, any, any, any, any>,
885
- ): AnyMiddleware {
886
- return {
887
- _types: undefined!,
888
- options: {
889
- validator: options.validator,
890
- validateClient: options.validateClient,
891
- client: async ({ next, sendContext, ...ctx }) => {
892
- const payload = {
893
- ...ctx,
894
- // switch the sendContext over to context
895
- context: sendContext,
896
- type: typeof ctx.type === 'function' ? ctx.type(ctx) : ctx.type,
897
- } as any
898
-
899
- if (
900
- ctx.type === 'static' &&
901
- process.env.NODE_ENV === 'production' &&
902
- typeof document !== 'undefined'
903
- ) {
904
- invariant(
905
- serverFnStaticCache,
906
- 'serverFnStaticCache.fetchItem is not available!',
907
- )
908
-
909
- const result = await serverFnStaticCache.fetchItem(payload)
910
-
911
- if (result) {
912
- if (result.error) {
913
- throw result.error
914
- }
915
-
916
- return next(result.ctx)
917
- }
918
-
919
- warning(
920
- result,
921
- `No static cache item found for ${payload.functionId}__${JSON.stringify(payload.data)}, falling back to server function...`,
922
- )
923
- }
924
-
925
- // Execute the extracted function
926
- // but not before serializing the context
927
- const res = await options.extractedFn?.(payload)
928
-
929
- return next(res) as unknown as MiddlewareClientFnResult<any, any, any>
930
- },
931
- server: async ({ next, ...ctx }) => {
932
- // Execute the server function
933
- const result = await options.serverFn?.(ctx)
934
-
935
- return next({
936
- ...ctx,
937
- result,
938
- } as any) as unknown as MiddlewareServerFnResult<any, any, any, any>
939
- },
940
- },
941
- }
942
- }