@awsless/awsless 0.0.16 → 0.0.17
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/README.MD +207 -1
- package/dist/bin.cjs +27 -32
- package/dist/bin.js +27 -32
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -1,6 +1,212 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
TODO:
|
|
3
|
+
# TODO:
|
|
4
4
|
- onFailure for lambda, sqs, dynamodb streams
|
|
5
5
|
- add cache plugin & think about VPC lambda solutions
|
|
6
6
|
- add fargate container stuff for long lived services
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
---
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Features
|
|
14
|
+
|
|
15
|
+
- Domains
|
|
16
|
+
- Functions
|
|
17
|
+
- Database
|
|
18
|
+
- Tables
|
|
19
|
+
- Stores
|
|
20
|
+
- Caches
|
|
21
|
+
- Searchs
|
|
22
|
+
- Queues
|
|
23
|
+
- Topics
|
|
24
|
+
- Pubsub
|
|
25
|
+
- Crons
|
|
26
|
+
- API
|
|
27
|
+
- HTTP
|
|
28
|
+
- GraphQL
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Domains
|
|
32
|
+
|
|
33
|
+
We use AWS Route53 to provide domain management.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
{
|
|
37
|
+
domains: {
|
|
38
|
+
'example.com': [{
|
|
39
|
+
name: 'sub',
|
|
40
|
+
type: 'A',
|
|
41
|
+
records: [ ... ],
|
|
42
|
+
}],
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Functions
|
|
48
|
+
|
|
49
|
+
We use AWS Lambda to provide serverless functions.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
{
|
|
53
|
+
defaults: {
|
|
54
|
+
function: {
|
|
55
|
+
// Setting default values for all functions...
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
stacks: [{
|
|
59
|
+
functions: {
|
|
60
|
+
FUNCTION_NAME: 'function.ts'
|
|
61
|
+
}
|
|
62
|
+
}]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Tables
|
|
67
|
+
|
|
68
|
+
We use AWS DynamoDB to provide serverless tables.
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
{
|
|
72
|
+
stacks: [{
|
|
73
|
+
tables: {
|
|
74
|
+
TABLE_NAME: {
|
|
75
|
+
hash: 'id',
|
|
76
|
+
fields: {
|
|
77
|
+
id: 'string',
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Stores
|
|
86
|
+
|
|
87
|
+
We use AWS S3 to provide serverless key-value storage.
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
{
|
|
91
|
+
stacks: [{
|
|
92
|
+
stores: [ 'STORE_NAME' ]
|
|
93
|
+
}]
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Caches
|
|
98
|
+
|
|
99
|
+
We use AWS MemoryDB to provide __redis compatible__ in-memory storage.
|
|
100
|
+
|
|
101
|
+
_WORK IN PROGRESS..._
|
|
102
|
+
|
|
103
|
+
## Searchs
|
|
104
|
+
|
|
105
|
+
We use AWS Open Search Serverless to provide serverless search api.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
{
|
|
109
|
+
stacks: [{
|
|
110
|
+
searchs: [ 'SEARCH_NAME' ]
|
|
111
|
+
}]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Queues
|
|
116
|
+
|
|
117
|
+
We use AWS SQS to provide serverless queues.
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
{
|
|
121
|
+
stacks: [{
|
|
122
|
+
queues: {
|
|
123
|
+
QUEUE_NAME: 'queue-consumer.ts',
|
|
124
|
+
}
|
|
125
|
+
}]
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Topics
|
|
130
|
+
|
|
131
|
+
We use AWS SNS to provide serverless pubsub topics.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
{
|
|
135
|
+
stacks: [{
|
|
136
|
+
topics: {
|
|
137
|
+
TOPIC_NAME: 'topic-consumer.ts',
|
|
138
|
+
}
|
|
139
|
+
}]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Pubsub
|
|
144
|
+
|
|
145
|
+
We use AWS IoT to provide a serverless mqtt pubsub channel.
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
{
|
|
149
|
+
stacks: [{
|
|
150
|
+
pubsub: {
|
|
151
|
+
PUBSUB_NAME: {
|
|
152
|
+
sql: `SELECT * FROM '$aws/events/presence/connected/+'`,
|
|
153
|
+
consumer: 'pubsub-consumer.ts',
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Crons
|
|
161
|
+
|
|
162
|
+
We use AWS Event Bridge to provide serverless cron jobs.
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
{
|
|
166
|
+
stacks: [{
|
|
167
|
+
crons: {
|
|
168
|
+
CRON_NAME: {
|
|
169
|
+
schedule: 'rate(1 day)',
|
|
170
|
+
consumer: 'cron-consumer.ts',
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## HTTP
|
|
178
|
+
|
|
179
|
+
We use AWS ELB to provide a REST HTTP API.
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
{
|
|
183
|
+
stacks: [{
|
|
184
|
+
http: {
|
|
185
|
+
HTTP_API_NAME: {
|
|
186
|
+
'GET /posts': 'list-posts.ts',
|
|
187
|
+
'POST /posts': 'create-post.ts',
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}]
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## GraphQL
|
|
195
|
+
|
|
196
|
+
We use AWS AppSync to provide a serverless GraphQL API.
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
{
|
|
200
|
+
stacks: [{
|
|
201
|
+
graphql: {
|
|
202
|
+
GRAPHQL_API_NAME: {
|
|
203
|
+
schema: 'schema.gql',
|
|
204
|
+
resolvers: {
|
|
205
|
+
'Query posts': 'list-posts.ts',
|
|
206
|
+
'Mutation createPost': 'create-post.ts',
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}]
|
|
211
|
+
}
|
|
212
|
+
```
|
package/dist/bin.cjs
CHANGED
|
@@ -932,6 +932,17 @@ var EventInvokeConfig = class extends Resource {
|
|
|
932
932
|
}
|
|
933
933
|
};
|
|
934
934
|
|
|
935
|
+
// src/plugins/on-failure/util.ts
|
|
936
|
+
var getGlobalOnFailure = ({ config, bootstrap: bootstrap2 }) => {
|
|
937
|
+
return hasOnFailure(config) ? bootstrap2.import("on-failure-queue-arn") : void 0;
|
|
938
|
+
};
|
|
939
|
+
var hasOnFailure = (config) => {
|
|
940
|
+
const onFailure = config.stacks.find((stack) => {
|
|
941
|
+
return typeof stack.onFailure !== "undefined";
|
|
942
|
+
});
|
|
943
|
+
return !!onFailure;
|
|
944
|
+
};
|
|
945
|
+
|
|
935
946
|
// src/plugins/function.ts
|
|
936
947
|
var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum memory size is 10 GB");
|
|
937
948
|
var TimeoutSchema = DurationSchema.refine(durationMin(Duration.seconds(10)), "Minimum timeout duration is 10 seconds").refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
|
|
@@ -1054,9 +1065,16 @@ var functionPlugin = definePlugin({
|
|
|
1054
1065
|
name: "function",
|
|
1055
1066
|
schema,
|
|
1056
1067
|
onStack(ctx) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1068
|
+
const { config, stack } = ctx;
|
|
1069
|
+
for (const [id, fileOrProps] of Object.entries(ctx.stackConfig.functions || {})) {
|
|
1070
|
+
const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
|
|
1071
|
+
const lambda = toLambdaFunction(ctx, id, fileOrProps);
|
|
1072
|
+
const invoke = new EventInvokeConfig(id, {
|
|
1073
|
+
functionName: lambda.name,
|
|
1074
|
+
retryAttempts: props.retryAttempts,
|
|
1075
|
+
onFailure: getGlobalOnFailure(ctx)
|
|
1076
|
+
}).dependsOn(lambda);
|
|
1077
|
+
stack.add(invoke, lambda);
|
|
1060
1078
|
}
|
|
1061
1079
|
}
|
|
1062
1080
|
});
|
|
@@ -1073,11 +1091,6 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1073
1091
|
if (props.runtime.startsWith("nodejs")) {
|
|
1074
1092
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1075
1093
|
}
|
|
1076
|
-
const invoke = new EventInvokeConfig(id, {
|
|
1077
|
-
functionName: lambda.name,
|
|
1078
|
-
retryAttempts: props.retryAttempts
|
|
1079
|
-
}).dependsOn(lambda);
|
|
1080
|
-
ctx.stack.add(invoke);
|
|
1081
1094
|
return lambda;
|
|
1082
1095
|
};
|
|
1083
1096
|
|
|
@@ -1392,7 +1405,8 @@ var queuePlugin = definePlugin({
|
|
|
1392
1405
|
});
|
|
1393
1406
|
const lambda = toLambdaFunction(ctx, `queue-${id}`, props.consumer);
|
|
1394
1407
|
const source = new SqsEventSource(id, lambda, {
|
|
1395
|
-
queueArn: queue2.arn
|
|
1408
|
+
queueArn: queue2.arn,
|
|
1409
|
+
onFailure: getGlobalOnFailure(ctx)
|
|
1396
1410
|
});
|
|
1397
1411
|
stack.add(queue2, lambda, source);
|
|
1398
1412
|
bind((lambda2) => {
|
|
@@ -1505,7 +1519,8 @@ var DynamoDBEventSource = class extends Group {
|
|
|
1505
1519
|
parallelizationFactor: props.parallelizationFactor ?? 1,
|
|
1506
1520
|
startingPosition: props.startingPosition,
|
|
1507
1521
|
startingPositionTimestamp: props.startingPositionTimestamp,
|
|
1508
|
-
tumblingWindow: props.tumblingWindow
|
|
1522
|
+
tumblingWindow: props.tumblingWindow,
|
|
1523
|
+
onFailure: props.onFailure
|
|
1509
1524
|
});
|
|
1510
1525
|
lambda.addPermissions({
|
|
1511
1526
|
actions: [
|
|
@@ -1631,6 +1646,7 @@ var tablePlugin = definePlugin({
|
|
|
1631
1646
|
const lambda = toLambdaFunction(ctx, `stream-${id}`, props.stream.consumer);
|
|
1632
1647
|
const source = new DynamoDBEventSource(id, lambda, {
|
|
1633
1648
|
tableArn: table.arn,
|
|
1649
|
+
onFailure: getGlobalOnFailure(ctx),
|
|
1634
1650
|
...props.stream
|
|
1635
1651
|
});
|
|
1636
1652
|
stack.add(lambda, source);
|
|
@@ -2666,14 +2682,8 @@ var domainPlugin = definePlugin({
|
|
|
2666
2682
|
}
|
|
2667
2683
|
});
|
|
2668
2684
|
|
|
2669
|
-
// src/plugins/on-failure.ts
|
|
2685
|
+
// src/plugins/on-failure/index.ts
|
|
2670
2686
|
var import_zod16 = require("zod");
|
|
2671
|
-
var hasOnFailure = (config) => {
|
|
2672
|
-
const onFailure = config.stacks.find((stack) => {
|
|
2673
|
-
return typeof stack.onFailure !== "undefined";
|
|
2674
|
-
});
|
|
2675
|
-
return !!onFailure;
|
|
2676
|
-
};
|
|
2677
2687
|
var onFailurePlugin = definePlugin({
|
|
2678
2688
|
name: "on-failure",
|
|
2679
2689
|
schema: import_zod16.z.object({
|
|
@@ -2720,21 +2730,6 @@ var onFailurePlugin = definePlugin({
|
|
|
2720
2730
|
resources: [queueArn]
|
|
2721
2731
|
});
|
|
2722
2732
|
stack.add(lambda, source);
|
|
2723
|
-
},
|
|
2724
|
-
onResource({ config, resource, bootstrap: bootstrap2 }) {
|
|
2725
|
-
if (!hasOnFailure(config)) {
|
|
2726
|
-
return;
|
|
2727
|
-
}
|
|
2728
|
-
const queueArn = bootstrap2.import("on-failure-queue-arn");
|
|
2729
|
-
if (resource instanceof Queue) {
|
|
2730
|
-
resource.setDeadLetter(queueArn);
|
|
2731
|
-
}
|
|
2732
|
-
if (resource instanceof EventInvokeConfig) {
|
|
2733
|
-
resource.setOnFailure(queueArn);
|
|
2734
|
-
}
|
|
2735
|
-
if (resource instanceof EventSourceMapping) {
|
|
2736
|
-
resource.setOnFailure(queueArn);
|
|
2737
|
-
}
|
|
2738
2733
|
}
|
|
2739
2734
|
});
|
|
2740
2735
|
|
package/dist/bin.js
CHANGED
|
@@ -909,6 +909,17 @@ var EventInvokeConfig = class extends Resource {
|
|
|
909
909
|
}
|
|
910
910
|
};
|
|
911
911
|
|
|
912
|
+
// src/plugins/on-failure/util.ts
|
|
913
|
+
var getGlobalOnFailure = ({ config, bootstrap: bootstrap2 }) => {
|
|
914
|
+
return hasOnFailure(config) ? bootstrap2.import("on-failure-queue-arn") : void 0;
|
|
915
|
+
};
|
|
916
|
+
var hasOnFailure = (config) => {
|
|
917
|
+
const onFailure = config.stacks.find((stack) => {
|
|
918
|
+
return typeof stack.onFailure !== "undefined";
|
|
919
|
+
});
|
|
920
|
+
return !!onFailure;
|
|
921
|
+
};
|
|
922
|
+
|
|
912
923
|
// src/plugins/function.ts
|
|
913
924
|
var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum memory size is 10 GB");
|
|
914
925
|
var TimeoutSchema = DurationSchema.refine(durationMin(Duration.seconds(10)), "Minimum timeout duration is 10 seconds").refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
|
|
@@ -1031,9 +1042,16 @@ var functionPlugin = definePlugin({
|
|
|
1031
1042
|
name: "function",
|
|
1032
1043
|
schema,
|
|
1033
1044
|
onStack(ctx) {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1045
|
+
const { config, stack } = ctx;
|
|
1046
|
+
for (const [id, fileOrProps] of Object.entries(ctx.stackConfig.functions || {})) {
|
|
1047
|
+
const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
|
|
1048
|
+
const lambda = toLambdaFunction(ctx, id, fileOrProps);
|
|
1049
|
+
const invoke = new EventInvokeConfig(id, {
|
|
1050
|
+
functionName: lambda.name,
|
|
1051
|
+
retryAttempts: props.retryAttempts,
|
|
1052
|
+
onFailure: getGlobalOnFailure(ctx)
|
|
1053
|
+
}).dependsOn(lambda);
|
|
1054
|
+
stack.add(invoke, lambda);
|
|
1037
1055
|
}
|
|
1038
1056
|
}
|
|
1039
1057
|
});
|
|
@@ -1050,11 +1068,6 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1050
1068
|
if (props.runtime.startsWith("nodejs")) {
|
|
1051
1069
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1052
1070
|
}
|
|
1053
|
-
const invoke = new EventInvokeConfig(id, {
|
|
1054
|
-
functionName: lambda.name,
|
|
1055
|
-
retryAttempts: props.retryAttempts
|
|
1056
|
-
}).dependsOn(lambda);
|
|
1057
|
-
ctx.stack.add(invoke);
|
|
1058
1071
|
return lambda;
|
|
1059
1072
|
};
|
|
1060
1073
|
|
|
@@ -1369,7 +1382,8 @@ var queuePlugin = definePlugin({
|
|
|
1369
1382
|
});
|
|
1370
1383
|
const lambda = toLambdaFunction(ctx, `queue-${id}`, props.consumer);
|
|
1371
1384
|
const source = new SqsEventSource(id, lambda, {
|
|
1372
|
-
queueArn: queue2.arn
|
|
1385
|
+
queueArn: queue2.arn,
|
|
1386
|
+
onFailure: getGlobalOnFailure(ctx)
|
|
1373
1387
|
});
|
|
1374
1388
|
stack.add(queue2, lambda, source);
|
|
1375
1389
|
bind((lambda2) => {
|
|
@@ -1482,7 +1496,8 @@ var DynamoDBEventSource = class extends Group {
|
|
|
1482
1496
|
parallelizationFactor: props.parallelizationFactor ?? 1,
|
|
1483
1497
|
startingPosition: props.startingPosition,
|
|
1484
1498
|
startingPositionTimestamp: props.startingPositionTimestamp,
|
|
1485
|
-
tumblingWindow: props.tumblingWindow
|
|
1499
|
+
tumblingWindow: props.tumblingWindow,
|
|
1500
|
+
onFailure: props.onFailure
|
|
1486
1501
|
});
|
|
1487
1502
|
lambda.addPermissions({
|
|
1488
1503
|
actions: [
|
|
@@ -1608,6 +1623,7 @@ var tablePlugin = definePlugin({
|
|
|
1608
1623
|
const lambda = toLambdaFunction(ctx, `stream-${id}`, props.stream.consumer);
|
|
1609
1624
|
const source = new DynamoDBEventSource(id, lambda, {
|
|
1610
1625
|
tableArn: table.arn,
|
|
1626
|
+
onFailure: getGlobalOnFailure(ctx),
|
|
1611
1627
|
...props.stream
|
|
1612
1628
|
});
|
|
1613
1629
|
stack.add(lambda, source);
|
|
@@ -2643,14 +2659,8 @@ var domainPlugin = definePlugin({
|
|
|
2643
2659
|
}
|
|
2644
2660
|
});
|
|
2645
2661
|
|
|
2646
|
-
// src/plugins/on-failure.ts
|
|
2662
|
+
// src/plugins/on-failure/index.ts
|
|
2647
2663
|
import { z as z16 } from "zod";
|
|
2648
|
-
var hasOnFailure = (config) => {
|
|
2649
|
-
const onFailure = config.stacks.find((stack) => {
|
|
2650
|
-
return typeof stack.onFailure !== "undefined";
|
|
2651
|
-
});
|
|
2652
|
-
return !!onFailure;
|
|
2653
|
-
};
|
|
2654
2664
|
var onFailurePlugin = definePlugin({
|
|
2655
2665
|
name: "on-failure",
|
|
2656
2666
|
schema: z16.object({
|
|
@@ -2697,21 +2707,6 @@ var onFailurePlugin = definePlugin({
|
|
|
2697
2707
|
resources: [queueArn]
|
|
2698
2708
|
});
|
|
2699
2709
|
stack.add(lambda, source);
|
|
2700
|
-
},
|
|
2701
|
-
onResource({ config, resource, bootstrap: bootstrap2 }) {
|
|
2702
|
-
if (!hasOnFailure(config)) {
|
|
2703
|
-
return;
|
|
2704
|
-
}
|
|
2705
|
-
const queueArn = bootstrap2.import("on-failure-queue-arn");
|
|
2706
|
-
if (resource instanceof Queue) {
|
|
2707
|
-
resource.setDeadLetter(queueArn);
|
|
2708
|
-
}
|
|
2709
|
-
if (resource instanceof EventInvokeConfig) {
|
|
2710
|
-
resource.setOnFailure(queueArn);
|
|
2711
|
-
}
|
|
2712
|
-
if (resource instanceof EventSourceMapping) {
|
|
2713
|
-
resource.setOnFailure(queueArn);
|
|
2714
|
-
}
|
|
2715
2710
|
}
|
|
2716
2711
|
});
|
|
2717
2712
|
|