import type { FunctionType, FunctionVisibility, RegisteredAction, RegisteredMutation, RegisteredQuery, } from "convex/server"; import type { Schema } from "effect"; import * as Predicate from "effect/Predicate"; import * as FunctionProvenance from "./FunctionProvenance"; import { validateConfectFunctionIdentifier } from "./Identifier"; import * as RuntimeAndFunctionType from "./RuntimeAndFunctionType"; export const TypeId = "@confect/core/FunctionSpec"; export type TypeId = typeof TypeId; export const isFunctionSpec = (u: unknown): u is AnyWithProps => Predicate.hasProperty(u, TypeId); export interface FunctionSpec< RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility_ extends FunctionVisibility, Name_ extends string, FunctionProvenance_ extends FunctionProvenance.FunctionProvenance, > { readonly [TypeId]: TypeId; readonly runtimeAndFunctionType: RuntimeAndFunctionType_; readonly functionVisibility: FunctionVisibility_; readonly name: Name_; readonly functionProvenance: FunctionProvenance_; } export interface Any { readonly [TypeId]: TypeId; } export interface AnyWithProps extends FunctionSpec< RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility, string, FunctionProvenance.FunctionProvenance > {} export interface AnyConfect extends FunctionSpec< RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility, string, FunctionProvenance.AnyConfect > {} export interface AnyConvex extends FunctionSpec< RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility, string, FunctionProvenance.AnyConvex > {} export interface AnyWithPropsWithRuntime< Runtime extends RuntimeAndFunctionType.Runtime, > extends FunctionSpec< RuntimeAndFunctionType.WithRuntime, FunctionVisibility, string, FunctionProvenance.FunctionProvenance > {} export interface AnyWithPropsWithFunctionType< RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, > extends FunctionSpec< RuntimeAndFunctionType_, FunctionVisibility, string, FunctionProvenance.FunctionProvenance > {} export interface AnyWithPropsWithFunctionProvenance< FunctionProvenance_ extends FunctionProvenance.FunctionProvenance, > extends FunctionSpec< RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility, string, FunctionProvenance_ > {} export type GetRuntimeAndFunctionType = FunctionSpec_["runtimeAndFunctionType"]; export type GetFunctionVisibility = FunctionSpec_["functionVisibility"]; export type Name = FunctionSpec_["name"]; export type Args = FunctionSpec_ extends { functionProvenance: { _tag: "Confect"; args: infer ArgsSchema_ extends Schema.Schema.AnyNoContext; }; } ? ArgsSchema_["Type"] : FunctionSpec_ extends { functionProvenance: { _tag: "Convex"; _args: infer Args_ }; } ? Args_ : never; export type Returns = FunctionSpec_ extends { functionProvenance: { _tag: "Confect"; returns: infer ReturnsSchema_ extends Schema.Schema.AnyNoContext; }; } ? ReturnsSchema_["Type"] : FunctionSpec_ extends { functionProvenance: { _tag: "Convex"; _returns: infer Returns_ }; } ? Awaited : never; export type EncodedArgs = FunctionSpec_ extends { functionProvenance: { _tag: "Confect"; args: infer ArgsSchema_ extends Schema.Schema.AnyNoContext; }; } ? ArgsSchema_["Encoded"] : FunctionSpec_ extends { functionProvenance: { _tag: "Convex"; _args: infer Args_ }; } ? Args_ : never; export type EncodedReturns = FunctionSpec_ extends { functionProvenance: { _tag: "Confect"; returns: infer ReturnsSchema_ extends Schema.Schema.AnyNoContext; }; } ? ReturnsSchema_["Encoded"] : FunctionSpec_ extends { functionProvenance: { _tag: "Convex"; _returns: infer Returns_ }; } ? Returns_ : never; export type Error = FunctionSpec_ extends { functionProvenance: FunctionProvenance.Confect< any, any, infer ErrorSchema_ extends Schema.Schema.AnyNoContext >; } ? ErrorSchema_["Type"] : never; export type EncodedError = FunctionSpec_ extends { functionProvenance: FunctionProvenance.Confect< any, any, infer ErrorSchema_ extends Schema.Schema.AnyNoContext >; } ? ErrorSchema_["Encoded"] : never; export type WithName< FunctionSpec_ extends AnyWithProps, Name_ extends string, > = Extract; export type WithRuntimeAndFunctionType< FunctionSpec_ extends AnyWithProps, RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, > = Extract< FunctionSpec_, { readonly runtimeAndFunctionType: RuntimeAndFunctionType_ } >; export type WithFunctionType< FunctionSpec_ extends AnyWithProps, FunctionType_ extends FunctionType, > = Extract< FunctionSpec_, { readonly runtimeAndFunctionType: { readonly functionType: FunctionType_ } } >; export type WithFunctionProvenance< FunctionSpec_ extends AnyWithProps, FunctionProvenance_ extends FunctionProvenance.FunctionProvenance, > = Extract< FunctionSpec_, { readonly functionProvenance: FunctionProvenance_ } >; export type WithoutName< FunctionSpec_ extends AnyWithProps, Name_ extends Name, > = Exclude; const Proto = { [TypeId]: TypeId, }; const make = < RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility_ extends FunctionVisibility, >( runtimeAndFunctionType: RuntimeAndFunctionType_, functionVisibility: FunctionVisibility_, ) => < const Name_ extends string, Args_ extends Schema.Schema.AnyNoContext, Returns_ extends Schema.Schema.AnyNoContext, Error_ extends Schema.Schema.AnyNoContext = never, >({ name, args, returns, error, }: { name: Name_; args: () => Args_; returns: () => Returns_; error?: () => Error_; }): FunctionSpec< RuntimeAndFunctionType_, FunctionVisibility_, Name_, FunctionProvenance.Confect > => { validateConfectFunctionIdentifier(name); return Object.assign(Object.create(Proto), { runtimeAndFunctionType, functionVisibility, name, functionProvenance: FunctionProvenance.Confect(args, returns, error), }); }; export const publicQuery = make(RuntimeAndFunctionType.ConvexQuery, "public"); export const internalQuery = make( RuntimeAndFunctionType.ConvexQuery, "internal", ); export const publicMutation = make( RuntimeAndFunctionType.ConvexMutation, "public", ); export const internalMutation = make( RuntimeAndFunctionType.ConvexMutation, "internal", ); export const publicAction = make(RuntimeAndFunctionType.ConvexAction, "public"); export const internalAction = make( RuntimeAndFunctionType.ConvexAction, "internal", ); export const publicNodeAction = make( RuntimeAndFunctionType.NodeAction, "public", ); export const internalNodeAction = make( RuntimeAndFunctionType.NodeAction, "internal", ); type MatchingRegisteredFunction< RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility_ extends FunctionVisibility, > = RuntimeAndFunctionType.GetFunctionType extends "query" ? RegisteredQuery : RuntimeAndFunctionType.GetFunctionType extends "mutation" ? RegisteredMutation : RuntimeAndFunctionType.GetFunctionType extends "action" ? RegisteredAction : never; type ExtractArgs = F extends RegisteredQuery ? A : F extends RegisteredMutation ? A : F extends RegisteredAction ? A : never; type ExtractReturns = F extends RegisteredQuery ? R : F extends RegisteredMutation ? R : F extends RegisteredAction ? R : never; const makeConvex = < RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType, FunctionVisibility_ extends FunctionVisibility, >( runtimeAndFunctionType: RuntimeAndFunctionType_, functionVisibility: FunctionVisibility_, ) => < F extends MatchingRegisteredFunction< RuntimeAndFunctionType_, FunctionVisibility_ >, >() => ( name: Name_, ): FunctionSpec< RuntimeAndFunctionType_, FunctionVisibility_, Name_, FunctionProvenance.Convex, ExtractReturns> > => { validateConfectFunctionIdentifier(name); return Object.assign(Object.create(Proto), { runtimeAndFunctionType, functionVisibility, name, functionProvenance: FunctionProvenance.Convex< ExtractArgs, ExtractReturns >(), }) as any; }; export const convexPublicQuery = makeConvex( RuntimeAndFunctionType.ConvexQuery, "public", ); export const convexInternalQuery = makeConvex( RuntimeAndFunctionType.ConvexQuery, "internal", ); export const convexPublicMutation = makeConvex( RuntimeAndFunctionType.ConvexMutation, "public", ); export const convexInternalMutation = makeConvex( RuntimeAndFunctionType.ConvexMutation, "internal", ); export const convexPublicAction = makeConvex( RuntimeAndFunctionType.ConvexAction, "public", ); export const convexInternalAction = makeConvex( RuntimeAndFunctionType.ConvexAction, "internal", ); export const convexPublicNodeAction = makeConvex( RuntimeAndFunctionType.NodeAction, "public", ); export const convexInternalNodeAction = makeConvex( RuntimeAndFunctionType.NodeAction, "internal", );