1import * as Effect from "effect/Effect";
2import * as Output from "../../Output.ts";
3import type { Instance } from "./Instance.ts";
4import { bindGcpHost } from "../Host.ts";
5import { type BindingIam, type GcpHttpOp, grantFor } from "../HttpBinding.ts";
6
7/**
8 * Shared HTTP scaffolding for Compute Engine instance bindings.
9 * NOT exported from index.ts.
10 */
11export const makeInstanceHttpBinding = <
12 I extends { instance?: string; zone?: string; project?: string },
13 A,
14 E,
15>(options: {
16 tag: string;
17 iam: BindingIam;
18 operation: GcpHttpOp<I, A, E>;
19}) =>
20 Effect.gen(function* () {
21 const run = yield* options.operation;
22 return Effect.fn(function* (instance: Instance) {
23 yield* bindGcpHost({
24 tag: options.tag,
25 resource: instance,
26 iam: [
27 grantFor(
28 options.iam,
29 Output.interpolate`projects/${instance.project}/zones/${instance.zone}/instances/${instance.instanceName}`,
30 ),
31 ],
32 });
33 const instanceName = yield* instance.instanceName;
34 const zone = yield* instance.zone;
35 const project = yield* instance.project;
36 return Effect.fn(`${options.tag}(${instance.LogicalId})`)(function* (
37 request?: Omit<I, "instance" | "zone" | "project">,
38 ) {
39 return yield* run({
40 ...(request as I),
41 instance: yield* instanceName,
42 zone: yield* zone,
43 project: yield* project,
44 } as I);
45 });
46 });
47 });