import { type HandlerContext } from "@aotter/mantle-runtime"; export interface CloudflareTurnstileCheckOptions { /** Server-side secret. Pulled from `env.TURNSTILE_SECRET_KEY` by the * factory. The literal string `"dev-stub"` short-circuits to a * local check (`token === "fail"` is rejected, anything else * passes) — useful for integration smokes that run with no * network. Any other value triggers real `siteverify`. */ readonly secret: string; /** Field name on the procedure input carrying the client-side * widget token. Defaults to `"turnstileToken"` (matches the * starter's contact-messages Schema). */ readonly tokenField?: string; } /** * `before_create` (or any pre-mutation) hook that verifies a * Cloudflare Turnstile token. Builtin handler factory — register * with: * * register("captchaCheck", cloudflareTurnstileCheck({ * secret: env.TURNSTILE_SECRET_KEY ?? "dev-stub", * })); * * Behavior: * * - Authenticated callers (`ctx.user` non-null) bypass — the gate * guards anonymous public-form abuse, not signed-in writes * (admin UI, MCP agents). * - `secret === "dev-stub"`: short-circuit. `token === "fail"` * rejects; anything else passes. Tests assert on this token * shape; integration runs need no network. * - Otherwise: POSTs to `siteverify`, fails on `{ success: false }` * or any HTTP error. * * Throws `InvokeFailure(AUTH_DENIED)` on rejection so the procedure * mount maps it to HTTP 403, the right code for "your form * submission was rejected by abuse-prevention." A plain `Error` * surfaces as INTERNAL_ERROR (500) and falsely implies a server * bug. */ export declare function cloudflareTurnstileCheck(options: CloudflareTurnstileCheckOptions): (input: unknown, ctx: HandlerContext) => Promise<{ ok: true; }>; //# sourceMappingURL=turnstile.d.ts.map