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