effortless-aws 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-B4P7ZKNM.js → chunk-HINWSFWC.js} +105 -20
- package/dist/cli/index.js +1477 -1111
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +193 -77
- package/dist/index.js.map +1 -1
- package/dist/runtime/wrap-app.js +1 -1
- package/dist/runtime/wrap-fifo-queue.js +1 -1
- package/dist/runtime/wrap-http.js +1 -1
- package/dist/runtime/wrap-middleware.js +83 -0
- package/dist/runtime/wrap-table-stream.js +19 -7
- package/package.json +2 -1
|
@@ -1,28 +1,67 @@
|
|
|
1
1
|
// src/runtime/table-client.ts
|
|
2
2
|
import { DynamoDB } from "@aws-sdk/client-dynamodb";
|
|
3
3
|
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";
|
|
4
|
-
var
|
|
4
|
+
var GSI_TAG_PK = "tag-pk-index";
|
|
5
|
+
var marshallKey = (key) => marshall(key, { removeUndefinedValues: true });
|
|
6
|
+
var buildSkCondition = (sk) => {
|
|
7
|
+
const names = { "#sk": "sk" };
|
|
8
|
+
if (typeof sk === "string") {
|
|
9
|
+
return { expression: "AND #sk = :sk", names, values: { ":sk": sk } };
|
|
10
|
+
}
|
|
11
|
+
if ("begins_with" in sk) {
|
|
12
|
+
return { expression: "AND begins_with(#sk, :sk)", names, values: { ":sk": sk.begins_with } };
|
|
13
|
+
}
|
|
14
|
+
if ("gt" in sk) {
|
|
15
|
+
return { expression: "AND #sk > :sk", names, values: { ":sk": sk.gt } };
|
|
16
|
+
}
|
|
17
|
+
if ("gte" in sk) {
|
|
18
|
+
return { expression: "AND #sk >= :sk", names, values: { ":sk": sk.gte } };
|
|
19
|
+
}
|
|
20
|
+
if ("lt" in sk) {
|
|
21
|
+
return { expression: "AND #sk < :sk", names, values: { ":sk": sk.lt } };
|
|
22
|
+
}
|
|
23
|
+
if ("lte" in sk) {
|
|
24
|
+
return { expression: "AND #sk <= :sk", names, values: { ":sk": sk.lte } };
|
|
25
|
+
}
|
|
26
|
+
if ("between" in sk) {
|
|
27
|
+
return { expression: "AND #sk BETWEEN :sk1 AND :sk2", names, values: { ":sk1": sk.between[0], ":sk2": sk.between[1] } };
|
|
28
|
+
}
|
|
29
|
+
return { expression: "", names: {}, values: {} };
|
|
30
|
+
};
|
|
31
|
+
var createTableClient = (tableName, options) => {
|
|
5
32
|
let client2 = null;
|
|
6
33
|
const getClient2 = () => client2 ??= new DynamoDB({});
|
|
34
|
+
const tagField = options?.tagField ?? "tag";
|
|
7
35
|
return {
|
|
8
36
|
tableName,
|
|
9
|
-
async put(item) {
|
|
37
|
+
async put(item, putOptions) {
|
|
38
|
+
const dataObj = item.data;
|
|
39
|
+
const tag = dataObj?.[tagField] || "";
|
|
40
|
+
if (!tag) throw new Error(`tag is required: data must include a "${tagField}" field`);
|
|
41
|
+
const dynamoItem = {
|
|
42
|
+
pk: item.pk,
|
|
43
|
+
sk: item.sk,
|
|
44
|
+
tag,
|
|
45
|
+
data: item.data
|
|
46
|
+
};
|
|
47
|
+
if (item.ttl !== void 0) dynamoItem.ttl = item.ttl;
|
|
10
48
|
await getClient2().putItem({
|
|
11
49
|
TableName: tableName,
|
|
12
|
-
Item: marshall(
|
|
50
|
+
Item: marshall(dynamoItem, { removeUndefinedValues: true }),
|
|
51
|
+
...putOptions?.ifNotExists ? { ConditionExpression: "attribute_not_exists(pk)" } : {}
|
|
13
52
|
});
|
|
14
53
|
},
|
|
15
54
|
async get(key) {
|
|
16
55
|
const result = await getClient2().getItem({
|
|
17
56
|
TableName: tableName,
|
|
18
|
-
Key:
|
|
57
|
+
Key: marshallKey(key)
|
|
19
58
|
});
|
|
20
59
|
return result.Item ? unmarshall(result.Item) : void 0;
|
|
21
60
|
},
|
|
22
61
|
async delete(key) {
|
|
23
62
|
await getClient2().deleteItem({
|
|
24
63
|
TableName: tableName,
|
|
25
|
-
Key:
|
|
64
|
+
Key: marshallKey(key)
|
|
26
65
|
});
|
|
27
66
|
},
|
|
28
67
|
async update(key, actions) {
|
|
@@ -31,63 +70,108 @@ var createTableClient = (tableName) => {
|
|
|
31
70
|
const setClauses = [];
|
|
32
71
|
const removeClauses = [];
|
|
33
72
|
let counter = 0;
|
|
73
|
+
const DATA_ALIAS = "#data";
|
|
74
|
+
let needsDataAlias = false;
|
|
34
75
|
if (actions.set) {
|
|
35
76
|
for (const [attr, val] of Object.entries(actions.set)) {
|
|
77
|
+
needsDataAlias = true;
|
|
36
78
|
const alias = `#a${counter}`;
|
|
37
79
|
const valAlias = `:v${counter}`;
|
|
38
80
|
names[alias] = attr;
|
|
39
81
|
values[valAlias] = val;
|
|
40
|
-
setClauses.push(`${alias} = ${valAlias}`);
|
|
82
|
+
setClauses.push(`${DATA_ALIAS}.${alias} = ${valAlias}`);
|
|
41
83
|
counter++;
|
|
42
84
|
}
|
|
43
85
|
}
|
|
44
86
|
if (actions.append) {
|
|
45
87
|
for (const [attr, val] of Object.entries(actions.append)) {
|
|
88
|
+
needsDataAlias = true;
|
|
46
89
|
const alias = `#a${counter}`;
|
|
47
90
|
const valAlias = `:v${counter}`;
|
|
48
91
|
const emptyAlias = `:empty${counter}`;
|
|
49
92
|
names[alias] = attr;
|
|
50
93
|
values[valAlias] = val;
|
|
51
94
|
values[emptyAlias] = [];
|
|
52
|
-
setClauses.push(`${alias} = list_append(if_not_exists(${alias}, ${emptyAlias}), ${valAlias})`);
|
|
95
|
+
setClauses.push(`${DATA_ALIAS}.${alias} = list_append(if_not_exists(${DATA_ALIAS}.${alias}, ${emptyAlias}), ${valAlias})`);
|
|
53
96
|
counter++;
|
|
54
97
|
}
|
|
55
98
|
}
|
|
56
99
|
if (actions.remove) {
|
|
57
100
|
for (const attr of actions.remove) {
|
|
101
|
+
needsDataAlias = true;
|
|
58
102
|
const alias = `#a${counter}`;
|
|
59
103
|
names[alias] = attr;
|
|
60
|
-
removeClauses.push(alias);
|
|
104
|
+
removeClauses.push(`${DATA_ALIAS}.${alias}`);
|
|
61
105
|
counter++;
|
|
62
106
|
}
|
|
63
107
|
}
|
|
108
|
+
if (needsDataAlias) {
|
|
109
|
+
names[DATA_ALIAS] = "data";
|
|
110
|
+
}
|
|
111
|
+
if (actions.tag !== void 0) {
|
|
112
|
+
names["#tag"] = "tag";
|
|
113
|
+
values[":tagVal"] = actions.tag;
|
|
114
|
+
setClauses.push("#tag = :tagVal");
|
|
115
|
+
}
|
|
116
|
+
if (actions.ttl !== void 0) {
|
|
117
|
+
names["#ttl"] = "ttl";
|
|
118
|
+
if (actions.ttl === null) {
|
|
119
|
+
removeClauses.push("#ttl");
|
|
120
|
+
} else {
|
|
121
|
+
values[":ttlVal"] = actions.ttl;
|
|
122
|
+
setClauses.push("#ttl = :ttlVal");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
64
125
|
const parts = [];
|
|
65
126
|
if (setClauses.length) parts.push(`SET ${setClauses.join(", ")}`);
|
|
66
127
|
if (removeClauses.length) parts.push(`REMOVE ${removeClauses.join(", ")}`);
|
|
67
128
|
if (!parts.length) return;
|
|
68
129
|
await getClient2().updateItem({
|
|
69
130
|
TableName: tableName,
|
|
70
|
-
Key:
|
|
131
|
+
Key: marshallKey(key),
|
|
71
132
|
UpdateExpression: parts.join(" "),
|
|
72
133
|
ExpressionAttributeNames: names,
|
|
73
134
|
...Object.keys(values).length ? { ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }) } : {}
|
|
74
135
|
});
|
|
75
136
|
},
|
|
76
137
|
async query(params) {
|
|
77
|
-
const names = { "#pk":
|
|
78
|
-
const values = { ":pk": params.pk
|
|
138
|
+
const names = { "#pk": "pk" };
|
|
139
|
+
const values = { ":pk": params.pk };
|
|
79
140
|
let keyCondition = "#pk = :pk";
|
|
80
|
-
if (params.sk) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
141
|
+
if (params.sk !== void 0) {
|
|
142
|
+
const skCond = buildSkCondition(params.sk);
|
|
143
|
+
keyCondition += ` ${skCond.expression}`;
|
|
144
|
+
Object.assign(names, skCond.names);
|
|
145
|
+
Object.assign(values, skCond.values);
|
|
146
|
+
}
|
|
147
|
+
const result = await getClient2().query({
|
|
148
|
+
TableName: tableName,
|
|
149
|
+
KeyConditionExpression: keyCondition,
|
|
150
|
+
ExpressionAttributeNames: names,
|
|
151
|
+
ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }),
|
|
152
|
+
...params.limit ? { Limit: params.limit } : {},
|
|
153
|
+
...params.scanIndexForward !== void 0 ? { ScanIndexForward: params.scanIndexForward } : {}
|
|
154
|
+
});
|
|
155
|
+
return (result.Items ?? []).map((item) => unmarshall(item));
|
|
156
|
+
},
|
|
157
|
+
async queryByTag(params) {
|
|
158
|
+
const names = { "#tag": "tag" };
|
|
159
|
+
const values = { ":tag": params.tag };
|
|
160
|
+
let keyCondition = "#tag = :tag";
|
|
161
|
+
if (params.pk !== void 0) {
|
|
162
|
+
const pkCond = buildSkCondition(params.pk);
|
|
163
|
+
const remapped = pkCond.expression.replace(/#sk/g, "#pk").replace(/:sk/g, ":pk");
|
|
164
|
+
keyCondition += ` ${remapped}`;
|
|
165
|
+
for (const [k, v] of Object.entries(pkCond.names)) {
|
|
166
|
+
names[k === "#sk" ? "#pk" : k] = v === "sk" ? "pk" : v;
|
|
167
|
+
}
|
|
168
|
+
for (const [k, v] of Object.entries(pkCond.values)) {
|
|
169
|
+
values[k.replace(":sk", ":pk")] = v;
|
|
87
170
|
}
|
|
88
171
|
}
|
|
89
172
|
const result = await getClient2().query({
|
|
90
173
|
TableName: tableName,
|
|
174
|
+
IndexName: GSI_TAG_PK,
|
|
91
175
|
KeyConditionExpression: keyCondition,
|
|
92
176
|
ExpressionAttributeNames: names,
|
|
93
177
|
ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }),
|
|
@@ -167,7 +251,7 @@ var buildParams = async (params) => {
|
|
|
167
251
|
return result;
|
|
168
252
|
};
|
|
169
253
|
var readStatic = (filePath) => readFileSync(join(process.cwd(), filePath), "utf-8");
|
|
170
|
-
var createHandlerRuntime = (handler, handlerType, logLevel = "info") => {
|
|
254
|
+
var createHandlerRuntime = (handler, handlerType, logLevel = "info", extraSetupArgs) => {
|
|
171
255
|
const handlerName = process.env.EFF_HANDLER ?? "unknown";
|
|
172
256
|
const rank = LOG_RANK[logLevel];
|
|
173
257
|
let ctx = null;
|
|
@@ -187,7 +271,8 @@ var createHandlerRuntime = (handler, handlerType, logLevel = "info") => {
|
|
|
187
271
|
const args = {};
|
|
188
272
|
if (params) args.config = params;
|
|
189
273
|
if (deps) args.deps = deps;
|
|
190
|
-
|
|
274
|
+
if (extraSetupArgs) Object.assign(args, extraSetupArgs());
|
|
275
|
+
ctx = Object.keys(args).length > 0 || extraSetupArgs ? await handler.setup(args) : await handler.setup();
|
|
191
276
|
}
|
|
192
277
|
return ctx;
|
|
193
278
|
};
|