import { TailorEnv, TailorPrincipal } from "../../../runtime/types.mjs"; import { InferFieldsOutput, output } from "../../../types/helpers.mjs"; import { MachineUserName } from "../auth/types.mjs"; import { ResolverInput } from "../../../types/resolver.generated.mjs"; import { ResolverPermission } from "./permission.mjs"; import "../../types/machine-user.mjs"; import { TailorAnyField, TailorField } from "../../types/type.mjs"; //#region src/configure/services/resolver/resolver.d.ts type Context | undefined> = { input: Input extends Record ? InferFieldsOutput : never; caller: TailorPrincipal | null; invoker: TailorPrincipal | null; env: TailorEnv; }; type OutputType = O extends TailorAnyField ? output : O extends Record ? InferFieldsOutput : never; /** * Normalized output type that preserves generic type information. * - If Output is already a TailorField, use it as-is * - If Output is a Record of fields, wrap it as a nested TailorField */ type NormalizedOutput> = Output extends TailorAnyField ? Output : TailorField<{ type: "nested"; array: false; }, InferFieldsOutput>>>; type ResolverReturn | undefined, Output extends TailorAnyField | Record> = Omit & Readonly<{ input?: Input; output: NormalizedOutput; body: (context: Context) => OutputType | Promise>; invoker?: MachineUserName; permission?: ResolverPermission; }>; /** * Create a resolver definition for the Tailor SDK. * * The `body` function receives a context with `input` (typed from `config.input`), * `caller`, `invoker` (reflects configured machine-user delegation), and `env`. * The return value of `body` must match the `output` type. * * `output` accepts either a single TailorField (e.g. `t.string()`) or a * Record of fields (e.g. `{ name: t.string(), age: t.int() }`). * * `publishEvents` enables publishing execution events for this resolver. * If not specified, this is automatically set to true when an executor uses this resolver * with `resolverExecutedTrigger`. If explicitly set to false while an executor uses this * resolver, an error will be thrown during apply. * * `permission` declares the resolver's access requirement, checked against `context.user` (the * original caller, unaffected by `authInvoker`) before `body` runs. Omitted (default): * unchanged, anonymous callers can reach the resolver. `"allowAnonymous"`: explicitly documents * that anonymous callers are allowed. An array of `{ conditions, permit }` policies (in the same * style as TailorDB's `.permission()`) rejects non-matching callers: at least one `permit: true` * policy is required (denied unless it matches), and a matching `permit: false` policy always * overrides that grant. * @template Input * @template Output * @param config - Resolver configuration * @returns Normalized resolver configuration * @example * import { createResolver, t } from "@tailor-platform/sdk"; * * export default createResolver({ * name: "getUser", * operation: "query", * permission: [{ conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true }], * input: { * id: t.string(), * }, * body: async ({ input, caller }) => { * const db = getDB("tailordb"); * const result = await db.selectFrom("User").selectAll().where("id", "=", input.id).executeTakeFirst(); * return { name: result?.name ?? "", email: result?.email ?? "" }; * }, * output: t.object({ * name: t.string(), * email: t.string(), * }), * }); */ export declare function createResolver | undefined = undefined, Output extends TailorAnyField | Record = TailorAnyField>(config: Omit & Readonly<{ input?: Input; output: Output; body: (context: Context) => OutputType | Promise>; invoker?: MachineUserName; permission?: ResolverPermission; }>): ResolverReturn; export type ResolverConfig = ReturnType>; //#endregion