@tanstack/start-client-core 1.132.0-alpha.1 → 1.132.0-alpha.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.
- package/dist/esm/constants.d.ts +5 -0
- package/dist/esm/constants.js +13 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/createClientRpc.d.ts +6 -0
- package/dist/esm/createClientRpc.js +26 -0
- package/dist/esm/createClientRpc.js.map +1 -0
- package/dist/esm/createMiddleware.d.ts +35 -40
- package/dist/esm/createMiddleware.js.map +1 -1
- package/dist/esm/createServerFn.d.ts +46 -58
- package/dist/esm/createServerFn.js +39 -45
- package/dist/esm/createServerFn.js.map +1 -1
- package/dist/esm/envOnly.d.ts +2 -2
- package/dist/esm/envOnly.js +4 -4
- package/dist/esm/envOnly.js.map +1 -1
- package/dist/esm/getRouterInstance.d.ts +1 -0
- package/dist/esm/getRouterInstance.js +7 -0
- package/dist/esm/getRouterInstance.js.map +1 -0
- package/dist/esm/index.d.ts +6 -5
- package/dist/esm/index.js +13 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/serializer/ServerFunctionSerializationAdapter.d.ts +5 -0
- package/dist/esm/serializer/ServerFunctionSerializationAdapter.js +17 -0
- package/dist/esm/serializer/ServerFunctionSerializationAdapter.js.map +1 -0
- package/dist/esm/serializer/getClientSerovalPlugins.d.ts +3 -0
- package/dist/esm/serializer/getClientSerovalPlugins.js +13 -0
- package/dist/esm/serializer/getClientSerovalPlugins.js.map +1 -0
- package/dist/esm/serializer/getDefaultSerovalPlugins.d.ts +1 -0
- package/dist/esm/serializer/getDefaultSerovalPlugins.js +16 -0
- package/dist/esm/serializer/getDefaultSerovalPlugins.js.map +1 -0
- package/dist/esm/serverFnFetcher.d.ts +1 -0
- package/dist/esm/serverFnFetcher.js +217 -0
- package/dist/esm/serverFnFetcher.js.map +1 -0
- package/package.json +5 -4
- package/src/constants.ts +8 -0
- package/src/createClientRpc.ts +26 -0
- package/src/createMiddleware.ts +93 -91
- package/src/createServerFn.ts +158 -206
- package/src/envOnly.ts +2 -2
- package/src/getRouterInstance.ts +7 -0
- package/src/index.tsx +11 -15
- package/src/serializer/ServerFunctionSerializationAdapter.ts +16 -0
- package/src/serializer/getClientSerovalPlugins.ts +10 -0
- package/src/serializer/getDefaultSerovalPlugins.ts +19 -0
- package/src/serverFnFetcher.ts +299 -0
- package/src/tests/createServerFn.test-d.ts +124 -105
- package/src/tests/createServerMiddleware.test-d.ts +11 -9
- package/src/tests/envOnly.test-d.ts +9 -9
- package/dist/esm/serializer.d.ts +0 -23
- package/dist/esm/serializer.js +0 -152
- package/dist/esm/serializer.js.map +0 -1
- package/dist/esm/tests/serializer.test.d.ts +0 -1
- package/src/serializer.ts +0 -206
- package/src/tests/serializer.test.tsx +0 -151
|
@@ -1,48 +1,56 @@
|
|
|
1
1
|
import { isRedirect, isNotFound } from "@tanstack/router-core";
|
|
2
2
|
import { mergeHeaders } from "@tanstack/router-core/ssr/client";
|
|
3
|
-
import { getStartContext } from "@tanstack/start-storage-context";
|
|
4
3
|
import { globalMiddleware } from "./registerGlobalMiddleware.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
const getRouterInstance = createIsomorphicFn().client(() => window.__TSR_ROUTER__).server(() => getStartContext({ throwIfNotFound: false })?.router);
|
|
4
|
+
import { getRouterInstance } from "./getRouterInstance.js";
|
|
5
|
+
import { TSS_SERVER_FUNCTION_FACTORY } from "./constants.js";
|
|
8
6
|
function createServerFn(options, __opts) {
|
|
9
7
|
const resolvedOptions = __opts || options || {};
|
|
10
8
|
if (typeof resolvedOptions.method === "undefined") {
|
|
11
9
|
resolvedOptions.method = "GET";
|
|
12
10
|
}
|
|
13
|
-
|
|
11
|
+
const res = {
|
|
14
12
|
options: resolvedOptions,
|
|
15
13
|
middleware: (middleware) => {
|
|
16
|
-
|
|
14
|
+
const newMiddleware = [...resolvedOptions.middleware || []];
|
|
15
|
+
middleware.map((m) => {
|
|
16
|
+
if (TSS_SERVER_FUNCTION_FACTORY in m) {
|
|
17
|
+
if (m.options.middleware) {
|
|
18
|
+
newMiddleware.push(...m.options.middleware);
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
newMiddleware.push(m);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
const newOptions = {
|
|
25
|
+
...resolvedOptions,
|
|
26
|
+
middleware: newMiddleware
|
|
27
|
+
};
|
|
28
|
+
const res2 = createServerFn(void 0, newOptions);
|
|
29
|
+
res2[TSS_SERVER_FUNCTION_FACTORY] = true;
|
|
30
|
+
return res2;
|
|
17
31
|
},
|
|
18
32
|
validator: (validator) => {
|
|
19
|
-
|
|
33
|
+
const newOptions = { ...resolvedOptions, validator };
|
|
34
|
+
return createServerFn(void 0, newOptions);
|
|
20
35
|
},
|
|
21
36
|
handler: (...args) => {
|
|
22
37
|
const [extractedFn, serverFn] = args;
|
|
23
|
-
|
|
24
|
-
...extractedFn,
|
|
25
|
-
extractedFn,
|
|
26
|
-
serverFn
|
|
27
|
-
});
|
|
38
|
+
const newOptions = { ...resolvedOptions, extractedFn, serverFn };
|
|
28
39
|
const resolvedMiddleware = [
|
|
29
|
-
...
|
|
30
|
-
serverFnBaseToMiddleware(
|
|
40
|
+
...newOptions.middleware || [],
|
|
41
|
+
serverFnBaseToMiddleware(newOptions)
|
|
31
42
|
];
|
|
32
43
|
return Object.assign(
|
|
33
44
|
async (opts) => {
|
|
34
45
|
return executeMiddleware(resolvedMiddleware, "client", {
|
|
35
46
|
...extractedFn,
|
|
36
|
-
...
|
|
47
|
+
...newOptions,
|
|
37
48
|
data: opts?.data,
|
|
38
49
|
headers: opts?.headers,
|
|
39
50
|
signal: opts?.signal,
|
|
40
51
|
context: {},
|
|
41
52
|
router: getRouterInstance()
|
|
42
53
|
}).then((d) => {
|
|
43
|
-
if (resolvedOptions.response === "full") {
|
|
44
|
-
return d;
|
|
45
|
-
}
|
|
46
54
|
if (d.error) throw d.error;
|
|
47
55
|
return d.result;
|
|
48
56
|
});
|
|
@@ -52,8 +60,7 @@ function createServerFn(options, __opts) {
|
|
|
52
60
|
...extractedFn,
|
|
53
61
|
// The extracted function on the server-side calls
|
|
54
62
|
// this function
|
|
55
|
-
__executeServer: async (
|
|
56
|
-
const opts = opts_ instanceof FormData ? extractFormDataContext(opts_) : opts_;
|
|
63
|
+
__executeServer: async (opts, signal) => {
|
|
57
64
|
const ctx = {
|
|
58
65
|
...extractedFn,
|
|
59
66
|
...opts,
|
|
@@ -72,6 +79,16 @@ function createServerFn(options, __opts) {
|
|
|
72
79
|
);
|
|
73
80
|
}
|
|
74
81
|
};
|
|
82
|
+
const fun = (options2) => {
|
|
83
|
+
return {
|
|
84
|
+
...res,
|
|
85
|
+
options: {
|
|
86
|
+
...res.options,
|
|
87
|
+
...options2
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
return Object.assign(fun, res);
|
|
75
92
|
}
|
|
76
93
|
async function executeMiddleware(middlewares, env, opts) {
|
|
77
94
|
const flattenedMiddlewares = flattenMiddlewares([
|
|
@@ -83,7 +100,7 @@ async function executeMiddleware(middlewares, env, opts) {
|
|
|
83
100
|
if (!nextMiddleware) {
|
|
84
101
|
return ctx;
|
|
85
102
|
}
|
|
86
|
-
if (nextMiddleware.options.validator &&
|
|
103
|
+
if (nextMiddleware.options.validator && env === "server") {
|
|
87
104
|
ctx.data = await execValidator(nextMiddleware.options.validator, ctx.data);
|
|
88
105
|
}
|
|
89
106
|
const middlewareFn = env === "client" ? nextMiddleware.options.client : nextMiddleware.options.server;
|
|
@@ -109,27 +126,6 @@ async function executeMiddleware(middlewares, env, opts) {
|
|
|
109
126
|
context: opts.context || {}
|
|
110
127
|
});
|
|
111
128
|
}
|
|
112
|
-
function extractFormDataContext(formData) {
|
|
113
|
-
const serializedContext = formData.get("__TSR_CONTEXT");
|
|
114
|
-
formData.delete("__TSR_CONTEXT");
|
|
115
|
-
if (typeof serializedContext !== "string") {
|
|
116
|
-
return {
|
|
117
|
-
context: {},
|
|
118
|
-
data: formData
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
const context = startSerializer.parse(serializedContext);
|
|
123
|
-
return {
|
|
124
|
-
context,
|
|
125
|
-
data: formData
|
|
126
|
-
};
|
|
127
|
-
} catch {
|
|
128
|
-
return {
|
|
129
|
-
data: formData
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
129
|
function flattenMiddlewares(middlewares) {
|
|
134
130
|
const seen = /* @__PURE__ */ new Set();
|
|
135
131
|
const flattened = [];
|
|
@@ -163,7 +159,7 @@ const applyMiddleware = async (middlewareFn, ctx, nextFn) => {
|
|
|
163
159
|
...userCtx.sendContext ?? {}
|
|
164
160
|
},
|
|
165
161
|
headers: mergeHeaders(ctx.headers, userCtx.headers),
|
|
166
|
-
result: userCtx.result !== void 0 ? userCtx.result :
|
|
162
|
+
result: userCtx.result !== void 0 ? userCtx.result : userCtx instanceof Response ? userCtx : ctx.result,
|
|
167
163
|
error: userCtx.error ?? ctx.error
|
|
168
164
|
});
|
|
169
165
|
}
|
|
@@ -192,7 +188,6 @@ function serverFnBaseToMiddleware(options) {
|
|
|
192
188
|
_types: void 0,
|
|
193
189
|
options: {
|
|
194
190
|
validator: options.validator,
|
|
195
|
-
validateClient: options.validateClient,
|
|
196
191
|
client: async ({ next, sendContext, ...ctx }) => {
|
|
197
192
|
const payload = {
|
|
198
193
|
...ctx,
|
|
@@ -217,7 +212,6 @@ export {
|
|
|
217
212
|
createServerFn,
|
|
218
213
|
execValidator,
|
|
219
214
|
executeMiddleware,
|
|
220
|
-
extractFormDataContext,
|
|
221
215
|
flattenMiddlewares,
|
|
222
216
|
serverFnBaseToMiddleware
|
|
223
217
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createServerFn.js","sources":["../../src/createServerFn.ts"],"sourcesContent":["import { isNotFound, isRedirect } from '@tanstack/router-core'\nimport { mergeHeaders } from '@tanstack/router-core/ssr/client'\nimport { getStartContext } from '@tanstack/start-storage-context'\nimport { globalMiddleware } from './registerGlobalMiddleware'\n\nimport { startSerializer } from './serializer'\n\nimport { createIsomorphicFn } from './createIsomorphicFn'\nimport type {\n SerializerParse,\n SerializerStringify,\n SerializerStringifyBy,\n} from './serializer'\nimport type {\n AnyRouter,\n AnyValidator,\n Constrain,\n Expand,\n ResolveValidatorInput,\n Validator,\n} from '@tanstack/router-core'\nimport type { JsonResponse } from '@tanstack/router-core/ssr/client'\nimport type { Readable } from 'node:stream'\nimport type {\n AnyFunctionMiddleware,\n AssignAllClientSendContext,\n AssignAllServerContext,\n FunctionMiddlewareClientFnResult,\n FunctionMiddlewareServerFnResult,\n IntersectAllValidatorInputs,\n IntersectAllValidatorOutputs,\n} from './createMiddleware'\n\ntype TODO = any\n\nconst getRouterInstance = createIsomorphicFn()\n .client(() => window.__TSR_ROUTER__!)\n .server(() => getStartContext({ throwIfNotFound: false })?.router)\n\nexport function createServerFn<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType = 'data',\n TResponse = unknown,\n TMiddlewares = undefined,\n TValidator = undefined,\n>(\n options?: {\n method?: TMethod\n response?: TServerFnResponseType\n },\n __opts?: ServerFnBaseOptions<\n TMethod,\n TServerFnResponseType,\n TResponse,\n TMiddlewares,\n TValidator\n >,\n): ServerFnBuilder<TMethod, TServerFnResponseType> {\n const resolvedOptions = (__opts || options || {}) as ServerFnBaseOptions<\n TMethod,\n ServerFnResponseType,\n TResponse,\n TMiddlewares,\n TValidator\n >\n\n if (typeof resolvedOptions.method === 'undefined') {\n resolvedOptions.method = 'GET' as TMethod\n }\n\n return {\n options: resolvedOptions as any,\n middleware: (middleware) => {\n return createServerFn<\n TMethod,\n ServerFnResponseType,\n TResponse,\n TMiddlewares,\n TValidator\n >(undefined, Object.assign(resolvedOptions, { middleware })) as any\n },\n validator: (validator) => {\n return createServerFn<\n TMethod,\n ServerFnResponseType,\n TResponse,\n TMiddlewares,\n TValidator\n >(undefined, Object.assign(resolvedOptions, { validator })) as any\n },\n handler: (...args) => {\n // This function signature changes due to AST transformations\n // in the babel plugin. We need to cast it to the correct\n // function signature post-transformation\n const [extractedFn, serverFn] = args as unknown as [\n CompiledFetcherFn<TResponse, TServerFnResponseType>,\n ServerFn<\n TMethod,\n TServerFnResponseType,\n TMiddlewares,\n TValidator,\n TResponse\n >,\n ]\n\n // Keep the original function around so we can use it\n // in the server environment\n Object.assign(resolvedOptions, {\n ...extractedFn,\n extractedFn,\n serverFn,\n })\n\n const resolvedMiddleware = [\n ...(resolvedOptions.middleware || []),\n serverFnBaseToMiddleware(resolvedOptions),\n ]\n\n // We want to make sure the new function has the same\n // properties as the original function\n\n return Object.assign(\n async (opts?: CompiledFetcherFnOptions) => {\n // Start by executing the client-side middleware chain\n return executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...resolvedOptions,\n data: opts?.data as any,\n headers: opts?.headers,\n signal: opts?.signal,\n context: {},\n router: getRouterInstance(),\n }).then((d) => {\n if (resolvedOptions.response === 'full') {\n return d\n }\n if (d.error) throw d.error\n return d.result\n })\n },\n {\n // This copies over the URL, function ID\n ...extractedFn,\n // The extracted function on the server-side calls\n // this function\n __executeServer: async (opts_: any, signal: AbortSignal) => {\n const opts =\n opts_ instanceof FormData ? extractFormDataContext(opts_) : opts_\n\n const ctx = {\n ...extractedFn,\n ...opts,\n signal,\n }\n\n return executeMiddleware(resolvedMiddleware, 'server', ctx).then(\n (d) => ({\n // Only send the result and sendContext back to the client\n result: d.result,\n error: d.error,\n context: d.sendContext,\n }),\n )\n },\n },\n ) as any\n },\n }\n}\n\nexport async function executeMiddleware(\n middlewares: Array<AnyFunctionMiddleware>,\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> {\n const flattenedMiddlewares = flattenMiddlewares([\n ...globalMiddleware,\n ...middlewares,\n ])\n\n const next: NextFn = async (ctx) => {\n // Get the next middleware\n const nextMiddleware = flattenedMiddlewares.shift()\n\n // If there are no more middlewares, return the context\n if (!nextMiddleware) {\n return ctx\n }\n\n if (\n nextMiddleware.options.validator &&\n (env === 'client' ? nextMiddleware.options.validateClient : true)\n ) {\n // Execute the middleware's input function\n ctx.data = await execValidator(nextMiddleware.options.validator, ctx.data)\n }\n\n const middlewareFn = (\n env === 'client'\n ? nextMiddleware.options.client\n : nextMiddleware.options.server\n ) as MiddlewareFn | undefined\n\n if (middlewareFn) {\n // Execute the middleware\n return applyMiddleware(middlewareFn, ctx, async (newCtx) => {\n return next(newCtx).catch((error: any) => {\n if (isRedirect(error) || isNotFound(error)) {\n return {\n ...newCtx,\n error,\n }\n }\n\n throw error\n })\n })\n }\n\n return next(ctx)\n }\n\n // Start the middleware chain\n return next({\n ...opts,\n headers: opts.headers || {},\n sendContext: opts.sendContext || {},\n context: opts.context || {},\n })\n}\n\nexport type CompiledFetcherFnOptions = {\n method: Method\n data: unknown\n response?: ServerFnResponseType\n headers?: HeadersInit\n signal?: AbortSignal\n context?: any\n // router?: AnyRouter\n}\n\nexport type Fetcher<\n TMiddlewares,\n TValidator,\n TResponse,\n TServerFnResponseType extends ServerFnResponseType,\n> =\n undefined extends IntersectAllValidatorInputs<TMiddlewares, TValidator>\n ? OptionalFetcher<\n TMiddlewares,\n TValidator,\n TResponse,\n TServerFnResponseType\n >\n : RequiredFetcher<\n TMiddlewares,\n TValidator,\n TResponse,\n TServerFnResponseType\n >\n\nexport interface FetcherBase {\n url: string\n __executeServer: (opts: {\n method: Method\n response?: ServerFnResponseType\n data: unknown\n headers?: HeadersInit\n context?: any\n signal: AbortSignal\n }) => Promise<unknown>\n}\n\nexport type FetchResult<\n TMiddlewares,\n TResponse,\n TServerFnResponseType extends ServerFnResponseType,\n> = TServerFnResponseType extends 'raw'\n ? Promise<Response>\n : TServerFnResponseType extends 'full'\n ? Promise<FullFetcherData<TMiddlewares, TResponse>>\n : Promise<FetcherData<TResponse>>\n\nexport interface OptionalFetcher<\n TMiddlewares,\n TValidator,\n TResponse,\n TServerFnResponseType extends ServerFnResponseType,\n> extends FetcherBase {\n (\n options?: OptionalFetcherDataOptions<TMiddlewares, TValidator>,\n ): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>\n}\n\nexport interface RequiredFetcher<\n TMiddlewares,\n TValidator,\n TResponse,\n TServerFnResponseType extends ServerFnResponseType,\n> extends FetcherBase {\n (\n opts: RequiredFetcherDataOptions<TMiddlewares, TValidator>,\n ): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>\n}\n\nexport type FetcherBaseOptions = {\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport interface OptionalFetcherDataOptions<TMiddlewares, TValidator>\n extends FetcherBaseOptions {\n data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>\n}\n\nexport interface RequiredFetcherDataOptions<TMiddlewares, TValidator>\n extends FetcherBaseOptions {\n data: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>\n}\n\nexport interface FullFetcherData<TMiddlewares, TResponse> {\n error: unknown\n result: FetcherData<TResponse>\n context: AssignAllClientSendContext<TMiddlewares>\n}\n\nexport type FetcherData<TResponse> =\n TResponse extends JsonResponse<any>\n ? SerializerParse<ReturnType<TResponse['json']>>\n : SerializerParse<TResponse>\n\nexport type RscStream<T> = {\n __cacheState: T\n}\n\nexport type Method = 'GET' | 'POST'\nexport type ServerFnResponseType = 'data' | 'full' | 'raw'\n\n// see https://h3.unjs.io/guide/event-handler#responses-types\nexport type RawResponse = Response | ReadableStream | Readable | null | string\n\nexport type ServerFnReturnType<\n TServerFnResponseType extends ServerFnResponseType,\n TResponse,\n> = TServerFnResponseType extends 'raw'\n ? RawResponse | Promise<RawResponse>\n : Promise<SerializerStringify<TResponse>> | SerializerStringify<TResponse>\n\nexport type ServerFn<\n TMethod,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n TResponse,\n> = (\n ctx: ServerFnCtx<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,\n) => ServerFnReturnType<TServerFnResponseType, TResponse>\n\nexport interface ServerFnCtx<\n TMethod,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n> {\n method: TMethod\n response: TServerFnResponseType\n data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TValidator>>\n context: Expand<AssignAllServerContext<TMiddlewares>>\n signal: AbortSignal\n}\n\nexport type CompiledFetcherFn<\n TResponse,\n TServerFnResponseType extends ServerFnResponseType,\n> = {\n (\n opts: CompiledFetcherFnOptions &\n ServerFnBaseOptions<Method, TServerFnResponseType>,\n ): Promise<TResponse>\n url: string\n}\n\nexport type ServerFnBaseOptions<\n TMethod extends Method = 'GET',\n TServerFnResponseType extends ServerFnResponseType = 'data',\n TResponse = unknown,\n TMiddlewares = unknown,\n TInput = unknown,\n> = {\n method: TMethod\n response?: TServerFnResponseType\n validateClient?: boolean\n middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyFunctionMiddleware>>\n validator?: ConstrainValidator<TInput>\n extractedFn?: CompiledFetcherFn<TResponse, TServerFnResponseType>\n serverFn?: ServerFn<\n TMethod,\n TServerFnResponseType,\n TMiddlewares,\n TInput,\n TResponse\n >\n functionId: string\n}\n\nexport type ValidatorInputStringify<TValidator> = SerializerStringifyBy<\n ResolveValidatorInput<TValidator>,\n Date | undefined | FormData\n>\n\nexport type ValidatorSerializerStringify<TValidator> =\n ValidatorInputStringify<TValidator> extends infer TInput\n ? Validator<TInput, any>\n : never\n\nexport type ConstrainValidator<TValidator> =\n | (unknown extends TValidator\n ? TValidator\n : ResolveValidatorInput<TValidator> extends ValidatorInputStringify<TValidator>\n ? TValidator\n : never)\n | ValidatorSerializerStringify<TValidator>\n\nexport interface ServerFnMiddleware<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TValidator,\n> {\n middleware: <const TNewMiddlewares = undefined>(\n middlewares: Constrain<\n TNewMiddlewares,\n ReadonlyArray<AnyFunctionMiddleware>\n >,\n ) => ServerFnAfterMiddleware<\n TMethod,\n TServerFnResponseType,\n TNewMiddlewares,\n TValidator\n >\n}\n\nexport interface ServerFnAfterMiddleware<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n> extends ServerFnValidator<TMethod, TServerFnResponseType, TMiddlewares>,\n ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}\n\nexport type ValidatorFn<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n> = <TValidator>(\n validator: ConstrainValidator<TValidator>,\n) => ServerFnAfterValidator<\n TMethod,\n TServerFnResponseType,\n TMiddlewares,\n TValidator\n>\n\nexport interface ServerFnValidator<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n> {\n validator: ValidatorFn<TMethod, TServerFnResponseType, TMiddlewares>\n}\n\nexport interface ServerFnAfterValidator<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n> extends ServerFnMiddleware<TMethod, TServerFnResponseType, TValidator>,\n ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}\n\nexport interface ServerFnAfterTyper<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n> extends ServerFnHandler<\n TMethod,\n TServerFnResponseType,\n TMiddlewares,\n TValidator\n > {}\n\n// Handler\nexport interface ServerFnHandler<\n TMethod extends Method,\n TServerFnResponseType extends ServerFnResponseType,\n TMiddlewares,\n TValidator,\n> {\n handler: <TNewResponse>(\n fn?: ServerFn<\n TMethod,\n TServerFnResponseType,\n TMiddlewares,\n TValidator,\n TNewResponse\n >,\n ) => Fetcher<TMiddlewares, TValidator, TNewResponse, TServerFnResponseType>\n}\n\nexport interface ServerFnBuilder<\n TMethod extends Method = 'GET',\n TServerFnResponseType extends ServerFnResponseType = 'data',\n> extends ServerFnMiddleware<TMethod, TServerFnResponseType, undefined>,\n ServerFnValidator<TMethod, TServerFnResponseType, undefined>,\n ServerFnHandler<TMethod, TServerFnResponseType, undefined, undefined> {\n options: ServerFnBaseOptions<\n TMethod,\n TServerFnResponseType,\n unknown,\n undefined,\n undefined\n >\n}\n\nexport function extractFormDataContext(formData: FormData) {\n const serializedContext = formData.get('__TSR_CONTEXT')\n formData.delete('__TSR_CONTEXT')\n\n if (typeof serializedContext !== 'string') {\n return {\n context: {},\n data: formData,\n }\n }\n\n try {\n const context = startSerializer.parse(serializedContext)\n return {\n context,\n data: formData,\n }\n } catch {\n return {\n data: formData,\n }\n }\n}\n\nexport function flattenMiddlewares(\n middlewares: Array<AnyFunctionMiddleware>,\n): Array<AnyFunctionMiddleware> {\n const seen = new Set<AnyFunctionMiddleware>()\n const flattened: Array<AnyFunctionMiddleware> = []\n\n const recurse = (middleware: Array<AnyFunctionMiddleware>) => {\n middleware.forEach((m) => {\n if (m.options.middleware) {\n recurse(m.options.middleware)\n }\n\n if (!seen.has(m)) {\n seen.add(m)\n flattened.push(m)\n }\n })\n }\n\n recurse(middlewares)\n\n return flattened\n}\n\nexport type ServerFnMiddlewareOptions = {\n method: Method\n response?: ServerFnResponseType\n data: any\n headers?: HeadersInit\n signal?: AbortSignal\n sendContext?: any\n context?: any\n functionId: string\n router?: AnyRouter\n}\n\nexport type ServerFnMiddlewareResult = ServerFnMiddlewareOptions & {\n result?: unknown\n error?: unknown\n}\n\nexport type NextFn = (\n ctx: ServerFnMiddlewareResult,\n) => Promise<ServerFnMiddlewareResult>\n\nexport type MiddlewareFn = (\n ctx: ServerFnMiddlewareOptions & {\n next: NextFn\n },\n) => Promise<ServerFnMiddlewareResult>\n\nexport const applyMiddleware = async (\n middlewareFn: MiddlewareFn,\n ctx: ServerFnMiddlewareOptions,\n nextFn: NextFn,\n) => {\n return middlewareFn({\n ...ctx,\n next: (async (\n userCtx: ServerFnMiddlewareResult | undefined = {} as any,\n ) => {\n // Return the next middleware\n return nextFn({\n ...ctx,\n ...userCtx,\n context: {\n ...ctx.context,\n ...userCtx.context,\n },\n sendContext: {\n ...ctx.sendContext,\n ...(userCtx.sendContext ?? {}),\n },\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n result:\n userCtx.result !== undefined\n ? userCtx.result\n : ctx.response === 'raw'\n ? userCtx\n : (ctx as any).result,\n error: userCtx.error ?? (ctx as any).error,\n })\n }) as any,\n } as any)\n}\n\nexport function execValidator(\n validator: AnyValidator,\n input: unknown,\n): unknown {\n if (validator == null) return {}\n\n if ('~standard' in validator) {\n const result = validator['~standard'].validate(input)\n\n if (result instanceof Promise)\n throw new Error('Async validation not supported')\n\n if (result.issues)\n throw new Error(JSON.stringify(result.issues, undefined, 2))\n\n return result.value\n }\n\n if ('parse' in validator) {\n return validator.parse(input)\n }\n\n if (typeof validator === 'function') {\n return validator(input)\n }\n\n throw new Error('Invalid validator type!')\n}\n\nexport function serverFnBaseToMiddleware(\n options: ServerFnBaseOptions<any, any, any, any, any>,\n): AnyFunctionMiddleware {\n return {\n _types: undefined!,\n options: {\n validator: options.validator,\n validateClient: options.validateClient,\n client: async ({ next, sendContext, ...ctx }) => {\n const payload = {\n ...ctx,\n // switch the sendContext over to context\n context: sendContext,\n } as any\n\n // Execute the extracted function\n // but not before serializing the context\n const res = await options.extractedFn?.(payload)\n\n return next(res) as unknown as FunctionMiddlewareClientFnResult<\n any,\n any,\n any\n >\n },\n server: async ({ next, ...ctx }) => {\n // Execute the server function\n const result = await options.serverFn?.(ctx as TODO)\n\n return next({\n ...ctx,\n result,\n } as any) as unknown as FunctionMiddlewareServerFnResult<\n any,\n any,\n any,\n any\n >\n },\n },\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createServerFn.js","sources":["../../src/createServerFn.ts"],"sourcesContent":["import { isNotFound, isRedirect } from '@tanstack/router-core'\nimport { mergeHeaders } from '@tanstack/router-core/ssr/client'\nimport { globalMiddleware } from './registerGlobalMiddleware'\n\nimport { getRouterInstance } from './getRouterInstance'\nimport { TSS_SERVER_FUNCTION_FACTORY } from './constants'\nimport type {\n AnyRouter,\n AnyValidator,\n Constrain,\n Expand,\n Register,\n RegisteredSerializableInput,\n ResolveValidatorInput,\n ValidateSerializable,\n ValidateSerializableInput,\n ValidateSerializableInputResult,\n Validator,\n} from '@tanstack/router-core'\nimport type { JsonResponse } from '@tanstack/router-core/ssr/client'\nimport type {\n AnyFunctionMiddleware,\n AssignAllServerContext,\n FunctionMiddlewareClientFnResult,\n FunctionMiddlewareServerFnResult,\n IntersectAllValidatorInputs,\n IntersectAllValidatorOutputs,\n} from './createMiddleware'\n\ntype TODO = any\n\nexport function createServerFn<\n TRegister extends Register,\n TMethod extends Method,\n TResponse = unknown,\n TMiddlewares = undefined,\n TValidator = undefined,\n>(\n options?: {\n method?: TMethod\n },\n __opts?: ServerFnBaseOptions<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TValidator\n >,\n): ServerFnBuilder<TRegister, TMethod> {\n const resolvedOptions = (__opts || options || {}) as ServerFnBaseOptions<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TValidator\n >\n\n if (typeof resolvedOptions.method === 'undefined') {\n resolvedOptions.method = 'GET' as TMethod\n }\n\n const res: ServerFnBuilder<TRegister, TMethod> = {\n options: resolvedOptions as any,\n middleware: (middleware) => {\n // multiple calls to `middleware()` merge the middlewares with the previously supplied ones\n // this is primarily useful for letting users create their own abstractions on top of `createServerFn`\n\n const newMiddleware = [...(resolvedOptions.middleware || [])]\n middleware.map((m) => {\n if (TSS_SERVER_FUNCTION_FACTORY in m) {\n if (m.options.middleware) {\n newMiddleware.push(...m.options.middleware)\n }\n } else {\n newMiddleware.push(m)\n }\n })\n\n const newOptions = {\n ...resolvedOptions,\n middleware: newMiddleware,\n }\n const res = createServerFn<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TValidator\n >(undefined, newOptions) as any\n res[TSS_SERVER_FUNCTION_FACTORY] = true\n return res\n },\n validator: (validator) => {\n const newOptions = { ...resolvedOptions, validator: validator as any }\n return createServerFn<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TValidator\n >(undefined, newOptions) as any\n },\n handler: (...args) => {\n // This function signature changes due to AST transformations\n // in the babel plugin. We need to cast it to the correct\n // function signature post-transformation\n const [extractedFn, serverFn] = args as unknown as [\n CompiledFetcherFn<TRegister, TResponse>,\n ServerFn<TRegister, TMethod, TMiddlewares, TValidator, TResponse>,\n ]\n\n // Keep the original function around so we can use it\n // in the server environment\n const newOptions = { ...resolvedOptions, extractedFn, serverFn }\n\n const resolvedMiddleware = [\n ...(newOptions.middleware || []),\n serverFnBaseToMiddleware(newOptions),\n ]\n\n // We want to make sure the new function has the same\n // properties as the original function\n\n return Object.assign(\n async (opts?: CompiledFetcherFnOptions) => {\n // Start by executing the client-side middleware chain\n return executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...newOptions,\n data: opts?.data as any,\n headers: opts?.headers,\n signal: opts?.signal,\n context: {},\n router: getRouterInstance(),\n }).then((d) => {\n if (d.error) throw d.error\n return d.result\n })\n },\n {\n // This copies over the URL, function ID\n ...extractedFn,\n // The extracted function on the server-side calls\n // this function\n __executeServer: async (opts: any, signal: AbortSignal) => {\n const ctx = {\n ...extractedFn,\n ...opts,\n signal,\n }\n\n return executeMiddleware(resolvedMiddleware, 'server', ctx).then(\n (d) => ({\n // Only send the result and sendContext back to the client\n result: d.result,\n error: d.error,\n context: d.sendContext,\n }),\n )\n },\n },\n ) as any\n },\n }\n const fun = (options?: { method?: TMethod }) => {\n return {\n ...res,\n options: {\n ...res.options,\n ...options,\n },\n }\n }\n return Object.assign(fun, res)\n}\n\nexport async function executeMiddleware(\n middlewares: Array<AnyFunctionMiddleware>,\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> {\n const flattenedMiddlewares = flattenMiddlewares([\n ...globalMiddleware,\n ...middlewares,\n ])\n\n const next: NextFn = async (ctx) => {\n // Get the next middleware\n const nextMiddleware = flattenedMiddlewares.shift()\n\n // If there are no more middlewares, return the context\n if (!nextMiddleware) {\n return ctx\n }\n\n if (nextMiddleware.options.validator && env === 'server') {\n // Execute the middleware's input function\n ctx.data = await execValidator(nextMiddleware.options.validator, ctx.data)\n }\n\n const middlewareFn = (\n env === 'client'\n ? nextMiddleware.options.client\n : nextMiddleware.options.server\n ) as MiddlewareFn | undefined\n\n if (middlewareFn) {\n // Execute the middleware\n return applyMiddleware(middlewareFn, ctx, async (newCtx) => {\n return next(newCtx).catch((error: any) => {\n if (isRedirect(error) || isNotFound(error)) {\n return {\n ...newCtx,\n error,\n }\n }\n\n throw error\n })\n })\n }\n\n return next(ctx)\n }\n\n // Start the middleware chain\n return next({\n ...opts,\n headers: opts.headers || {},\n sendContext: opts.sendContext || {},\n context: opts.context || {},\n })\n}\n\nexport type CompiledFetcherFnOptions = {\n method: Method\n data: unknown\n headers?: HeadersInit\n signal?: AbortSignal\n context?: any\n // router?: AnyRouter\n}\n\nexport type Fetcher<\n TRegister extends Register,\n TMiddlewares,\n TValidator,\n TResponse,\n> =\n undefined extends IntersectAllValidatorInputs<TMiddlewares, TValidator>\n ? OptionalFetcher<TRegister, TMiddlewares, TValidator, TResponse>\n : RequiredFetcher<TRegister, TMiddlewares, TValidator, TResponse>\n\nexport interface FetcherBase {\n url: string\n __executeServer: (opts: {\n method: Method\n data: unknown\n headers?: HeadersInit\n context?: any\n signal: AbortSignal\n }) => Promise<unknown>\n}\n\nexport interface OptionalFetcher<\n TRegister extends Register,\n TMiddlewares,\n TValidator,\n TResponse,\n> extends FetcherBase {\n (\n options?: OptionalFetcherDataOptions<TMiddlewares, TValidator>,\n ): Promise<FetcherData<TRegister, TResponse>>\n}\n\nexport interface RequiredFetcher<\n TRegister extends Register,\n TMiddlewares,\n TValidator,\n TResponse,\n> extends FetcherBase {\n (\n opts: RequiredFetcherDataOptions<TMiddlewares, TValidator>,\n ): Promise<FetcherData<TRegister, TResponse>>\n}\n\nexport type FetcherBaseOptions = {\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport interface OptionalFetcherDataOptions<TMiddlewares, TValidator>\n extends FetcherBaseOptions {\n data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>\n}\n\nexport interface RequiredFetcherDataOptions<TMiddlewares, TValidator>\n extends FetcherBaseOptions {\n data: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>\n}\n\nexport type FetcherData<\n TRegister extends Register,\n TResponse,\n> = TResponse extends Response\n ? Response\n : TResponse extends JsonResponse<any>\n ? ValidateSerializableInputResult<TRegister, ReturnType<TResponse['json']>>\n : ValidateSerializableInputResult<TRegister, TResponse>\n\nexport type RscStream<T> = {\n __cacheState: T\n}\n\nexport type Method = 'GET' | 'POST'\n\nexport type ServerFnReturnType<TRegister extends Register, TResponse> =\n | Response\n | Promise<ValidateSerializableInput<TRegister, TResponse>>\n | ValidateSerializableInput<TRegister, TResponse>\n\nexport type ServerFn<\n TRegister extends Register,\n TMethod,\n TMiddlewares,\n TValidator,\n TResponse,\n> = (\n ctx: ServerFnCtx<TMethod, TMiddlewares, TValidator>,\n) => ServerFnReturnType<TRegister, TResponse>\n\nexport interface ServerFnCtx<TMethod, TMiddlewares, TValidator> {\n method: TMethod\n data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TValidator>>\n context: Expand<AssignAllServerContext<TMiddlewares>>\n signal: AbortSignal\n}\n\nexport type CompiledFetcherFn<TRegister extends Register, TResponse> = {\n (\n opts: CompiledFetcherFnOptions & ServerFnBaseOptions<TRegister, Method>,\n ): Promise<TResponse>\n url: string\n}\n\nexport type ServerFnBaseOptions<\n TRegister extends Register,\n TMethod extends Method = 'GET',\n TResponse = unknown,\n TMiddlewares = unknown,\n TInput = unknown,\n> = {\n method: TMethod\n middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyFunctionMiddleware>>\n validator?: ConstrainValidator<TRegister, TInput>\n extractedFn?: CompiledFetcherFn<TRegister, TResponse>\n serverFn?: ServerFn<TRegister, TMethod, TMiddlewares, TInput, TResponse>\n functionId: string\n}\n\nexport type ValidateValidatorInput<\n TRegister extends Register,\n TValidator,\n> = ValidateSerializable<\n ResolveValidatorInput<TValidator>,\n RegisteredSerializableInput<TRegister> | FormData\n>\n\nexport type ValidateValidator<TRegister extends Register, TValidator> =\n ValidateValidatorInput<TRegister, TValidator> extends infer TInput\n ? Validator<TInput, any>\n : never\n\nexport type ConstrainValidator<TRegister extends Register, TValidator> =\n | (unknown extends TValidator\n ? TValidator\n : ResolveValidatorInput<TValidator> extends ValidateValidator<\n TRegister,\n TValidator\n >\n ? TValidator\n : never)\n | ValidateValidator<TRegister, TValidator>\n\ntype ToTuple<T> = T extends undefined\n ? []\n : T extends ReadonlyArray<any>\n ? T\n : [T]\n\ntype ExtractMiddlewareArray<T> = T extends readonly [infer Head, ...infer Tail]\n ? Head extends ServerFnAfterMiddleware<\n any,\n any,\n infer TMiddlewares extends ReadonlyArray<unknown>,\n any\n >\n ? [...TMiddlewares, ...ExtractMiddlewareArray<Tail>]\n : [Head, ...ExtractMiddlewareArray<Tail>]\n : []\n\nexport interface ServerFnMiddleware<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n TValidator,\n> {\n middleware: <const TNewMiddlewares>(\n middlewares: Constrain<\n TNewMiddlewares,\n ReadonlyArray<\n AnyFunctionMiddleware | ServerFnAfterMiddleware<any, any, any, any>\n >\n >,\n ) => ServerFnAfterMiddleware<\n TRegister,\n TMethod,\n [...ToTuple<TMiddlewares>, ...ExtractMiddlewareArray<TNewMiddlewares>],\n TValidator\n >\n}\n\nexport interface ServerFnAfterMiddleware<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n TValidator,\n> extends ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined>,\n ServerFnValidator<TRegister, TMethod, TMiddlewares>,\n ServerFnHandler<TRegister, TMethod, TMiddlewares, TValidator> {\n <TNewMethod extends Method = TMethod>(options?: {\n method?: TNewMethod\n }): ServerFnAfterMiddleware<TRegister, TNewMethod, TMiddlewares, TValidator>\n options: ServerFnBaseOptions<\n TRegister,\n TMethod,\n unknown,\n TMiddlewares,\n TValidator\n >\n [TSS_SERVER_FUNCTION_FACTORY]: true\n}\n\nexport type ValidatorFn<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n> = <TValidator>(\n validator: ConstrainValidator<TRegister, TValidator>,\n) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TValidator>\n\nexport interface ServerFnValidator<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n> {\n validator: ValidatorFn<TRegister, TMethod, TMiddlewares>\n}\n\nexport interface ServerFnAfterValidator<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n TValidator,\n> extends ServerFnMiddleware<TRegister, TMethod, TMiddlewares, TValidator>,\n ServerFnHandler<TRegister, TMethod, TMiddlewares, TValidator> {}\n\nexport interface ServerFnAfterTyper<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n TValidator,\n> extends ServerFnHandler<TRegister, TMethod, TMiddlewares, TValidator> {}\n\n// Handler\nexport interface ServerFnHandler<\n TRegister extends Register,\n TMethod extends Method,\n TMiddlewares,\n TValidator,\n> {\n handler: <TNewResponse>(\n fn?: ServerFn<TRegister, TMethod, TMiddlewares, TValidator, TNewResponse>,\n ) => Fetcher<TRegister, TMiddlewares, TValidator, TNewResponse>\n}\n\nexport interface ServerFnBuilder<\n TRegister extends Register,\n TMethod extends Method = 'GET',\n> extends ServerFnMiddleware<TRegister, TMethod, undefined, undefined>,\n ServerFnValidator<TRegister, TMethod, undefined>,\n ServerFnHandler<TRegister, TMethod, undefined, undefined> {\n options: ServerFnBaseOptions<\n TRegister,\n TMethod,\n unknown,\n undefined,\n undefined\n >\n}\n\nexport function flattenMiddlewares(\n middlewares: Array<AnyFunctionMiddleware>,\n): Array<AnyFunctionMiddleware> {\n const seen = new Set<AnyFunctionMiddleware>()\n const flattened: Array<AnyFunctionMiddleware> = []\n\n const recurse = (middleware: Array<AnyFunctionMiddleware>) => {\n middleware.forEach((m) => {\n if (m.options.middleware) {\n recurse(m.options.middleware)\n }\n\n if (!seen.has(m)) {\n seen.add(m)\n flattened.push(m)\n }\n })\n }\n\n recurse(middlewares)\n\n return flattened\n}\n\nexport type ServerFnMiddlewareOptions = {\n method: Method\n data: any\n headers?: HeadersInit\n signal?: AbortSignal\n sendContext?: any\n context?: any\n functionId: string\n router?: AnyRouter\n}\n\nexport type ServerFnMiddlewareResult = ServerFnMiddlewareOptions & {\n result?: unknown\n error?: unknown\n}\n\nexport type NextFn = (\n ctx: ServerFnMiddlewareResult,\n) => Promise<ServerFnMiddlewareResult>\n\nexport type MiddlewareFn = (\n ctx: ServerFnMiddlewareOptions & {\n next: NextFn\n },\n) => Promise<ServerFnMiddlewareResult>\n\nexport const applyMiddleware = async (\n middlewareFn: MiddlewareFn,\n ctx: ServerFnMiddlewareOptions,\n nextFn: NextFn,\n) => {\n return middlewareFn({\n ...ctx,\n next: (async (\n userCtx: ServerFnMiddlewareResult | undefined = {} as any,\n ) => {\n // Return the next middleware\n return nextFn({\n ...ctx,\n ...userCtx,\n context: {\n ...ctx.context,\n ...userCtx.context,\n },\n sendContext: {\n ...ctx.sendContext,\n ...(userCtx.sendContext ?? {}),\n },\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n result:\n userCtx.result !== undefined\n ? userCtx.result\n : userCtx instanceof Response\n ? userCtx\n : (ctx as any).result,\n error: userCtx.error ?? (ctx as any).error,\n })\n }) as any,\n } as any)\n}\n\nexport function execValidator(\n validator: AnyValidator,\n input: unknown,\n): unknown {\n if (validator == null) return {}\n\n if ('~standard' in validator) {\n const result = validator['~standard'].validate(input)\n\n if (result instanceof Promise)\n throw new Error('Async validation not supported')\n\n if (result.issues)\n throw new Error(JSON.stringify(result.issues, undefined, 2))\n\n return result.value\n }\n\n if ('parse' in validator) {\n return validator.parse(input)\n }\n\n if (typeof validator === 'function') {\n return validator(input)\n }\n\n throw new Error('Invalid validator type!')\n}\n\nexport function serverFnBaseToMiddleware(\n options: ServerFnBaseOptions<any, any, any, any, any>,\n): AnyFunctionMiddleware {\n return {\n _types: undefined!,\n options: {\n validator: options.validator,\n client: async ({ next, sendContext, ...ctx }) => {\n const payload = {\n ...ctx,\n // switch the sendContext over to context\n context: sendContext,\n } as any\n\n // Execute the extracted function\n // but not before serializing the context\n const res = await options.extractedFn?.(payload)\n\n return next(res) as unknown as FunctionMiddlewareClientFnResult<\n any,\n any,\n any\n >\n },\n server: async ({ next, ...ctx }) => {\n // Execute the server function\n const result = await options.serverFn?.(ctx as TODO)\n\n return next({\n ...ctx,\n result,\n } as any) as unknown as FunctionMiddlewareServerFnResult<\n any,\n any,\n any,\n any\n >\n },\n },\n }\n}\n"],"names":["res","options"],"mappings":"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"}
|
package/dist/esm/envOnly.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
type EnvOnlyFn = <TFn extends (...args: Array<any>) => any>(fn: TFn) => TFn;
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
2
|
+
export declare const createServerOnlyFn: EnvOnlyFn;
|
|
3
|
+
export declare const createClientOnlyFn: EnvOnlyFn;
|
|
4
4
|
export {};
|
package/dist/esm/envOnly.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const createServerOnlyFn = (fn) => fn;
|
|
2
|
+
const createClientOnlyFn = (fn) => fn;
|
|
3
3
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
createClientOnlyFn,
|
|
5
|
+
createServerOnlyFn
|
|
6
6
|
};
|
|
7
7
|
//# sourceMappingURL=envOnly.js.map
|
package/dist/esm/envOnly.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envOnly.js","sources":["../../src/envOnly.ts"],"sourcesContent":["type EnvOnlyFn = <TFn extends (...args: Array<any>) => any>(fn: TFn) => TFn\n\n// A function that will only be available in the server build\n// If called on the client, it will throw an error\nexport const
|
|
1
|
+
{"version":3,"file":"envOnly.js","sources":["../../src/envOnly.ts"],"sourcesContent":["type EnvOnlyFn = <TFn extends (...args: Array<any>) => any>(fn: TFn) => TFn\n\n// A function that will only be available in the server build\n// If called on the client, it will throw an error\nexport const createServerOnlyFn: EnvOnlyFn = (fn) => fn\n\n// A function that will only be available in the client build\n// If called on the server, it will throw an error\nexport const createClientOnlyFn: EnvOnlyFn = (fn) => fn\n"],"names":[],"mappings":"AAIO,MAAM,qBAAgC,CAAC,OAAO;AAI9C,MAAM,qBAAgC,CAAC,OAAO;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getRouterInstance: import('./createIsomorphicFn.js').IsomorphicFn<[], import('@tanstack/router-core').AnyRouter, import('@tanstack/router-core').AnyRouter>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { getStartContext } from "@tanstack/start-storage-context";
|
|
2
|
+
import { createIsomorphicFn } from "./createIsomorphicFn.js";
|
|
3
|
+
const getRouterInstance = createIsomorphicFn().client(() => window.__TSR_ROUTER__).server(() => getStartContext().router);
|
|
4
|
+
export {
|
|
5
|
+
getRouterInstance
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=getRouterInstance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRouterInstance.js","sources":["../../src/getRouterInstance.ts"],"sourcesContent":["import { getStartContext } from '@tanstack/start-storage-context'\nimport { createIsomorphicFn } from './createIsomorphicFn'\n\n// TODO should this be a public API\nexport const getRouterInstance = createIsomorphicFn()\n .client(() => window.__TSR_ROUTER__!)\n .server(() => getStartContext().router)\n"],"names":[],"mappings":";;AAIO,MAAM,oBAAoB,qBAC9B,OAAO,MAAM,OAAO,cAAe,EACnC,OAAO,MAAM,gBAAA,EAAkB,MAAM;"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export type { DehydratedRouter, JsonResponse, } from '@tanstack/router-core/ssr/client';
|
|
2
2
|
export { hydrate, json, mergeHeaders } from '@tanstack/router-core/ssr/client';
|
|
3
|
-
export { startSerializer } from './serializer.js';
|
|
4
|
-
export type { StartSerializer, Serializable, SerializerParse, SerializerParseBy, SerializerStringify, SerializerStringifyBy, SerializerExtensions, } from './serializer.js';
|
|
5
3
|
export { createIsomorphicFn, type IsomorphicFn, type ServerOnlyFn, type ClientOnlyFn, type IsomorphicFnBase, } from './createIsomorphicFn.js';
|
|
6
|
-
export {
|
|
4
|
+
export { createServerOnlyFn, createClientOnlyFn } from './envOnly.js';
|
|
7
5
|
export { createServerFn } from './createServerFn.js';
|
|
8
6
|
export { createMiddleware, type IntersectAllValidatorInputs, type IntersectAllValidatorOutputs, type FunctionMiddlewareServerFn, type AnyFunctionMiddleware, type FunctionMiddlewareOptions, type FunctionMiddlewareWithTypes, type FunctionMiddlewareValidator, type FunctionMiddlewareServer, type FunctionMiddlewareAfterClient, type FunctionMiddlewareAfterServer, type FunctionMiddleware, type FunctionMiddlewareClientFnOptions, type FunctionMiddlewareClientFnResult, type FunctionMiddlewareClientNextFn, type FunctionClientResultWithContext, type AssignAllClientContextBeforeNext, type AssignAllMiddleware, type AssignAllServerContext, type FunctionMiddlewareAfterValidator, type FunctionMiddlewareClientFn, type FunctionMiddlewareServerFnResult, type FunctionMiddlewareClient, type FunctionMiddlewareServerFnOptions, type FunctionMiddlewareServerNextFn, type FunctionServerResultWithContext, type AnyRequestMiddleware, } from './createMiddleware.js';
|
|
9
7
|
export { registerGlobalMiddleware, globalMiddleware, } from './registerGlobalMiddleware.js';
|
|
10
|
-
export type { CompiledFetcherFnOptions, CompiledFetcherFn, Fetcher, RscStream, FetcherData, FetcherBaseOptions, ServerFn, ServerFnCtx,
|
|
11
|
-
export { applyMiddleware, execValidator, serverFnBaseToMiddleware,
|
|
8
|
+
export type { CompiledFetcherFnOptions, CompiledFetcherFn, Fetcher, RscStream, FetcherData, FetcherBaseOptions, ServerFn, ServerFnCtx, MiddlewareFn, ServerFnMiddlewareOptions, ServerFnMiddlewareResult, ServerFnBuilder, ServerFnBaseOptions, NextFn, Method, OptionalFetcher, RequiredFetcher, } from './createServerFn.js';
|
|
9
|
+
export { applyMiddleware, execValidator, serverFnBaseToMiddleware, flattenMiddlewares, executeMiddleware, } from './createServerFn.js';
|
|
10
|
+
export { createClientRpc } from './createClientRpc.js';
|
|
11
|
+
export { getDefaultSerovalPlugins } from './serializer/getDefaultSerovalPlugins.js';
|
|
12
|
+
export { TSS_FORMDATA_CONTEXT, TSS_SERVER_FUNCTION, X_TSS_SERIALIZED, } from './constants.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
import { hydrate, json, mergeHeaders } from "@tanstack/router-core/ssr/client";
|
|
2
|
-
import { startSerializer } from "./serializer.js";
|
|
3
2
|
import { createIsomorphicFn } from "./createIsomorphicFn.js";
|
|
4
|
-
import {
|
|
5
|
-
import { applyMiddleware, createServerFn, execValidator, executeMiddleware,
|
|
3
|
+
import { createClientOnlyFn, createServerOnlyFn } from "./envOnly.js";
|
|
4
|
+
import { applyMiddleware, createServerFn, execValidator, executeMiddleware, flattenMiddlewares, serverFnBaseToMiddleware } from "./createServerFn.js";
|
|
6
5
|
import { createMiddleware } from "./createMiddleware.js";
|
|
7
6
|
import { globalMiddleware, registerGlobalMiddleware } from "./registerGlobalMiddleware.js";
|
|
7
|
+
import { createClientRpc } from "./createClientRpc.js";
|
|
8
|
+
import { getDefaultSerovalPlugins } from "./serializer/getDefaultSerovalPlugins.js";
|
|
9
|
+
import { TSS_FORMDATA_CONTEXT, TSS_SERVER_FUNCTION, X_TSS_SERIALIZED } from "./constants.js";
|
|
8
10
|
export {
|
|
11
|
+
TSS_FORMDATA_CONTEXT,
|
|
12
|
+
TSS_SERVER_FUNCTION,
|
|
13
|
+
X_TSS_SERIALIZED,
|
|
9
14
|
applyMiddleware,
|
|
10
|
-
|
|
15
|
+
createClientOnlyFn,
|
|
16
|
+
createClientRpc,
|
|
11
17
|
createIsomorphicFn,
|
|
12
18
|
createMiddleware,
|
|
13
19
|
createServerFn,
|
|
20
|
+
createServerOnlyFn,
|
|
14
21
|
execValidator,
|
|
15
22
|
executeMiddleware,
|
|
16
|
-
extractFormDataContext,
|
|
17
23
|
flattenMiddlewares,
|
|
24
|
+
getDefaultSerovalPlugins,
|
|
18
25
|
globalMiddleware,
|
|
19
26
|
hydrate,
|
|
20
27
|
json,
|
|
21
28
|
mergeHeaders,
|
|
22
29
|
registerGlobalMiddleware,
|
|
23
|
-
serverFnBaseToMiddleware
|
|
24
|
-
serverOnly,
|
|
25
|
-
startSerializer
|
|
30
|
+
serverFnBaseToMiddleware
|
|
26
31
|
};
|
|
27
32
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createSerializationAdapter } from "@tanstack/router-core";
|
|
2
|
+
import { createClientRpc } from "../createClientRpc.js";
|
|
3
|
+
import { TSS_SERVER_FUNCTION } from "../constants.js";
|
|
4
|
+
const ServerFunctionSerializationAdapter = createSerializationAdapter({
|
|
5
|
+
key: "$TSS/serverfn",
|
|
6
|
+
test: (v) => {
|
|
7
|
+
if (typeof v !== "object" || v === null) return false;
|
|
8
|
+
if (!(TSS_SERVER_FUNCTION in v)) return false;
|
|
9
|
+
return !!v[TSS_SERVER_FUNCTION];
|
|
10
|
+
},
|
|
11
|
+
toSerializable: ({ functionId }) => ({ functionId }),
|
|
12
|
+
fromSerializable: ({ functionId }) => createClientRpc(functionId)
|
|
13
|
+
});
|
|
14
|
+
export {
|
|
15
|
+
ServerFunctionSerializationAdapter
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=ServerFunctionSerializationAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerFunctionSerializationAdapter.js","sources":["../../../src/serializer/ServerFunctionSerializationAdapter.ts"],"sourcesContent":["import { createSerializationAdapter } from '@tanstack/router-core'\nimport { createClientRpc } from '../createClientRpc'\nimport { TSS_SERVER_FUNCTION } from '../constants'\n\nexport const ServerFunctionSerializationAdapter = createSerializationAdapter({\n key: '$TSS/serverfn',\n test: (v): v is { functionId: string } => {\n if (typeof v !== 'object' || v === null) return false\n\n if (!(TSS_SERVER_FUNCTION in v)) return false\n\n return !!v[TSS_SERVER_FUNCTION]\n },\n toSerializable: ({ functionId }) => ({ functionId }),\n fromSerializable: ({ functionId }) => createClientRpc(functionId),\n})\n"],"names":[],"mappings":";;;AAIO,MAAM,qCAAqC,2BAA2B;AAAA,EAC3E,KAAK;AAAA,EACL,MAAM,CAAC,MAAmC;AACxC,QAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAEhD,QAAI,EAAE,uBAAuB,GAAI,QAAO;AAExC,WAAO,CAAC,CAAC,EAAE,mBAAmB;AAAA,EAChC;AAAA,EACA,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,WAAA;AAAA,EACvC,kBAAkB,CAAC,EAAE,WAAA,MAAiB,gBAAgB,UAAU;AAClE,CAAC;"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function getClientSerovalPlugins(): (import('seroval').Plugin<any, import('seroval').SerovalNode> | import('seroval').Plugin<Error, any> | import('seroval').Plugin<ReadableStream<any>, any> | import('seroval').Plugin<{
|
|
2
|
+
functionId: string;
|
|
3
|
+
}, import('seroval').SerovalNode>)[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { makeSerovalPlugin } from "@tanstack/router-core";
|
|
2
|
+
import { getDefaultSerovalPlugins } from "./getDefaultSerovalPlugins.js";
|
|
3
|
+
import { ServerFunctionSerializationAdapter } from "./ServerFunctionSerializationAdapter.js";
|
|
4
|
+
function getClientSerovalPlugins() {
|
|
5
|
+
return [
|
|
6
|
+
...getDefaultSerovalPlugins(),
|
|
7
|
+
makeSerovalPlugin(ServerFunctionSerializationAdapter)
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
getClientSerovalPlugins
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=getClientSerovalPlugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getClientSerovalPlugins.js","sources":["../../../src/serializer/getClientSerovalPlugins.ts"],"sourcesContent":["import { makeSerovalPlugin } from '@tanstack/router-core'\nimport { getDefaultSerovalPlugins } from './getDefaultSerovalPlugins'\nimport { ServerFunctionSerializationAdapter } from './ServerFunctionSerializationAdapter'\n\nexport function getClientSerovalPlugins() {\n return [\n ...getDefaultSerovalPlugins(),\n makeSerovalPlugin(ServerFunctionSerializationAdapter),\n ]\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,0BAA0B;AACxC,SAAO;AAAA,IACL,GAAG,yBAAA;AAAA,IACH,kBAAkB,kCAAkC;AAAA,EAAA;AAExD;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getDefaultSerovalPlugins(): (import('seroval').Plugin<any, import('seroval').SerovalNode> | import('seroval').Plugin<Error, any> | import('seroval').Plugin<ReadableStream<any>, any>)[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import invariant from "tiny-invariant";
|
|
2
|
+
import { defaultSerovalPlugins, makeSerovalPlugin } from "@tanstack/router-core";
|
|
3
|
+
import { getRouterInstance } from "../getRouterInstance.js";
|
|
4
|
+
function getDefaultSerovalPlugins() {
|
|
5
|
+
const router = getRouterInstance();
|
|
6
|
+
invariant(router, "Expected router instance to be available");
|
|
7
|
+
const adapters = router.options.serializationAdapters;
|
|
8
|
+
return [
|
|
9
|
+
...adapters?.map(makeSerovalPlugin) ?? [],
|
|
10
|
+
...defaultSerovalPlugins
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
getDefaultSerovalPlugins
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=getDefaultSerovalPlugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDefaultSerovalPlugins.js","sources":["../../../src/serializer/getDefaultSerovalPlugins.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport {\n makeSerovalPlugin,\n defaultSerovalPlugins as routerDefaultSerovalPlugins,\n} from '@tanstack/router-core'\nimport { getRouterInstance } from '../getRouterInstance'\nimport type { AnySerializationAdapter } from '@tanstack/router-core'\n\nexport function getDefaultSerovalPlugins() {\n const router = getRouterInstance()\n invariant(router, 'Expected router instance to be available')\n const adapters = router.options.serializationAdapters as\n | Array<AnySerializationAdapter>\n | undefined\n return [\n ...(adapters?.map(makeSerovalPlugin) ?? []),\n ...routerDefaultSerovalPlugins,\n ]\n}\n"],"names":["routerDefaultSerovalPlugins"],"mappings":";;;AAQO,SAAS,2BAA2B;AACzC,QAAM,SAAS,kBAAA;AACf,YAAU,QAAQ,0CAA0C;AAC5D,QAAM,WAAW,OAAO,QAAQ;AAGhC,SAAO;AAAA,IACL,GAAI,UAAU,IAAI,iBAAiB,KAAK,CAAA;AAAA,IACxC,GAAGA;AAAAA,EAAA;AAEP;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function serverFnFetcher(url: string, args: Array<any>, handler: (url: string, requestInit: RequestInit) => Promise<Response>): Promise<any>;
|