🚨 Active Supply Chain Attack:node-ipc Package Compromised.Learn More
Socket
Book a DemoSign in
Socket

@tanstack/start-client-core

Package Overview
Dependencies
Maintainers
7
Versions
378
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/start-client-core - npm Package Compare versions

Comparing version
1.167.22
to
1.168.0
+43
-30
dist/esm/createServerFn.d.ts
import { TSS_SERVER_FUNCTION_FACTORY, ClientFnMeta, ServerFnMeta, TSS_SERVER_FUNCTION } from './constants.js';
import { AnyValidator, Constrain, Expand, Register, RegisteredSerializableInput, ResolveValidatorInput, ValidateSerializable, ValidateSerializableInput, Validator } from '@tanstack/router-core';
import { AnyFunctionMiddleware, AnyRequestMiddleware, AssignAllServerFnContext, IntersectAllValidatorInputs, IntersectAllValidatorOutputs } from './createMiddleware.js';
export type CreateServerFn<TRegister> = <TMethod extends Method, TResponse = unknown, TMiddlewares = undefined, TInputValidator = undefined>(options?: {
export type ServerFnStrict = boolean | {
input?: boolean;
output?: boolean;
};
export interface ServerFnOptions<TMethod extends Method = Method, TStrict extends ServerFnStrict = true> {
method?: TMethod;
}, __opts?: ServerFnBaseOptions<TRegister, TMethod, TResponse, TMiddlewares, TInputValidator>) => ServerFnBuilder<TRegister, TMethod>;
strict?: TStrict;
}
export type ServerFnStrictInput<TStrict extends ServerFnStrict> = TStrict extends false ? false : TStrict extends {
input: infer TInput extends boolean;
} ? TInput : true;
export type ServerFnStrictOutput<TStrict extends ServerFnStrict> = TStrict extends false ? false : TStrict extends {
output: infer TOutput extends boolean;
} ? TOutput : true;
export type CreateServerFn<TRegister> = <TMethod extends Method, TStrict extends ServerFnStrict = true, TResponse = unknown, TMiddlewares = undefined, TInputValidator = undefined>(options?: ServerFnOptions<TMethod, TStrict>, __opts?: ServerFnBaseOptions<TRegister, TMethod, TResponse, TMiddlewares, TInputValidator, TStrict>) => ServerFnBuilder<TRegister, TMethod, TStrict>;
export declare const createServerFn: CreateServerFn<Register>;

@@ -51,4 +63,4 @@ export declare function executeMiddleware(middlewares: Array<AnyFunctionMiddleware | AnyRequestMiddleware>, env: 'client' | 'server', opts: ServerFnMiddlewareOptions): Promise<ServerFnMiddlewareResult>;

