1import * as keyspaces from "@distilled.cloud/aws/keyspaces";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import * as Output from "../../Output.ts";
6import { isBindingHost } from "../Lambda/Function.ts";
7import type { Keyspace } from "./Keyspace.ts";
8import { RestoreTable, type RestoreTableRequest } from "./RestoreTable.ts";
9import type { Table } from "./Table.ts";
10
11/**
12 * HTTP implementation of {@link RestoreTable}: grants `cassandra:Select` on
13 * the source table plus `cassandra:Restore` (and the `Create`/`TagResource`
14 * actions the restore performs) on the target keyspace and its tables, and
15 * calls the Keyspaces HTTP API with the function's IAM credentials.
16 */
17export const RestoreTableHttp = Layer.effect(
18 RestoreTable,
19 Effect.gen(function* () {
20 const restoreTable = yield* keyspaces.restoreTable;
21
22 return Effect.fn(function* <From extends Table, To extends Keyspace>(
23 source: From,
24 targetKeyspace: To,
25 ) {
26 const SourceKeyspaceName = yield* source.keyspaceName;
27 const SourceTableName = yield* source.tableName;
28 const TargetKeyspaceName = yield* targetKeyspace.keyspaceName;
29 if (!globalThis.__ALCHEMY_RUNTIME__) {
30 const host = yield* Binding.Host;
31 if (isBindingHost(host)) {
32 yield* host.bind`Allow(${host}, AWS.Keyspaces.RestoreTable(${source}, ${targetKeyspace}))`(
33 {
34 policyStatements: [
35 {
36 Effect: "Allow",
37 Action: ["cassandra:Select"],
38 Resource: [source.tableArn],
39 },
40 {
41 // The keyspace ARN ends with a trailing slash
42 // (`.../keyspace/name/`), so its tables match `table/*`.
43 Effect: "Allow",
44 Action: [
45 "cassandra:Restore",
46 "cassandra:Create",
47 "cassandra:TagResource",
48 ],
49 Resource: [
50 targetKeyspace.keyspaceArn,
51 Output.interpolate`${targetKeyspace.keyspaceArn}table/*`,
52 ],
53 },
54 ],
55 },
56 );
57 }
58 }
59 return Effect.fn(`AWS.Keyspaces.RestoreTable(${source.LogicalId})`)(
60 function* (request: RestoreTableRequest) {
61 const sourceKeyspaceName = yield* SourceKeyspaceName;
62 const sourceTableName = yield* SourceTableName;
63 const targetKeyspaceName = yield* TargetKeyspaceName;
64 return yield* restoreTable({
65 ...request,
66 sourceKeyspaceName,
67 sourceTableName,
68 targetKeyspaceName,
69 });
70 },
71 );
72 });
73 }),
74);