1import type { GcpOpContext } from "@distilled.cloud/gcp/documentai_v1";
2import * as Effect from "effect/Effect";
3import type { Output } from "../../Output.ts";
4import type { Processor } from "./Processor.ts";
5import type { Schema } from "./Schema.ts";
6import type { SchemasSchemaVersion } from "./SchemasSchemaVersion.ts";
7import { bindGcpHost } from "../Host.ts";
8import { grantFor, type BindingIam } from "../HttpBinding.ts";
9
10/**
11 * Distilled ops are OperationMethods: yield them once at Layer construction
12 * (after providing Credentials + HttpClient) so the inner runtime Effect is
13 * `Effect<A, E>` and does not leak `GcpOpContext`.
14 */
15type GcpHttpOp<I, A, E> = Effect.Effect<
16 (input: I) => Effect.Effect<A, E>,
17 never,
18 GcpOpContext
19> &
20 ((input: I) => Effect.Effect<A, E, GcpOpContext>);
21
22const makeNamedHttpBinding = <
23 Resource extends { name: Output<string, never>; LogicalId: string },
24 I extends { name: string },
25 A,
26 E,
27>(options: {
28 tag: string;
29 iam: BindingIam;
30 operation: GcpHttpOp<I, A, E>;
31}) =>
32 Effect.gen(function* () {
33 const run = yield* options.operation;
34 return Effect.fn(function* (resource: Resource) {
35 yield* bindGcpHost({
36 tag: options.tag,
37 resource: resource,
38 iam: [grantFor(options.iam, resource.name)],
39 });
40 const name = yield* resource.name;
41 return Effect.fn(`${options.tag}(${resource.LogicalId})`)(function* (
42 request?: Omit<I, "name">,
43 ) {
44 const resourceName = yield* name;
45 return yield* run({
46 ...(request ?? {}),
47 name: resourceName,
48 } as I);
49 });
50 });
51 });
52
53/**
54 * Shared HTTP scaffolding for Document AI bindings.
55 * NOT exported from index.ts.
56 */
57export const makeProcessorHttpBinding = <
58 I extends { name: string },
59 A,
60 E,
61>(options: {
62 tag: string;
63 iam: BindingIam;
64 operation: GcpHttpOp<I, A, E>;
65}) => makeNamedHttpBinding<Processor, I, A, E>(options);
66
67export const makeSchemaHttpBinding = <
68 I extends { name: string },
69 A,
70 E,
71>(options: {
72 tag: string;
73 iam: BindingIam;
74 operation: GcpHttpOp<I, A, E>;
75}) => makeNamedHttpBinding<Schema, I, A, E>(options);
76
77export const makeSchemaVersionHttpBinding = <
78 I extends { name: string },
79 A,
80 E,
81>(options: {
82 tag: string;
83 iam: BindingIam;
84 operation: GcpHttpOp<I, A, E>;
85}) => makeNamedHttpBinding<SchemasSchemaVersion, I, A, E>(options);