export type Method = 'GET' | 'POST';
export type ServerFnReturnType<TRegister, TResponse> = TResponse extends PromiseLike<infer U> ? Promise<ServerFnReturnType<TRegister, U>> : TResponse extends Response ? TResponse : ValidateSerializableInput<TRegister, TResponse>;
export type ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse> = (ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>) => ServerFnReturnType<TRegister, TResponse>;
export type ServerFnReturnType<TRegister, TResponse, TStrict extends ServerFnStrict = true> = ServerFnStrictOutput<TStrict> extends false ? TResponse : TResponse extends PromiseLike<infer U> ? Promise<ServerFnReturnType<TRegister, U, TStrict>> : TResponse extends Response ? TResponse : ValidateSerializableInput<TRegister, TResponse>;
export type ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse, TStrict extends ServerFnStrict = true> = (ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>) => ServerFnReturnType<TRegister, TResponse, TStrict>;
export interface ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator> {

@@ -65,43 +77,44 @@ data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>;

};
export type ServerFnBaseOptions<TRegister, TMethod extends Method = 'GET', TResponse = unknown, TMiddlewares = unknown, TInputValidator = unknown> = {
export type ServerFnBaseOptions<TRegister, TMethod extends Method = 'GET', TResponse = unknown, TMiddlewares = unknown, TInputValidator = unknown, TStrict extends ServerFnStrict = true> = {
method: TMethod;
strict?: TStrict;
middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware>>;
inputValidator?: ConstrainValidator<TRegister, TMethod, TInputValidator>;
inputValidator?: ConstrainValidator<TRegister, TMethod, TInputValidator, TStrict>;
extractedFn?: CompiledFetcherFn<TRegister, TResponse>;
serverFn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse>;
serverFn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse, TStrict>;
};
export type ValidateValidatorInput<TRegister, TMethod extends Method, TInputValidator> = TMethod extends 'POST' ? ResolveValidatorInput<TInputValidator> extends FormData ? ResolveValidatorInput<TInputValidator> : ValidateSerializable<ResolveValidatorInput<TInputValidator>, RegisteredSerializableInput<TRegister>> : ValidateSerializable<ResolveValidatorInput<TInputValidator>, RegisteredSerializableInput<TRegister>>;
export type ValidateValidator<TRegister, TMethod extends Method, TInputValidator> = ValidateValidatorInput<TRegister, TMethod, TInputValidator> extends infer TInput ? Validator<TInput, any> : never;
export type ConstrainValidator<TRegister, TMethod extends Method, TInputValidator> = (unknown extends TInputValidator ? TInputValidator : ResolveValidatorInput<TInputValidator> extends ValidateValidator<TRegister, TMethod, TInputValidator> ? TInputValidator : never) | ValidateValidator<TRegister, TMethod, TInputValidator>;
export type ValidateValidatorInput<TRegister, TMethod extends Method, TInputValidator, TStrict extends ServerFnStrict = true> = ServerFnStrictInput<TStrict> extends false ? ResolveValidatorInput<TInputValidator> : TMethod extends 'POST' ? ResolveValidatorInput<TInputValidator> extends FormData ? ResolveValidatorInput<TInputValidator> : ValidateSerializable<ResolveValidatorInput<TInputValidator>, RegisteredSerializableInput<TRegister>> : ValidateSerializable<ResolveValidatorInput<TInputValidator>, RegisteredSerializableInput<TRegister>>;
export type ValidateValidator<TRegister, TMethod extends Method, TInputValidator, TStrict extends ServerFnStrict = true> = ValidateValidatorInput<TRegister, TMethod, TInputValidator, TStrict> extends infer TInput ? Validator<TInput, any> : never;
export type ConstrainValidator<TRegister, TMethod extends Method, TInputValidator, TStrict extends ServerFnStrict = true> = (unknown extends TInputValidator ? TInputValidator : ResolveValidatorInput<TInputValidator> extends ValidateValidator<TRegister, TMethod, TInputValidator, TStrict> ? TInputValidator : never) | ValidateValidator<TRegister, TMethod, TInputValidator, TStrict>;
export type AppendMiddlewares<TMiddlewares, TNewMiddlewares> = TMiddlewares extends ReadonlyArray<any> ? TNewMiddlewares extends ReadonlyArray<any> ? readonly [...TMiddlewares, ...TNewMiddlewares] : TMiddlewares : TNewMiddlewares;
export interface ServerFnMiddleware<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> {
middleware: <const TNewMiddlewares>(middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn>>) => ServerFnAfterMiddleware<TRegister, TMethod, AppendMiddlewares<TMiddlewares, TNewMiddlewares>, TInputValidator>;
export interface ServerFnMiddleware<TRegister, TMethod extends Method, TMiddlewares, TInputValidator, TStrict extends ServerFnStrict> {
middleware: <const TNewMiddlewares>(middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn>>) => ServerFnAfterMiddleware<TRegister, TMethod, AppendMiddlewares<TMiddlewares, TNewMiddlewares>, TInputValidator, TStrict>;
}
export interface ServerFnAfterMiddleware<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined>, ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined>, ServerFnValidator<TRegister, TMethod, TMiddlewares>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {
<TNewMethod extends Method = TMethod>(options?: {
method?: TNewMethod;
}): ServerFnAfterMiddleware<TRegister, TNewMethod, TMiddlewares, TInputValidator>;
export interface ServerFnAfterMiddleware<TRegister, TMethod extends Method, TMiddlewares, TInputValidator, TStrict extends ServerFnStrict> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined, TStrict>, ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined, TStrict>, ServerFnValidator<TRegister, TMethod, TMiddlewares, TStrict>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator, TStrict> {
<TNewMethod extends Method = TMethod, TNewStrict extends ServerFnStrict = TStrict>(options?: ServerFnOptions<TNewMethod, TNewStrict>): ServerFnAfterMiddleware<TRegister, TNewMethod, TMiddlewares, TInputValidator, TNewStrict>;
}
export type ValidatorFn<TRegister, TMethod extends Method, TMiddlewares> = <TInputValidator>(inputValidator: ConstrainValidator<TRegister, TMethod, TInputValidator>) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TInputValidator>;
export interface ServerFnValidator<TRegister, TMethod extends Method, TMiddlewares> {
inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares>;
export type ValidatorFn<TRegister, TMethod extends Method, TMiddlewares, TStrict extends ServerFnStrict> = <TInputValidator>(inputValidator: ConstrainValidator<TRegister, TMethod, TInputValidator, TStrict>) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TInputValidator, TStrict>;
export interface ServerFnValidator<TRegister, TMethod extends Method, TMiddlewares, TStrict extends ServerFnStrict> {
inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares, TStrict>;
}
export interface ServerFnAfterValidator<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined>, ServerFnMiddleware<TRegister, TMethod, TMiddlewares, TInputValidator>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {
export interface ServerFnAfterValidator<TRegister, TMethod extends Method, TMiddlewares, TInputValidator, TStrict extends ServerFnStrict> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined, TStrict>, ServerFnMiddleware<TRegister, TMethod, TMiddlewares, TInputValidator, TStrict>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator, TStrict> {
}
export interface ServerFnAfterTyper<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {
export interface ServerFnAfterTyper<TRegister, TMethod extends Method, TMiddlewares, TInputValidator, TStrict extends ServerFnStrict> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined, TStrict>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator, TStrict> {
}
export interface ServerFnHandler<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> {
handler: <TNewResponse>(fn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TNewResponse>) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>;
export interface ServerFnHandler<TRegister, TMethod extends Method, TMiddlewares, TInputValidator, TStrict extends ServerFnStrict> {
handler: <TNewResponse>(fn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TNewResponse, TStrict>) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>;
}
export interface ServerFnBuilder<TRegister, TMethod extends Method = 'GET'> extends ServerFnWithTypes<TRegister, TMethod, undefined, undefined, undefined>, ServerFnMiddleware<TRegister, TMethod, undefined, undefined>, ServerFnValidator<TRegister, TMethod, undefined>, ServerFnHandler<TRegister, TMethod, undefined, undefined> {
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined>;
export interface ServerFnBuilder<TRegister, TMethod extends Method = 'GET', TStrict extends ServerFnStrict = true> extends ServerFnWithTypes<TRegister, TMethod, undefined, undefined, undefined, TStrict>, ServerFnMiddleware<TRegister, TMethod, undefined, undefined, TStrict>, ServerFnValidator<TRegister, TMethod, undefined, TStrict>, ServerFnHandler<TRegister, TMethod, undefined, undefined, TStrict> {
<TNewMethod extends Method = TMethod, TNewStrict extends ServerFnStrict = TStrict>(options?: ServerFnOptions<TNewMethod, TNewStrict>): ServerFnBuilder<TRegister, TNewMethod, TNewStrict>;
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined, TStrict>;
}
export interface ServerFnWithTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse> {
'~types': ServerFnTypes<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse>;
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined>;
export interface ServerFnWithTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse, in out TStrict extends ServerFnStrict> {
'~types': ServerFnTypes<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse, TStrict>;
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined, TStrict>;
[TSS_SERVER_FUNCTION_FACTORY]: true;
}
export type AnyServerFn = ServerFnWithTypes<any, any, any, any, any>;
export interface ServerFnTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse> {
export type AnyServerFn = ServerFnWithTypes<any, any, any, any, any, any>;
export interface ServerFnTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse, in out TStrict extends ServerFnStrict> {
method: TMethod;
strict: TStrict;
middlewares: TMiddlewares;

@@ -108,0 +121,0 @@ inputValidator: TInputValidator;

@@ -1,1 +0,1 @@

{"version":3,"file":"createServerFn.js","names":[],"sources":["../../src/createServerFn.ts"],"sourcesContent":["import { mergeHeaders } from '@tanstack/router-core/ssr/client'\n\nimport { isRedirect, parseRedirect } from '@tanstack/router-core'\nimport { TSS_SERVER_FUNCTION_FACTORY } from './constants'\nimport { getStartOptions } from './getStartOptions'\nimport { getStartContextServerOnly } from './getStartContextServerOnly'\nimport { createNullProtoObject, safeObjectMerge } from './safeObjectMerge'\nimport type {\n ClientFnMeta,\n ServerFnMeta,\n TSS_SERVER_FUNCTION,\n} from './constants'\nimport type {\n AnyValidator,\n Constrain,\n Expand,\n Register,\n RegisteredSerializableInput,\n ResolveValidatorInput,\n ValidateSerializable,\n ValidateSerializableInput,\n Validator,\n} from '@tanstack/router-core'\nimport type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AssignAllServerFnContext,\n FunctionMiddlewareServerFnResult,\n IntersectAllValidatorInputs,\n IntersectAllValidatorOutputs,\n} from './createMiddleware'\n\ntype TODO = any\n\nexport type CreateServerFn<TRegister> = <\n TMethod extends Method,\n TResponse = unknown,\n TMiddlewares = undefined,\n TInputValidator = undefined,\n>(\n options?: {\n method?: TMethod\n },\n __opts?: ServerFnBaseOptions<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TInputValidator\n >,\n) => ServerFnBuilder<TRegister, TMethod>\n\nexport const createServerFn: CreateServerFn<Register> = (options, __opts) => {\n const resolvedOptions = (__opts || options || {}) as ServerFnBaseOptions<\n any,\n any,\n any,\n any,\n any\n >\n\n if (typeof resolvedOptions.method === 'undefined') {\n resolvedOptions.method = 'GET' as Method\n }\n\n const res: ServerFnBuilder<Register, Method> = {\n options: resolvedOptions,\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(undefined, newOptions) as any\n res[TSS_SERVER_FUNCTION_FACTORY] = true\n return res\n },\n inputValidator: (inputValidator) => {\n const newOptions = { ...resolvedOptions, inputValidator }\n return createServerFn(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<Register, any>,\n ServerFn<Register, Method, any, any, any>,\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 // Propagate the declared HTTP method onto the extracted handler\n // so the manifest-exported symbol (resolved by getServerFnById)\n // carries `method`, enabling the server handler to reject\n // mismatched HTTP methods before parsing request payloads.\n ;(extractedFn as any).method = resolvedOptions.method\n\n return Object.assign(\n async (opts?: CompiledFetcherFnOptions) => {\n // Start by executing the client-side middleware chain\n const result = await executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...newOptions,\n data: opts?.data as any,\n headers: opts?.headers,\n signal: opts?.signal,\n fetch: opts?.fetch,\n context: createNullProtoObject(),\n })\n\n const redirect = parseRedirect(result.error)\n if (redirect) {\n throw redirect\n }\n\n if (result.error) throw result.error\n return result.result\n },\n {\n // This copies over the URL, function ID\n ...extractedFn,\n // Expose the declared HTTP method so the server handler\n // can reject mismatched methods before parsing payloads\n method: resolvedOptions.method,\n // The extracted function on the server-side calls\n // this function\n __executeServer: async (opts: any) => {\n const startContext = getStartContextServerOnly()\n const serverContextAfterGlobalMiddlewares =\n startContext.contextAfterGlobalMiddlewares\n const ctx = {\n ...extractedFn,\n ...opts,\n // Ensure we use the full serverFnMeta from the provider file's extractedFn\n // (which has id, name, filename) rather than the partial one from SSR/client\n // callers (which only has id)\n serverFnMeta: extractedFn.serverFnMeta,\n // Merge client context first so trusted server middleware context wins.\n context: safeObjectMerge(\n opts.context,\n serverContextAfterGlobalMiddlewares,\n ),\n request: startContext.request,\n }\n\n const result = await executeMiddleware(\n resolvedMiddleware,\n 'server',\n ctx,\n ).then((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 return result\n },\n },\n ) as any\n },\n } as ServerFnBuilder<Register, Method>\n const fun = (options?: { method?: Method }) => {\n const newOptions = {\n ...resolvedOptions,\n ...options,\n }\n return createServerFn(undefined, newOptions) as any\n }\n return Object.assign(fun, res) as any\n}\n\nexport async function executeMiddleware(\n middlewares: Array<AnyFunctionMiddleware | AnyRequestMiddleware>,\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> {\n const globalMiddlewares = getStartOptions()?.functionMiddleware || []\n let flattenedMiddlewares = flattenMiddlewares([\n ...globalMiddlewares,\n ...middlewares,\n ])\n\n // On server, filter out middlewares that already executed in the request phase\n // to prevent duplicate execution (issue #5239)\n if (env === 'server') {\n const startContext = getStartContextServerOnly({ throwIfNotFound: false })\n if (startContext?.executedRequestMiddlewares) {\n flattenedMiddlewares = flattenedMiddlewares.filter(\n (m) => !startContext.executedRequestMiddlewares.has(m),\n )\n }\n }\n\n const callNextMiddleware: 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 // Execute the middleware\n try {\n if (\n 'inputValidator' in nextMiddleware.options &&\n nextMiddleware.options.inputValidator &&\n env === 'server'\n ) {\n // Execute the middleware's input function\n ctx.data = await execValidator(\n nextMiddleware.options.inputValidator,\n ctx.data,\n )\n }\n\n let middlewareFn: MiddlewareFn | undefined = undefined\n if (env === 'client') {\n if ('client' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.client as\n | MiddlewareFn\n | undefined\n }\n }\n // env === 'server'\n else if ('server' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.server as MiddlewareFn | undefined\n }\n\n if (middlewareFn) {\n const userNext = async (\n userCtx: ServerFnMiddlewareResult | undefined = {} as any,\n ) => {\n // Return the next middleware\n // Use safeObjectMerge for context objects to prevent prototype pollution\n const nextCtx = {\n ...ctx,\n ...userCtx,\n context: safeObjectMerge(ctx.context, userCtx.context),\n sendContext: safeObjectMerge(ctx.sendContext, userCtx.sendContext),\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n _callSiteFetch: ctx._callSiteFetch,\n fetch: ctx._callSiteFetch ?? userCtx.fetch ?? ctx.fetch,\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\n const result = await callNextMiddleware(nextCtx)\n\n if (result.error) {\n throw result.error\n }\n\n return result\n }\n\n // Execute the middleware\n const result = await middlewareFn({\n ...ctx,\n next: userNext,\n })\n\n // If result is NOT a ctx object, we need to return it as\n // the { result }\n if (isRedirect(result)) {\n return {\n ...ctx,\n error: result,\n }\n }\n\n if (result instanceof Response) {\n return {\n ...ctx,\n result,\n }\n }\n\n if (!(result as any)) {\n throw new Error(\n 'User middleware returned undefined. You must call next() or return a result in your middlewares.',\n )\n }\n\n return result\n }\n\n return callNextMiddleware(ctx)\n } catch (error: any) {\n return {\n ...ctx,\n error,\n }\n }\n }\n\n // Start the middleware chain\n return callNextMiddleware({\n ...opts,\n headers: opts.headers || {},\n sendContext: opts.sendContext || {},\n context: opts.context || createNullProtoObject(),\n _callSiteFetch: opts.fetch,\n })\n}\n\nexport type CompiledFetcherFnOptions = {\n method: Method\n data: unknown\n headers?: HeadersInit\n signal?: AbortSignal\n fetch?: CustomFetch\n context?: any\n}\n\nexport type Fetcher<TMiddlewares, TInputValidator, TResponse> =\n undefined extends IntersectAllValidatorInputs<TMiddlewares, TInputValidator>\n ? OptionalFetcher<TMiddlewares, TInputValidator, TResponse>\n : RequiredFetcher<TMiddlewares, TInputValidator, TResponse>\n\nexport interface FetcherBase {\n [TSS_SERVER_FUNCTION]: true\n url: string\n method: Method\n __executeServer: (opts: {\n method: Method\n data: unknown\n headers?: HeadersInit\n context?: any\n }) => Promise<unknown>\n}\n\nexport interface OptionalFetcher<\n TMiddlewares,\n TInputValidator,\n TResponse,\n> extends FetcherBase {\n (\n options?: OptionalFetcherDataOptions<TMiddlewares, TInputValidator>,\n ): Promise<Awaited<TResponse>>\n}\n\nexport interface RequiredFetcher<\n TMiddlewares,\n TInputValidator,\n TResponse,\n> extends FetcherBase {\n (\n opts: RequiredFetcherDataOptions<TMiddlewares, TInputValidator>,\n ): Promise<Awaited<TResponse>>\n}\n\n// Ideally, this type should just be `export type CustomFetch = typeof globalThis.fetch`, but that conflicts with the type overrides the `bun-types` package - a dependency of unplugin.\n// Relevant bun issues:\n// - https://github.com/oven-sh/bun/issues/23500\n// - https://github.com/oven-sh/bun/issues/23741\nexport type CustomFetch = typeof fetch extends (...args: infer A) => infer R\n ? (...args: A) => R\n : never\n\nexport type FetcherBaseOptions = {\n headers?: HeadersInit\n signal?: AbortSignal\n fetch?: CustomFetch\n}\n\nexport interface OptionalFetcherDataOptions<\n TMiddlewares,\n TInputValidator,\n> extends FetcherBaseOptions {\n data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>\n}\n\nexport interface RequiredFetcherDataOptions<\n TMiddlewares,\n TInputValidator,\n> extends FetcherBaseOptions {\n data: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>\n}\n\nexport type RscStream<T> = {\n __cacheState: T\n}\n\nexport type Method = 'GET' | 'POST'\n\nexport type ServerFnReturnType<TRegister, TResponse> =\n TResponse extends PromiseLike<infer U>\n ? Promise<ServerFnReturnType<TRegister, U>>\n : TResponse extends Response\n ? TResponse\n : ValidateSerializableInput<TRegister, TResponse>\n\nexport type ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse,\n> = (\n ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>,\n) => ServerFnReturnType<TRegister, TResponse>\n\nexport interface ServerFnCtx<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n> {\n data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>\n serverFnMeta: ServerFnMeta\n context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, {}>>\n method: TMethod\n}\n\nexport type CompiledFetcherFn<TRegister, TResponse> = {\n (\n opts: CompiledFetcherFnOptions & ServerFnBaseOptions<TRegister, Method>,\n ): Promise<TResponse>\n url: string\n serverFnMeta: ServerFnMeta\n}\n\nexport type ServerFnBaseOptions<\n TRegister,\n TMethod extends Method = 'GET',\n TResponse = unknown,\n TMiddlewares = unknown,\n TInputValidator = unknown,\n> = {\n method: TMethod\n middleware?: Constrain<\n TMiddlewares,\n ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware>\n >\n inputValidator?: ConstrainValidator<TRegister, TMethod, TInputValidator>\n extractedFn?: CompiledFetcherFn<TRegister, TResponse>\n serverFn?: ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse\n >\n}\n\nexport type ValidateValidatorInput<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n> = TMethod extends 'POST'\n ? ResolveValidatorInput<TInputValidator> extends FormData\n ? ResolveValidatorInput<TInputValidator>\n : ValidateSerializable<\n ResolveValidatorInput<TInputValidator>,\n RegisteredSerializableInput<TRegister>\n >\n : ValidateSerializable<\n ResolveValidatorInput<TInputValidator>,\n RegisteredSerializableInput<TRegister>\n >\n\nexport type ValidateValidator<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n> =\n ValidateValidatorInput<\n TRegister,\n TMethod,\n TInputValidator\n > extends infer TInput\n ? Validator<TInput, any>\n : never\n\nexport type ConstrainValidator<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n> =\n | (unknown extends TInputValidator\n ? TInputValidator\n : ResolveValidatorInput<TInputValidator> extends ValidateValidator<\n TRegister,\n TMethod,\n TInputValidator\n >\n ? TInputValidator\n : never)\n | ValidateValidator<TRegister, TMethod, TInputValidator>\n\nexport type AppendMiddlewares<TMiddlewares, TNewMiddlewares> =\n TMiddlewares extends ReadonlyArray<any>\n ? TNewMiddlewares extends ReadonlyArray<any>\n ? readonly [...TMiddlewares, ...TNewMiddlewares]\n : TMiddlewares\n : TNewMiddlewares\n\nexport interface ServerFnMiddleware<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n> {\n middleware: <const TNewMiddlewares>(\n middlewares: Constrain<\n TNewMiddlewares,\n ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn>\n >,\n ) => ServerFnAfterMiddleware<\n TRegister,\n TMethod,\n AppendMiddlewares<TMiddlewares, TNewMiddlewares>,\n TInputValidator\n >\n}\n\nexport interface ServerFnAfterMiddleware<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined\n >,\n ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined>,\n ServerFnValidator<TRegister, TMethod, TMiddlewares>,\n ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {\n <TNewMethod extends Method = TMethod>(options?: {\n method?: TNewMethod\n }): ServerFnAfterMiddleware<\n TRegister,\n TNewMethod,\n TMiddlewares,\n TInputValidator\n >\n}\n\nexport type ValidatorFn<TRegister, TMethod extends Method, TMiddlewares> = <\n TInputValidator,\n>(\n inputValidator: ConstrainValidator<TRegister, TMethod, TInputValidator>,\n) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TInputValidator>\n\nexport interface ServerFnValidator<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n> {\n inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares>\n}\n\nexport interface ServerFnAfterValidator<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined\n >,\n ServerFnMiddleware<TRegister, TMethod, TMiddlewares, TInputValidator>,\n ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {}\n\nexport interface ServerFnAfterTyper<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined\n >,\n ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {}\n\n// Handler\nexport interface ServerFnHandler<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n> {\n handler: <TNewResponse>(\n fn?: ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TNewResponse\n >,\n ) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>\n}\n\nexport interface ServerFnBuilder<TRegister, TMethod extends Method = 'GET'>\n extends\n ServerFnWithTypes<TRegister, TMethod, undefined, undefined, undefined>,\n 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 interface ServerFnWithTypes<\n in out TRegister,\n in out TMethod extends Method,\n in out TMiddlewares,\n in out TInputValidator,\n in out TResponse,\n> {\n '~types': ServerFnTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse\n >\n options: ServerFnBaseOptions<\n TRegister,\n TMethod,\n unknown,\n undefined,\n undefined\n >\n [TSS_SERVER_FUNCTION_FACTORY]: true\n}\n\nexport type AnyServerFn = ServerFnWithTypes<any, any, any, any, any>\n\nexport interface ServerFnTypes<\n in out TRegister,\n in out TMethod extends Method,\n in out TMiddlewares,\n in out TInputValidator,\n in out TResponse,\n> {\n method: TMethod\n middlewares: TMiddlewares\n inputValidator: TInputValidator\n response: TResponse\n allServerContext: AssignAllServerFnContext<TRegister, TMiddlewares>\n allInput: IntersectAllValidatorInputs<TMiddlewares, TInputValidator>\n allOutput: IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>\n}\n\nexport function flattenMiddlewares<\n T extends AnyFunctionMiddleware | AnyRequestMiddleware,\n>(middlewares: Array<T>, maxDepth: number = 100): Array<T> {\n const seen = new Set<T>()\n const flattened: Array<T> = []\n\n const recurse = (middleware: Array<T>, depth: number) => {\n if (depth > maxDepth) {\n throw new Error(\n `Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`,\n )\n }\n middleware.forEach((m) => {\n if (m.options.middleware) {\n recurse(m.options.middleware as Array<T>, depth + 1)\n }\n\n if (!seen.has(m)) {\n seen.add(m)\n flattened.push(m)\n }\n })\n }\n\n recurse(middlewares, 0)\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 serverFnMeta: ClientFnMeta\n fetch?: CustomFetch\n /** @internal - Preserves the call-site fetch to ensure it has highest priority over middleware */\n _callSiteFetch?: CustomFetch\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 async function execValidator(\n validator: AnyValidator,\n input: unknown,\n): Promise<unknown> {\n if (validator == null) return {}\n\n if ('~standard' in validator) {\n const result = await validator['~standard'].validate(input)\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\nfunction serverFnBaseToMiddleware(\n options: ServerFnBaseOptions<any, any, any, any, any>,\n): AnyFunctionMiddleware {\n return {\n '~types': undefined!,\n options: {\n inputValidator: options.inputValidator,\n client: async ({ next, sendContext, fetch, ...ctx }) => {\n const payload = {\n ...ctx,\n // switch the sendContext over to context\n context: sendContext,\n fetch,\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)\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 any\n >\n },\n },\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"createServerFn.js","names":[],"sources":["../../src/createServerFn.ts"],"sourcesContent":["import { mergeHeaders } from '@tanstack/router-core/ssr/client'\n\nimport { isRedirect, parseRedirect } from '@tanstack/router-core'\nimport { TSS_SERVER_FUNCTION_FACTORY } from './constants'\nimport { getStartOptions } from './getStartOptions'\nimport { getStartContextServerOnly } from './getStartContextServerOnly'\nimport { createNullProtoObject, safeObjectMerge } from './safeObjectMerge'\nimport type {\n ClientFnMeta,\n ServerFnMeta,\n TSS_SERVER_FUNCTION,\n} from './constants'\nimport type {\n AnyValidator,\n Constrain,\n Expand,\n Register,\n RegisteredSerializableInput,\n ResolveValidatorInput,\n ValidateSerializable,\n ValidateSerializableInput,\n Validator,\n} from '@tanstack/router-core'\nimport type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AssignAllServerFnContext,\n FunctionMiddlewareServerFnResult,\n IntersectAllValidatorInputs,\n IntersectAllValidatorOutputs,\n} from './createMiddleware'\n\ntype TODO = any\n\nexport type ServerFnStrict = boolean | { input?: boolean; output?: boolean }\n\nexport interface ServerFnOptions<\n TMethod extends Method = Method,\n TStrict extends ServerFnStrict = true,\n> {\n method?: TMethod\n strict?: TStrict\n}\n\nexport type ServerFnStrictInput<TStrict extends ServerFnStrict> =\n TStrict extends false\n ? false\n : TStrict extends { input: infer TInput extends boolean }\n ? TInput\n : true\n\nexport type ServerFnStrictOutput<TStrict extends ServerFnStrict> =\n TStrict extends false\n ? false\n : TStrict extends { output: infer TOutput extends boolean }\n ? TOutput\n : true\n\nexport type CreateServerFn<TRegister> = <\n TMethod extends Method,\n TStrict extends ServerFnStrict = true,\n TResponse = unknown,\n TMiddlewares = undefined,\n TInputValidator = undefined,\n>(\n options?: ServerFnOptions<TMethod, TStrict>,\n __opts?: ServerFnBaseOptions<\n TRegister,\n TMethod,\n TResponse,\n TMiddlewares,\n TInputValidator,\n TStrict\n >,\n) => ServerFnBuilder<TRegister, TMethod, TStrict>\n\nexport const createServerFn: CreateServerFn<Register> = (options, __opts) => {\n const resolvedOptions = (__opts || options || {}) as ServerFnBaseOptions<\n any,\n any,\n any,\n any,\n any,\n any\n >\n\n if (typeof resolvedOptions.method === 'undefined') {\n resolvedOptions.method = 'GET' as Method\n }\n\n const res: ServerFnBuilder<Register, Method, ServerFnStrict> = {\n options: resolvedOptions,\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(undefined, newOptions) as any\n res[TSS_SERVER_FUNCTION_FACTORY] = true\n return res\n },\n inputValidator: (inputValidator) => {\n const newOptions = { ...resolvedOptions, inputValidator }\n return createServerFn(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<Register, any>,\n ServerFn<Register, Method, any, any, any>,\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 // Propagate the declared HTTP method onto the extracted handler\n // so the manifest-exported symbol (resolved by getServerFnById)\n // carries `method`, enabling the server handler to reject\n // mismatched HTTP methods before parsing request payloads.\n ;(extractedFn as any).method = resolvedOptions.method\n\n return Object.assign(\n async (opts?: CompiledFetcherFnOptions) => {\n // Start by executing the client-side middleware chain\n const result = await executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...newOptions,\n data: opts?.data as any,\n headers: opts?.headers,\n signal: opts?.signal,\n fetch: opts?.fetch,\n context: createNullProtoObject(),\n })\n\n const redirect = parseRedirect(result.error)\n if (redirect) {\n throw redirect\n }\n\n if (result.error) throw result.error\n return result.result\n },\n {\n // This copies over the URL, function ID\n ...extractedFn,\n // Expose the declared HTTP method so the server handler\n // can reject mismatched methods before parsing payloads\n method: resolvedOptions.method,\n // The extracted function on the server-side calls\n // this function\n __executeServer: async (opts: any) => {\n const startContext = getStartContextServerOnly()\n const serverContextAfterGlobalMiddlewares =\n startContext.contextAfterGlobalMiddlewares\n const ctx = {\n ...extractedFn,\n ...opts,\n // Ensure we use the full serverFnMeta from the provider file's extractedFn\n // (which has id, name, filename) rather than the partial one from SSR/client\n // callers (which only has id)\n serverFnMeta: extractedFn.serverFnMeta,\n // Merge client context first so trusted server middleware context wins.\n context: safeObjectMerge(\n opts.context,\n serverContextAfterGlobalMiddlewares,\n ),\n request: startContext.request,\n }\n\n const result = await executeMiddleware(\n resolvedMiddleware,\n 'server',\n ctx,\n ).then((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 return result\n },\n },\n ) as any\n },\n } as ServerFnBuilder<Register, Method, ServerFnStrict>\n const fun = (options?: ServerFnOptions<Method, ServerFnStrict>) => {\n const newOptions = {\n ...resolvedOptions,\n ...options,\n }\n return createServerFn(undefined, newOptions) as any\n }\n return Object.assign(fun, res) as any\n}\n\nexport async function executeMiddleware(\n middlewares: Array<AnyFunctionMiddleware | AnyRequestMiddleware>,\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> {\n const globalMiddlewares = getStartOptions()?.functionMiddleware || []\n let flattenedMiddlewares = flattenMiddlewares([\n ...globalMiddlewares,\n ...middlewares,\n ])\n\n // On server, filter out middlewares that already executed in the request phase\n // to prevent duplicate execution (issue #5239)\n if (env === 'server') {\n const startContext = getStartContextServerOnly({ throwIfNotFound: false })\n if (startContext?.executedRequestMiddlewares) {\n flattenedMiddlewares = flattenedMiddlewares.filter(\n (m) => !startContext.executedRequestMiddlewares.has(m),\n )\n }\n }\n\n const callNextMiddleware: 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 // Execute the middleware\n try {\n if (\n 'inputValidator' in nextMiddleware.options &&\n nextMiddleware.options.inputValidator &&\n env === 'server'\n ) {\n // Execute the middleware's input function\n ctx.data = await execValidator(\n nextMiddleware.options.inputValidator,\n ctx.data,\n )\n }\n\n let middlewareFn: MiddlewareFn | undefined = undefined\n if (env === 'client') {\n if ('client' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.client as\n | MiddlewareFn\n | undefined\n }\n }\n // env === 'server'\n else if ('server' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.server as MiddlewareFn | undefined\n }\n\n if (middlewareFn) {\n const userNext = async (\n userCtx: ServerFnMiddlewareResult | undefined = {} as any,\n ) => {\n // Return the next middleware\n // Use safeObjectMerge for context objects to prevent prototype pollution\n const nextCtx = {\n ...ctx,\n ...userCtx,\n context: safeObjectMerge(ctx.context, userCtx.context),\n sendContext: safeObjectMerge(ctx.sendContext, userCtx.sendContext),\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n _callSiteFetch: ctx._callSiteFetch,\n fetch: ctx._callSiteFetch ?? userCtx.fetch ?? ctx.fetch,\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\n const result = await callNextMiddleware(nextCtx)\n\n if (result.error) {\n throw result.error\n }\n\n return result\n }\n\n // Execute the middleware\n const result = await middlewareFn({\n ...ctx,\n next: userNext,\n })\n\n // If result is NOT a ctx object, we need to return it as\n // the { result }\n if (isRedirect(result)) {\n return {\n ...ctx,\n error: result,\n }\n }\n\n if (result instanceof Response) {\n return {\n ...ctx,\n result,\n }\n }\n\n if (!(result as any)) {\n throw new Error(\n 'User middleware returned undefined. You must call next() or return a result in your middlewares.',\n )\n }\n\n return result\n }\n\n return callNextMiddleware(ctx)\n } catch (error: any) {\n return {\n ...ctx,\n error,\n }\n }\n }\n\n // Start the middleware chain\n return callNextMiddleware({\n ...opts,\n headers: opts.headers || {},\n sendContext: opts.sendContext || {},\n context: opts.context || createNullProtoObject(),\n _callSiteFetch: opts.fetch,\n })\n}\n\nexport type CompiledFetcherFnOptions = {\n method: Method\n data: unknown\n headers?: HeadersInit\n signal?: AbortSignal\n fetch?: CustomFetch\n context?: any\n}\n\nexport type Fetcher<TMiddlewares, TInputValidator, TResponse> =\n undefined extends IntersectAllValidatorInputs<TMiddlewares, TInputValidator>\n ? OptionalFetcher<TMiddlewares, TInputValidator, TResponse>\n : RequiredFetcher<TMiddlewares, TInputValidator, TResponse>\n\nexport interface FetcherBase {\n [TSS_SERVER_FUNCTION]: true\n url: string\n method: Method\n __executeServer: (opts: {\n method: Method\n data: unknown\n headers?: HeadersInit\n context?: any\n }) => Promise<unknown>\n}\n\nexport interface OptionalFetcher<\n TMiddlewares,\n TInputValidator,\n TResponse,\n> extends FetcherBase {\n (\n options?: OptionalFetcherDataOptions<TMiddlewares, TInputValidator>,\n ): Promise<Awaited<TResponse>>\n}\n\nexport interface RequiredFetcher<\n TMiddlewares,\n TInputValidator,\n TResponse,\n> extends FetcherBase {\n (\n opts: RequiredFetcherDataOptions<TMiddlewares, TInputValidator>,\n ): Promise<Awaited<TResponse>>\n}\n\n// Ideally, this type should just be `export type CustomFetch = typeof globalThis.fetch`, but that conflicts with the type overrides the `bun-types` package - a dependency of unplugin.\n// Relevant bun issues:\n// - https://github.com/oven-sh/bun/issues/23500\n// - https://github.com/oven-sh/bun/issues/23741\nexport type CustomFetch = typeof fetch extends (...args: infer A) => infer R\n ? (...args: A) => R\n : never\n\nexport type FetcherBaseOptions = {\n headers?: HeadersInit\n signal?: AbortSignal\n fetch?: CustomFetch\n}\n\nexport interface OptionalFetcherDataOptions<\n TMiddlewares,\n TInputValidator,\n> extends FetcherBaseOptions {\n data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>\n}\n\nexport interface RequiredFetcherDataOptions<\n TMiddlewares,\n TInputValidator,\n> extends FetcherBaseOptions {\n data: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>\n}\n\nexport type RscStream<T> = {\n __cacheState: T\n}\n\nexport type Method = 'GET' | 'POST'\n\nexport type ServerFnReturnType<\n TRegister,\n TResponse,\n TStrict extends ServerFnStrict = true,\n> =\n ServerFnStrictOutput<TStrict> extends false\n ? TResponse\n : TResponse extends PromiseLike<infer U>\n ? Promise<ServerFnReturnType<TRegister, U, TStrict>>\n : TResponse extends Response\n ? TResponse\n : ValidateSerializableInput<TRegister, TResponse>\n\nexport type ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse,\n TStrict extends ServerFnStrict = true,\n> = (\n ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>,\n) => ServerFnReturnType<TRegister, TResponse, TStrict>\n\nexport interface ServerFnCtx<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n> {\n data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>\n serverFnMeta: ServerFnMeta\n context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, {}>>\n method: TMethod\n}\n\nexport type CompiledFetcherFn<TRegister, TResponse> = {\n (\n opts: CompiledFetcherFnOptions & ServerFnBaseOptions<TRegister, Method>,\n ): Promise<TResponse>\n url: string\n serverFnMeta: ServerFnMeta\n}\n\nexport type ServerFnBaseOptions<\n TRegister,\n TMethod extends Method = 'GET',\n TResponse = unknown,\n TMiddlewares = unknown,\n TInputValidator = unknown,\n TStrict extends ServerFnStrict = true,\n> = {\n method: TMethod\n strict?: TStrict\n middleware?: Constrain<\n TMiddlewares,\n ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware>\n >\n inputValidator?: ConstrainValidator<\n TRegister,\n TMethod,\n TInputValidator,\n TStrict\n >\n extractedFn?: CompiledFetcherFn<TRegister, TResponse>\n serverFn?: ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse,\n TStrict\n >\n}\n\nexport type ValidateValidatorInput<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n TStrict extends ServerFnStrict = true,\n> =\n ServerFnStrictInput<TStrict> extends false\n ? ResolveValidatorInput<TInputValidator>\n : TMethod extends 'POST'\n ? ResolveValidatorInput<TInputValidator> extends FormData\n ? ResolveValidatorInput<TInputValidator>\n : ValidateSerializable<\n ResolveValidatorInput<TInputValidator>,\n RegisteredSerializableInput<TRegister>\n >\n : ValidateSerializable<\n ResolveValidatorInput<TInputValidator>,\n RegisteredSerializableInput<TRegister>\n >\n\nexport type ValidateValidator<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n TStrict extends ServerFnStrict = true,\n> =\n ValidateValidatorInput<\n TRegister,\n TMethod,\n TInputValidator,\n TStrict\n > extends infer TInput\n ? Validator<TInput, any>\n : never\n\nexport type ConstrainValidator<\n TRegister,\n TMethod extends Method,\n TInputValidator,\n TStrict extends ServerFnStrict = true,\n> =\n | (unknown extends TInputValidator\n ? TInputValidator\n : ResolveValidatorInput<TInputValidator> extends ValidateValidator<\n TRegister,\n TMethod,\n TInputValidator,\n TStrict\n >\n ? TInputValidator\n : never)\n | ValidateValidator<TRegister, TMethod, TInputValidator, TStrict>\n\nexport type AppendMiddlewares<TMiddlewares, TNewMiddlewares> =\n TMiddlewares extends ReadonlyArray<any>\n ? TNewMiddlewares extends ReadonlyArray<any>\n ? readonly [...TMiddlewares, ...TNewMiddlewares]\n : TMiddlewares\n : TNewMiddlewares\n\nexport interface ServerFnMiddleware<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n TStrict extends ServerFnStrict,\n> {\n middleware: <const TNewMiddlewares>(\n middlewares: Constrain<\n TNewMiddlewares,\n ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn>\n >,\n ) => ServerFnAfterMiddleware<\n TRegister,\n TMethod,\n AppendMiddlewares<TMiddlewares, TNewMiddlewares>,\n TInputValidator,\n TStrict\n >\n}\n\nexport interface ServerFnAfterMiddleware<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n TStrict extends ServerFnStrict,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined,\n TStrict\n >,\n ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined, TStrict>,\n ServerFnValidator<TRegister, TMethod, TMiddlewares, TStrict>,\n ServerFnHandler<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TStrict\n > {\n <\n TNewMethod extends Method = TMethod,\n TNewStrict extends ServerFnStrict = TStrict,\n >(\n options?: ServerFnOptions<TNewMethod, TNewStrict>,\n ): ServerFnAfterMiddleware<\n TRegister,\n TNewMethod,\n TMiddlewares,\n TInputValidator,\n TNewStrict\n >\n}\n\nexport type ValidatorFn<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TStrict extends ServerFnStrict,\n> = <TInputValidator>(\n inputValidator: ConstrainValidator<\n TRegister,\n TMethod,\n TInputValidator,\n TStrict\n >,\n) => ServerFnAfterValidator<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TStrict\n>\n\nexport interface ServerFnValidator<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TStrict extends ServerFnStrict,\n> {\n inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares, TStrict>\n}\n\nexport interface ServerFnAfterValidator<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n TStrict extends ServerFnStrict,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined,\n TStrict\n >,\n ServerFnMiddleware<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TStrict\n >,\n ServerFnHandler<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TStrict\n > {}\n\nexport interface ServerFnAfterTyper<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n TStrict extends ServerFnStrict,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n undefined,\n TStrict\n >,\n ServerFnHandler<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TStrict\n > {}\n\n// Handler\nexport interface ServerFnHandler<\n TRegister,\n TMethod extends Method,\n TMiddlewares,\n TInputValidator,\n TStrict extends ServerFnStrict,\n> {\n handler: <TNewResponse>(\n fn?: ServerFn<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TNewResponse,\n TStrict\n >,\n ) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>\n}\n\nexport interface ServerFnBuilder<\n TRegister,\n TMethod extends Method = 'GET',\n TStrict extends ServerFnStrict = true,\n>\n extends\n ServerFnWithTypes<\n TRegister,\n TMethod,\n undefined,\n undefined,\n undefined,\n TStrict\n >,\n ServerFnMiddleware<TRegister, TMethod, undefined, undefined, TStrict>,\n ServerFnValidator<TRegister, TMethod, undefined, TStrict>,\n ServerFnHandler<TRegister, TMethod, undefined, undefined, TStrict> {\n <\n TNewMethod extends Method = TMethod,\n TNewStrict extends ServerFnStrict = TStrict,\n >(\n options?: ServerFnOptions<TNewMethod, TNewStrict>,\n ): ServerFnBuilder<TRegister, TNewMethod, TNewStrict>\n options: ServerFnBaseOptions<\n TRegister,\n TMethod,\n unknown,\n undefined,\n undefined,\n TStrict\n >\n}\n\nexport interface ServerFnWithTypes<\n in out TRegister,\n in out TMethod extends Method,\n in out TMiddlewares,\n in out TInputValidator,\n in out TResponse,\n in out TStrict extends ServerFnStrict,\n> {\n '~types': ServerFnTypes<\n TRegister,\n TMethod,\n TMiddlewares,\n TInputValidator,\n TResponse,\n TStrict\n >\n options: ServerFnBaseOptions<\n TRegister,\n TMethod,\n unknown,\n undefined,\n undefined,\n TStrict\n >\n [TSS_SERVER_FUNCTION_FACTORY]: true\n}\n\nexport type AnyServerFn = ServerFnWithTypes<any, any, any, any, any, any>\n\nexport interface ServerFnTypes<\n in out TRegister,\n in out TMethod extends Method,\n in out TMiddlewares,\n in out TInputValidator,\n in out TResponse,\n in out TStrict extends ServerFnStrict,\n> {\n method: TMethod\n strict: TStrict\n middlewares: TMiddlewares\n inputValidator: TInputValidator\n response: TResponse\n allServerContext: AssignAllServerFnContext<TRegister, TMiddlewares>\n allInput: IntersectAllValidatorInputs<TMiddlewares, TInputValidator>\n allOutput: IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>\n}\n\nexport function flattenMiddlewares<\n T extends AnyFunctionMiddleware | AnyRequestMiddleware,\n>(middlewares: Array<T>, maxDepth: number = 100): Array<T> {\n const seen = new Set<T>()\n const flattened: Array<T> = []\n\n const recurse = (middleware: Array<T>, depth: number) => {\n if (depth > maxDepth) {\n throw new Error(\n `Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`,\n )\n }\n middleware.forEach((m) => {\n if (m.options.middleware) {\n recurse(m.options.middleware as Array<T>, depth + 1)\n }\n\n if (!seen.has(m)) {\n seen.add(m)\n flattened.push(m)\n }\n })\n }\n\n recurse(middlewares, 0)\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 serverFnMeta: ClientFnMeta\n fetch?: CustomFetch\n /** @internal - Preserves the call-site fetch to ensure it has highest priority over middleware */\n _callSiteFetch?: CustomFetch\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 async function execValidator(\n validator: AnyValidator,\n input: unknown,\n): Promise<unknown> {\n if (validator == null) return {}\n\n if ('~standard' in validator) {\n const result = await validator['~standard'].validate(input)\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\nfunction serverFnBaseToMiddleware(\n options: ServerFnBaseOptions<any, any, any, any, any>,\n): AnyFunctionMiddleware {\n return {\n '~types': undefined!,\n options: {\n inputValidator: options.inputValidator,\n client: async ({ next, sendContext, fetch, ...ctx }) => {\n const payload = {\n ...ctx,\n // switch the sendContext over to context\n context: sendContext,\n fetch,\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)\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 any\n >\n },\n },\n }\n}\n"],"mappings":"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"}

@@ -8,3 +8,3 @@ export type { JsonResponse } from '@tanstack/router-core/ssr/client';

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 FunctionMiddlewareAfterMiddleware, type FunctionMiddlewareClientFnOptions, type FunctionMiddlewareClientFnResult, type FunctionMiddlewareClientNextFn, type FunctionClientResultWithContext, type AssignAllClientContextBeforeNext, type AssignAllMiddleware, type FunctionMiddlewareAfterValidator, type FunctionMiddlewareClientFn, type FunctionMiddlewareServerFnResult, type FunctionMiddlewareClient, type FunctionMiddlewareServerFnOptions, type FunctionMiddlewareServerNextFn, type FunctionServerResultWithContext, type AnyRequestMiddleware, type RequestMiddlewareOptions, type RequestMiddlewareWithTypes, type RequestMiddlewareServer, type RequestMiddlewareAfterServer, type RequestMiddleware, type RequestMiddlewareAfterMiddleware, type RequestServerFn, type RequestMiddlewareServerFnResult, type RequestServerOptions, type RequestServerNextFn, type RequestServerNextFnOptions, type RequestServerResult, } from './createMiddleware.js';
export type { CompiledFetcherFnOptions, CompiledFetcherFn, CustomFetch, Fetcher, RscStream, FetcherBaseOptions, ServerFn, ServerFnCtx, MiddlewareFn, ServerFnMiddlewareOptions, ServerFnMiddlewareResult, ServerFnBuilder, ServerFnBaseOptions, NextFn, Method, OptionalFetcher, RequiredFetcher, } from './createServerFn.js';
export type { CompiledFetcherFnOptions, CompiledFetcherFn, CustomFetch, Fetcher, RscStream, FetcherBaseOptions, ServerFn, ServerFnCtx, ServerFnOptions, ServerFnStrict, ServerFnStrictInput, ServerFnStrictOutput, MiddlewareFn, ServerFnMiddlewareOptions, ServerFnMiddlewareResult, ServerFnBuilder, ServerFnBaseOptions, NextFn, Method, OptionalFetcher, RequiredFetcher, } from './createServerFn.js';
export { execValidator, flattenMiddlewares, executeMiddleware, } from './createServerFn.js';

@@ -11,0 +11,0 @@ export { TSS_FORMDATA_CONTEXT, TSS_SERVER_FUNCTION, TSS_CONTENT_TYPE_FRAMED, TSS_CONTENT_TYPE_FRAMED_VERSIONED, TSS_FRAMED_PROTOCOL_VERSION, FrameType, FRAME_HEADER_SIZE, X_TSS_SERIALIZED, X_TSS_RAW_RESPONSE, X_TSS_CONTEXT, validateFramedProtocolVersion, } from './constants.js';

{
"name": "@tanstack/start-client-core",
"version": "1.167.22",
"version": "1.168.0",
"description": "Modern and scalable routing for React applications",

@@ -5,0 +5,0 @@ "author": "Tanner Linsley",

@@ -35,4 +35,29 @@ import { mergeHeaders } from '@tanstack/router-core/ssr/client'

export type ServerFnStrict = boolean | { input?: boolean; output?: boolean }
export interface ServerFnOptions<
TMethod extends Method = Method,
TStrict extends ServerFnStrict = true,
> {
method?: TMethod
strict?: TStrict
}
export type ServerFnStrictInput<TStrict extends ServerFnStrict> =
TStrict extends false
? false
: TStrict extends { input: infer TInput extends boolean }
? TInput
: true
export type ServerFnStrictOutput<TStrict extends ServerFnStrict> =
TStrict extends false
? false
: TStrict extends { output: infer TOutput extends boolean }
? TOutput
: true
export type CreateServerFn<TRegister> = <
TMethod extends Method,
TStrict extends ServerFnStrict = true,
TResponse = unknown,

@@ -42,5 +67,3 @@ TMiddlewares = undefined,

>(
options?: {
method?: TMethod
},
options?: ServerFnOptions<TMethod, TStrict>,
__opts?: ServerFnBaseOptions<

@@ -51,5 +74,6 @@ TRegister,

TMiddlewares,
TInputValidator
TInputValidator,
TStrict
>,
) => ServerFnBuilder<TRegister, TMethod>
) => ServerFnBuilder<TRegister, TMethod, TStrict>

@@ -62,2 +86,3 @@ export const createServerFn: CreateServerFn<Register> = (options, __opts) => {

any,
any,
any

@@ -70,3 +95,3 @@ >

const res: ServerFnBuilder<Register, Method> = {
const res: ServerFnBuilder<Register, Method, ServerFnStrict> = {
options: resolvedOptions,

@@ -191,4 +216,4 @@ middleware: (middleware) => {

},
} as ServerFnBuilder<Register, Method>
const fun = (options?: { method?: Method }) => {
} as ServerFnBuilder<Register, Method, ServerFnStrict>
const fun = (options?: ServerFnOptions<Method, ServerFnStrict>) => {
const newOptions = {

@@ -423,8 +448,14 @@ ...resolvedOptions,

export type ServerFnReturnType<TRegister, TResponse> =
TResponse extends PromiseLike<infer U>
? Promise<ServerFnReturnType<TRegister, U>>
: TResponse extends Response
? TResponse
: ValidateSerializableInput<TRegister, TResponse>
export type ServerFnReturnType<
TRegister,
TResponse,
TStrict extends ServerFnStrict = true,
> =
ServerFnStrictOutput<TStrict> extends false
? TResponse
: TResponse extends PromiseLike<infer U>
? Promise<ServerFnReturnType<TRegister, U, TStrict>>
: TResponse extends Response
? TResponse
: ValidateSerializableInput<TRegister, TResponse>

@@ -437,5 +468,6 @@ export type ServerFn<

TResponse,
TStrict extends ServerFnStrict = true,
> = (
ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>,
) => ServerFnReturnType<TRegister, TResponse>
) => ServerFnReturnType<TRegister, TResponse, TStrict>

@@ -468,4 +500,6 @@ export interface ServerFnCtx<

TInputValidator = unknown,
TStrict extends ServerFnStrict = true,
> = {
method: TMethod
strict?: TStrict
middleware?: Constrain<

@@ -475,3 +509,8 @@ TMiddlewares,

>
inputValidator?: ConstrainValidator<TRegister, TMethod, TInputValidator>
inputValidator?: ConstrainValidator<
TRegister,
TMethod,
TInputValidator,
TStrict
>
extractedFn?: CompiledFetcherFn<TRegister, TResponse>

@@ -483,3 +522,4 @@ serverFn?: ServerFn<

TInputValidator,
TResponse
TResponse,
TStrict
>

@@ -492,13 +532,17 @@ }

TInputValidator,
> = TMethod extends 'POST'
? ResolveValidatorInput<TInputValidator> extends FormData
TStrict extends ServerFnStrict = true,
> =
ServerFnStrictInput<TStrict> extends false
? ResolveValidatorInput<TInputValidator>
: ValidateSerializable<
ResolveValidatorInput<TInputValidator>,
RegisteredSerializableInput<TRegister>
>
: ValidateSerializable<
ResolveValidatorInput<TInputValidator>,
RegisteredSerializableInput<TRegister>
>
: TMethod extends 'POST'
? ResolveValidatorInput<TInputValidator> extends FormData
? ResolveValidatorInput<TInputValidator>
: ValidateSerializable<
ResolveValidatorInput<TInputValidator>,
RegisteredSerializableInput<TRegister>
>
: ValidateSerializable<
ResolveValidatorInput<TInputValidator>,
RegisteredSerializableInput<TRegister>
>

@@ -509,2 +553,3 @@ export type ValidateValidator<

TInputValidator,
TStrict extends ServerFnStrict = true,
> =

@@ -514,3 +559,4 @@ ValidateValidatorInput<

TMethod,
TInputValidator
TInputValidator,
TStrict
> extends infer TInput

@@ -524,2 +570,3 @@ ? Validator<TInput, any>

TInputValidator,
TStrict extends ServerFnStrict = true,
> =

@@ -531,7 +578,8 @@ | (unknown extends TInputValidator

TMethod,
TInputValidator
TInputValidator,
TStrict
>
? TInputValidator
: never)
| ValidateValidator<TRegister, TMethod, TInputValidator>
| ValidateValidator<TRegister, TMethod, TInputValidator, TStrict>

@@ -550,2 +598,3 @@ export type AppendMiddlewares<TMiddlewares, TNewMiddlewares> =

TInputValidator,
TStrict extends ServerFnStrict,
> {

@@ -561,3 +610,4 @@ middleware: <const TNewMiddlewares>(

AppendMiddlewares<TMiddlewares, TNewMiddlewares>,
TInputValidator
TInputValidator,
TStrict
>

@@ -571,2 +621,3 @@ }

TInputValidator,
TStrict extends ServerFnStrict,
>

@@ -579,22 +630,47 @@ extends

TInputValidator,
undefined
undefined,
TStrict
>,
ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined>,
ServerFnValidator<TRegister, TMethod, TMiddlewares>,
ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {
<TNewMethod extends Method = TMethod>(options?: {
method?: TNewMethod
}): ServerFnAfterMiddleware<
ServerFnMiddleware<TRegister, TMethod, TMiddlewares, undefined, TStrict>,
ServerFnValidator<TRegister, TMethod, TMiddlewares, TStrict>,
ServerFnHandler<
TRegister,
TMethod,
TMiddlewares,
TInputValidator,
TStrict
> {
<
TNewMethod extends Method = TMethod,
TNewStrict extends ServerFnStrict = TStrict,
>(
options?: ServerFnOptions<TNewMethod, TNewStrict>,
): ServerFnAfterMiddleware<
TRegister,
TNewMethod,
TMiddlewares,
TInputValidator
TInputValidator,
TNewStrict
>
}
export type ValidatorFn<TRegister, TMethod extends Method, TMiddlewares> = <
export type ValidatorFn<
TRegister,
TMethod extends Method,
TMiddlewares,
TStrict extends ServerFnStrict,
> = <TInputValidator>(
inputValidator: ConstrainValidator<
TRegister,
TMethod,
TInputValidator,
TStrict
>,
) => ServerFnAfterValidator<
TRegister,
TMethod,
TMiddlewares,
TInputValidator,
>(
inputValidator: ConstrainValidator<TRegister, TMethod, TInputValidator>,
) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TInputValidator>
TStrict
>

@@ -605,4 +681,5 @@ export interface ServerFnValidator<

TMiddlewares,
TStrict extends ServerFnStrict,
> {
inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares>
inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares, TStrict>
}

@@ -615,2 +692,3 @@

TInputValidator,
TStrict extends ServerFnStrict,
>

@@ -623,6 +701,19 @@ extends

TInputValidator,
undefined
undefined,
TStrict
>,
ServerFnMiddleware<TRegister, TMethod, TMiddlewares, TInputValidator>,
ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {}
ServerFnMiddleware<
TRegister,
TMethod,
TMiddlewares,
TInputValidator,
TStrict
>,
ServerFnHandler<
TRegister,
TMethod,
TMiddlewares,
TInputValidator,
TStrict
> {}

@@ -634,2 +725,3 @@ export interface ServerFnAfterTyper<

TInputValidator,
TStrict extends ServerFnStrict,
>

@@ -642,5 +734,12 @@ extends

TInputValidator,
undefined
undefined,
TStrict
>,
ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {}
ServerFnHandler<
TRegister,
TMethod,
TMiddlewares,
TInputValidator,
TStrict
> {}

@@ -653,2 +752,3 @@ // Handler

TInputValidator,
TStrict extends ServerFnStrict,
> {

@@ -661,3 +761,4 @@ handler: <TNewResponse>(

TInputValidator,
TNewResponse
TNewResponse,
TStrict
>,

@@ -667,8 +768,25 @@ ) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>

export interface ServerFnBuilder<TRegister, TMethod extends Method = 'GET'>
export interface ServerFnBuilder<
TRegister,
TMethod extends Method = 'GET',
TStrict extends ServerFnStrict = true,
>
extends
ServerFnWithTypes<TRegister, TMethod, undefined, undefined, undefined>,
ServerFnMiddleware<TRegister, TMethod, undefined, undefined>,
ServerFnValidator<TRegister, TMethod, undefined>,
ServerFnHandler<TRegister, TMethod, undefined, undefined> {
ServerFnWithTypes<
TRegister,
TMethod,
undefined,
undefined,
undefined,
TStrict
>,
ServerFnMiddleware<TRegister, TMethod, undefined, undefined, TStrict>,
ServerFnValidator<TRegister, TMethod, undefined, TStrict>,
ServerFnHandler<TRegister, TMethod, undefined, undefined, TStrict> {
<
TNewMethod extends Method = TMethod,
TNewStrict extends ServerFnStrict = TStrict,
>(
options?: ServerFnOptions<TNewMethod, TNewStrict>,
): ServerFnBuilder<TRegister, TNewMethod, TNewStrict>
options: ServerFnBaseOptions<

@@ -679,3 +797,4 @@ TRegister,

undefined,
undefined
undefined,
TStrict
>

@@ -690,2 +809,3 @@ }

in out TResponse,
in out TStrict extends ServerFnStrict,
> {

@@ -697,3 +817,4 @@ '~types': ServerFnTypes<

TInputValidator,
TResponse
TResponse,
TStrict
>

@@ -705,3 +826,4 @@ options: ServerFnBaseOptions<

undefined,
undefined
undefined,
TStrict
>

@@ -711,3 +833,3 @@ [TSS_SERVER_FUNCTION_FACTORY]: true

export type AnyServerFn = ServerFnWithTypes<any, any, any, any, any>
export type AnyServerFn = ServerFnWithTypes<any, any, any, any, any, any>

@@ -720,4 +842,6 @@ export interface ServerFnTypes<

in out TResponse,
in out TStrict extends ServerFnStrict,
> {
method: TMethod
strict: TStrict
middlewares: TMiddlewares

@@ -724,0 +848,0 @@ inputValidator: TInputValidator

@@ -68,2 +68,6 @@ export type { JsonResponse } from '@tanstack/router-core/ssr/client'

ServerFnCtx,
ServerFnOptions,
ServerFnStrict,
ServerFnStrictInput,
ServerFnStrictOutput,
MiddlewareFn,

@@ -70,0 +74,0 @@ ServerFnMiddlewareOptions,

@@ -521,2 +521,127 @@ import { describe, expectTypeOf, test } from 'vitest'

test('createServerFn strict false can validate and return function', () => {
const fn = createServerFn({ method: 'GET', strict: false })
.inputValidator((input: { func: () => 'input' }) => ({
output: input.func(),
}))
.handler(({ data }) => {
expectTypeOf(data).toEqualTypeOf<{ output: 'input' }>()
return {
func: () => 'func' as const,
}
})
expectTypeOf(fn).parameter(0).toEqualTypeOf<{
data: { func: () => 'input' }
headers?: HeadersInit
signal?: AbortSignal
fetch?: CustomFetch
}>()
expectTypeOf(fn({ data: { func: () => 'input' } })).toEqualTypeOf<
Promise<{
func: () => 'func'
}>
>()
})
test('createServerFn strict false factory preserves strictness', () => {
const createServerFnWithoutSerializationCheck = createServerFn({
strict: false,
})
const myServerFn = createServerFnWithoutSerializationCheck()
.inputValidator((input: { func: () => 'input' }) => ({
output: input.func(),
}))
.handler(({ data }) => {
expectTypeOf(data).toEqualTypeOf<{ output: 'input' }>()
return {
func: () => 'func' as const,
}
})
expectTypeOf(myServerFn).parameter(0).toEqualTypeOf<{
data: { func: () => 'input' }
headers?: HeadersInit
signal?: AbortSignal
fetch?: CustomFetch
}>()
expectTypeOf(myServerFn({ data: { func: () => 'input' } })).toEqualTypeOf<
Promise<{
func: () => 'func'
}>
>()
})
test('createServerFn strict input false can validate function', () => {
const fn = createServerFn({ strict: { input: false } })
.inputValidator((input: { func: () => 'input' }) => ({
output: input.func(),
}))
.handler(({ data }) => {
expectTypeOf(data).toEqualTypeOf<{ output: 'input' }>()
return {
value: 'serializable' as const,
}
})
expectTypeOf(fn).parameter(0).toEqualTypeOf<{
data: { func: () => 'input' }
headers?: HeadersInit
signal?: AbortSignal
fetch?: CustomFetch
}>()
expectTypeOf(fn({ data: { func: () => 'input' } })).toEqualTypeOf<
Promise<{
value: 'serializable'
}>
>()
})
test('createServerFn strict output false can return function', () => {
const fn = createServerFn({ strict: { output: false } }).handler(() => ({
func: () => 'func' as const,
}))
expectTypeOf(fn()).toEqualTypeOf<
Promise<{
func: () => 'func'
}>
>()
const promiseFn = createServerFn({ strict: { output: false } }).handler(() =>
Promise.resolve({
func: () => 'func' as const,
}),
)
expectTypeOf(promiseFn()).toEqualTypeOf<
Promise<{
func: () => 'func'
}>
>()
})
test('ServerFnReturnType skips serialization when strict is false', () => {
expectTypeOf<
ServerFnReturnType<Register, { func: () => 'func' }, false>
>().toEqualTypeOf<{
func: () => 'func'
}>()
})
test('ServerFnReturnType skips serialization when strict output is false', () => {
expectTypeOf<
ServerFnReturnType<Register, { func: () => 'func' }, { output: false }>
>().toEqualTypeOf<{
func: () => 'func'
}>()
})
test('createServerFn cannot validate function', () => {

@@ -540,2 +665,21 @@ const validator = createServerFn().inputValidator<

test('createServerFn strict output false still checks input', () => {
const validator = createServerFn({
method: 'GET',
strict: { output: false },
}).inputValidator<(input: { func: () => 'string' }) => { output: 'string' }>
expectTypeOf(validator)
.parameter(0)
.toEqualTypeOf<
Constrain<
(input: { func: () => 'string' }) => { output: 'string' },
Validator<
{ func: SerializationError<'Function may not be serializable'> },
any
>
>
>()
})
test('createServerFn can validate Date', () => {

@@ -542,0 +686,0 @@ const validator = createServerFn().inputValidator<