Skip to content

Commit 15bc4bc

Browse files
authored
feat(aws/dynamodb): support Cloudflare Worker hosts in HTTP bindings (#1782)
1 parent add85a9 commit 15bc4bc

15 files changed

Lines changed: 677 additions & 349 deletions

‎packages/alchemy/src/AWS/DynamoDB/BatchExecuteStatementHttp.ts‎

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,43 @@
11
import * as DynamoDB from "@distilled.cloud/aws/dynamodb";
22
import * as Effect from "effect/Effect";
33
import * as Layer from "effect/Layer";
4-
import * as Binding from "../../Binding.ts";
54
import * as Output from "../../Output.ts";
6-
import { isBindingHost } from "../Lambda/Function.ts";
75
import {
86
BatchExecuteStatement,
97
type BatchExecuteStatementRequest,
108
type BatchExecuteStatementTables,
119
sortBatchExecuteStatementTables,
1210
} from "./BatchExecuteStatement.ts";
11+
import { grantTables, signed, tablesRegion } from "./BindingHttp.ts";
1312

1413
export const BatchExecuteStatementHttp = Layer.effect(
1514
BatchExecuteStatement,
1615
Effect.gen(function* () {
17-
const batchExecuteStatement = yield* DynamoDB.batchExecuteStatement;
18-
1916
return Effect.fn(function* (...tables: BatchExecuteStatementTables) {
2017
const sortedTables = sortBatchExecuteStatementTables(tables);
21-
if (!globalThis.__ALCHEMY_RUNTIME__) {
22-
const host = yield* Binding.Host;
23-
if (isBindingHost(host)) {
24-
yield* host.bind`Allow(${host}, AWS.DynamoDB.BatchExecuteStatement(${sortedTables}))`({
25-
policyStatements: [
26-
{
27-
Effect: "Allow",
28-
Action: [
29-
"dynamodb:PartiQLDelete",
30-
"dynamodb:PartiQLInsert",
31-
"dynamodb:PartiQLSelect",
32-
"dynamodb:PartiQLUpdate",
33-
],
34-
Resource: sortedTables.flatMap((table) => [
35-
table.tableArn,
36-
Output.interpolate`${table.tableArn}/index/*`,
37-
]),
38-
},
18+
const access = yield* grantTables(
19+
`AWS.DynamoDB.BatchExecuteStatement(${sortedTables.map((table) => table.LogicalId).join(", ")})`,
20+
() => [
21+
{
22+
Effect: "Allow",
23+
Action: [
24+
"dynamodb:PartiQLDelete",
25+
"dynamodb:PartiQLInsert",
26+
"dynamodb:PartiQLSelect",
27+
"dynamodb:PartiQLUpdate",
3928
],
40-
});
41-
}
42-
}
29+
Resource: sortedTables.flatMap((table) => [
30+
table.tableArn,
31+
Output.interpolate`${table.tableArn}/index/*`,
32+
]),
33+
},
34+
],
35+
);
36+
const region = yield* tablesRegion(access, sortedTables);
4337
return Effect.fn(`AWS.DynamoDB.BatchExecuteStatement(${sortedTables})`)(function* (
4438
request: BatchExecuteStatementRequest,
4539
) {
46-
return yield* batchExecuteStatement(request);
40+
return yield* signed(access, region, DynamoDB.batchExecuteStatement(request));
4741
});
4842
});
4943
}),

‎packages/alchemy/src/AWS/DynamoDB/BatchGetItemHttp.ts‎

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import * as DynamoDB from "@distilled.cloud/aws/dynamodb";
22
import * as Effect from "effect/Effect";
33
import * as Layer from "effect/Layer";
4-
import * as Binding from "../../Binding.ts";
5-
import { isBindingHost } from "../Lambda/Function.ts";
64
import { BatchGetItem, type BatchGetItemRequest, type BatchGetItemTables } from "./BatchGetItem.ts";
5+
import { grantTables, signed, tablesRegion } from "./BindingHttp.ts";
76

87
export const BatchGetItemHttp = Layer.effect(
98
BatchGetItem,
109
Effect.gen(function* () {
11-
const batchGetItem = yield* DynamoDB.batchGetItem;
12-
1310
return Effect.fn(function* (...tables: BatchGetItemTables) {
1411
const sortedTables = sortTables(tables);
1512
const tableNames = new Map(
@@ -30,20 +27,17 @@ export const BatchGetItemHttp = Layer.effect(
3027
return yield* TableName;
3128
});
3229

33-
if (!globalThis.__ALCHEMY_RUNTIME__) {
34-
const host = yield* Binding.Host;
35-
if (isBindingHost(host)) {
36-
yield* host.bind`Allow(${host}, AWS.DynamoDB.BatchGetItem(${sortedTables}))`({
37-
policyStatements: [
38-
{
39-
Effect: "Allow",
40-
Action: ["dynamodb:BatchGetItem"],
41-
Resource: sortedTables.map((table) => table.tableArn),
42-
},
43-
],
44-
});
45-
}
46-
}
30+
const access = yield* grantTables(
31+
`AWS.DynamoDB.BatchGetItem(${sortedTables.map((table) => table.LogicalId).join(", ")})`,
32+
() => [
33+
{
34+
Effect: "Allow",
35+
Action: ["dynamodb:BatchGetItem"],
36+
Resource: sortedTables.map((table) => table.tableArn),
37+
},
38+
],
39+
);
40+
const region = yield* tablesRegion(access, sortedTables);
4741

4842
return Effect.fn(`AWS.DynamoDB.BatchGetItem(${sortedTables})`)(function* (
4943
request: BatchGetItemRequest,
@@ -56,10 +50,14 @@ export const BatchGetItemHttp = Layer.effect(
5650
}),
5751
);
5852

59-
return yield* batchGetItem({
60-
...request,
61-
RequestItems: Object.fromEntries(requestItems),
62-
});
53+
return yield* signed(
54+
access,
55+
region,
56+
DynamoDB.batchGetItem({
57+
...request,
58+
RequestItems: Object.fromEntries(requestItems),
59+
}),
60+
);
6361
});
6462
});
6563
}),

‎packages/alchemy/src/AWS/DynamoDB/BatchWriteItemHttp.ts‎

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import * as DynamoDB from "@distilled.cloud/aws/dynamodb";
22
import * as Effect from "effect/Effect";
33
import * as Layer from "effect/Layer";
4-
import * as Binding from "../../Binding.ts";
5-
import { isBindingHost } from "../Lambda/Function.ts";
64
import {
75
BatchWriteItem,
86
type BatchWriteItemRequest,
97
type BatchWriteItemTables,
108
sortBatchWriteItemTables,
119
} from "./BatchWriteItem.ts";
10+
import { grantTables, signed, tablesRegion } from "./BindingHttp.ts";
1211

1312
export const BatchWriteItemHttp = Layer.effect(
1413
BatchWriteItem,
1514
Effect.gen(function* () {
16-
const batchWriteItem = yield* DynamoDB.batchWriteItem;
17-
1815
return Effect.fn(function* (...tables: BatchWriteItemTables) {
1916
const sortedTables = sortBatchWriteItemTables(tables);
2017
const tableNames = new Map(
@@ -35,20 +32,17 @@ export const BatchWriteItemHttp = Layer.effect(
3532
return yield* TableName;
3633
});
3734

38-
if (!globalThis.__ALCHEMY_RUNTIME__) {
39-
const host = yield* Binding.Host;
40-
if (isBindingHost(host)) {
41-
yield* host.bind`Allow(${host}, AWS.DynamoDB.BatchWriteItem(${sortedTables}))`({
42-
policyStatements: [
43-
{
44-
Effect: "Allow",
45-
Action: ["dynamodb:BatchWriteItem"],
46-
Resource: sortedTables.map((table) => table.tableArn),
47-
},
48-
],
49-
});
50-
}
51-
}
35+
const access = yield* grantTables(
36+
`AWS.DynamoDB.BatchWriteItem(${sortedTables.map((table) => table.LogicalId).join(", ")})`,
37+
() => [
38+
{
39+
Effect: "Allow",
40+
Action: ["dynamodb:BatchWriteItem"],
41+
Resource: sortedTables.map((table) => table.tableArn),
42+
},
43+
],
44+
);
45+
const region = yield* tablesRegion(access, sortedTables);
5246

5347
return Effect.fn(`AWS.DynamoDB.BatchWriteItem(${sortedTables})`)(function* (
5448
request: BatchWriteItemRequest,
@@ -61,10 +55,14 @@ export const BatchWriteItemHttp = Layer.effect(
6155
}),
6256
);
6357

64-
return yield* batchWriteItem({
65-
...request,
66-
RequestItems: Object.fromEntries(requestItems),
67-
});
58+
return yield* signed(
59+
access,
60+
region,
61+
DynamoDB.batchWriteItem({
62+
...request,
63+
RequestItems: Object.fromEntries(requestItems),
64+
}),
65+
);
6866
});
6967
});
7068
}),

0 commit comments

Comments
 (0)