1import * as Effect from "effect/Effect";
2import { bindGcpHost } from "../Host.ts";
3import { grantFor, type BindingIam, type GcpHttpOp } from "../HttpBinding.ts";
4import type { Subscription } from "./Subscription.ts";
5import type { Topic } from "./Topic.ts";
6
7/**
8 * Shared HTTP scaffolding for Pub/Sub bindings.
9 * NOT exported from index.ts.
10 */
11export const makeTopicHttpBinding = <
12 I extends { topic: 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* (topic: Topic) {
23 const name = yield* topic.name;
24 yield* bindGcpHost({
25 tag: options.tag,
26 resource: topic,
27 iam: [grantFor(options.iam, topic.name)],
28 });
29 return Effect.fn(`${options.tag}(${topic.LogicalId})`)(function* (
30 request: Omit<I, "topic">,
31 ) {
32 return yield* run({
33 ...request,
34 topic: yield* name,
35 } as I);
36 });
37 });
38 });
39
40export const makeSubscriptionHttpBinding = <
41 I extends { subscription: string },
42 A,
43 E,
44>(options: {
45 tag: string;
46 iam: BindingIam;
47 operation: GcpHttpOp<I, A, E>;
48}) =>
49 Effect.gen(function* () {
50 const run = yield* options.operation;
51 return Effect.fn(function* (subscription: Subscription) {
52 const name = yield* subscription.name;
53 yield* bindGcpHost({
54 tag: options.tag,
55 resource: subscription,
56 iam: [grantFor(options.iam, subscription.name)],
57 });
58 return Effect.fn(`${options.tag}(${subscription.LogicalId})`)(function* (
59 request: Omit<I, "subscription">,
60 ) {
61 return yield* run({
62 ...request,
63 subscription: yield* name,
64 } as I);
65 });
66 });
67 });