@awsless/awsless 0.0.18 → 0.0.20
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/bin.cjs +548 -175
- package/dist/bin.js +549 -176
- package/dist/index.d.ts +441 -18
- package/package.json +3 -1
package/dist/bin.js
CHANGED
|
@@ -171,6 +171,12 @@ var formatLogicalId = (id) => {
|
|
|
171
171
|
var formatName = (name) => {
|
|
172
172
|
return paramCase2(name);
|
|
173
173
|
};
|
|
174
|
+
var formatArn = (props) => {
|
|
175
|
+
return sub("arn:${AWS::Partition}:${service}:${AWS::Region}:${AWS::AccountId}:${resource}${seperator}${resourceName}", {
|
|
176
|
+
seperator: "/",
|
|
177
|
+
...props
|
|
178
|
+
});
|
|
179
|
+
};
|
|
174
180
|
|
|
175
181
|
// src/formation/resource.ts
|
|
176
182
|
var Resource = class {
|
|
@@ -180,13 +186,19 @@ var Resource = class {
|
|
|
180
186
|
this.logicalId = formatLogicalId(`${logicalId}-${type.replace(/^AWS::/, "")}`);
|
|
181
187
|
}
|
|
182
188
|
logicalId;
|
|
189
|
+
tags = /* @__PURE__ */ new Map();
|
|
183
190
|
deps = /* @__PURE__ */ new Set();
|
|
191
|
+
stack;
|
|
184
192
|
dependsOn(...dependencies) {
|
|
185
193
|
for (const dependency of dependencies) {
|
|
186
194
|
this.deps.add(dependency);
|
|
187
195
|
}
|
|
188
196
|
return this;
|
|
189
197
|
}
|
|
198
|
+
tag(key, value) {
|
|
199
|
+
this.tags.set(key, value);
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
190
202
|
attr(name, value) {
|
|
191
203
|
if (typeof value === "undefined") {
|
|
192
204
|
return {};
|
|
@@ -195,12 +207,41 @@ var Resource = class {
|
|
|
195
207
|
[name]: value
|
|
196
208
|
};
|
|
197
209
|
}
|
|
210
|
+
setStack(stack) {
|
|
211
|
+
this.stack = stack;
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
ref() {
|
|
215
|
+
return this.getAtt("ref");
|
|
216
|
+
}
|
|
217
|
+
getAtt(attr) {
|
|
218
|
+
return new Lazy((stack) => {
|
|
219
|
+
if (!this.stack) {
|
|
220
|
+
throw new TypeError("Resource stack not defined before building template");
|
|
221
|
+
}
|
|
222
|
+
const value = attr === "ref" ? ref(this.logicalId) : getAtt(this.logicalId, attr);
|
|
223
|
+
if (stack === this.stack) {
|
|
224
|
+
return value;
|
|
225
|
+
}
|
|
226
|
+
const name = `${this.stack.name}-${this.logicalId}-${attr}`;
|
|
227
|
+
this.stack.export(name, value);
|
|
228
|
+
return this.stack.import(name);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
198
231
|
toJSON() {
|
|
199
232
|
return {
|
|
200
233
|
[this.logicalId]: {
|
|
201
234
|
Type: this.type,
|
|
202
235
|
DependsOn: [...this.deps].map((dep) => dep.logicalId),
|
|
203
|
-
Properties:
|
|
236
|
+
Properties: {
|
|
237
|
+
...this.tags.size ? {
|
|
238
|
+
Tags: Array.from(this.tags.entries()).map(([key, value]) => ({
|
|
239
|
+
Key: key,
|
|
240
|
+
Value: value
|
|
241
|
+
}))
|
|
242
|
+
} : {},
|
|
243
|
+
...this.properties()
|
|
244
|
+
}
|
|
204
245
|
}
|
|
205
246
|
};
|
|
206
247
|
}
|
|
@@ -210,6 +251,11 @@ var Group = class {
|
|
|
210
251
|
this.children = children;
|
|
211
252
|
}
|
|
212
253
|
};
|
|
254
|
+
var Lazy = class {
|
|
255
|
+
constructor(callback) {
|
|
256
|
+
this.callback = callback;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
213
259
|
|
|
214
260
|
// src/formation/resource/iam/inline-policy.ts
|
|
215
261
|
var InlinePolicy = class {
|
|
@@ -315,6 +361,7 @@ var Function = class extends Resource {
|
|
|
315
361
|
this.policy = policy;
|
|
316
362
|
this.name = formatName(this.props.name || logicalId);
|
|
317
363
|
this.environmentVariables = props.environment ? { ...props.environment } : {};
|
|
364
|
+
this.tag("name", this.name);
|
|
318
365
|
}
|
|
319
366
|
name;
|
|
320
367
|
role;
|
|
@@ -328,11 +375,15 @@ var Function = class extends Resource {
|
|
|
328
375
|
this.environmentVariables[name] = value;
|
|
329
376
|
return this;
|
|
330
377
|
}
|
|
378
|
+
setVpc(vpc) {
|
|
379
|
+
this.props.vpc = vpc;
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
331
382
|
get id() {
|
|
332
|
-
return ref(
|
|
383
|
+
return this.ref();
|
|
333
384
|
}
|
|
334
385
|
get arn() {
|
|
335
|
-
return getAtt(
|
|
386
|
+
return this.getAtt("Arn");
|
|
336
387
|
}
|
|
337
388
|
get permissions() {
|
|
338
389
|
return {
|
|
@@ -340,7 +391,14 @@ var Function = class extends Resource {
|
|
|
340
391
|
"lambda:InvokeFunction",
|
|
341
392
|
"lambda:InvokeAsync"
|
|
342
393
|
],
|
|
343
|
-
resources: [
|
|
394
|
+
resources: [
|
|
395
|
+
formatArn({
|
|
396
|
+
service: "lambda",
|
|
397
|
+
resource: "function",
|
|
398
|
+
resourceName: this.name,
|
|
399
|
+
seperator: ":"
|
|
400
|
+
})
|
|
401
|
+
]
|
|
344
402
|
};
|
|
345
403
|
}
|
|
346
404
|
properties() {
|
|
@@ -351,10 +409,17 @@ var Function = class extends Resource {
|
|
|
351
409
|
Timeout: this.props.timeout?.toSeconds() ?? 10,
|
|
352
410
|
Architectures: [this.props.architecture ?? "arm64"],
|
|
353
411
|
Role: this.role.arn,
|
|
412
|
+
...this.attr("ReservedConcurrentExecutions", this.props.reserved),
|
|
354
413
|
...this.props.code.toCodeJson(),
|
|
355
414
|
EphemeralStorage: {
|
|
356
415
|
Size: this.props.ephemeralStorageSize?.toMegaBytes() ?? 512
|
|
357
416
|
},
|
|
417
|
+
...this.props.vpc ? {
|
|
418
|
+
VpcConfig: {
|
|
419
|
+
SecurityGroupIds: this.props.vpc.securityGroupIds,
|
|
420
|
+
SubnetIds: this.props.vpc.subnetIds
|
|
421
|
+
}
|
|
422
|
+
} : {},
|
|
358
423
|
Environment: {
|
|
359
424
|
Variables: this.environmentVariables
|
|
360
425
|
}
|
|
@@ -379,6 +444,7 @@ var Stack = class {
|
|
|
379
444
|
} else {
|
|
380
445
|
this.add(...item.children);
|
|
381
446
|
if (item instanceof Resource) {
|
|
447
|
+
item.setStack(this);
|
|
382
448
|
this.resources.add(item);
|
|
383
449
|
}
|
|
384
450
|
}
|
|
@@ -422,8 +488,24 @@ var Stack = class {
|
|
|
422
488
|
toJSON() {
|
|
423
489
|
const resources = {};
|
|
424
490
|
const outputs = {};
|
|
491
|
+
const walk = (object) => {
|
|
492
|
+
for (const [key, value] of Object.entries(object)) {
|
|
493
|
+
if (!object.hasOwnProperty(key)) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
if (value instanceof Lazy) {
|
|
497
|
+
object[key] = value.callback(this);
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (typeof value === "object" && value !== null) {
|
|
501
|
+
walk(value);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
425
505
|
for (const resource of this) {
|
|
426
|
-
|
|
506
|
+
const json2 = resource.toJSON();
|
|
507
|
+
walk(json2);
|
|
508
|
+
Object.assign(resources, json2);
|
|
427
509
|
}
|
|
428
510
|
for (const [name, value] of this.exports.entries()) {
|
|
429
511
|
Object.assign(outputs, {
|
|
@@ -491,54 +573,33 @@ var toStack = ({ config, app, stackConfig, bootstrap: bootstrap2, usEastBootstra
|
|
|
491
573
|
}
|
|
492
574
|
return {
|
|
493
575
|
stack,
|
|
494
|
-
|
|
576
|
+
bindings
|
|
577
|
+
// depends: stackConfig.depends,
|
|
495
578
|
};
|
|
496
579
|
};
|
|
497
580
|
|
|
498
581
|
// src/util/deployment.ts
|
|
499
|
-
var
|
|
582
|
+
var createDeploymentLine = (stacks) => {
|
|
500
583
|
const list3 = stacks.map(({ stack, config }) => ({
|
|
501
584
|
stack,
|
|
502
585
|
depends: config?.depends?.map((dep) => dep.name) || []
|
|
503
586
|
}));
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
rests.push(item);
|
|
587
|
+
const line = [];
|
|
588
|
+
const deps = [];
|
|
589
|
+
let limit = 10;
|
|
590
|
+
while (deps.length < list3.length) {
|
|
591
|
+
const local = [];
|
|
592
|
+
for (const { stack, depends } of list3) {
|
|
593
|
+
if (!deps.includes(stack.name) && depends.filter((dep) => !deps.includes(dep)).length === 0) {
|
|
594
|
+
local.push(stack);
|
|
513
595
|
}
|
|
514
596
|
}
|
|
515
|
-
if (
|
|
516
|
-
|
|
517
|
-
stack,
|
|
518
|
-
children: []
|
|
519
|
-
}));
|
|
597
|
+
if (limit-- <= 0) {
|
|
598
|
+
throw new Error(`Circular stack dependencies arn't allowed.`);
|
|
520
599
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
children: findChildren(rests, [...parents, stack.name])
|
|
525
|
-
};
|
|
526
|
-
});
|
|
527
|
-
};
|
|
528
|
-
return findChildren(list3, []);
|
|
529
|
-
};
|
|
530
|
-
var createDeploymentLine = (stacks) => {
|
|
531
|
-
const line = [];
|
|
532
|
-
const walk = (stacks2, level) => {
|
|
533
|
-
stacks2.forEach((node) => {
|
|
534
|
-
if (!line[level]) {
|
|
535
|
-
line[level] = [];
|
|
536
|
-
}
|
|
537
|
-
line[level].push(node.stack);
|
|
538
|
-
walk(node.children, level + 1);
|
|
539
|
-
});
|
|
540
|
-
};
|
|
541
|
-
walk(stacks, 0);
|
|
600
|
+
deps.push(...local.map((stack) => stack.name));
|
|
601
|
+
line.push(local);
|
|
602
|
+
}
|
|
542
603
|
return line;
|
|
543
604
|
};
|
|
544
605
|
|
|
@@ -924,6 +985,7 @@ var hasOnFailure = (config) => {
|
|
|
924
985
|
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");
|
|
925
986
|
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");
|
|
926
987
|
var EphemeralStorageSizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(512)), "Minimum ephemeral storage size is 512 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum ephemeral storage size is 10 GB");
|
|
988
|
+
var ReservedConcurrentExecutionsSchema = z6.number().int().min(0);
|
|
927
989
|
var EnvironmentSchema = z6.record(z6.string(), z6.string()).optional();
|
|
928
990
|
var ArchitectureSchema = z6.enum(["x86_64", "arm64"]);
|
|
929
991
|
var RetryAttemptsSchema = z6.number().int().min(0).max(2);
|
|
@@ -934,8 +996,12 @@ var RuntimeSchema = z6.enum([
|
|
|
934
996
|
var FunctionSchema = z6.union([
|
|
935
997
|
LocalFileSchema,
|
|
936
998
|
z6.object({
|
|
937
|
-
/** The file path
|
|
999
|
+
/** The file path of the function code. */
|
|
938
1000
|
file: LocalFileSchema,
|
|
1001
|
+
/** Put the function inside your global VPC.
|
|
1002
|
+
* @default false
|
|
1003
|
+
*/
|
|
1004
|
+
vpc: z6.boolean().optional(),
|
|
939
1005
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
940
1006
|
* You can specify a size value from 1 second to 15 minutes.
|
|
941
1007
|
* @default '10 seconds'
|
|
@@ -966,6 +1032,10 @@ var FunctionSchema = z6.union([
|
|
|
966
1032
|
* @default 2
|
|
967
1033
|
*/
|
|
968
1034
|
retryAttempts: RetryAttemptsSchema.optional(),
|
|
1035
|
+
/** The number of simultaneous executions to reserve for the function.
|
|
1036
|
+
* You can specify a number from 0.
|
|
1037
|
+
*/
|
|
1038
|
+
reserved: ReservedConcurrentExecutionsSchema.optional(),
|
|
969
1039
|
/** Environment variable key-value pairs.
|
|
970
1040
|
* @example
|
|
971
1041
|
* {
|
|
@@ -981,6 +1051,10 @@ var FunctionSchema = z6.union([
|
|
|
981
1051
|
var schema = z6.object({
|
|
982
1052
|
defaults: z6.object({
|
|
983
1053
|
function: z6.object({
|
|
1054
|
+
/** Put the function inside your global VPC.
|
|
1055
|
+
* @default false
|
|
1056
|
+
*/
|
|
1057
|
+
vpc: z6.boolean().default(false),
|
|
984
1058
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
985
1059
|
* You can specify a size value from 1 second to 15 minutes.
|
|
986
1060
|
* @default '10 seconds'
|
|
@@ -1011,6 +1085,10 @@ var schema = z6.object({
|
|
|
1011
1085
|
* @default 2
|
|
1012
1086
|
*/
|
|
1013
1087
|
retryAttempts: RetryAttemptsSchema.default(2),
|
|
1088
|
+
/** The number of simultaneous executions to reserve for the function.
|
|
1089
|
+
* You can specify a number from 0.
|
|
1090
|
+
*/
|
|
1091
|
+
reserved: ReservedConcurrentExecutionsSchema.optional(),
|
|
1014
1092
|
/** Environment variable key-value pairs.
|
|
1015
1093
|
* @example
|
|
1016
1094
|
* {
|
|
@@ -1051,6 +1129,12 @@ var functionPlugin = definePlugin({
|
|
|
1051
1129
|
retryAttempts: props.retryAttempts,
|
|
1052
1130
|
onFailure: getGlobalOnFailure(ctx)
|
|
1053
1131
|
}).dependsOn(lambda);
|
|
1132
|
+
if (hasOnFailure(ctx.config)) {
|
|
1133
|
+
lambda.addPermissions({
|
|
1134
|
+
actions: ["sqs:SendMessage"],
|
|
1135
|
+
resources: [getGlobalOnFailure(ctx)]
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1054
1138
|
stack.add(invoke, lambda);
|
|
1055
1139
|
}
|
|
1056
1140
|
}
|
|
@@ -1062,12 +1146,36 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1062
1146
|
const lambda = new Function(id, {
|
|
1063
1147
|
name: `${config.name}-${stack.name}-${id}`,
|
|
1064
1148
|
code: Code.fromFile(id, props.file),
|
|
1065
|
-
...props
|
|
1149
|
+
...props,
|
|
1150
|
+
vpc: void 0
|
|
1066
1151
|
});
|
|
1067
1152
|
lambda.addEnvironment("APP", config.name).addEnvironment("STAGE", config.stage).addEnvironment("STACK", stack.name);
|
|
1153
|
+
if (props.vpc) {
|
|
1154
|
+
lambda.setVpc({
|
|
1155
|
+
securityGroupIds: [
|
|
1156
|
+
ctx.bootstrap.import(`vpc-security-group-id`)
|
|
1157
|
+
],
|
|
1158
|
+
subnetIds: [
|
|
1159
|
+
ctx.bootstrap.import(`public-subnet-1`),
|
|
1160
|
+
ctx.bootstrap.import(`public-subnet-2`)
|
|
1161
|
+
]
|
|
1162
|
+
}).addPermissions({
|
|
1163
|
+
actions: [
|
|
1164
|
+
"ec2:CreateNetworkInterface",
|
|
1165
|
+
"ec2:DescribeNetworkInterfaces",
|
|
1166
|
+
"ec2:DeleteNetworkInterface",
|
|
1167
|
+
"ec2:AssignPrivateIpAddresses",
|
|
1168
|
+
"ec2:UnassignPrivateIpAddresses"
|
|
1169
|
+
],
|
|
1170
|
+
resources: ["*"]
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1068
1173
|
if (props.runtime.startsWith("nodejs")) {
|
|
1069
1174
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1070
1175
|
}
|
|
1176
|
+
ctx.bind((other) => {
|
|
1177
|
+
other.addPermissions(lambda.permissions);
|
|
1178
|
+
});
|
|
1071
1179
|
return lambda;
|
|
1072
1180
|
};
|
|
1073
1181
|
|
|
@@ -1145,7 +1253,7 @@ var cronPlugin = definePlugin({
|
|
|
1145
1253
|
name: "cron",
|
|
1146
1254
|
schema: z7.object({
|
|
1147
1255
|
stacks: z7.object({
|
|
1148
|
-
/** Define the crons in your stack
|
|
1256
|
+
/** Define the crons in your stack.
|
|
1149
1257
|
* @example
|
|
1150
1258
|
* {
|
|
1151
1259
|
* crons: {
|
|
@@ -1157,7 +1265,7 @@ var cronPlugin = definePlugin({
|
|
|
1157
1265
|
* }
|
|
1158
1266
|
* */
|
|
1159
1267
|
crons: z7.record(ResourceIdSchema, z7.object({
|
|
1160
|
-
/** The consuming lambda function properties */
|
|
1268
|
+
/** The consuming lambda function properties. */
|
|
1161
1269
|
consumer: FunctionSchema,
|
|
1162
1270
|
/** The scheduling expression.
|
|
1163
1271
|
* @example 'cron(0 20 * * ? *)'
|
|
@@ -1191,6 +1299,7 @@ var Queue = class extends Resource {
|
|
|
1191
1299
|
super("AWS::SQS::Queue", logicalId);
|
|
1192
1300
|
this.props = props;
|
|
1193
1301
|
this.name = formatName(this.props.name || logicalId);
|
|
1302
|
+
this.tag("name", this.name);
|
|
1194
1303
|
}
|
|
1195
1304
|
name;
|
|
1196
1305
|
setDeadLetter(arn) {
|
|
@@ -1211,7 +1320,13 @@ var Queue = class extends Resource {
|
|
|
1211
1320
|
"sqs:GetQueueUrl",
|
|
1212
1321
|
"sqs:GetQueueAttributes"
|
|
1213
1322
|
],
|
|
1214
|
-
resources: [
|
|
1323
|
+
resources: [
|
|
1324
|
+
formatArn({
|
|
1325
|
+
service: "sqs",
|
|
1326
|
+
resource: "queue",
|
|
1327
|
+
resourceName: this.name
|
|
1328
|
+
})
|
|
1329
|
+
]
|
|
1215
1330
|
};
|
|
1216
1331
|
}
|
|
1217
1332
|
properties() {
|
|
@@ -1224,7 +1339,8 @@ var Queue = class extends Resource {
|
|
|
1224
1339
|
VisibilityTimeout: this.props.visibilityTimeout?.toSeconds() ?? 30,
|
|
1225
1340
|
...this.props.deadLetterArn ? {
|
|
1226
1341
|
RedrivePolicy: {
|
|
1227
|
-
deadLetterTargetArn: this.props.deadLetterArn
|
|
1342
|
+
deadLetterTargetArn: this.props.deadLetterArn,
|
|
1343
|
+
maxReceiveCount: this.props.maxReceiveCount ?? 100
|
|
1228
1344
|
}
|
|
1229
1345
|
} : {}
|
|
1230
1346
|
};
|
|
@@ -1280,8 +1396,7 @@ var SqsEventSource = class extends Group {
|
|
|
1280
1396
|
sourceArn: props.queueArn,
|
|
1281
1397
|
batchSize: props.batchSize ?? 10,
|
|
1282
1398
|
maxBatchingWindow: props.maxBatchingWindow,
|
|
1283
|
-
maxConcurrency: props.maxConcurrency
|
|
1284
|
-
onFailure: props.onFailure
|
|
1399
|
+
maxConcurrency: props.maxConcurrency
|
|
1285
1400
|
});
|
|
1286
1401
|
lambda.addPermissions({
|
|
1287
1402
|
actions: [
|
|
@@ -1296,6 +1411,14 @@ var SqsEventSource = class extends Group {
|
|
|
1296
1411
|
};
|
|
1297
1412
|
|
|
1298
1413
|
// src/plugins/queue.ts
|
|
1414
|
+
var RetentionPeriodSchema = DurationSchema.refine(durationMin(Duration.minutes(1)), "Minimum retention period is 1 minute").refine(durationMax(Duration.days(14)), "Maximum retention period is 14 days");
|
|
1415
|
+
var VisibilityTimeoutSchema = DurationSchema.refine(durationMax(Duration.hours(12)), "Maximum visibility timeout is 12 hours");
|
|
1416
|
+
var DeliveryDelaySchema = DurationSchema.refine(durationMax(Duration.minutes(15)), "Maximum delivery delay is 15 minutes");
|
|
1417
|
+
var ReceiveMessageWaitTimeSchema = DurationSchema.refine(durationMin(Duration.seconds(1)), "Minimum receive message wait time is 1 second").refine(durationMax(Duration.seconds(20)), "Maximum receive message wait time is 20 seconds");
|
|
1418
|
+
var MaxMessageSizeSchema = SizeSchema.refine(sizeMin(Size.kiloBytes(1)), "Minimum max message size is 1 KB").refine(sizeMax(Size.kiloBytes(256)), "Maximum max message size is 256 KB");
|
|
1419
|
+
var BatchSizeSchema = z8.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000");
|
|
1420
|
+
var MaxConcurrencySchema = z8.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000");
|
|
1421
|
+
var MaxBatchingWindow = DurationSchema.refine(durationMax(Duration.minutes(5)), "Maximum max batching window is 5 minutes");
|
|
1299
1422
|
var queuePlugin = definePlugin({
|
|
1300
1423
|
name: "queue",
|
|
1301
1424
|
schema: z8.object({
|
|
@@ -1303,29 +1426,40 @@ var queuePlugin = definePlugin({
|
|
|
1303
1426
|
/** Define the defaults properties for all queue's in your app. */
|
|
1304
1427
|
queue: z8.object({
|
|
1305
1428
|
/** The number of seconds that Amazon SQS retains a message.
|
|
1306
|
-
* You can specify a duration
|
|
1429
|
+
* You can specify a duration from 1 minute to 14 days.
|
|
1307
1430
|
* @default '7 days' */
|
|
1308
|
-
retentionPeriod:
|
|
1431
|
+
retentionPeriod: RetentionPeriodSchema.default("7 days"),
|
|
1309
1432
|
/** The length of time during which a message will be unavailable after a message is delivered from the queue.
|
|
1310
1433
|
* This blocks other components from receiving the same message and gives the initial component time to process and delete the message from the queue.
|
|
1311
|
-
* You can specify a duration
|
|
1434
|
+
* You can specify a duration from 0 to 12 hours.
|
|
1312
1435
|
* @default '30 seconds' */
|
|
1313
|
-
visibilityTimeout:
|
|
1436
|
+
visibilityTimeout: VisibilityTimeoutSchema.default("30 seconds"),
|
|
1314
1437
|
/** The time in seconds for which the delivery of all messages in the queue is delayed.
|
|
1315
|
-
* You can specify a duration
|
|
1438
|
+
* You can specify a duration from 0 to 15 minutes.
|
|
1316
1439
|
* @default '0 seconds' */
|
|
1317
|
-
deliveryDelay:
|
|
1440
|
+
deliveryDelay: DeliveryDelaySchema.default("0 seconds"),
|
|
1318
1441
|
/** Specifies the duration, in seconds,
|
|
1319
1442
|
* that the ReceiveMessage action call waits until a message is in the queue in order to include it in the response,
|
|
1320
1443
|
* rather than returning an empty response if a message isn't yet available.
|
|
1321
|
-
* You can specify
|
|
1322
|
-
*
|
|
1323
|
-
|
|
1324
|
-
receiveMessageWaitTime: DurationSchema.default("0 seconds"),
|
|
1444
|
+
* You can specify a duration from 1 to 20 seconds.
|
|
1445
|
+
* Short polling is used as the default. */
|
|
1446
|
+
receiveMessageWaitTime: ReceiveMessageWaitTimeSchema.optional(),
|
|
1325
1447
|
/** The limit of how many bytes that a message can contain before Amazon SQS rejects it.
|
|
1326
|
-
* You can specify an size
|
|
1448
|
+
* You can specify an size from 1 KB to 256 KB.
|
|
1327
1449
|
* @default '256 KB' */
|
|
1328
|
-
maxMessageSize:
|
|
1450
|
+
maxMessageSize: MaxMessageSizeSchema.default("256 KB"),
|
|
1451
|
+
/** The maximum number of records in each batch that Lambda pulls from your queue and sends to your function.
|
|
1452
|
+
* Lambda passes all of the records in the batch to the function in a single call, up to the payload limit for synchronous invocation (6 MB).
|
|
1453
|
+
* You can specify an integer from 1 to 10000.
|
|
1454
|
+
* @default 10 */
|
|
1455
|
+
batchSize: BatchSizeSchema.default(10),
|
|
1456
|
+
/** Limits the number of concurrent instances that the queue worker can invoke.
|
|
1457
|
+
* You can specify an integer from 2 to 1000. */
|
|
1458
|
+
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1459
|
+
/** The maximum amount of time, that Lambda spends gathering records before invoking the function.
|
|
1460
|
+
* You can specify an duration from 0 seconds to 5 minutes.
|
|
1461
|
+
* @default '0 seconds' */
|
|
1462
|
+
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1329
1463
|
}).default({})
|
|
1330
1464
|
}).default({}),
|
|
1331
1465
|
stacks: z8.object({
|
|
@@ -1347,26 +1481,38 @@ var queuePlugin = definePlugin({
|
|
|
1347
1481
|
/** The number of seconds that Amazon SQS retains a message.
|
|
1348
1482
|
* You can specify a duration value from 1 minute to 14 days.
|
|
1349
1483
|
* @default '7 days' */
|
|
1350
|
-
retentionPeriod:
|
|
1484
|
+
retentionPeriod: RetentionPeriodSchema.optional(),
|
|
1351
1485
|
/** The length of time during which a message will be unavailable after a message is delivered from the queue.
|
|
1352
1486
|
* This blocks other components from receiving the same message and gives the initial component time to process and delete the message from the queue.
|
|
1353
1487
|
* You can specify a duration value from 0 to 12 hours.
|
|
1354
1488
|
* @default '30 seconds' */
|
|
1355
|
-
visibilityTimeout:
|
|
1489
|
+
visibilityTimeout: VisibilityTimeoutSchema.optional(),
|
|
1356
1490
|
/** The time in seconds for which the delivery of all messages in the queue is delayed.
|
|
1357
1491
|
* You can specify a duration value from 0 to 15 minutes.
|
|
1358
1492
|
* @default '0 seconds' */
|
|
1359
|
-
deliveryDelay:
|
|
1493
|
+
deliveryDelay: DeliveryDelaySchema.optional(),
|
|
1360
1494
|
/** Specifies the duration, in seconds,
|
|
1361
1495
|
* that the ReceiveMessage action call waits until a message is in the queue in order to include it in the response,
|
|
1362
1496
|
* rather than returning an empty response if a message isn't yet available.
|
|
1363
1497
|
* You can specify a duration value from 1 to 20 seconds.
|
|
1364
|
-
*
|
|
1365
|
-
receiveMessageWaitTime:
|
|
1498
|
+
* Short polling is used as the default. */
|
|
1499
|
+
receiveMessageWaitTime: ReceiveMessageWaitTimeSchema.optional(),
|
|
1366
1500
|
/** The limit of how many bytes that a message can contain before Amazon SQS rejects it.
|
|
1367
1501
|
* You can specify an size value from 1 KB to 256 KB.
|
|
1368
1502
|
* @default '256 KB' */
|
|
1369
|
-
maxMessageSize:
|
|
1503
|
+
maxMessageSize: MaxMessageSizeSchema.optional(),
|
|
1504
|
+
/** The maximum number of records in each batch that Lambda pulls from your queue and sends to your function.
|
|
1505
|
+
* Lambda passes all of the records in the batch to the function in a single call, up to the payload limit for synchronous invocation (6 MB).
|
|
1506
|
+
* You can specify an integer from 1 to 10000.
|
|
1507
|
+
* @default 10 */
|
|
1508
|
+
batchSize: BatchSizeSchema.optional(),
|
|
1509
|
+
/** Limits the number of concurrent instances that the queue worker can invoke.
|
|
1510
|
+
* You can specify an integer from 2 to 1000. */
|
|
1511
|
+
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1512
|
+
/** The maximum amount of time, that Lambda spends gathering records before invoking the function.
|
|
1513
|
+
* You can specify an duration from 0 seconds to 5 minutes.
|
|
1514
|
+
* @default '0 seconds' */
|
|
1515
|
+
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1370
1516
|
})
|
|
1371
1517
|
])
|
|
1372
1518
|
).optional()
|
|
@@ -1378,12 +1524,15 @@ var queuePlugin = definePlugin({
|
|
|
1378
1524
|
const props = typeof functionOrProps === "string" ? { ...config.defaults.queue, consumer: functionOrProps } : { ...config.defaults.queue, ...functionOrProps };
|
|
1379
1525
|
const queue2 = new Queue(id, {
|
|
1380
1526
|
name: `${config.name}-${stack.name}-${id}`,
|
|
1527
|
+
deadLetterArn: getGlobalOnFailure(ctx),
|
|
1381
1528
|
...props
|
|
1382
1529
|
});
|
|
1383
1530
|
const lambda = toLambdaFunction(ctx, `queue-${id}`, props.consumer);
|
|
1384
1531
|
const source = new SqsEventSource(id, lambda, {
|
|
1385
1532
|
queueArn: queue2.arn,
|
|
1386
|
-
|
|
1533
|
+
batchSize: props.batchSize,
|
|
1534
|
+
maxConcurrency: props.maxConcurrency,
|
|
1535
|
+
maxBatchingWindow: props.maxBatchingWindow
|
|
1387
1536
|
});
|
|
1388
1537
|
stack.add(queue2, lambda, source);
|
|
1389
1538
|
bind((lambda2) => {
|
|
@@ -1404,6 +1553,7 @@ var Table = class extends Resource {
|
|
|
1404
1553
|
this.props = props;
|
|
1405
1554
|
this.name = formatName(this.props.name || logicalId);
|
|
1406
1555
|
this.indexes = { ...this.props.indexes || {} };
|
|
1556
|
+
this.tag("name", this.name);
|
|
1407
1557
|
}
|
|
1408
1558
|
name;
|
|
1409
1559
|
indexes;
|
|
@@ -1436,7 +1586,13 @@ var Table = class extends Resource {
|
|
|
1436
1586
|
"dynamodb:Query",
|
|
1437
1587
|
"dynamodb:Scan"
|
|
1438
1588
|
],
|
|
1439
|
-
resources: [
|
|
1589
|
+
resources: [
|
|
1590
|
+
formatArn({
|
|
1591
|
+
service: "dynamodb",
|
|
1592
|
+
resource: "table",
|
|
1593
|
+
resourceName: this.name
|
|
1594
|
+
})
|
|
1595
|
+
]
|
|
1440
1596
|
};
|
|
1441
1597
|
}
|
|
1442
1598
|
attributeDefinitions() {
|
|
@@ -1670,6 +1826,7 @@ var Bucket = class extends Resource {
|
|
|
1670
1826
|
super("AWS::S3::Bucket", logicalId);
|
|
1671
1827
|
this.props = props;
|
|
1672
1828
|
this.name = formatName(this.props.name || logicalId);
|
|
1829
|
+
this.tag("name", this.name);
|
|
1673
1830
|
}
|
|
1674
1831
|
name;
|
|
1675
1832
|
get arn() {
|
|
@@ -1686,7 +1843,13 @@ var Bucket = class extends Resource {
|
|
|
1686
1843
|
"s3:GetQueueUrl",
|
|
1687
1844
|
"s3:GetQueueAttributes"
|
|
1688
1845
|
],
|
|
1689
|
-
resources: [
|
|
1846
|
+
resources: [
|
|
1847
|
+
formatArn({
|
|
1848
|
+
service: "s3",
|
|
1849
|
+
resource: "bucket",
|
|
1850
|
+
resourceName: this.name
|
|
1851
|
+
})
|
|
1852
|
+
]
|
|
1690
1853
|
};
|
|
1691
1854
|
}
|
|
1692
1855
|
properties() {
|
|
@@ -1739,6 +1902,7 @@ var Topic = class extends Resource {
|
|
|
1739
1902
|
super("AWS::SNS::Topic", logicalId);
|
|
1740
1903
|
this.props = props;
|
|
1741
1904
|
this.name = formatName(this.props.name || logicalId);
|
|
1905
|
+
this.tag("name", this.name);
|
|
1742
1906
|
}
|
|
1743
1907
|
name;
|
|
1744
1908
|
get arn() {
|
|
@@ -1747,7 +1911,13 @@ var Topic = class extends Resource {
|
|
|
1747
1911
|
get permissions() {
|
|
1748
1912
|
return {
|
|
1749
1913
|
actions: ["sns:Publish"],
|
|
1750
|
-
resources: [
|
|
1914
|
+
resources: [
|
|
1915
|
+
formatArn({
|
|
1916
|
+
service: "sns",
|
|
1917
|
+
resource: "topic",
|
|
1918
|
+
resourceName: this.name
|
|
1919
|
+
})
|
|
1920
|
+
]
|
|
1751
1921
|
};
|
|
1752
1922
|
}
|
|
1753
1923
|
properties() {
|
|
@@ -1980,6 +2150,7 @@ var GraphQLApi = class extends Resource {
|
|
|
1980
2150
|
super("AWS::AppSync::GraphQLApi", logicalId);
|
|
1981
2151
|
this.props = props;
|
|
1982
2152
|
this.name = formatName(this.props.name || logicalId);
|
|
2153
|
+
this.tag("name", this.name);
|
|
1983
2154
|
}
|
|
1984
2155
|
name;
|
|
1985
2156
|
lambdaAuthProviders = [];
|
|
@@ -2632,7 +2803,7 @@ var domainPlugin = definePlugin({
|
|
|
2632
2803
|
name: DomainNameSchema.optional(),
|
|
2633
2804
|
/** The DNS record type. */
|
|
2634
2805
|
type: z15.enum(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"]),
|
|
2635
|
-
/** The resource record cache time to live (TTL) */
|
|
2806
|
+
/** The resource record cache time to live (TTL). */
|
|
2636
2807
|
ttl: DurationSchema,
|
|
2637
2808
|
/** One or more values that correspond with the value that you specified for the Type property. */
|
|
2638
2809
|
records: z15.string().array()
|
|
@@ -2744,6 +2915,12 @@ var Vpc = class extends Resource {
|
|
|
2744
2915
|
get id() {
|
|
2745
2916
|
return ref(this.logicalId);
|
|
2746
2917
|
}
|
|
2918
|
+
get defaultNetworkAcl() {
|
|
2919
|
+
return getAtt(this.logicalId, "DefaultNetworkAcl");
|
|
2920
|
+
}
|
|
2921
|
+
get defaultSecurityGroup() {
|
|
2922
|
+
return getAtt(this.logicalId, "DefaultSecurityGroup");
|
|
2923
|
+
}
|
|
2747
2924
|
properties() {
|
|
2748
2925
|
return {
|
|
2749
2926
|
CidrBlock: this.props.cidrBlock.ip
|
|
@@ -2755,6 +2932,7 @@ var RouteTable = class extends Resource {
|
|
|
2755
2932
|
super("AWS::EC2::RouteTable", logicalId);
|
|
2756
2933
|
this.props = props;
|
|
2757
2934
|
this.name = formatName(props.name || logicalId);
|
|
2935
|
+
this.tag("name", this.name);
|
|
2758
2936
|
}
|
|
2759
2937
|
name;
|
|
2760
2938
|
get id() {
|
|
@@ -2762,11 +2940,7 @@ var RouteTable = class extends Resource {
|
|
|
2762
2940
|
}
|
|
2763
2941
|
properties() {
|
|
2764
2942
|
return {
|
|
2765
|
-
VpcId: this.props.vpcId
|
|
2766
|
-
Tags: [{
|
|
2767
|
-
Key: "name",
|
|
2768
|
-
Value: this.name
|
|
2769
|
-
}]
|
|
2943
|
+
VpcId: this.props.vpcId
|
|
2770
2944
|
};
|
|
2771
2945
|
}
|
|
2772
2946
|
};
|
|
@@ -2919,6 +3093,7 @@ var vpcPlugin = definePlugin({
|
|
|
2919
3093
|
routeTableId: publicRouteTable.id,
|
|
2920
3094
|
destination: Peer.anyIpv4()
|
|
2921
3095
|
}).dependsOn(gateway, publicRouteTable);
|
|
3096
|
+
bootstrap2.export("vpc-security-group-id", vpc.defaultSecurityGroup);
|
|
2922
3097
|
bootstrap2.export(`vpc-id`, vpc.id);
|
|
2923
3098
|
bootstrap2.add(
|
|
2924
3099
|
vpc,
|
|
@@ -2961,7 +3136,9 @@ var SecurityGroup = class extends Resource {
|
|
|
2961
3136
|
constructor(logicalId, props) {
|
|
2962
3137
|
super("AWS::EC2::SecurityGroup", logicalId);
|
|
2963
3138
|
this.props = props;
|
|
3139
|
+
this.name = formatName(props.name ?? logicalId);
|
|
2964
3140
|
}
|
|
3141
|
+
name;
|
|
2965
3142
|
ingress = [];
|
|
2966
3143
|
egress = [];
|
|
2967
3144
|
get id() {
|
|
@@ -2986,7 +3163,7 @@ var SecurityGroup = class extends Resource {
|
|
|
2986
3163
|
properties() {
|
|
2987
3164
|
return {
|
|
2988
3165
|
VpcId: this.props.vpcId,
|
|
2989
|
-
GroupName: this.
|
|
3166
|
+
GroupName: this.name,
|
|
2990
3167
|
GroupDescription: this.props.description,
|
|
2991
3168
|
SecurityGroupIngress: this.ingress.map((rule) => ({
|
|
2992
3169
|
Description: rule.description || "",
|
|
@@ -3397,6 +3574,7 @@ var Collection = class extends Resource {
|
|
|
3397
3574
|
super("AWS::OpenSearchServerless::Collection", logicalId);
|
|
3398
3575
|
this.props = props;
|
|
3399
3576
|
this.name = this.props.name || logicalId;
|
|
3577
|
+
this.tag("name", this.name);
|
|
3400
3578
|
}
|
|
3401
3579
|
name;
|
|
3402
3580
|
get id() {
|
|
@@ -3408,6 +3586,18 @@ var Collection = class extends Resource {
|
|
|
3408
3586
|
get endpoint() {
|
|
3409
3587
|
return getAtt(this.logicalId, "CollectionEndpoint");
|
|
3410
3588
|
}
|
|
3589
|
+
get permissions() {
|
|
3590
|
+
return {
|
|
3591
|
+
actions: ["aoss:APIAccessAll"],
|
|
3592
|
+
resources: [
|
|
3593
|
+
formatArn({
|
|
3594
|
+
service: "aoss",
|
|
3595
|
+
resource: "collection",
|
|
3596
|
+
resourceName: this.name
|
|
3597
|
+
})
|
|
3598
|
+
]
|
|
3599
|
+
};
|
|
3600
|
+
}
|
|
3411
3601
|
properties() {
|
|
3412
3602
|
return {
|
|
3413
3603
|
Name: this.name,
|
|
@@ -3432,10 +3622,155 @@ var searchPlugin = definePlugin({
|
|
|
3432
3622
|
type: "search"
|
|
3433
3623
|
});
|
|
3434
3624
|
bind((lambda) => {
|
|
3435
|
-
lambda.addPermissions(
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3625
|
+
lambda.addPermissions(collection.permissions);
|
|
3626
|
+
});
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
});
|
|
3630
|
+
|
|
3631
|
+
// src/plugins/cache.ts
|
|
3632
|
+
import { z as z19 } from "zod";
|
|
3633
|
+
|
|
3634
|
+
// src/formation/resource/memorydb/cluster.ts
|
|
3635
|
+
var Cluster = class extends Resource {
|
|
3636
|
+
constructor(logicalId, props) {
|
|
3637
|
+
super("AWS::MemoryDB::Cluster", logicalId);
|
|
3638
|
+
this.props = props;
|
|
3639
|
+
this.name = formatName(this.props.name || logicalId);
|
|
3640
|
+
this.tag("name", this.name);
|
|
3641
|
+
}
|
|
3642
|
+
name;
|
|
3643
|
+
get status() {
|
|
3644
|
+
return this.getAtt("Status");
|
|
3645
|
+
}
|
|
3646
|
+
get arn() {
|
|
3647
|
+
return this.getAtt("ARN");
|
|
3648
|
+
}
|
|
3649
|
+
get address() {
|
|
3650
|
+
return this.getAtt("ClusterEndpoint.Address");
|
|
3651
|
+
}
|
|
3652
|
+
get port() {
|
|
3653
|
+
return this.getAtt("ClusterEndpoint.Port");
|
|
3654
|
+
}
|
|
3655
|
+
properties() {
|
|
3656
|
+
return {
|
|
3657
|
+
ClusterName: this.name,
|
|
3658
|
+
ClusterEndpoint: {
|
|
3659
|
+
Port: this.props.port
|
|
3660
|
+
},
|
|
3661
|
+
Port: this.props.port,
|
|
3662
|
+
...this.attr("Description", this.props.description),
|
|
3663
|
+
ACLName: this.props.aclName,
|
|
3664
|
+
EngineVersion: this.props.engine ?? "7.0",
|
|
3665
|
+
...this.attr("SubnetGroupName", this.props.subnetGroupName),
|
|
3666
|
+
...this.attr("SecurityGroupIds", this.props.securityGroupIds),
|
|
3667
|
+
NodeType: "db." + this.props.type,
|
|
3668
|
+
NumReplicasPerShard: this.props.replicasPerShard ?? 1,
|
|
3669
|
+
NumShards: this.props.shards ?? 1,
|
|
3670
|
+
TLSEnabled: this.props.tls ?? false,
|
|
3671
|
+
DataTiering: this.props.dataTiering ? "true" : "false",
|
|
3672
|
+
AutoMinorVersionUpgrade: this.props.autoMinorVersionUpgrade ?? true,
|
|
3673
|
+
MaintenanceWindow: this.props.maintenanceWindow ?? "Sat:02:00-Sat:05:00"
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3676
|
+
};
|
|
3677
|
+
|
|
3678
|
+
// src/formation/resource/memorydb/subnet-group.ts
|
|
3679
|
+
var SubnetGroup = class extends Resource {
|
|
3680
|
+
constructor(logicalId, props) {
|
|
3681
|
+
super("AWS::MemoryDB::SubnetGroup", logicalId);
|
|
3682
|
+
this.props = props;
|
|
3683
|
+
this.name = formatName(this.props.name || logicalId);
|
|
3684
|
+
}
|
|
3685
|
+
name;
|
|
3686
|
+
get arn() {
|
|
3687
|
+
return getAtt(this.logicalId, "Arn");
|
|
3688
|
+
}
|
|
3689
|
+
properties() {
|
|
3690
|
+
return {
|
|
3691
|
+
SubnetGroupName: this.name,
|
|
3692
|
+
SubnetIds: this.props.subnetIds,
|
|
3693
|
+
...this.attr("Description", this.props.description)
|
|
3694
|
+
};
|
|
3695
|
+
}
|
|
3696
|
+
};
|
|
3697
|
+
|
|
3698
|
+
// src/plugins/cache.ts
|
|
3699
|
+
var TypeSchema = z19.enum([
|
|
3700
|
+
"t4g.small",
|
|
3701
|
+
"t4g.medium",
|
|
3702
|
+
"r6g.large",
|
|
3703
|
+
"r6g.xlarge",
|
|
3704
|
+
"r6g.2xlarge",
|
|
3705
|
+
"r6g.4xlarge",
|
|
3706
|
+
"r6g.8xlarge",
|
|
3707
|
+
"r6g.12xlarge",
|
|
3708
|
+
"r6g.16xlarge",
|
|
3709
|
+
"r6gd.xlarge",
|
|
3710
|
+
"r6gd.2xlarge",
|
|
3711
|
+
"r6gd.4xlarge",
|
|
3712
|
+
"r6gd.8xlarge"
|
|
3713
|
+
]);
|
|
3714
|
+
var PortSchema = z19.number().int().min(1).max(5e4);
|
|
3715
|
+
var ShardsSchema = z19.number().int().min(0).max(100);
|
|
3716
|
+
var ReplicasPerShardSchema = z19.number().int().min(0).max(5);
|
|
3717
|
+
var EngineSchema = z19.enum(["7.0", "6.2"]);
|
|
3718
|
+
var cachePlugin = definePlugin({
|
|
3719
|
+
name: "cache",
|
|
3720
|
+
schema: z19.object({
|
|
3721
|
+
stacks: z19.object({
|
|
3722
|
+
/** Define the caches in your stack.
|
|
3723
|
+
* For access to the cache put your functions inside the global VPC.
|
|
3724
|
+
* @example
|
|
3725
|
+
* {
|
|
3726
|
+
* caches: {
|
|
3727
|
+
* CACHE_NAME: {
|
|
3728
|
+
* type: 't4g.small'
|
|
3729
|
+
* }
|
|
3730
|
+
* }
|
|
3731
|
+
* }
|
|
3732
|
+
*/
|
|
3733
|
+
caches: z19.record(
|
|
3734
|
+
ResourceIdSchema,
|
|
3735
|
+
z19.object({
|
|
3736
|
+
type: TypeSchema.default("t4g.small"),
|
|
3737
|
+
port: PortSchema.default(6379),
|
|
3738
|
+
shards: ShardsSchema.default(1),
|
|
3739
|
+
replicasPerShard: ReplicasPerShardSchema.default(1),
|
|
3740
|
+
engine: EngineSchema.default("7.0"),
|
|
3741
|
+
dataTiering: z19.boolean().default(false)
|
|
3742
|
+
})
|
|
3743
|
+
).optional()
|
|
3744
|
+
}).array()
|
|
3745
|
+
}),
|
|
3746
|
+
onStack({ config, stack, stackConfig, bootstrap: bootstrap2, bind }) {
|
|
3747
|
+
for (const [id, props] of Object.entries(stackConfig.caches || {})) {
|
|
3748
|
+
const name = `${config.name}-${stack.name}-${id}`;
|
|
3749
|
+
const subnetGroup = new SubnetGroup(id, {
|
|
3750
|
+
name,
|
|
3751
|
+
subnetIds: [
|
|
3752
|
+
bootstrap2.import(`private-subnet-1`),
|
|
3753
|
+
bootstrap2.import(`private-subnet-2`)
|
|
3754
|
+
]
|
|
3755
|
+
});
|
|
3756
|
+
const securityGroup = new SecurityGroup(id, {
|
|
3757
|
+
name,
|
|
3758
|
+
vpcId: bootstrap2.import(`vpc-id`),
|
|
3759
|
+
description: name
|
|
3760
|
+
});
|
|
3761
|
+
const port = Port.tcp(props.port);
|
|
3762
|
+
securityGroup.addIngressRule(Peer.anyIpv4(), port);
|
|
3763
|
+
securityGroup.addIngressRule(Peer.anyIpv6(), port);
|
|
3764
|
+
const cluster = new Cluster(id, {
|
|
3765
|
+
name,
|
|
3766
|
+
aclName: "open-access",
|
|
3767
|
+
securityGroupIds: [securityGroup.id],
|
|
3768
|
+
subnetGroupName: subnetGroup.name,
|
|
3769
|
+
...props
|
|
3770
|
+
}).dependsOn(subnetGroup, securityGroup);
|
|
3771
|
+
stack.add(subnetGroup, securityGroup, cluster);
|
|
3772
|
+
bind((lambda) => {
|
|
3773
|
+
lambda.addEnvironment(`CACHE_${stack.name}_${id}_HOST`, cluster.address).addEnvironment(`CACHE_${stack.name}_${id}_PORT`, props.port.toString());
|
|
3439
3774
|
});
|
|
3440
3775
|
}
|
|
3441
3776
|
}
|
|
@@ -3446,6 +3781,7 @@ var defaultPlugins = [
|
|
|
3446
3781
|
extendPlugin,
|
|
3447
3782
|
vpcPlugin,
|
|
3448
3783
|
functionPlugin,
|
|
3784
|
+
cachePlugin,
|
|
3449
3785
|
cronPlugin,
|
|
3450
3786
|
queuePlugin,
|
|
3451
3787
|
tablePlugin,
|
|
@@ -3627,7 +3963,7 @@ var toApp = async (config, filters) => {
|
|
|
3627
3963
|
config.stacks.filter((stack) => filters.includes(stack.name))
|
|
3628
3964
|
);
|
|
3629
3965
|
for (const stackConfig of filterdStacks) {
|
|
3630
|
-
const { stack } = toStack({
|
|
3966
|
+
const { stack, bindings: bindings2 } = toStack({
|
|
3631
3967
|
config,
|
|
3632
3968
|
stackConfig,
|
|
3633
3969
|
bootstrap: bootstrap2,
|
|
@@ -3636,7 +3972,7 @@ var toApp = async (config, filters) => {
|
|
|
3636
3972
|
app
|
|
3637
3973
|
});
|
|
3638
3974
|
app.add(stack);
|
|
3639
|
-
stacks.push({ stack, config: stackConfig });
|
|
3975
|
+
stacks.push({ stack, config: stackConfig, bindings: bindings2 });
|
|
3640
3976
|
}
|
|
3641
3977
|
for (const plugin of plugins) {
|
|
3642
3978
|
for (const stack of app.stacks) {
|
|
@@ -3658,23 +3994,31 @@ var toApp = async (config, filters) => {
|
|
|
3658
3994
|
bind2(fn);
|
|
3659
3995
|
}
|
|
3660
3996
|
}
|
|
3661
|
-
|
|
3997
|
+
for (const entry of stacks) {
|
|
3998
|
+
for (const dep of entry.config.depends || []) {
|
|
3999
|
+
const depStack = stacks.find((entry2) => entry2.config.name === dep.name);
|
|
4000
|
+
if (!depStack) {
|
|
4001
|
+
throw new Error(`Stack dependency not found: ${dep.name}`);
|
|
4002
|
+
}
|
|
4003
|
+
const functions2 = entry.stack.find(Function);
|
|
4004
|
+
for (const bind2 of depStack.bindings) {
|
|
4005
|
+
for (const fn of functions2) {
|
|
4006
|
+
bind2(fn);
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
const deploymentLine = createDeploymentLine(stacks);
|
|
3662
4012
|
if (bootstrap2.size > 0) {
|
|
3663
|
-
|
|
3664
|
-
stack: bootstrap2,
|
|
3665
|
-
children: dependencyTree
|
|
3666
|
-
}];
|
|
4013
|
+
deploymentLine.unshift([bootstrap2]);
|
|
3667
4014
|
}
|
|
3668
4015
|
if (usEastBootstrap.size > 0) {
|
|
3669
|
-
|
|
3670
|
-
stack: usEastBootstrap,
|
|
3671
|
-
children: dependencyTree
|
|
3672
|
-
}];
|
|
4016
|
+
deploymentLine.unshift([usEastBootstrap]);
|
|
3673
4017
|
}
|
|
3674
4018
|
return {
|
|
3675
4019
|
app,
|
|
3676
4020
|
plugins,
|
|
3677
|
-
|
|
4021
|
+
deploymentLine
|
|
3678
4022
|
};
|
|
3679
4023
|
};
|
|
3680
4024
|
|
|
@@ -3698,17 +4042,17 @@ var getCredentials = (profile) => {
|
|
|
3698
4042
|
};
|
|
3699
4043
|
|
|
3700
4044
|
// src/schema/app.ts
|
|
3701
|
-
import { z as
|
|
4045
|
+
import { z as z23 } from "zod";
|
|
3702
4046
|
|
|
3703
4047
|
// src/schema/stack.ts
|
|
3704
|
-
import { z as
|
|
3705
|
-
var StackSchema =
|
|
4048
|
+
import { z as z20 } from "zod";
|
|
4049
|
+
var StackSchema = z20.object({
|
|
3706
4050
|
name: ResourceIdSchema,
|
|
3707
|
-
depends:
|
|
4051
|
+
depends: z20.array(z20.lazy(() => StackSchema)).optional()
|
|
3708
4052
|
});
|
|
3709
4053
|
|
|
3710
4054
|
// src/schema/region.ts
|
|
3711
|
-
import { z as
|
|
4055
|
+
import { z as z21 } from "zod";
|
|
3712
4056
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
3713
4057
|
var AF = ["af-south-1"];
|
|
3714
4058
|
var AP = ["ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-4", "ap-south-1", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1"];
|
|
@@ -3725,47 +4069,49 @@ var regions = [
|
|
|
3725
4069
|
...ME,
|
|
3726
4070
|
...SA
|
|
3727
4071
|
];
|
|
3728
|
-
var RegionSchema =
|
|
4072
|
+
var RegionSchema = z21.enum(regions);
|
|
3729
4073
|
|
|
3730
4074
|
// src/schema/plugin.ts
|
|
3731
|
-
import { z as
|
|
3732
|
-
var PluginSchema =
|
|
3733
|
-
name:
|
|
3734
|
-
schema:
|
|
4075
|
+
import { z as z22 } from "zod";
|
|
4076
|
+
var PluginSchema = z22.object({
|
|
4077
|
+
name: z22.string(),
|
|
4078
|
+
schema: z22.custom().optional(),
|
|
3735
4079
|
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
3736
|
-
onApp:
|
|
3737
|
-
onStack:
|
|
3738
|
-
onResource:
|
|
4080
|
+
onApp: z22.function().returns(z22.void()).optional(),
|
|
4081
|
+
onStack: z22.function().returns(z22.any()).optional(),
|
|
4082
|
+
onResource: z22.function().returns(z22.any()).optional()
|
|
3739
4083
|
// bind: z.function().optional(),
|
|
3740
4084
|
});
|
|
3741
4085
|
|
|
3742
4086
|
// src/schema/app.ts
|
|
3743
|
-
var AppSchema =
|
|
4087
|
+
var AppSchema = z23.object({
|
|
3744
4088
|
/** App name */
|
|
3745
4089
|
name: ResourceIdSchema,
|
|
3746
4090
|
/** The AWS region to deploy to. */
|
|
3747
4091
|
region: RegionSchema,
|
|
3748
4092
|
/** The AWS profile to deploy to. */
|
|
3749
|
-
profile:
|
|
4093
|
+
profile: z23.string(),
|
|
3750
4094
|
/** The deployment stage.
|
|
3751
4095
|
* @default 'prod'
|
|
3752
4096
|
*/
|
|
3753
|
-
stage:
|
|
4097
|
+
stage: z23.string().regex(/[a-z]+/).default("prod"),
|
|
3754
4098
|
/** Default properties. */
|
|
3755
|
-
defaults:
|
|
4099
|
+
defaults: z23.object({}).default({}),
|
|
3756
4100
|
/** The application stacks. */
|
|
3757
|
-
stacks:
|
|
4101
|
+
stacks: z23.array(StackSchema).min(1).refine((stacks) => {
|
|
3758
4102
|
const unique = new Set(stacks.map((stack) => stack.name));
|
|
3759
4103
|
return unique.size === stacks.length;
|
|
3760
4104
|
}, "Must be an array of unique stacks"),
|
|
3761
4105
|
/** Custom plugins. */
|
|
3762
|
-
plugins:
|
|
4106
|
+
plugins: z23.array(PluginSchema).optional()
|
|
3763
4107
|
});
|
|
3764
4108
|
|
|
3765
4109
|
// src/util/import.ts
|
|
3766
|
-
import {
|
|
4110
|
+
import { rollup as rollup2 } from "rollup";
|
|
4111
|
+
import { swc as swc2 } from "rollup-plugin-swc3";
|
|
4112
|
+
import replace from "rollup-plugin-replace";
|
|
3767
4113
|
import { dirname, join as join2 } from "path";
|
|
3768
|
-
import {
|
|
4114
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
3769
4115
|
|
|
3770
4116
|
// src/util/path.ts
|
|
3771
4117
|
import { lstat } from "fs/promises";
|
|
@@ -3812,54 +4158,25 @@ var fileExist = async (file) => {
|
|
|
3812
4158
|
};
|
|
3813
4159
|
|
|
3814
4160
|
// src/util/import.ts
|
|
3815
|
-
var resolveFileNameExtension = async (path) => {
|
|
3816
|
-
const options = [
|
|
3817
|
-
"",
|
|
3818
|
-
".ts",
|
|
3819
|
-
".js",
|
|
3820
|
-
"/index.ts",
|
|
3821
|
-
"/index.js"
|
|
3822
|
-
];
|
|
3823
|
-
for (const option of options) {
|
|
3824
|
-
const file = path.replace(/\.js$/, "") + option;
|
|
3825
|
-
let stat;
|
|
3826
|
-
try {
|
|
3827
|
-
stat = await lstat2(file);
|
|
3828
|
-
} catch (error) {
|
|
3829
|
-
continue;
|
|
3830
|
-
}
|
|
3831
|
-
if (stat.isFile()) {
|
|
3832
|
-
return file;
|
|
3833
|
-
}
|
|
3834
|
-
}
|
|
3835
|
-
throw new Error(`Failed to load file: ${path}`);
|
|
3836
|
-
};
|
|
3837
|
-
var resolveDir = (path) => {
|
|
3838
|
-
return dirname(path).replace(directories.root + "/", "");
|
|
3839
|
-
};
|
|
3840
4161
|
var importFile = async (path) => {
|
|
3841
|
-
const
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
await Promise.all(matches?.map(async (match) => {
|
|
3853
|
-
const parts = /('|")(\.\.?[\/a-z0-9\_\-\.]+)('|")/ig.exec(match);
|
|
3854
|
-
const from = parts[2];
|
|
3855
|
-
const file2 = await resolveFileNameExtension(join2(path2, from));
|
|
3856
|
-
const result = await load(file2);
|
|
3857
|
-
code2 = code2.replace(match, result);
|
|
3858
|
-
}));
|
|
3859
|
-
return code2;
|
|
3860
|
-
};
|
|
3861
|
-
const code = await load(path);
|
|
4162
|
+
const bundle = await rollup2({
|
|
4163
|
+
input: path,
|
|
4164
|
+
plugins: [
|
|
4165
|
+
replace({
|
|
4166
|
+
__dirname: (id) => `'${dirname(id)}'`
|
|
4167
|
+
}),
|
|
4168
|
+
swc2({
|
|
4169
|
+
minify: false
|
|
4170
|
+
})
|
|
4171
|
+
]
|
|
4172
|
+
});
|
|
3862
4173
|
const outputFile = join2(directories.cache, "config.js");
|
|
4174
|
+
const result = await bundle.generate({
|
|
4175
|
+
format: "esm",
|
|
4176
|
+
exports: "default"
|
|
4177
|
+
});
|
|
4178
|
+
const output = result.output[0];
|
|
4179
|
+
const code = output.code;
|
|
3863
4180
|
await mkdir(directories.cache, { recursive: true });
|
|
3864
4181
|
await writeFile(outputFile, code);
|
|
3865
4182
|
debug("Save config file:", style.info(outputFile));
|
|
@@ -4161,7 +4478,7 @@ var Renderer = class {
|
|
|
4161
4478
|
flushing = false;
|
|
4162
4479
|
screen = [];
|
|
4163
4480
|
width() {
|
|
4164
|
-
return this.output.columns;
|
|
4481
|
+
return this.output.columns - 1;
|
|
4165
4482
|
}
|
|
4166
4483
|
height() {
|
|
4167
4484
|
return this.output.rows;
|
|
@@ -4999,12 +5316,73 @@ var assetPublisher = (config, app) => {
|
|
|
4999
5316
|
};
|
|
5000
5317
|
};
|
|
5001
5318
|
|
|
5319
|
+
// src/cli/ui/complex/deployer.ts
|
|
5320
|
+
var stacksDeployer = (deploymentLine) => {
|
|
5321
|
+
const stackNames = deploymentLine.map((line) => line.map((stack) => stack.name)).flat();
|
|
5322
|
+
const stackNameSize = Math.max(...stackNames.map((name) => name.length));
|
|
5323
|
+
return (term) => {
|
|
5324
|
+
const ui = {};
|
|
5325
|
+
term.out.gap();
|
|
5326
|
+
for (const i in deploymentLine) {
|
|
5327
|
+
const line = flexLine(
|
|
5328
|
+
term,
|
|
5329
|
+
[" "],
|
|
5330
|
+
[
|
|
5331
|
+
" ",
|
|
5332
|
+
style.placeholder(Number(i) + 1),
|
|
5333
|
+
style.placeholder(" \u2500\u2500")
|
|
5334
|
+
]
|
|
5335
|
+
);
|
|
5336
|
+
term.out.write(line);
|
|
5337
|
+
term.out.write(br());
|
|
5338
|
+
for (const stack of deploymentLine[i]) {
|
|
5339
|
+
const icon = new Signal(" ");
|
|
5340
|
+
const name = new Signal(style.label.dim(stack.name));
|
|
5341
|
+
const status2 = new Signal(style.info.dim("waiting"));
|
|
5342
|
+
let stopSpinner;
|
|
5343
|
+
term.out.write([
|
|
5344
|
+
icon,
|
|
5345
|
+
" ",
|
|
5346
|
+
name,
|
|
5347
|
+
" ".repeat(stackNameSize - stack.name.length),
|
|
5348
|
+
" ",
|
|
5349
|
+
style.placeholder(symbol.pointerSmall),
|
|
5350
|
+
" ",
|
|
5351
|
+
status2,
|
|
5352
|
+
br()
|
|
5353
|
+
]);
|
|
5354
|
+
ui[stack.name] = {
|
|
5355
|
+
start: (value) => {
|
|
5356
|
+
const [spinner, stop] = createSpinner();
|
|
5357
|
+
name.set(style.label(stack.name));
|
|
5358
|
+
icon.set(spinner);
|
|
5359
|
+
status2.set(style.warning(value));
|
|
5360
|
+
stopSpinner = stop;
|
|
5361
|
+
},
|
|
5362
|
+
done(value) {
|
|
5363
|
+
stopSpinner();
|
|
5364
|
+
icon.set(style.success(symbol.success));
|
|
5365
|
+
status2.set(style.success(value));
|
|
5366
|
+
},
|
|
5367
|
+
fail(value) {
|
|
5368
|
+
stopSpinner();
|
|
5369
|
+
icon.set(style.error(symbol.error));
|
|
5370
|
+
status2.set(style.error(value));
|
|
5371
|
+
}
|
|
5372
|
+
};
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
term.out.gap();
|
|
5376
|
+
return ui;
|
|
5377
|
+
};
|
|
5378
|
+
};
|
|
5379
|
+
|
|
5002
5380
|
// src/cli/command/deploy.ts
|
|
5003
5381
|
var deploy = (program2) => {
|
|
5004
5382
|
program2.command("deploy").argument("[stacks...]", "Optionally filter stacks to deploy").description("Deploy your app to AWS").action(async (filters) => {
|
|
5005
5383
|
await layout(async (config, write) => {
|
|
5006
5384
|
await write(bootstrapDeployer(config));
|
|
5007
|
-
const { app,
|
|
5385
|
+
const { app, deploymentLine } = await toApp(config, filters);
|
|
5008
5386
|
const stackNames = app.stacks.map((stack) => stack.name);
|
|
5009
5387
|
const formattedFilter = stackNames.map((i) => style.info(i)).join(style.placeholder(", "));
|
|
5010
5388
|
debug("Stacks to deploy", formattedFilter);
|
|
@@ -5018,26 +5396,21 @@ var deploy = (program2) => {
|
|
|
5018
5396
|
await write(assetBuilder(app));
|
|
5019
5397
|
await write(assetPublisher(config, app));
|
|
5020
5398
|
await write(templateBuilder(app));
|
|
5021
|
-
const statuses = {};
|
|
5022
|
-
for (const stack of app) {
|
|
5023
|
-
statuses[stack.name] = new Signal(style.info("waiting"));
|
|
5024
|
-
}
|
|
5025
5399
|
const doneDeploying = write(loadingDialog("Deploying stacks to AWS..."));
|
|
5026
|
-
write(stackTree(dependencyTree, statuses));
|
|
5027
5400
|
const client = new StackClient(app, config.account, config.region, config.credentials);
|
|
5028
|
-
const
|
|
5029
|
-
for (const
|
|
5030
|
-
const results = await Promise.allSettled(
|
|
5031
|
-
const
|
|
5032
|
-
|
|
5401
|
+
const ui = write(stacksDeployer(deploymentLine));
|
|
5402
|
+
for (const line of deploymentLine) {
|
|
5403
|
+
const results = await Promise.allSettled(line.map(async (stack) => {
|
|
5404
|
+
const item = ui[stack.name];
|
|
5405
|
+
item.start("deploying");
|
|
5033
5406
|
try {
|
|
5034
5407
|
await client.deploy(stack);
|
|
5035
5408
|
} catch (error) {
|
|
5036
5409
|
debugError(error);
|
|
5037
|
-
|
|
5410
|
+
item.fail("failed");
|
|
5038
5411
|
throw error;
|
|
5039
5412
|
}
|
|
5040
|
-
|
|
5413
|
+
item.done("deployed");
|
|
5041
5414
|
}));
|
|
5042
5415
|
for (const result of results) {
|
|
5043
5416
|
if (result.status === "rejected") {
|