@benjavicente/start-client-core 1.167.9
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/LICENSE +21 -0
- package/README.md +12 -0
- package/bin/intent.js +25 -0
- package/dist/esm/client/ServerFunctionSerializationAdapter.d.ts +7 -0
- package/dist/esm/client/ServerFunctionSerializationAdapter.js +18 -0
- package/dist/esm/client/ServerFunctionSerializationAdapter.js.map +1 -0
- package/dist/esm/client/hydrateStart.d.ts +2 -0
- package/dist/esm/client/hydrateStart.js +31 -0
- package/dist/esm/client/hydrateStart.js.map +1 -0
- package/dist/esm/client/index.d.ts +2 -0
- package/dist/esm/client/index.js +2 -0
- package/dist/esm/client-rpc/createClientRpc.d.ts +6 -0
- package/dist/esm/client-rpc/createClientRpc.js +21 -0
- package/dist/esm/client-rpc/createClientRpc.js.map +1 -0
- package/dist/esm/client-rpc/frame-decoder.d.ts +23 -0
- package/dist/esm/client-rpc/frame-decoder.js +231 -0
- package/dist/esm/client-rpc/frame-decoder.js.map +1 -0
- package/dist/esm/client-rpc/index.d.ts +1 -0
- package/dist/esm/client-rpc/index.js +2 -0
- package/dist/esm/client-rpc/serverFnFetcher.d.ts +1 -0
- package/dist/esm/client-rpc/serverFnFetcher.js +231 -0
- package/dist/esm/client-rpc/serverFnFetcher.js.map +1 -0
- package/dist/esm/constants.d.ts +53 -0
- package/dist/esm/constants.js +46 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/createMiddleware.d.ts +195 -0
- package/dist/esm/createMiddleware.js +26 -0
- package/dist/esm/createMiddleware.js.map +1 -0
- package/dist/esm/createServerFn.d.ts +131 -0
- package/dist/esm/createServerFn.js +200 -0
- package/dist/esm/createServerFn.js.map +1 -0
- package/dist/esm/createStart.d.ts +50 -0
- package/dist/esm/createStart.js +29 -0
- package/dist/esm/createStart.js.map +1 -0
- package/dist/esm/fake-start-entry.d.ts +2 -0
- package/dist/esm/fake-start-entry.js +7 -0
- package/dist/esm/fake-start-entry.js.map +1 -0
- package/dist/esm/getDefaultSerovalPlugins.d.ts +1 -0
- package/dist/esm/getDefaultSerovalPlugins.js +10 -0
- package/dist/esm/getDefaultSerovalPlugins.js.map +1 -0
- package/dist/esm/getGlobalStartContext.d.ts +3 -0
- package/dist/esm/getGlobalStartContext.js +12 -0
- package/dist/esm/getGlobalStartContext.js.map +1 -0
- package/dist/esm/getRouterInstance.d.ts +2 -0
- package/dist/esm/getRouterInstance.js +8 -0
- package/dist/esm/getRouterInstance.js.map +1 -0
- package/dist/esm/getStartContextServerOnly.d.ts +2 -0
- package/dist/esm/getStartContextServerOnly.js +8 -0
- package/dist/esm/getStartContextServerOnly.js.map +1 -0
- package/dist/esm/getStartOptions.d.ts +2 -0
- package/dist/esm/getStartOptions.js +8 -0
- package/dist/esm/getStartOptions.js.map +1 -0
- package/dist/esm/global.d.ts +7 -0
- package/dist/esm/index.d.ts +20 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/safeObjectMerge.d.ts +10 -0
- package/dist/esm/safeObjectMerge.js +30 -0
- package/dist/esm/safeObjectMerge.js.map +1 -0
- package/dist/esm/serverRoute.d.ts +65 -0
- package/dist/esm/startEntry.d.ts +8 -0
- package/dist/esm/tests/createServerFn.test-d.d.ts +1 -0
- package/dist/esm/tests/createServerMiddleware.test-d.d.ts +1 -0
- package/package.json +98 -0
- package/skills/start-core/SKILL.md +210 -0
- package/skills/start-core/deployment/SKILL.md +306 -0
- package/skills/start-core/execution-model/SKILL.md +302 -0
- package/skills/start-core/middleware/SKILL.md +365 -0
- package/skills/start-core/server-functions/SKILL.md +335 -0
- package/skills/start-core/server-routes/SKILL.md +280 -0
- package/src/client/ServerFunctionSerializationAdapter.ts +16 -0
- package/src/client/hydrateStart.ts +43 -0
- package/src/client/index.ts +2 -0
- package/src/client-rpc/createClientRpc.ts +20 -0
- package/src/client-rpc/frame-decoder.ts +389 -0
- package/src/client-rpc/index.ts +1 -0
- package/src/client-rpc/serverFnFetcher.ts +416 -0
- package/src/constants.ts +90 -0
- package/src/createMiddleware.ts +824 -0
- package/src/createServerFn.ts +813 -0
- package/src/createStart.ts +166 -0
- package/src/fake-start-entry.ts +2 -0
- package/src/getDefaultSerovalPlugins.ts +17 -0
- package/src/getGlobalStartContext.ts +18 -0
- package/src/getRouterInstance.ts +8 -0
- package/src/getStartContextServerOnly.ts +4 -0
- package/src/getStartOptions.ts +8 -0
- package/src/global.ts +9 -0
- package/src/index.tsx +119 -0
- package/src/safeObjectMerge.ts +38 -0
- package/src/serverRoute.ts +509 -0
- package/src/start-entry.d.ts +11 -0
- package/src/startEntry.ts +10 -0
- package/src/tests/createServerFn.test-d.ts +866 -0
- package/src/tests/createServerMiddleware.test-d.ts +810 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMiddleware.js","names":[],"sources":["../../src/createMiddleware.ts"],"sourcesContent":["import type { StartInstanceOptions } from './createStart'\nimport type {\n AnyServerFn,\n ConstrainValidator,\n CustomFetch,\n Method,\n} from './createServerFn'\nimport type { ClientFnMeta, ServerFnMeta } from './constants'\nimport type {\n AnyContext,\n Assign,\n Constrain,\n Expand,\n IntersectAssign,\n Register,\n ResolveValidatorInput,\n ResolveValidatorOutput,\n ValidateSerializableInput,\n} from '@benjavicente/router-core'\n\nexport type CreateMiddlewareFn<TRegister> = <TType extends MiddlewareType>(\n options?: {\n type?: TType\n },\n __opts?: FunctionMiddlewareOptions<\n TRegister,\n unknown,\n undefined,\n undefined,\n undefined\n >,\n) => CreateMiddlewareResult<TRegister, TType>\n\nexport const createMiddleware: CreateMiddlewareFn<{}> = (options, __opts) => {\n const resolvedOptions = {\n type: 'request',\n ...(__opts || options),\n }\n\n return {\n options: resolvedOptions,\n middleware: (middleware: any) => {\n return createMiddleware(\n {} as any,\n Object.assign(resolvedOptions, { middleware }),\n ) as any\n },\n inputValidator: (inputValidator: any) => {\n return createMiddleware(\n {} as any,\n Object.assign(resolvedOptions, { inputValidator }),\n ) as any\n },\n client: (client: any) => {\n return createMiddleware(\n {} as any,\n Object.assign(resolvedOptions, { client }),\n ) as any\n },\n server: (server: any) => {\n return createMiddleware(\n {} as any,\n Object.assign(resolvedOptions, { server }),\n ) as any\n },\n } as any\n}\n\nexport type MiddlewareType = 'request' | 'function'\n\nexport type CreateMiddlewareResult<\n TRegister,\n TType extends MiddlewareType,\n> = 'request' extends TType\n ? RequestMiddleware<TRegister>\n : FunctionMiddleware<TRegister>\n\nexport interface FunctionMiddleware<\n TRegister,\n> extends FunctionMiddlewareAfterMiddleware<TRegister, unknown> {\n middleware: <const TNewMiddlewares = undefined>(\n middlewares: Constrain<\n TNewMiddlewares,\n ReadonlyArray<AnyRequestMiddleware | AnyFunctionMiddleware>\n >,\n ) => FunctionMiddlewareAfterMiddleware<TRegister, TNewMiddlewares>\n}\n\nexport interface FunctionMiddlewareAfterMiddleware<TRegister, TMiddlewares>\n extends\n FunctionMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined\n >,\n FunctionMiddlewareServer<\n TRegister,\n TMiddlewares,\n undefined,\n undefined,\n undefined\n >,\n FunctionMiddlewareClient<TRegister, TMiddlewares, undefined>,\n FunctionMiddlewareValidator<TRegister, TMiddlewares> {}\n\nexport interface FunctionMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TServerSendContext,\n TClientContext,\n TClientSendContext,\n> {\n '~types': FunctionMiddlewareTypes<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TServerSendContext,\n TClientContext,\n TClientSendContext\n >\n options: FunctionMiddlewareOptions<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TClientContext\n >\n}\n\nexport interface FunctionMiddlewareTypes<\n in out TRegister,\n in out TMiddlewares,\n in out TInputValidator,\n in out TServerContext,\n in out TServerSendContext,\n in out TClientContext,\n in out TClientSendContext,\n> {\n type: 'function'\n middlewares: TMiddlewares\n input: ResolveValidatorInput<TInputValidator>\n allInput: IntersectAllValidatorInputs<TMiddlewares, TInputValidator>\n output: ResolveValidatorOutput<TInputValidator>\n allOutput: IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>\n clientContext: TClientContext\n allClientContextBeforeNext: AssignAllClientContextBeforeNext<\n TMiddlewares,\n TClientContext\n >\n allClientContextAfterNext: AssignAllClientContextAfterNext<\n TMiddlewares,\n TClientContext,\n TClientSendContext\n >\n serverContext: TServerContext\n serverSendContext: TServerSendContext\n allServerSendContext: AssignAllServerSendContext<\n TMiddlewares,\n TServerSendContext\n >\n allServerContext: AssignAllServerFnContext<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TServerContext\n >\n clientSendContext: TClientSendContext\n allClientSendContext: AssignAllClientSendContext<\n TMiddlewares,\n TClientSendContext\n >\n inputValidator: TInputValidator\n}\n\n/**\n * Recursively resolve the input type produced by a sequence of middleware\n */\nexport type IntersectAllValidatorInputs<TMiddlewares, TInputValidator> =\n unknown extends TInputValidator\n ? TInputValidator\n : TInputValidator extends undefined\n ? IntersectAllMiddleware<TMiddlewares, 'allInput'>\n : IntersectAssign<\n IntersectAllMiddleware<TMiddlewares, 'allInput'>,\n ResolveValidatorInput<TInputValidator>\n >\n\nexport type IntersectAllMiddleware<\n TMiddlewares,\n TType extends\n | keyof AnyFunctionMiddleware['~types']\n | keyof AnyRequestMiddleware['~types']\n | keyof AnyServerFn['~types'],\n TAcc = undefined,\n> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest]\n ? TMiddleware extends\n | AnyFunctionMiddleware\n | AnyRequestMiddleware\n | AnyServerFn\n ? IntersectAllMiddleware<\n TRest,\n TType,\n IntersectAssign<\n TAcc,\n TMiddleware['~types'][TType & keyof TMiddleware['~types']]\n >\n >\n : TAcc\n : TAcc\n\nexport type AnyFunctionMiddleware = FunctionMiddlewareWithTypes<\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\n/**\n * Recursively merge the output type produced by a sequence of middleware\n */\nexport type IntersectAllValidatorOutputs<TMiddlewares, TInputValidator> =\n unknown extends TInputValidator\n ? TInputValidator\n : TInputValidator extends undefined\n ? IntersectAllMiddleware<TMiddlewares, 'allOutput'>\n : IntersectAssign<\n IntersectAllMiddleware<TMiddlewares, 'allOutput'>,\n Awaited<ResolveValidatorOutput<TInputValidator>>\n >\n\n/**\n * Recursively resolve the client context type produced by a sequence of middleware\n */\nexport type AssignAllClientContextBeforeNext<\n TMiddlewares,\n TClientContext = undefined,\n> = unknown extends TClientContext\n ? TClientContext\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allClientContextBeforeNext'>,\n TClientContext\n >\n\nexport type AssignAllMiddleware<\n TMiddlewares,\n TType extends\n | keyof AnyFunctionMiddleware['~types']\n | keyof AnyRequestMiddleware['~types']\n | keyof AnyServerFn['~types'],\n TAcc = undefined,\n> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest]\n ? TMiddleware extends\n | AnyFunctionMiddleware\n | AnyRequestMiddleware\n | AnyServerFn\n ? AssignAllMiddleware<\n TRest,\n TType,\n Assign<TAcc, TMiddleware['~types'][TType & keyof TMiddleware['~types']]>\n >\n : TAcc\n : TAcc\n\nexport type AssignAllClientContextAfterNext<\n TMiddlewares,\n TClientContext = undefined,\n TSendContext = undefined,\n> = unknown extends TClientContext\n ? Assign<TClientContext, TSendContext>\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allClientContextAfterNext'>,\n Assign<TClientContext, TSendContext>\n >\n\nexport type AssignAllServerSendContext<\n TMiddlewares,\n TSendContext = undefined,\n> = unknown extends TSendContext\n ? TSendContext\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allServerSendContext'>,\n TSendContext\n >\n\nexport type AssignAllServerRequestContext<\n TRegister,\n TMiddlewares,\n TSendContext = undefined,\n TServerContext = undefined,\n> = Assign<\n // Fetch Request Context\n GlobalFetchRequestContext,\n Assign<\n GlobalServerRequestContext<TRegister>,\n __AssignAllServerRequestContext<TMiddlewares, TSendContext, TServerContext>\n >\n>\n\n// export type GlobalFetchRequestContext<TRegister> = AnyContext\nexport type GlobalFetchRequestContext = Register extends {\n server: { requestContext: infer TRequestContext }\n}\n ? TRequestContext\n : AnyContext\n\nexport type GlobalServerRequestContext<TRegister> = TRegister extends {\n config: StartInstanceOptions<any, any, infer TRequestMiddlewares, any>\n}\n ? AssignAllMiddleware<TRequestMiddlewares, 'allServerContext'>\n : AnyContext\n\ntype __AssignAllServerRequestContext<\n TMiddlewares,\n TSendContext = undefined,\n TServerContext = undefined,\n> = unknown extends TSendContext\n ? Assign<TSendContext, TServerContext>\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allServerContext'>,\n Assign<TSendContext, TServerContext>\n >\n\nexport type AssignAllServerFnContext<\n TRegister,\n TMiddlewares,\n TSendContext = undefined,\n TServerContext = undefined,\n> = Assign<\n GlobalFetchRequestContext,\n Assign<\n GlobalServerRequestContext<TRegister>, // TODO: This enabled global middleware\n // type inference, but creates a circular types issue. No idea how to fix this.\n // AnyContext,\n Assign<\n GlobalServerFnContext<TRegister>, // TODO: This enabled global middleware\n // type inference, but creates a circular types issue. No idea how to fix this.\n // AnyContext,/\n __AssignAllServerFnContext<TMiddlewares, TSendContext, TServerContext>\n >\n >\n>\n\ntype GlobalServerFnContext<TRegister> = TRegister extends {\n config: StartInstanceOptions<any, any, any, infer TFunctionMiddlewares>\n}\n ? AssignAllMiddleware<TFunctionMiddlewares, 'allServerContext'>\n : AnyContext\n\ntype __AssignAllServerFnContext<\n TMiddlewares,\n TSendContext = undefined,\n TServerContext = undefined,\n> = unknown extends TSendContext\n ? Assign<TSendContext, TServerContext>\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allServerContext'>,\n Assign<TSendContext, TServerContext>\n >\n\nexport type AssignAllClientSendContext<\n TMiddlewares,\n TSendContext = undefined,\n> = unknown extends TSendContext\n ? TSendContext\n : Assign<\n AssignAllMiddleware<TMiddlewares, 'allClientSendContext'>,\n TSendContext\n >\n\nexport interface FunctionMiddlewareOptions<\n in out TRegister,\n in out TMiddlewares,\n in out TInputValidator,\n in out TServerContext,\n in out TClientContext,\n> {\n middleware?: TMiddlewares\n inputValidator?: ConstrainValidator<TRegister, 'GET', TInputValidator>\n client?: FunctionMiddlewareClientFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TClientContext\n >\n server?: FunctionMiddlewareServerFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n unknown,\n unknown\n >\n}\n\nexport type FunctionMiddlewareClientNextFn<TRegister, TMiddlewares> = <\n TSendContext = undefined,\n TNewClientContext = undefined,\n>(ctx?: {\n context?: TNewClientContext\n sendContext?: ValidateSerializableInput<TRegister, TSendContext>\n headers?: HeadersInit\n fetch?: CustomFetch\n}) => Promise<\n FunctionClientResultWithContext<TMiddlewares, TSendContext, TNewClientContext>\n>\n\nexport interface FunctionMiddlewareServer<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext,\n TClientContext,\n> {\n server: <TNewServerContext = undefined, TSendContext = undefined>(\n server: FunctionMiddlewareServerFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext,\n TNewServerContext,\n TSendContext\n >,\n ) => FunctionMiddlewareAfterServer<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TNewServerContext,\n TServerSendContext,\n TClientContext,\n TSendContext\n >\n}\n\nexport type FunctionMiddlewareServerFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext,\n TNewServerContext,\n TSendContext,\n> = (\n options: FunctionMiddlewareServerFnOptions<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext\n >,\n) => FunctionMiddlewareServerFnResult<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TNewServerContext,\n TSendContext\n>\n\nexport type FunctionMiddlewareServerNextFn<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n> = <TNewServerContext = undefined, TSendContext = undefined>(ctx?: {\n context?: TNewServerContext\n sendContext?: ValidateSerializableInput<TRegister, TSendContext>\n}) => Promise<\n FunctionServerResultWithContext<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TNewServerContext,\n TSendContext\n >\n>\n\nexport type FunctionServerResultWithContext<\n in out TRegister,\n in out TMiddlewares,\n in out TServerSendContext,\n in out TServerContext,\n in out TSendContext,\n> = {\n 'use functions must return the result of next()': true\n '~types': {\n context: TServerContext\n sendContext: TSendContext\n }\n context: Expand<\n AssignAllServerFnContext<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TServerContext\n >\n >\n sendContext: Expand<AssignAllClientSendContext<TMiddlewares, TSendContext>>\n}\n\nexport interface FunctionMiddlewareServerFnOptions<\n in out TRegister,\n in out TMiddlewares,\n in out TInputValidator,\n in out TServerSendContext,\n> {\n data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>\n context: Expand<\n AssignAllServerFnContext<TRegister, TMiddlewares, TServerSendContext>\n >\n next: FunctionMiddlewareServerNextFn<\n TRegister,\n TMiddlewares,\n TServerSendContext\n >\n method: Method\n serverFnMeta: ServerFnMeta\n signal: AbortSignal\n}\n\nexport type FunctionMiddlewareServerFnResult<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TServerContext,\n TSendContext,\n> =\n | Promise<\n FunctionServerResultWithContext<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TServerContext,\n TSendContext\n >\n >\n | FunctionServerResultWithContext<\n TRegister,\n TMiddlewares,\n TServerSendContext,\n TServerContext,\n TSendContext\n >\n\nexport interface FunctionMiddlewareAfterServer<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TServerSendContext,\n TClientContext,\n TClientSendContext,\n> extends FunctionMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerContext,\n TServerSendContext,\n TClientContext,\n TClientSendContext\n> {}\n\nexport interface FunctionMiddlewareClient<\n TRegister,\n TMiddlewares,\n TInputValidator,\n> {\n client: <TSendServerContext = undefined, TNewClientContext = undefined>(\n client: FunctionMiddlewareClientFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TSendServerContext,\n TNewClientContext\n >,\n ) => FunctionMiddlewareAfterClient<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TSendServerContext,\n TNewClientContext\n >\n}\n\nexport type FunctionMiddlewareClientFn<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TSendContext,\n TClientContext,\n> = (\n options: FunctionMiddlewareClientFnOptions<\n TRegister,\n TMiddlewares,\n TInputValidator\n >,\n) => FunctionMiddlewareClientFnResult<\n TMiddlewares,\n TSendContext,\n TClientContext\n>\n\nexport interface FunctionMiddlewareClientFnOptions<\n in out TRegister,\n in out TMiddlewares,\n in out TInputValidator,\n> {\n data: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>\n context: Expand<AssignAllClientContextBeforeNext<TMiddlewares>>\n sendContext: Expand<AssignAllServerSendContext<TMiddlewares>>\n method: Method\n signal: AbortSignal\n serverFnMeta: ClientFnMeta\n next: FunctionMiddlewareClientNextFn<TRegister, TMiddlewares>\n filename: string\n fetch?: CustomFetch\n}\n\nexport type FunctionMiddlewareClientFnResult<\n TMiddlewares,\n TSendContext,\n TClientContext,\n> =\n | Promise<\n FunctionClientResultWithContext<\n TMiddlewares,\n TSendContext,\n TClientContext\n >\n >\n | FunctionClientResultWithContext<TMiddlewares, TSendContext, TClientContext>\n\nexport type FunctionClientResultWithContext<\n in out TMiddlewares,\n in out TSendContext,\n in out TClientContext,\n> = {\n 'use functions must return the result of next()': true\n context: Expand<AssignAllClientContextAfterNext<TMiddlewares, TClientContext>>\n sendContext: Expand<AssignAllServerSendContext<TMiddlewares, TSendContext>>\n headers: HeadersInit\n fetch?: CustomFetch\n}\n\nexport interface FunctionMiddlewareAfterClient<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext,\n TClientContext,\n>\n extends\n FunctionMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n TInputValidator,\n undefined,\n TServerSendContext,\n TClientContext,\n undefined\n >,\n FunctionMiddlewareServer<\n TRegister,\n TMiddlewares,\n TInputValidator,\n TServerSendContext,\n TClientContext\n > {}\n\nexport interface FunctionMiddlewareValidator<TRegister, TMiddlewares> {\n inputValidator: <TNewValidator>(\n inputValidator: ConstrainValidator<TRegister, 'GET', TNewValidator>,\n ) => FunctionMiddlewareAfterValidator<TRegister, TMiddlewares, TNewValidator>\n}\n\nexport interface FunctionMiddlewareAfterValidator<\n TRegister,\n TMiddlewares,\n TInputValidator,\n>\n extends\n FunctionMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n TInputValidator,\n undefined,\n undefined,\n undefined,\n undefined\n >,\n FunctionMiddlewareServer<\n TRegister,\n TMiddlewares,\n TInputValidator,\n undefined,\n undefined\n >,\n FunctionMiddlewareClient<TRegister, TMiddlewares, TInputValidator> {}\n\nexport interface RequestMiddleware<\n TRegister,\n> extends RequestMiddlewareAfterMiddleware<TRegister, undefined> {\n middleware: <const TMiddlewares = undefined>(\n middlewares: Constrain<TMiddlewares, ReadonlyArray<AnyRequestMiddleware>>,\n ) => RequestMiddlewareAfterMiddleware<TRegister, TMiddlewares>\n}\n\nexport type AnyRequestMiddleware = RequestMiddlewareWithTypes<any, any, any>\n\nexport interface RequestMiddlewareWithTypes<\n TRegister,\n TMiddlewares,\n TServerContext,\n> {\n '~types': RequestMiddlewareTypes<TRegister, TMiddlewares, TServerContext>\n options: RequestMiddlewareOptions<TRegister, TMiddlewares, TServerContext>\n}\n\nexport interface RequestMiddlewareOptions<\n in out TRegister,\n in out TMiddlewares,\n in out TServerContext,\n> {\n middleware?: TMiddlewares\n server?: RequestServerFn<TRegister, TMiddlewares, TServerContext>\n}\nexport interface RequestMiddlewareTypes<\n TRegister,\n TMiddlewares,\n TServerContext,\n> {\n type: 'request'\n // this only exists so we can use request middlewares in server functions\n allInput: undefined\n // this only exists so we can use request middlewares in server functions\n allOutput: undefined\n middlewares: TMiddlewares\n serverContext: TServerContext\n allServerContext: AssignAllServerRequestContext<\n TRegister,\n TMiddlewares,\n undefined,\n TServerContext\n >\n}\n\nexport interface RequestMiddlewareAfterMiddleware<TRegister, TMiddlewares>\n extends\n RequestMiddlewareWithTypes<TRegister, TMiddlewares, undefined>,\n RequestMiddlewareServer<TRegister, TMiddlewares> {}\n\nexport interface RequestMiddlewareServer<TRegister, TMiddlewares> {\n server: <TServerContext = undefined>(\n fn: RequestServerFn<TRegister, TMiddlewares, TServerContext>,\n ) => RequestMiddlewareAfterServer<TRegister, TMiddlewares, TServerContext>\n}\n\nexport type RequestServerFn<TRegister, TMiddlewares, TServerContext> = (\n options: RequestServerOptions<TRegister, TMiddlewares>,\n) => RequestMiddlewareServerFnResult<TRegister, TMiddlewares, TServerContext>\n\nexport interface RequestServerOptions<TRegister, TMiddlewares> {\n request: Request\n pathname: string\n context: Expand<AssignAllServerRequestContext<TRegister, TMiddlewares>>\n next: RequestServerNextFn<TRegister, TMiddlewares>\n /**\n * Metadata about the server function being invoked.\n * This is only present when the request is handling a server function call.\n * For regular page requests, this will be undefined.\n */\n serverFnMeta?: ServerFnMeta\n}\n\nexport type RequestServerNextFn<TRegister, TMiddlewares> = <\n TServerContext = undefined,\n>(\n options?: RequestServerNextFnOptions<TServerContext>,\n) => RequestServerNextFnResult<TRegister, TMiddlewares, TServerContext>\n\nexport interface RequestServerNextFnOptions<TServerContext> {\n context?: TServerContext\n}\n\nexport type RequestServerNextFnResult<TRegister, TMiddlewares, TServerContext> =\n | Promise<RequestServerResult<TRegister, TMiddlewares, TServerContext>>\n | RequestServerResult<TRegister, TMiddlewares, TServerContext>\n\nexport type RequestMiddlewareServerFnResult<\n TRegister,\n TMiddlewares,\n TServerContext,\n> =\n | Promise<\n RequestServerResult<TRegister, TMiddlewares, TServerContext> | Response\n >\n | RequestServerResult<TRegister, TMiddlewares, TServerContext>\n | Response\n\nexport interface RequestServerResult<TRegister, TMiddlewares, TServerContext> {\n request: Request\n pathname: string\n context: Expand<\n AssignAllServerRequestContext<\n TRegister,\n TMiddlewares,\n undefined,\n TServerContext\n >\n >\n response: Response\n}\n\nexport interface RequestMiddlewareAfterServer<\n TRegister,\n TMiddlewares,\n TServerContext,\n> extends RequestMiddlewareWithTypes<TRegister, TMiddlewares, TServerContext> {}\n"],"mappings":";AAiCA,IAAa,oBAA4C,SAAS,WAAW;CAC3E,MAAM,kBAAkB;EACtB,MAAM;EACN,GAAI,UAAU;EACf;AAED,QAAO;EACL,SAAS;EACT,aAAa,eAAoB;AAC/B,UAAO,iBACL,EAAE,EACF,OAAO,OAAO,iBAAiB,EAAE,YAAY,CAAC,CAC/C;;EAEH,iBAAiB,mBAAwB;AACvC,UAAO,iBACL,EAAE,EACF,OAAO,OAAO,iBAAiB,EAAE,gBAAgB,CAAC,CACnD;;EAEH,SAAS,WAAgB;AACvB,UAAO,iBACL,EAAE,EACF,OAAO,OAAO,iBAAiB,EAAE,QAAQ,CAAC,CAC3C;;EAEH,SAAS,WAAgB;AACvB,UAAO,iBACL,EAAE,EACF,OAAO,OAAO,iBAAiB,EAAE,QAAQ,CAAC,CAC3C;;EAEJ"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { TSS_SERVER_FUNCTION_FACTORY, ClientFnMeta, ServerFnMeta, TSS_SERVER_FUNCTION } from './constants.js';
|
|
2
|
+
import { AnyValidator, Constrain, Expand, Register, RegisteredSerializableInput, ResolveValidatorInput, ValidateSerializable, ValidateSerializableInput, Validator } from '@benjavicente/router-core';
|
|
3
|
+
import { AnyFunctionMiddleware, AnyRequestMiddleware, AssignAllServerFnContext, IntersectAllValidatorInputs, IntersectAllValidatorOutputs } from './createMiddleware.js';
|
|
4
|
+
export type CreateServerFn<TRegister> = <TMethod extends Method, TResponse = unknown, TMiddlewares = undefined, TInputValidator = undefined>(options?: {
|
|
5
|
+
method?: TMethod;
|
|
6
|
+
}, __opts?: ServerFnBaseOptions<TRegister, TMethod, TResponse, TMiddlewares, TInputValidator>) => ServerFnBuilder<TRegister, TMethod>;
|
|
7
|
+
export declare const createServerFn: CreateServerFn<Register>;
|
|
8
|
+
export declare function executeMiddleware(middlewares: Array<AnyFunctionMiddleware | AnyRequestMiddleware>, env: 'client' | 'server', opts: ServerFnMiddlewareOptions): Promise<ServerFnMiddlewareResult>;
|
|
9
|
+
export type CompiledFetcherFnOptions = {
|
|
10
|
+
method: Method;
|
|
11
|
+
data: unknown;
|
|
12
|
+
headers?: HeadersInit;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
fetch?: CustomFetch;
|
|
15
|
+
context?: any;
|
|
16
|
+
};
|
|
17
|
+
export type Fetcher<TMiddlewares, TInputValidator, TResponse> = undefined extends IntersectAllValidatorInputs<TMiddlewares, TInputValidator> ? OptionalFetcher<TMiddlewares, TInputValidator, TResponse> : RequiredFetcher<TMiddlewares, TInputValidator, TResponse>;
|
|
18
|
+
export interface FetcherBase {
|
|
19
|
+
[TSS_SERVER_FUNCTION]: true;
|
|
20
|
+
url: string;
|
|
21
|
+
method: Method;
|
|
22
|
+
__executeServer: (opts: {
|
|
23
|
+
method: Method;
|
|
24
|
+
data: unknown;
|
|
25
|
+
headers?: HeadersInit;
|
|
26
|
+
context?: any;
|
|
27
|
+
}) => Promise<unknown>;
|
|
28
|
+
}
|
|
29
|
+
export interface OptionalFetcher<TMiddlewares, TInputValidator, TResponse> extends FetcherBase {
|
|
30
|
+
(options?: OptionalFetcherDataOptions<TMiddlewares, TInputValidator>): Promise<Awaited<TResponse>>;
|
|
31
|
+
}
|
|
32
|
+
export interface RequiredFetcher<TMiddlewares, TInputValidator, TResponse> extends FetcherBase {
|
|
33
|
+
(opts: RequiredFetcherDataOptions<TMiddlewares, TInputValidator>): Promise<Awaited<TResponse>>;
|
|
34
|
+
}
|
|
35
|
+
export type CustomFetch = typeof globalThis.fetch;
|
|
36
|
+
export type FetcherBaseOptions = {
|
|
37
|
+
headers?: HeadersInit;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
fetch?: CustomFetch;
|
|
40
|
+
};
|
|
41
|
+
export interface OptionalFetcherDataOptions<TMiddlewares, TInputValidator> extends FetcherBaseOptions {
|
|
42
|
+
data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>;
|
|
43
|
+
}
|
|
44
|
+
export interface RequiredFetcherDataOptions<TMiddlewares, TInputValidator> extends FetcherBaseOptions {
|
|
45
|
+
data: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>;
|
|
46
|
+
}
|
|
47
|
+
export type RscStream<T> = {
|
|
48
|
+
__cacheState: T;
|
|
49
|
+
};
|
|
50
|
+
export type Method = 'GET' | 'POST';
|
|
51
|
+
export type ServerFnReturnType<TRegister, TResponse> = TResponse extends PromiseLike<infer U> ? Promise<ServerFnReturnType<TRegister, U>> : TResponse extends Response ? TResponse : ValidateSerializableInput<TRegister, TResponse>;
|
|
52
|
+
export type ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse> = (ctx: ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator>) => ServerFnReturnType<TRegister, TResponse>;
|
|
53
|
+
export interface ServerFnCtx<TRegister, TMethod, TMiddlewares, TInputValidator> {
|
|
54
|
+
data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>;
|
|
55
|
+
serverFnMeta: ServerFnMeta;
|
|
56
|
+
context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, {}>>;
|
|
57
|
+
method: TMethod;
|
|
58
|
+
}
|
|
59
|
+
export type CompiledFetcherFn<TRegister, TResponse> = {
|
|
60
|
+
(opts: CompiledFetcherFnOptions & ServerFnBaseOptions<TRegister, Method>): Promise<TResponse>;
|
|
61
|
+
url: string;
|
|
62
|
+
serverFnMeta: ServerFnMeta;
|
|
63
|
+
};
|
|
64
|
+
export type ServerFnBaseOptions<TRegister, TMethod extends Method = 'GET', TResponse = unknown, TMiddlewares = unknown, TInputValidator = unknown> = {
|
|
65
|
+
method: TMethod;
|
|
66
|
+
middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware>>;
|
|
67
|
+
inputValidator?: ConstrainValidator<TRegister, TMethod, TInputValidator>;
|
|
68
|
+
extractedFn?: CompiledFetcherFn<TRegister, TResponse>;
|
|
69
|
+
serverFn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse>;
|
|
70
|
+
};
|
|
71
|
+
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>>;
|
|
72
|
+
export type ValidateValidator<TRegister, TMethod extends Method, TInputValidator> = ValidateValidatorInput<TRegister, TMethod, TInputValidator> extends infer TInput ? Validator<TInput, any> : never;
|
|
73
|
+
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>;
|
|
74
|
+
export type AppendMiddlewares<TMiddlewares, TNewMiddlewares> = TMiddlewares extends ReadonlyArray<any> ? TNewMiddlewares extends ReadonlyArray<any> ? readonly [...TMiddlewares, ...TNewMiddlewares] : TMiddlewares : TNewMiddlewares;
|
|
75
|
+
export interface ServerFnMiddleware<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> {
|
|
76
|
+
middleware: <const TNewMiddlewares>(middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn>>) => ServerFnAfterMiddleware<TRegister, TMethod, AppendMiddlewares<TMiddlewares, TNewMiddlewares>, TInputValidator>;
|
|
77
|
+
}
|
|
78
|
+
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> {
|
|
79
|
+
<TNewMethod extends Method = TMethod>(options?: {
|
|
80
|
+
method?: TNewMethod;
|
|
81
|
+
}): ServerFnAfterMiddleware<TRegister, TNewMethod, TMiddlewares, TInputValidator>;
|
|
82
|
+
}
|
|
83
|
+
export type ValidatorFn<TRegister, TMethod extends Method, TMiddlewares> = <TInputValidator>(inputValidator: ConstrainValidator<TRegister, TMethod, TInputValidator>) => ServerFnAfterValidator<TRegister, TMethod, TMiddlewares, TInputValidator>;
|
|
84
|
+
export interface ServerFnValidator<TRegister, TMethod extends Method, TMiddlewares> {
|
|
85
|
+
inputValidator: ValidatorFn<TRegister, TMethod, TMiddlewares>;
|
|
86
|
+
}
|
|
87
|
+
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> {
|
|
88
|
+
}
|
|
89
|
+
export interface ServerFnAfterTyper<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> extends ServerFnWithTypes<TRegister, TMethod, TMiddlewares, TInputValidator, undefined>, ServerFnHandler<TRegister, TMethod, TMiddlewares, TInputValidator> {
|
|
90
|
+
}
|
|
91
|
+
export interface ServerFnHandler<TRegister, TMethod extends Method, TMiddlewares, TInputValidator> {
|
|
92
|
+
handler: <TNewResponse>(fn?: ServerFn<TRegister, TMethod, TMiddlewares, TInputValidator, TNewResponse>) => Fetcher<TMiddlewares, TInputValidator, TNewResponse>;
|
|
93
|
+
}
|
|
94
|
+
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> {
|
|
95
|
+
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined>;
|
|
96
|
+
}
|
|
97
|
+
export interface ServerFnWithTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse> {
|
|
98
|
+
'~types': ServerFnTypes<TRegister, TMethod, TMiddlewares, TInputValidator, TResponse>;
|
|
99
|
+
options: ServerFnBaseOptions<TRegister, TMethod, unknown, undefined, undefined>;
|
|
100
|
+
[TSS_SERVER_FUNCTION_FACTORY]: true;
|
|
101
|
+
}
|
|
102
|
+
export type AnyServerFn = ServerFnWithTypes<any, any, any, any, any>;
|
|
103
|
+
export interface ServerFnTypes<in out TRegister, in out TMethod extends Method, in out TMiddlewares, in out TInputValidator, in out TResponse> {
|
|
104
|
+
method: TMethod;
|
|
105
|
+
middlewares: TMiddlewares;
|
|
106
|
+
inputValidator: TInputValidator;
|
|
107
|
+
response: TResponse;
|
|
108
|
+
allServerContext: AssignAllServerFnContext<TRegister, TMiddlewares>;
|
|
109
|
+
allInput: IntersectAllValidatorInputs<TMiddlewares, TInputValidator>;
|
|
110
|
+
allOutput: IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>;
|
|
111
|
+
}
|
|
112
|
+
export declare function flattenMiddlewares<T extends AnyFunctionMiddleware | AnyRequestMiddleware>(middlewares: Array<T>, maxDepth?: number): Array<T>;
|
|
113
|
+
export type ServerFnMiddlewareOptions = {
|
|
114
|
+
method: Method;
|
|
115
|
+
data: any;
|
|
116
|
+
headers?: HeadersInit;
|
|
117
|
+
signal?: AbortSignal;
|
|
118
|
+
sendContext?: any;
|
|
119
|
+
context?: any;
|
|
120
|
+
serverFnMeta: ClientFnMeta;
|
|
121
|
+
fetch?: CustomFetch;
|
|
122
|
+
};
|
|
123
|
+
export type ServerFnMiddlewareResult = ServerFnMiddlewareOptions & {
|
|
124
|
+
result?: unknown;
|
|
125
|
+
error?: unknown;
|
|
126
|
+
};
|
|
127
|
+
export type NextFn = (ctx: ServerFnMiddlewareResult) => Promise<ServerFnMiddlewareResult>;
|
|
128
|
+
export type MiddlewareFn = (ctx: ServerFnMiddlewareOptions & {
|
|
129
|
+
next: NextFn;
|
|
130
|
+
}) => Promise<ServerFnMiddlewareResult>;
|
|
131
|
+
export declare function execValidator(validator: AnyValidator, input: unknown): Promise<unknown>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { TSS_SERVER_FUNCTION_FACTORY } from "./constants.js";
|
|
2
|
+
import { getStartOptions } from "./getStartOptions.js";
|
|
3
|
+
import { getStartContextServerOnly } from "./getStartContextServerOnly.js";
|
|
4
|
+
import { createNullProtoObject, safeObjectMerge } from "./safeObjectMerge.js";
|
|
5
|
+
import { mergeHeaders } from "@benjavicente/router-core/ssr/client";
|
|
6
|
+
import { isRedirect, parseRedirect } from "@benjavicente/router-core";
|
|
7
|
+
//#region src/createServerFn.ts
|
|
8
|
+
var createServerFn = (options, __opts) => {
|
|
9
|
+
const resolvedOptions = __opts || options || {};
|
|
10
|
+
if (typeof resolvedOptions.method === "undefined") resolvedOptions.method = "GET";
|
|
11
|
+
const res = {
|
|
12
|
+
options: resolvedOptions,
|
|
13
|
+
middleware: (middleware) => {
|
|
14
|
+
const newMiddleware = [...resolvedOptions.middleware || []];
|
|
15
|
+
middleware.map((m) => {
|
|
16
|
+
if (TSS_SERVER_FUNCTION_FACTORY in m) {
|
|
17
|
+
if (m.options.middleware) newMiddleware.push(...m.options.middleware);
|
|
18
|
+
} else newMiddleware.push(m);
|
|
19
|
+
});
|
|
20
|
+
const res = createServerFn(void 0, {
|
|
21
|
+
...resolvedOptions,
|
|
22
|
+
middleware: newMiddleware
|
|
23
|
+
});
|
|
24
|
+
res[TSS_SERVER_FUNCTION_FACTORY] = true;
|
|
25
|
+
return res;
|
|
26
|
+
},
|
|
27
|
+
inputValidator: (inputValidator) => {
|
|
28
|
+
return createServerFn(void 0, {
|
|
29
|
+
...resolvedOptions,
|
|
30
|
+
inputValidator
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
handler: (...args) => {
|
|
34
|
+
const [extractedFn, serverFn] = args;
|
|
35
|
+
const newOptions = {
|
|
36
|
+
...resolvedOptions,
|
|
37
|
+
extractedFn,
|
|
38
|
+
serverFn
|
|
39
|
+
};
|
|
40
|
+
const resolvedMiddleware = [...newOptions.middleware || [], serverFnBaseToMiddleware(newOptions)];
|
|
41
|
+
extractedFn.method = resolvedOptions.method;
|
|
42
|
+
return Object.assign(async (opts) => {
|
|
43
|
+
const result = await executeMiddleware(resolvedMiddleware, "client", {
|
|
44
|
+
...extractedFn,
|
|
45
|
+
...newOptions,
|
|
46
|
+
data: opts?.data,
|
|
47
|
+
headers: opts?.headers,
|
|
48
|
+
signal: opts?.signal,
|
|
49
|
+
fetch: opts?.fetch,
|
|
50
|
+
context: createNullProtoObject()
|
|
51
|
+
});
|
|
52
|
+
const redirect = parseRedirect(result.error);
|
|
53
|
+
if (redirect) throw redirect;
|
|
54
|
+
if (result.error) throw result.error;
|
|
55
|
+
return result.result;
|
|
56
|
+
}, {
|
|
57
|
+
...extractedFn,
|
|
58
|
+
method: resolvedOptions.method,
|
|
59
|
+
__executeServer: async (opts) => {
|
|
60
|
+
const startContext = getStartContextServerOnly();
|
|
61
|
+
const serverContextAfterGlobalMiddlewares = startContext.contextAfterGlobalMiddlewares;
|
|
62
|
+
return await executeMiddleware(resolvedMiddleware, "server", {
|
|
63
|
+
...extractedFn,
|
|
64
|
+
...opts,
|
|
65
|
+
serverFnMeta: extractedFn.serverFnMeta,
|
|
66
|
+
context: safeObjectMerge(serverContextAfterGlobalMiddlewares, opts.context),
|
|
67
|
+
request: startContext.request
|
|
68
|
+
}).then((d) => ({
|
|
69
|
+
result: d.result,
|
|
70
|
+
error: d.error,
|
|
71
|
+
context: d.sendContext
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const fun = (options) => {
|
|
78
|
+
return createServerFn(void 0, {
|
|
79
|
+
...resolvedOptions,
|
|
80
|
+
...options
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
return Object.assign(fun, res);
|
|
84
|
+
};
|
|
85
|
+
async function executeMiddleware(middlewares, env, opts) {
|
|
86
|
+
let flattenedMiddlewares = flattenMiddlewares([...getStartOptions()?.functionMiddleware || [], ...middlewares]);
|
|
87
|
+
if (env === "server") {
|
|
88
|
+
const startContext = getStartContextServerOnly({ throwIfNotFound: false });
|
|
89
|
+
if (startContext?.executedRequestMiddlewares) flattenedMiddlewares = flattenedMiddlewares.filter((m) => !startContext.executedRequestMiddlewares.has(m));
|
|
90
|
+
}
|
|
91
|
+
const callNextMiddleware = async (ctx) => {
|
|
92
|
+
const nextMiddleware = flattenedMiddlewares.shift();
|
|
93
|
+
if (!nextMiddleware) return ctx;
|
|
94
|
+
try {
|
|
95
|
+
if ("inputValidator" in nextMiddleware.options && nextMiddleware.options.inputValidator && env === "server") ctx.data = await execValidator(nextMiddleware.options.inputValidator, ctx.data);
|
|
96
|
+
let middlewareFn = void 0;
|
|
97
|
+
if (env === "client") {
|
|
98
|
+
if ("client" in nextMiddleware.options) middlewareFn = nextMiddleware.options.client;
|
|
99
|
+
} else if ("server" in nextMiddleware.options) middlewareFn = nextMiddleware.options.server;
|
|
100
|
+
if (middlewareFn) {
|
|
101
|
+
const userNext = async (userCtx = {}) => {
|
|
102
|
+
const result = await callNextMiddleware({
|
|
103
|
+
...ctx,
|
|
104
|
+
...userCtx,
|
|
105
|
+
context: safeObjectMerge(ctx.context, userCtx.context),
|
|
106
|
+
sendContext: safeObjectMerge(ctx.sendContext, userCtx.sendContext),
|
|
107
|
+
headers: mergeHeaders(ctx.headers, userCtx.headers),
|
|
108
|
+
_callSiteFetch: ctx._callSiteFetch,
|
|
109
|
+
fetch: ctx._callSiteFetch ?? userCtx.fetch ?? ctx.fetch,
|
|
110
|
+
result: userCtx.result !== void 0 ? userCtx.result : userCtx instanceof Response ? userCtx : ctx.result,
|
|
111
|
+
error: userCtx.error ?? ctx.error
|
|
112
|
+
});
|
|
113
|
+
if (result.error) throw result.error;
|
|
114
|
+
return result;
|
|
115
|
+
};
|
|
116
|
+
const result = await middlewareFn({
|
|
117
|
+
...ctx,
|
|
118
|
+
next: userNext
|
|
119
|
+
});
|
|
120
|
+
if (isRedirect(result)) return {
|
|
121
|
+
...ctx,
|
|
122
|
+
error: result
|
|
123
|
+
};
|
|
124
|
+
if (result instanceof Response) return {
|
|
125
|
+
...ctx,
|
|
126
|
+
result
|
|
127
|
+
};
|
|
128
|
+
if (!result) throw new Error("User middleware returned undefined. You must call next() or return a result in your middlewares.");
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
return callNextMiddleware(ctx);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
return {
|
|
134
|
+
...ctx,
|
|
135
|
+
error
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
return callNextMiddleware({
|
|
140
|
+
...opts,
|
|
141
|
+
headers: opts.headers || {},
|
|
142
|
+
sendContext: opts.sendContext || {},
|
|
143
|
+
context: opts.context || createNullProtoObject(),
|
|
144
|
+
_callSiteFetch: opts.fetch
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function flattenMiddlewares(middlewares, maxDepth = 100) {
|
|
148
|
+
const seen = /* @__PURE__ */ new Set();
|
|
149
|
+
const flattened = [];
|
|
150
|
+
const recurse = (middleware, depth) => {
|
|
151
|
+
if (depth > maxDepth) throw new Error(`Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`);
|
|
152
|
+
middleware.forEach((m) => {
|
|
153
|
+
if (m.options.middleware) recurse(m.options.middleware, depth + 1);
|
|
154
|
+
if (!seen.has(m)) {
|
|
155
|
+
seen.add(m);
|
|
156
|
+
flattened.push(m);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
recurse(middlewares, 0);
|
|
161
|
+
return flattened;
|
|
162
|
+
}
|
|
163
|
+
async function execValidator(validator, input) {
|
|
164
|
+
if (validator == null) return {};
|
|
165
|
+
if ("~standard" in validator) {
|
|
166
|
+
const result = await validator["~standard"].validate(input);
|
|
167
|
+
if (result.issues) throw new Error(JSON.stringify(result.issues, void 0, 2));
|
|
168
|
+
return result.value;
|
|
169
|
+
}
|
|
170
|
+
if ("parse" in validator) return validator.parse(input);
|
|
171
|
+
if (typeof validator === "function") return validator(input);
|
|
172
|
+
throw new Error("Invalid validator type!");
|
|
173
|
+
}
|
|
174
|
+
function serverFnBaseToMiddleware(options) {
|
|
175
|
+
return {
|
|
176
|
+
"~types": void 0,
|
|
177
|
+
options: {
|
|
178
|
+
inputValidator: options.inputValidator,
|
|
179
|
+
client: async ({ next, sendContext, fetch, ...ctx }) => {
|
|
180
|
+
const payload = {
|
|
181
|
+
...ctx,
|
|
182
|
+
context: sendContext,
|
|
183
|
+
fetch
|
|
184
|
+
};
|
|
185
|
+
return next(await options.extractedFn?.(payload));
|
|
186
|
+
},
|
|
187
|
+
server: async ({ next, ...ctx }) => {
|
|
188
|
+
const result = await options.serverFn?.(ctx);
|
|
189
|
+
return next({
|
|
190
|
+
...ctx,
|
|
191
|
+
result
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
export { createServerFn, execValidator, executeMiddleware, flattenMiddlewares };
|
|
199
|
+
|
|
200
|
+
//# sourceMappingURL=createServerFn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createServerFn.js","names":[],"sources":["../../src/createServerFn.ts"],"sourcesContent":["import { mergeHeaders } from '@benjavicente/router-core/ssr/client'\n\nimport { isRedirect, parseRedirect } from '@benjavicente/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 '@benjavicente/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 // Use safeObjectMerge for opts.context which comes from client\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 // Use safeObjectMerge for opts.context which comes from client\n context: safeObjectMerge(\n serverContextAfterGlobalMiddlewares,\n opts.context,\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\nexport type CustomFetch = typeof globalThis.fetch\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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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TSS_SERVER_FUNCTION } from './constants.js';
|
|
2
|
+
import { AnyFunctionMiddleware, AnyRequestMiddleware, CreateMiddlewareFn } from './createMiddleware.js';
|
|
3
|
+
import { CustomFetch } from './createServerFn.js';
|
|
4
|
+
import { AnySerializationAdapter, Register, SSROption } from '@benjavicente/router-core';
|
|
5
|
+
export interface StartInstanceOptions<in out TSerializationAdapters, in out TDefaultSsr, in out TRequestMiddlewares, in out TFunctionMiddlewares> {
|
|
6
|
+
'~types': StartInstanceTypes<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>;
|
|
7
|
+
serializationAdapters?: TSerializationAdapters;
|
|
8
|
+
defaultSsr?: TDefaultSsr;
|
|
9
|
+
requestMiddleware?: TRequestMiddlewares;
|
|
10
|
+
functionMiddleware?: TFunctionMiddlewares;
|
|
11
|
+
/**
|
|
12
|
+
* Configuration options for server functions.
|
|
13
|
+
*/
|
|
14
|
+
serverFns?: {
|
|
15
|
+
/**
|
|
16
|
+
* A custom fetch implementation to use for all server function calls.
|
|
17
|
+
* This can be overridden by middleware or at the call site.
|
|
18
|
+
*
|
|
19
|
+
* Precedence (highest to lowest):
|
|
20
|
+
* 1. Call site: `serverFn({ fetch: customFetch })`
|
|
21
|
+
* 2. Later middleware: Last middleware in chain that provides `fetch`
|
|
22
|
+
* 3. Earlier middleware: First middleware in chain that provides `fetch`
|
|
23
|
+
* 4. createStart: `createStart({ serverFns: { fetch: customFetch } })`
|
|
24
|
+
* 5. Default: Global `fetch` function
|
|
25
|
+
*
|
|
26
|
+
* @note Only applies on the client side. During SSR, server functions are called directly.
|
|
27
|
+
*/
|
|
28
|
+
fetch?: CustomFetch;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface StartInstance<in out TSerializationAdapters, in out TDefaultSsr, in out TRequestMiddlewares, in out TFunctionMiddlewares> {
|
|
32
|
+
getOptions: () => Promise<StartInstanceOptions<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>> | StartInstanceOptions<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>;
|
|
33
|
+
createMiddleware: CreateMiddlewareFn<Register>;
|
|
34
|
+
}
|
|
35
|
+
export interface StartInstanceTypes<in out TSerializationAdapters, in out TDefaultSsr, in out TRequestMiddlewares, in out TFunctionMiddlewares> {
|
|
36
|
+
serializationAdapters: TSerializationAdapters;
|
|
37
|
+
defaultSsr: TDefaultSsr;
|
|
38
|
+
requestMiddleware: TRequestMiddlewares;
|
|
39
|
+
functionMiddleware: TFunctionMiddlewares;
|
|
40
|
+
}
|
|
41
|
+
export declare const createStart: <const TSerializationAdapters extends ReadonlyArray<AnySerializationAdapter> = [], TDefaultSsr extends SSROption = SSROption, const TRequestMiddlewares extends ReadonlyArray<AnyRequestMiddleware> = [], const TFunctionMiddlewares extends ReadonlyArray<AnyFunctionMiddleware> = []>(getOptions: () => Promise<Omit<StartInstanceOptions<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>, "~types">> | Omit<StartInstanceOptions<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>, "~types">) => StartInstance<TSerializationAdapters, TDefaultSsr, TRequestMiddlewares, TFunctionMiddlewares>;
|
|
42
|
+
export type AnyStartInstance = StartInstance<any, any, any, any>;
|
|
43
|
+
export type AnyStartInstanceOptions = StartInstanceOptions<any, any, any, any>;
|
|
44
|
+
declare module '@benjavicente/router-core' {
|
|
45
|
+
interface SerializableExtensions {
|
|
46
|
+
serverFn: {
|
|
47
|
+
[TSS_SERVER_FUNCTION]: true;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createMiddleware } from "./createMiddleware.js";
|
|
2
|
+
//#region src/createStart.ts
|
|
3
|
+
function dedupeSerializationAdapters(deduped, serializationAdapters) {
|
|
4
|
+
for (let i = 0, len = serializationAdapters.length; i < len; i++) {
|
|
5
|
+
const current = serializationAdapters[i];
|
|
6
|
+
if (!deduped.has(current)) {
|
|
7
|
+
deduped.add(current);
|
|
8
|
+
if (current.extends) dedupeSerializationAdapters(deduped, current.extends);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
var createStart = (getOptions) => {
|
|
13
|
+
return {
|
|
14
|
+
getOptions: async () => {
|
|
15
|
+
const options = await getOptions();
|
|
16
|
+
if (options.serializationAdapters) {
|
|
17
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
18
|
+
dedupeSerializationAdapters(deduped, options.serializationAdapters);
|
|
19
|
+
options.serializationAdapters = Array.from(deduped);
|
|
20
|
+
}
|
|
21
|
+
return options;
|
|
22
|
+
},
|
|
23
|
+
createMiddleware
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { createStart };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=createStart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createStart.js","names":[],"sources":["../../src/createStart.ts"],"sourcesContent":["import { createMiddleware } from './createMiddleware'\nimport type { TSS_SERVER_FUNCTION } from './constants'\nimport type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n CreateMiddlewareFn,\n} from './createMiddleware'\nimport type { CustomFetch } from './createServerFn'\nimport type {\n AnySerializationAdapter,\n Register,\n SSROption,\n} from '@benjavicente/router-core'\n\nexport interface StartInstanceOptions<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n in out TRequestMiddlewares,\n in out TFunctionMiddlewares,\n> {\n '~types': StartInstanceTypes<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >\n serializationAdapters?: TSerializationAdapters\n defaultSsr?: TDefaultSsr\n requestMiddleware?: TRequestMiddlewares\n functionMiddleware?: TFunctionMiddlewares\n /**\n * Configuration options for server functions.\n */\n serverFns?: {\n /**\n * A custom fetch implementation to use for all server function calls.\n * This can be overridden by middleware or at the call site.\n *\n * Precedence (highest to lowest):\n * 1. Call site: `serverFn({ fetch: customFetch })`\n * 2. Later middleware: Last middleware in chain that provides `fetch`\n * 3. Earlier middleware: First middleware in chain that provides `fetch`\n * 4. createStart: `createStart({ serverFns: { fetch: customFetch } })`\n * 5. Default: Global `fetch` function\n *\n * @note Only applies on the client side. During SSR, server functions are called directly.\n */\n fetch?: CustomFetch\n }\n}\n\nexport interface StartInstance<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n in out TRequestMiddlewares,\n in out TFunctionMiddlewares,\n> {\n getOptions: () =>\n | Promise<\n StartInstanceOptions<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >\n >\n | StartInstanceOptions<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >\n createMiddleware: CreateMiddlewareFn<Register>\n}\n\nexport interface StartInstanceTypes<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n in out TRequestMiddlewares,\n in out TFunctionMiddlewares,\n> {\n serializationAdapters: TSerializationAdapters\n defaultSsr: TDefaultSsr\n requestMiddleware: TRequestMiddlewares\n functionMiddleware: TFunctionMiddlewares\n}\n\nfunction dedupeSerializationAdapters(\n deduped: Set<AnySerializationAdapter>,\n serializationAdapters: Array<AnySerializationAdapter>,\n): void {\n for (let i = 0, len = serializationAdapters.length; i < len; i++) {\n const current = serializationAdapters[i]!\n if (!deduped.has(current)) {\n deduped.add(current)\n if (current.extends) {\n dedupeSerializationAdapters(deduped, current.extends)\n }\n }\n }\n}\n\nexport const createStart = <\n const TSerializationAdapters extends ReadonlyArray<AnySerializationAdapter> =\n [],\n TDefaultSsr extends SSROption = SSROption,\n const TRequestMiddlewares extends ReadonlyArray<AnyRequestMiddleware> = [],\n const TFunctionMiddlewares extends ReadonlyArray<AnyFunctionMiddleware> = [],\n>(\n getOptions: () =>\n | Promise<\n Omit<\n StartInstanceOptions<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >,\n '~types'\n >\n >\n | Omit<\n StartInstanceOptions<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >,\n '~types'\n >,\n): StartInstance<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n> => {\n return {\n getOptions: async () => {\n const options = await getOptions()\n if (options.serializationAdapters) {\n const deduped = new Set<AnySerializationAdapter>()\n dedupeSerializationAdapters(\n deduped,\n options.serializationAdapters as unknown as Array<AnySerializationAdapter>,\n )\n options.serializationAdapters = Array.from(deduped) as any\n }\n return options\n },\n createMiddleware: createMiddleware,\n } as StartInstance<\n TSerializationAdapters,\n TDefaultSsr,\n TRequestMiddlewares,\n TFunctionMiddlewares\n >\n}\n\nexport type AnyStartInstance = StartInstance<any, any, any, any>\nexport type AnyStartInstanceOptions = StartInstanceOptions<any, any, any, any>\n\ndeclare module '@benjavicente/router-core' {\n interface SerializableExtensions {\n serverFn: { [TSS_SERVER_FUNCTION]: true }\n }\n}\n"],"mappings":";;AAuFA,SAAS,4BACP,SACA,uBACM;AACN,MAAK,IAAI,IAAI,GAAG,MAAM,sBAAsB,QAAQ,IAAI,KAAK,KAAK;EAChE,MAAM,UAAU,sBAAsB;AACtC,MAAI,CAAC,QAAQ,IAAI,QAAQ,EAAE;AACzB,WAAQ,IAAI,QAAQ;AACpB,OAAI,QAAQ,QACV,6BAA4B,SAAS,QAAQ,QAAQ;;;;AAM7D,IAAa,eAOX,eA0BG;AACH,QAAO;EACL,YAAY,YAAY;GACtB,MAAM,UAAU,MAAM,YAAY;AAClC,OAAI,QAAQ,uBAAuB;IACjC,MAAM,0BAAU,IAAI,KAA8B;AAClD,gCACE,SACA,QAAQ,sBACT;AACD,YAAQ,wBAAwB,MAAM,KAAK,QAAQ;;AAErD,UAAO;;EAES;EACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-start-entry.js","names":[],"sources":["../../src/fake-start-entry.ts"],"sourcesContent":["export const startInstance = undefined\nexport const getRouter = () => {}\n"],"mappings":";AAAA,IAAa,gBAAgB,KAAA;AAC7B,IAAa,kBAAkB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getDefaultSerovalPlugins(): (import('seroval').Plugin<any, any> | import('seroval').Plugin<Error, any> | import('seroval').Plugin<ReadableStream<any>, any>)[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getStartOptions } from "./getStartOptions.js";
|
|
2
|
+
import { defaultSerovalPlugins, makeSerovalPlugin } from "@benjavicente/router-core";
|
|
3
|
+
//#region src/getDefaultSerovalPlugins.ts
|
|
4
|
+
function getDefaultSerovalPlugins() {
|
|
5
|
+
return [...(getStartOptions()?.serializationAdapters)?.map(makeSerovalPlugin) ?? [], ...defaultSerovalPlugins];
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { getDefaultSerovalPlugins };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=getDefaultSerovalPlugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDefaultSerovalPlugins.js","names":[],"sources":["../../src/getDefaultSerovalPlugins.ts"],"sourcesContent":["import {\n makeSerovalPlugin,\n defaultSerovalPlugins as routerDefaultSerovalPlugins,\n} from '@benjavicente/router-core'\nimport { getStartOptions } from './getStartOptions'\nimport type { AnySerializationAdapter } from '@benjavicente/router-core'\n\nexport function getDefaultSerovalPlugins() {\n const start = getStartOptions()\n const adapters = start?.serializationAdapters as\n | Array<AnySerializationAdapter>\n | undefined\n return [\n ...(adapters?.map(makeSerovalPlugin) ?? []),\n ...routerDefaultSerovalPlugins,\n ]\n}\n"],"mappings":";;;AAOA,SAAgB,2BAA2B;AAKzC,QAAO,CACL,IALY,iBAAiB,EACP,wBAIR,IAAI,kBAAkB,IAAI,EAAE,EAC1C,GAAG,sBACJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createIsomorphicFn } from "@benjavicente/start-fn-stubs";
|
|
2
|
+
import { getStartContext } from "@benjavicente/start-storage-context";
|
|
3
|
+
//#region src/getGlobalStartContext.ts
|
|
4
|
+
var getGlobalStartContext = createIsomorphicFn().client(() => void 0).server(() => {
|
|
5
|
+
const context = getStartContext().contextAfterGlobalMiddlewares;
|
|
6
|
+
if (!context) throw new Error(`Global context not set yet, you are calling getGlobalStartContext() before the global middlewares are applied.`);
|
|
7
|
+
return context;
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getGlobalStartContext };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=getGlobalStartContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getGlobalStartContext.js","names":[],"sources":["../../src/getGlobalStartContext.ts"],"sourcesContent":["import { getStartContext } from '@benjavicente/start-storage-context'\nimport { createIsomorphicFn } from '@benjavicente/start-fn-stubs'\nimport type { AssignAllServerRequestContext } from './createMiddleware'\nimport type { Expand, Register } from '@benjavicente/router-core'\n\nexport const getGlobalStartContext: () =>\n | Expand<AssignAllServerRequestContext<Register, []>>\n | undefined = createIsomorphicFn()\n .client(() => undefined)\n .server(() => {\n const context = getStartContext().contextAfterGlobalMiddlewares\n if (!context) {\n throw new Error(\n `Global context not set yet, you are calling getGlobalStartContext() before the global middlewares are applied.`,\n )\n }\n return context\n })\n"],"mappings":";;;AAKA,IAAa,wBAEG,oBAAoB,CACjC,aAAa,KAAA,EAAU,CACvB,aAAa;CACZ,MAAM,UAAU,iBAAiB,CAAC;AAClC,KAAI,CAAC,QACH,OAAM,IAAI,MACR,iHACD;AAEH,QAAO;EACP"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createIsomorphicFn } from "@benjavicente/start-fn-stubs";
|
|
2
|
+
import { getStartContext } from "@benjavicente/start-storage-context";
|
|
3
|
+
//#region src/getRouterInstance.ts
|
|
4
|
+
var getRouterInstance = createIsomorphicFn().client(() => window.__TSR_ROUTER__).server(() => getStartContext().getRouter());
|
|
5
|
+
//#endregion
|
|
6
|
+
export { getRouterInstance };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=getRouterInstance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRouterInstance.js","names":[],"sources":["../../src/getRouterInstance.ts"],"sourcesContent":["import { getStartContext } from '@benjavicente/start-storage-context'\nimport { createIsomorphicFn } from '@benjavicente/start-fn-stubs'\nimport type { Awaitable, RegisteredRouter } from '@benjavicente/router-core'\n\nexport const getRouterInstance: () => Awaitable<RegisteredRouter> =\n createIsomorphicFn()\n .client(() => window.__TSR_ROUTER__!)\n .server(() => getStartContext().getRouter())\n"],"mappings":";;;AAIA,IAAa,oBACX,oBAAoB,CACjB,aAAa,OAAO,eAAgB,CACpC,aAAa,iBAAiB,CAAC,WAAW,CAAC"}
|