1import * as Effect from "effect/Effect";
2import * as Binding from "../../Binding.ts";
3import type { Zone } from "../Zone/Zone.ts";
4import { type ReadDnsClient } from "./ReadDns.ts";
5import { type WriteDnsClient } from "./WriteDns.ts";
6
7/**
8 * Binding that lets a Worker perform the full Cloudflare DNS record CRUD
9 * surface at runtime.
10 *
11 * Creates a least-privilege {@link AccountApiToken} with both the `DNS Read`
12 * and `DNS Write` permissions, scoped to the single zone passed to `bind`, and
13 * binds its value into the Worker so runtime code can authenticate.
14 *
15 *
16 * ### Managing DNS records at runtime
17 * **Example:** Full CRUD from inside a Worker
18 * Bind the client in the Worker's Init phase and provide
19 * {@link ReadWriteDnsBinding}. The zone is fixed by `ReadWriteDnsBinding(zone)` — the
20 * provisioned token only grants access to that zone, so calls take no
21 * `zoneId`. Pass the {@link Zone} resource directly (it's an `Effect`), or
22 * `yield* Zone` for a resolved value.
23 * ```typescript
24 * import * as Cloudflare from "alchemy/Cloudflare";
25 * import * as Effect from "effect/Effect";
26 * import * as HttpServerResponse from "effect/http/HttpServerResponse";
27 *
28 * const Zone = Cloudflare.Zone.Zone("MyZone", { name: "example.com" });
29 *
30 * export class Worker extends Cloudflare.Worker<Worker>()(
31 * "Worker",
32 * { main: import.meta.url },
33 * Effect.gen(function* () {
34 * // Init phase — bind the full CRUD client scoped to the zone.
35 * const dns = yield* Cloudflare.DNS.ReadWriteDns(Zone);
36 *
37 * return {
38 * fetch: Effect.gen(function* () {
39 * const { result } = yield* dns.createDnsRecord({
40 * type: "A",
41 * name: "app.example.com",
42 * content: "192.0.2.1",
43 * ttl: 1,
44 * });
45 * const record = yield* dns.getDnsRecord(result.id);
46 * yield* dns.deleteDnsRecord(result.id);
47 * return yield* HttpServerResponse.json({ id: record.id });
48 * }),
49 * };
50 * }).pipe(Effect.provide(Cloudflare.DNS.ReadWriteDnsBinding)),
51 * ) {}
52 * ```
53 *
54 * @binding
55 * @product DNS
56 * @category Domains & DNS
57 */
58export interface ReadWriteDns extends Binding.Service<
59 ReadWriteDns,
60 "Cloudflare.DNS.ReadWriteDns",
61 (zone: Zone) => Effect.Effect<ReadWriteDnsClient>
62> {}
63
64export const ReadWriteDns = Binding.Service<ReadWriteDns>(
65 "Cloudflare.DNS.ReadWriteDns",
66);
67
68/** Combined read + write DNS record operations. */
69export interface ReadWriteDnsClient extends ReadDnsClient, WriteDnsClient {}