1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5/**
6 * Datastore-mode database the bindings are granted on (project roles under
7 * an IAM Condition matching only this database).
8 */
9export const Tasks = GCP.Firestore.Database("Tasks", {
10 type: "DATASTORE_MODE",
11});
12
13/** Entity the Commit probe upserts. */
14export const COMMITTED = { kind: "Task", name: "probe-commit" } as const;
15/** Entity the test seeds out of band for the Lookup / RunQuery probes. */
16export const SEEDED = { kind: "Seeded", name: "probe-seeded" } as const;
17
18/** The Datastore API names the default database `""`, not `(default)`. */
19export const apiDatabaseId = (databaseId: string) =>
20 databaseId === "(default)" ? "" : databaseId;
21
22/**
23 * Effect-native Cloud Run service exercising every Datastore binding as its
24 * own runtime service account. Deployed from {@link ../Bindings.test.ts}.
25 */
26export default class DatastoreBindingsHost extends GCP.Function<DatastoreBindingsHost>()(
27 "DatastoreBindingsHost",
28 { main: import.meta.url, invokerIamDisabled: true },
29 Effect.gen(function* () {
30 const database = yield* Tasks;
31 const project = yield* database.project;
32 const databaseId = yield* database.databaseId;
33 const commit = yield* GCP.Datastore.Commit(Tasks);
34 const lookup = yield* GCP.Datastore.Lookup(Tasks);
35 const runQuery = yield* GCP.Datastore.RunQuery(Tasks);
36
37 const keyOf = (path: { kind: string; name: string }) =>
38 Effect.gen(function* () {
39 return {
40 partitionId: {
41 projectId: yield* project,
42 databaseId: apiDatabaseId(yield* databaseId),
43 },
44 path: [path],
45 };
46 });
47
48 return {
49 fetch: serveProbes({
50 commit: Effect.gen(function* () {
51 return yield* commit({
52 body: {
53 mode: "NON_TRANSACTIONAL",
54 mutations: [
55 {
56 upsert: {
57 key: yield* keyOf(COMMITTED),
58 properties: { title: { stringValue: "committed" } },
59 },
60 },
61 ],
62 },
63 });
64 }),
65 lookup: Effect.gen(function* () {
66 return yield* lookup({ body: { keys: [yield* keyOf(SEEDED)] } });
67 }),
68 runQuery: Effect.gen(function* () {
69 const { partitionId } = yield* keyOf(SEEDED);
70 return yield* runQuery({
71 body: { partitionId, query: { kind: [{ name: SEEDED.kind }] } },
72 });
73 }),
74 }),
75 };
76 }).pipe(
77 Effect.provide(GCP.Datastore.CommitHttp),
78 Effect.provide(GCP.Datastore.LookupHttp),
79 Effect.provide(GCP.Datastore.RunQueryHttp),
80 ),
81) {}