1import type * as Credentials from "@distilled.cloud/aws/Credentials";
2import type * as SigV4 from "@distilled.cloud/aws/SigV4";
3import type * as Effect from "effect/Effect";
4import * as Binding from "../../Binding.ts";
5import type { OpenSearchApiError } from "./DataPlaneTypes.ts";
6import type { Domain } from "./Domain.ts";
7import type { ReadDomainClient } from "./DomainRead.ts";
8import type { WriteDomainClient } from "./DomainWrite.ts";
9
10/**
11 * Runtime client with full access to a domain's REST data plane — everything
12 * on {@link ReadDomainClient} and {@link WriteDomainClient} plus a raw
13 * any-method escape hatch.
14 */
15export interface ReadWriteDomainClient
16 extends ReadDomainClient, WriteDomainClient {
17 /**
18 * Raw escape hatch — a SigV4-signed request with any method against any
19 * data-plane path (e.g. `PUT /my-index` to create an index with explicit
20 * mappings, or `POST /_reindex`).
21 */
22 request(
23 method: "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "PATCH",
24 path: string,
25 options?: {
26 /** Query-string parameters. */
27 query?: Record<string, string | undefined>;
28 /** JSON body (sent as `application/json`). */
29 body?: unknown;
30 },
31 ): Effect.Effect<
32 unknown,
33 OpenSearchApiError | Credentials.CredentialsError | SigV4.SigningError
34 >;
35}
36
37/**
38 * Runtime binding for full read/write access to an OpenSearch
39 * {@link Domain}'s REST data plane (IAM action `es:ESHttp*` on the domain
40 * and its paths).
41 *
42 * Every request is a SigV4-signed HTTP call (service `es`) against the
43 * domain's endpoint, made with the host Function's own credentials — the
44 * domain's access policy must allow the function's role. Prefer the
45 * least-privilege `DomainRead` / `DomainWrite` bindings when one direction
46 * suffices. Provide the implementation with
47 * `Effect.provide(AWS.OpenSearch.DomainReadWriteHttp)`.
48 * ### Reading and Writing a Domain
49 * **Example:** Index Then Search
50 * ```typescript
51 * // init — grants es:ESHttp* on the domain
52 * const client = yield* AWS.OpenSearch.DomainReadWrite(domain);
53 *
54 * // runtime
55 * yield* client.indexDocument(
56 * "songs",
57 * { title: "The Wind Cries Mary" },
58 * { id: "1", refresh: true },
59 * );
60 * const result = yield* client.search({
61 * index: "songs",
62 * body: { query: { match: { title: "wind" } } },
63 * });
64 * ```
65 *
66 * **Example:** Create an Index With Explicit Mappings
67 * ```typescript
68 * yield* client.request("PUT", "songs", {
69 * body: { mappings: { properties: { title: { type: "text" } } } },
70 * });
71 * ```
72 *
73 * @binding
74 */
75export interface DomainReadWrite extends Binding.Service<
76 DomainReadWrite,
77 "AWS.OpenSearch.DomainReadWrite",
78 (domain: Domain) => Effect.Effect<ReadWriteDomainClient>
79> {}
80export const DomainReadWrite = Binding.Service<DomainReadWrite>(
81 "AWS.OpenSearch.DomainReadWrite",
82);