@awsless/awsless 0.0.654 → 0.0.656
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/app.json +1 -1
- package/dist/app.stage.json +1 -1
- package/dist/bin.js +980 -718
- package/dist/build-json-schema.js +326 -303
- package/dist/prebuild/icon/bundle.zip +0 -0
- package/dist/prebuild/image/HASH +1 -1
- package/dist/prebuild/image/bundle.zip +0 -0
- package/dist/prebuild/on-failure/HASH +1 -0
- package/dist/prebuild/on-failure/bundle.zip +0 -0
- package/dist/prebuild/rpc/bundle.zip +0 -0
- package/dist/prebuild.js +2 -1
- package/dist/server.d.ts +4 -1
- package/dist/server.js +23 -5
- package/dist/stack.json +1 -1
- package/dist/stack.stage.json +1 -1
- package/package.json +10 -10
package/dist/bin.js
CHANGED
|
@@ -939,7 +939,7 @@ var debug = (...parts) => {
|
|
|
939
939
|
};
|
|
940
940
|
|
|
941
941
|
// src/config/app.ts
|
|
942
|
-
import { z as
|
|
942
|
+
import { z as z30 } from "zod";
|
|
943
943
|
|
|
944
944
|
// src/feature/alert/schema.ts
|
|
945
945
|
import { kebabCase } from "change-case";
|
|
@@ -1139,9 +1139,6 @@ var EphemeralStorageSizeSchema = SizeSchema.refine(
|
|
|
1139
1139
|
var ReservedConcurrentExecutionsSchema = z15.number().int().min(0).describe("The number of simultaneous executions to reserve for the function. You can specify a number from 0.");
|
|
1140
1140
|
var EnvironmentSchema = z15.record(z15.string(), z15.string()).optional().describe("Environment variable key-value pairs.");
|
|
1141
1141
|
var ArchitectureSchema = z15.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the function supports.");
|
|
1142
|
-
var RetryAttemptsSchema = z15.number().int().min(0).max(2).describe(
|
|
1143
|
-
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
1144
|
-
);
|
|
1145
1142
|
var NodeRuntimeSchema = z15.enum(["nodejs18.x", "nodejs20.x", "nodejs22.x", "nodejs24.x"]);
|
|
1146
1143
|
var ContainerRuntimeSchema = z15.literal("container");
|
|
1147
1144
|
var RuntimeSchema = NodeRuntimeSchema.or(ContainerRuntimeSchema).or(z15.string()).describe("The identifier of the function's runtime.");
|
|
@@ -1234,7 +1231,7 @@ var FnSchema = z15.object({
|
|
|
1234
1231
|
memorySize: MemorySizeSchema.optional(),
|
|
1235
1232
|
architecture: ArchitectureSchema.optional(),
|
|
1236
1233
|
ephemeralStorageSize: EphemeralStorageSizeSchema.optional(),
|
|
1237
|
-
retryAttempts: RetryAttemptsSchema.optional(),
|
|
1234
|
+
// retryAttempts: RetryAttemptsSchema.optional(),
|
|
1238
1235
|
reserved: ReservedConcurrentExecutionsSchema.optional(),
|
|
1239
1236
|
layers: LayersSchema.optional(),
|
|
1240
1237
|
environment: EnvironmentSchema.optional(),
|
|
@@ -1268,7 +1265,7 @@ var FunctionDefaultSchema = z15.object({
|
|
|
1268
1265
|
memorySize: MemorySizeSchema.default("128 MB"),
|
|
1269
1266
|
architecture: ArchitectureSchema.default("arm64"),
|
|
1270
1267
|
ephemeralStorageSize: EphemeralStorageSizeSchema.default("512 MB"),
|
|
1271
|
-
retryAttempts: RetryAttemptsSchema.default(2),
|
|
1268
|
+
// retryAttempts: RetryAttemptsSchema.default(2),
|
|
1272
1269
|
reserved: ReservedConcurrentExecutionsSchema.optional(),
|
|
1273
1270
|
layers: LayersSchema.optional(),
|
|
1274
1271
|
environment: EnvironmentSchema.optional(),
|
|
@@ -1304,39 +1301,56 @@ var LayerSchema = z17.record(
|
|
|
1304
1301
|
).optional().describe("Define the lambda layers in your stack.");
|
|
1305
1302
|
|
|
1306
1303
|
// src/feature/on-failure/schema.ts
|
|
1307
|
-
|
|
1304
|
+
import { z as z18 } from "zod";
|
|
1305
|
+
var NotifySchema = z18.union([
|
|
1306
|
+
//
|
|
1307
|
+
EmailSchema.transform((v) => [v]),
|
|
1308
|
+
EmailSchema.array()
|
|
1309
|
+
]).describe("Receive an email notification when consuming failure entries goes wrong.");
|
|
1310
|
+
var OnFailureDefaultSchema = z18.union([
|
|
1311
|
+
FunctionSchema.transform((consumer) => ({
|
|
1312
|
+
consumer,
|
|
1313
|
+
notify: []
|
|
1314
|
+
})),
|
|
1315
|
+
z18.object({
|
|
1316
|
+
consumer: FunctionSchema,
|
|
1317
|
+
notify: NotifySchema.optional()
|
|
1318
|
+
})
|
|
1319
|
+
]).optional().describe(
|
|
1308
1320
|
[
|
|
1309
1321
|
"Defining a onFailure handler will add a global onFailure handler for the following resources:",
|
|
1310
|
-
"-
|
|
1311
|
-
"-
|
|
1312
|
-
"-
|
|
1313
|
-
"-
|
|
1322
|
+
"- Tasks",
|
|
1323
|
+
"- Crons",
|
|
1324
|
+
"- Queues",
|
|
1325
|
+
"- Topics",
|
|
1326
|
+
"- Pubsub",
|
|
1327
|
+
"- Table streams"
|
|
1314
1328
|
].join("\n")
|
|
1315
1329
|
);
|
|
1316
1330
|
|
|
1317
1331
|
// src/feature/on-log/schema.ts
|
|
1318
|
-
import { z as
|
|
1319
|
-
var FilterSchema =
|
|
1320
|
-
var OnLogDefaultSchema =
|
|
1332
|
+
import { z as z19 } from "zod";
|
|
1333
|
+
var FilterSchema = z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).array().describe("The log level that will gets delivered to the consumer.");
|
|
1334
|
+
var OnLogDefaultSchema = z19.union([
|
|
1321
1335
|
FunctionSchema.transform((consumer) => ({
|
|
1322
1336
|
consumer,
|
|
1323
1337
|
filter: ["error", "fatal"]
|
|
1324
1338
|
})),
|
|
1325
|
-
|
|
1339
|
+
z19.object({
|
|
1326
1340
|
consumer: FunctionSchema,
|
|
1327
1341
|
filter: FilterSchema
|
|
1328
1342
|
})
|
|
1329
1343
|
]).optional().describe("Define a subscription on all Lambda functions logs.");
|
|
1330
1344
|
|
|
1331
1345
|
// src/feature/pubsub/schema.ts
|
|
1332
|
-
import { z as
|
|
1346
|
+
import { z as z20 } from "zod";
|
|
1333
1347
|
var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
|
|
1334
|
-
var PubSubDefaultSchema =
|
|
1348
|
+
var PubSubDefaultSchema = z20.record(
|
|
1335
1349
|
ResourceIdSchema,
|
|
1336
|
-
|
|
1350
|
+
z20.object({
|
|
1337
1351
|
auth: FunctionSchema,
|
|
1338
1352
|
domain: DomainSchema.optional(),
|
|
1339
|
-
subDomain:
|
|
1353
|
+
subDomain: z20.string().optional()
|
|
1340
1354
|
// auth: z.union([
|
|
1341
1355
|
// ResourceIdSchema,
|
|
1342
1356
|
// z.object({
|
|
@@ -1352,19 +1366,23 @@ var PubSubDefaultSchema = z19.record(
|
|
|
1352
1366
|
// .optional(),
|
|
1353
1367
|
})
|
|
1354
1368
|
).optional().describe("Define the pubsub subscriber in your stack.");
|
|
1355
|
-
var
|
|
1369
|
+
var RetryAttemptsSchema = z20.number().int().min(0).max(2).describe(
|
|
1370
|
+
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
1371
|
+
);
|
|
1372
|
+
var PubSubSchema = z20.record(
|
|
1356
1373
|
ResourceIdSchema,
|
|
1357
|
-
|
|
1358
|
-
sql:
|
|
1359
|
-
sqlVersion:
|
|
1360
|
-
consumer: FunctionSchema.describe("The consuming lambda function properties.")
|
|
1374
|
+
z20.object({
|
|
1375
|
+
sql: z20.string().describe("The SQL statement used to query the IOT topic."),
|
|
1376
|
+
sqlVersion: z20.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23").describe("The version of the SQL rules engine to use when evaluating the rule."),
|
|
1377
|
+
consumer: FunctionSchema.describe("The consuming lambda function properties."),
|
|
1378
|
+
retryAttempts: RetryAttemptsSchema.default(2)
|
|
1361
1379
|
})
|
|
1362
1380
|
).optional().describe("Define the pubsub subscriber in your stack.");
|
|
1363
1381
|
|
|
1364
1382
|
// src/feature/queue/schema.ts
|
|
1365
1383
|
import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
|
|
1366
1384
|
import { kibibytes } from "@awsless/size";
|
|
1367
|
-
import { z as
|
|
1385
|
+
import { z as z21 } from "zod";
|
|
1368
1386
|
var RetentionPeriodSchema = DurationSchema.refine(
|
|
1369
1387
|
durationMin(minutes2(1)),
|
|
1370
1388
|
"Minimum retention period is 1 minute"
|
|
@@ -1392,10 +1410,10 @@ var ReceiveMessageWaitTimeSchema = DurationSchema.refine(
|
|
|
1392
1410
|
var MaxMessageSizeSchema = SizeSchema.refine(sizeMin(kibibytes(1)), "Minimum max message size is 1 KB").refine(sizeMax(kibibytes(256)), "Maximum max message size is 256 KB").describe(
|
|
1393
1411
|
"The limit of how many bytes that a message can contain before Amazon SQS rejects it. You can specify an size from 1 KB to 256 KB."
|
|
1394
1412
|
);
|
|
1395
|
-
var BatchSizeSchema =
|
|
1413
|
+
var BatchSizeSchema = z21.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
|
|
1396
1414
|
"The maximum number of records in each batch that Lambda pulls from your queue and sends to your function. 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). You can specify an integer from 1 to 10000."
|
|
1397
1415
|
);
|
|
1398
|
-
var MaxConcurrencySchema =
|
|
1416
|
+
var MaxConcurrencySchema = z21.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
|
|
1399
1417
|
"Limits the number of concurrent instances that the queue worker can invoke. You can specify an integer from 2 to 1000."
|
|
1400
1418
|
);
|
|
1401
1419
|
var MaxBatchingWindow = DurationSchema.refine(
|
|
@@ -1404,7 +1422,10 @@ var MaxBatchingWindow = DurationSchema.refine(
|
|
|
1404
1422
|
).describe(
|
|
1405
1423
|
"The maximum amount of time, that Lambda spends gathering records before invoking the function. You can specify an duration from 0 seconds to 5 minutes."
|
|
1406
1424
|
);
|
|
1407
|
-
var
|
|
1425
|
+
var RetryAttemptsSchema2 = z21.number().int().min(0).max(999).describe(
|
|
1426
|
+
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 999."
|
|
1427
|
+
);
|
|
1428
|
+
var QueueDefaultSchema = z21.object({
|
|
1408
1429
|
retentionPeriod: RetentionPeriodSchema.default("7 days"),
|
|
1409
1430
|
visibilityTimeout: VisibilityTimeoutSchema.default("30 seconds"),
|
|
1410
1431
|
deliveryDelay: DeliveryDelaySchema.default("0 seconds"),
|
|
@@ -1412,9 +1433,10 @@ var QueueDefaultSchema = z20.object({
|
|
|
1412
1433
|
maxMessageSize: MaxMessageSizeSchema.default("256 KB"),
|
|
1413
1434
|
batchSize: BatchSizeSchema.default(10),
|
|
1414
1435
|
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1415
|
-
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1436
|
+
maxBatchingWindow: MaxBatchingWindow.optional(),
|
|
1437
|
+
retryAttempts: RetryAttemptsSchema2.default(2)
|
|
1416
1438
|
}).default({});
|
|
1417
|
-
var QueueSchema =
|
|
1439
|
+
var QueueSchema = z21.object({
|
|
1418
1440
|
consumer: FunctionSchema.optional().describe("The consuming lambda function properties."),
|
|
1419
1441
|
retentionPeriod: RetentionPeriodSchema.optional(),
|
|
1420
1442
|
visibilityTimeout: VisibilityTimeoutSchema.optional(),
|
|
@@ -1423,11 +1445,12 @@ var QueueSchema = z20.object({
|
|
|
1423
1445
|
maxMessageSize: MaxMessageSizeSchema.optional(),
|
|
1424
1446
|
batchSize: BatchSizeSchema.optional(),
|
|
1425
1447
|
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1426
|
-
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1448
|
+
maxBatchingWindow: MaxBatchingWindow.optional(),
|
|
1449
|
+
retryAttempts: RetryAttemptsSchema2.optional()
|
|
1427
1450
|
});
|
|
1428
|
-
var QueuesSchema =
|
|
1451
|
+
var QueuesSchema = z21.record(
|
|
1429
1452
|
ResourceIdSchema,
|
|
1430
|
-
|
|
1453
|
+
z21.union([
|
|
1431
1454
|
LocalFileSchema.transform((consumer) => ({
|
|
1432
1455
|
consumer
|
|
1433
1456
|
})).pipe(QueueSchema),
|
|
@@ -1436,26 +1459,26 @@ var QueuesSchema = z20.record(
|
|
|
1436
1459
|
).optional().describe("Define the queues in your stack.");
|
|
1437
1460
|
|
|
1438
1461
|
// src/feature/rest/schema.ts
|
|
1439
|
-
import { z as
|
|
1462
|
+
import { z as z23 } from "zod";
|
|
1440
1463
|
|
|
1441
1464
|
// src/config/schema/route.ts
|
|
1442
|
-
import { z as
|
|
1443
|
-
var RouteSchema =
|
|
1444
|
-
|
|
1445
|
-
|
|
1465
|
+
import { z as z22 } from "zod";
|
|
1466
|
+
var RouteSchema = z22.union([
|
|
1467
|
+
z22.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS|ANY)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route"),
|
|
1468
|
+
z22.literal("$default")
|
|
1446
1469
|
]);
|
|
1447
1470
|
|
|
1448
1471
|
// src/feature/rest/schema.ts
|
|
1449
|
-
var RestDefaultSchema =
|
|
1472
|
+
var RestDefaultSchema = z23.record(
|
|
1450
1473
|
ResourceIdSchema,
|
|
1451
|
-
|
|
1474
|
+
z23.object({
|
|
1452
1475
|
domain: ResourceIdSchema.describe("The domain id to link your API with.").optional(),
|
|
1453
|
-
subDomain:
|
|
1476
|
+
subDomain: z23.string().optional()
|
|
1454
1477
|
})
|
|
1455
1478
|
).optional().describe("Define your global REST API's.");
|
|
1456
|
-
var RestSchema =
|
|
1479
|
+
var RestSchema = z23.record(
|
|
1457
1480
|
ResourceIdSchema,
|
|
1458
|
-
|
|
1481
|
+
z23.record(
|
|
1459
1482
|
RouteSchema.describe(
|
|
1460
1483
|
[
|
|
1461
1484
|
"The REST API route that is comprised by the http method and http path.",
|
|
@@ -1469,19 +1492,19 @@ var RestSchema = z22.record(
|
|
|
1469
1492
|
|
|
1470
1493
|
// src/feature/rpc/schema.ts
|
|
1471
1494
|
import { minutes as minutes4, seconds as seconds3 } from "@awsless/duration";
|
|
1472
|
-
import { z as
|
|
1495
|
+
import { z as z25 } from "zod";
|
|
1473
1496
|
|
|
1474
1497
|
// src/feature/router/schema.ts
|
|
1475
1498
|
import { days as days3, minutes as minutes3, parse as parse3 } from "@awsless/duration";
|
|
1476
|
-
import { z as
|
|
1477
|
-
var ErrorResponsePathSchema =
|
|
1499
|
+
import { z as z24 } from "zod";
|
|
1500
|
+
var ErrorResponsePathSchema = z24.string().describe(
|
|
1478
1501
|
[
|
|
1479
1502
|
"The path to the custom error page that you want to return to the viewer when your origin returns the HTTP status code specified.",
|
|
1480
1503
|
"- We recommend that you store custom error pages in an Amazon S3 bucket.",
|
|
1481
1504
|
"If you store custom error pages on an HTTP server and the server starts to return 5xx errors, CloudFront can't get the files that you want to return to viewers because the origin server is unavailable."
|
|
1482
1505
|
].join("\n")
|
|
1483
1506
|
);
|
|
1484
|
-
var StatusCodeSchema =
|
|
1507
|
+
var StatusCodeSchema = z24.number().int().positive().optional().describe(
|
|
1485
1508
|
[
|
|
1486
1509
|
"The HTTP status code that you want CloudFront to return to the viewer along with the custom error page.",
|
|
1487
1510
|
"There are a variety of reasons that you might want CloudFront to return a status code different from the status code that your origin returned to CloudFront, for example:",
|
|
@@ -1494,26 +1517,26 @@ var StatusCodeSchema = z23.number().int().positive().optional().describe(
|
|
|
1494
1517
|
var MinTTLSchema = DurationSchema.describe(
|
|
1495
1518
|
"The minimum amount of time, that you want to cache the error response. When this time period has elapsed, CloudFront queries your origin to see whether the problem that caused the error has been resolved and the requested object is now available."
|
|
1496
1519
|
);
|
|
1497
|
-
var ErrorResponseSchema =
|
|
1520
|
+
var ErrorResponseSchema = z24.union([
|
|
1498
1521
|
ErrorResponsePathSchema,
|
|
1499
|
-
|
|
1522
|
+
z24.object({
|
|
1500
1523
|
path: ErrorResponsePathSchema,
|
|
1501
1524
|
statusCode: StatusCodeSchema.optional(),
|
|
1502
1525
|
minTTL: MinTTLSchema.optional()
|
|
1503
1526
|
})
|
|
1504
1527
|
]).optional();
|
|
1505
|
-
var RouteSchema2 =
|
|
1506
|
-
var VisibilitySchema =
|
|
1507
|
-
var WafSettingsSchema =
|
|
1508
|
-
rateLimiter:
|
|
1509
|
-
limit:
|
|
1528
|
+
var RouteSchema2 = z24.string().regex(/^\//, "Route must start with a slash (/)");
|
|
1529
|
+
var VisibilitySchema = z24.boolean().default(false).describe("Whether to enable CloudWatch metrics for the WAF rule.");
|
|
1530
|
+
var WafSettingsSchema = z24.object({
|
|
1531
|
+
rateLimiter: z24.object({
|
|
1532
|
+
limit: z24.number().min(10).max(2e9).default(10).describe(
|
|
1510
1533
|
"The limit on requests during the specified evaluation window for a single aggregation instance for the rate-based rule."
|
|
1511
1534
|
),
|
|
1512
|
-
window:
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1535
|
+
window: z24.union([
|
|
1536
|
+
z24.literal("1 minute"),
|
|
1537
|
+
z24.literal("2 minutes"),
|
|
1538
|
+
z24.literal("5 minutes"),
|
|
1539
|
+
z24.literal("10 minutes")
|
|
1517
1540
|
]).default("5 minutes").transform((v) => parse3(v)).describe(
|
|
1518
1541
|
"The amount of time, in seconds, that AWS WAF should include in its request counts, looking back from the current time."
|
|
1519
1542
|
),
|
|
@@ -1521,18 +1544,18 @@ var WafSettingsSchema = z23.object({
|
|
|
1521
1544
|
}).optional().describe(
|
|
1522
1545
|
"A rate-based rule counts incoming requests and rate limits requests when they are coming at too fast a rate."
|
|
1523
1546
|
),
|
|
1524
|
-
ddosProtection:
|
|
1525
|
-
sensitivity:
|
|
1526
|
-
challenge:
|
|
1527
|
-
block:
|
|
1547
|
+
ddosProtection: z24.object({
|
|
1548
|
+
sensitivity: z24.object({
|
|
1549
|
+
challenge: z24.enum(["low", "medium", "high"]).default("low").transform((v) => v.toUpperCase()).describe("The sensitivity level for challenge requests."),
|
|
1550
|
+
block: z24.enum(["low", "medium", "high"]).default("low").transform((v) => v.toUpperCase()).describe("The sensitivity level for block requests.")
|
|
1528
1551
|
}),
|
|
1529
|
-
exemptUriRegex:
|
|
1552
|
+
exemptUriRegex: z24.string().default("^$"),
|
|
1530
1553
|
visibility: VisibilitySchema
|
|
1531
1554
|
}).optional().describe(
|
|
1532
1555
|
"Provides protection against DDoS attacks targeting the application layer, also known as Layer 7 attacks. Uses 50 WCU."
|
|
1533
1556
|
),
|
|
1534
|
-
botProtection:
|
|
1535
|
-
inspectionLevel:
|
|
1557
|
+
botProtection: z24.object({
|
|
1558
|
+
inspectionLevel: z24.enum(["common", "targeted"]).default("common").transform((v) => v.toUpperCase()),
|
|
1536
1559
|
visibility: VisibilitySchema
|
|
1537
1560
|
}).optional().describe(
|
|
1538
1561
|
"Provides protection against automated bots that can consume excess resources, skew business metrics, cause downtime, or perform malicious activities. Bot Control provides additional visibility through Amazon CloudWatch and generates labels that you can use to control bot traffic to your applications. Uses 50 WCU."
|
|
@@ -1546,14 +1569,14 @@ var WafSettingsSchema = z23.object({
|
|
|
1546
1569
|
}).describe(
|
|
1547
1570
|
"WAF settings for the router. Each rule consumes Web ACL capacity units (WCUs). The total WCUs for a web ACL can't exceed 5000. Using over 1500 WCUs affects your costs."
|
|
1548
1571
|
);
|
|
1549
|
-
var RouterDefaultSchema =
|
|
1572
|
+
var RouterDefaultSchema = z24.record(
|
|
1550
1573
|
ResourceIdSchema,
|
|
1551
|
-
|
|
1574
|
+
z24.object({
|
|
1552
1575
|
domain: ResourceIdSchema.describe("The domain id to link your Router.").optional(),
|
|
1553
|
-
subDomain:
|
|
1576
|
+
subDomain: z24.string().optional(),
|
|
1554
1577
|
waf: WafSettingsSchema.optional(),
|
|
1555
|
-
geoRestrictions:
|
|
1556
|
-
errors:
|
|
1578
|
+
geoRestrictions: z24.array(z24.string().length(2).toUpperCase()).default([]).describe("Specifies a blacklist of countries that should be blocked."),
|
|
1579
|
+
errors: z24.object({
|
|
1557
1580
|
400: ErrorResponseSchema.describe("Customize a `400 Bad Request` response."),
|
|
1558
1581
|
403: ErrorResponseSchema.describe("Customize a `403 Forbidden` response."),
|
|
1559
1582
|
404: ErrorResponseSchema.describe("Customize a `404 Not Found` response."),
|
|
@@ -1566,19 +1589,22 @@ var RouterDefaultSchema = z23.record(
|
|
|
1566
1589
|
503: ErrorResponseSchema.describe("Customize a `503 Service Unavailable` response."),
|
|
1567
1590
|
504: ErrorResponseSchema.describe("Customize a `504 Gateway Timeout` response.")
|
|
1568
1591
|
}).optional().describe("Customize the error responses for specific HTTP status codes."),
|
|
1569
|
-
cors:
|
|
1570
|
-
override:
|
|
1592
|
+
cors: z24.object({
|
|
1593
|
+
override: z24.boolean().default(false),
|
|
1571
1594
|
maxAge: DurationSchema.default("365 days"),
|
|
1572
|
-
exposeHeaders:
|
|
1573
|
-
credentials:
|
|
1574
|
-
headers:
|
|
1575
|
-
origins:
|
|
1576
|
-
methods:
|
|
1595
|
+
exposeHeaders: z24.string().array().optional(),
|
|
1596
|
+
credentials: z24.boolean().default(false),
|
|
1597
|
+
headers: z24.string().array().default(["*"]),
|
|
1598
|
+
origins: z24.string().array().default(["*"]),
|
|
1599
|
+
methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
|
|
1577
1600
|
}).optional().describe("Specify the cors headers."),
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1601
|
+
passwordAuth: z24.object({
|
|
1602
|
+
password: z24.string().describe("Password.")
|
|
1603
|
+
}).optional().describe("Enable password authentication for the router."),
|
|
1604
|
+
basicAuth: z24.object({
|
|
1605
|
+
username: z24.string().describe("Basic auth username."),
|
|
1606
|
+
password: z24.string().describe("Basic auth password.")
|
|
1607
|
+
}).optional().describe("Enable basic authentication for the router."),
|
|
1582
1608
|
// security: z
|
|
1583
1609
|
// .object({
|
|
1584
1610
|
// contentSecurityPolicy: z.object({
|
|
@@ -1624,10 +1650,10 @@ var RouterDefaultSchema = z23.record(
|
|
|
1624
1650
|
// })
|
|
1625
1651
|
// .optional()
|
|
1626
1652
|
// .describe('Specify the security policy.'),
|
|
1627
|
-
cache:
|
|
1628
|
-
cookies:
|
|
1629
|
-
headers:
|
|
1630
|
-
queries:
|
|
1653
|
+
cache: z24.object({
|
|
1654
|
+
cookies: z24.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
|
|
1655
|
+
headers: z24.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
|
|
1656
|
+
queries: z24.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
|
|
1631
1657
|
}).optional().describe(
|
|
1632
1658
|
"Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
|
|
1633
1659
|
)
|
|
@@ -1642,9 +1668,9 @@ var TimeoutSchema2 = DurationSchema.refine(durationMin(seconds3(10)), "Minimum t
|
|
|
1642
1668
|
"The timeouts of all inner RPC functions will be capped at 80% of this timeout."
|
|
1643
1669
|
].join(" ")
|
|
1644
1670
|
);
|
|
1645
|
-
var RpcDefaultSchema =
|
|
1671
|
+
var RpcDefaultSchema = z25.record(
|
|
1646
1672
|
ResourceIdSchema,
|
|
1647
|
-
|
|
1673
|
+
z25.object({
|
|
1648
1674
|
// domain: ResourceIdSchema.describe('The domain id to link your RPC API with.').optional(),
|
|
1649
1675
|
// subDomain: z.string().optional(),
|
|
1650
1676
|
//
|
|
@@ -1655,18 +1681,18 @@ var RpcDefaultSchema = z24.record(
|
|
|
1655
1681
|
timeout: TimeoutSchema2.default("1 minutes")
|
|
1656
1682
|
})
|
|
1657
1683
|
).describe(`Define the global RPC API's.`).optional();
|
|
1658
|
-
var RpcSchema =
|
|
1684
|
+
var RpcSchema = z25.record(
|
|
1659
1685
|
ResourceIdSchema,
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1686
|
+
z25.record(
|
|
1687
|
+
z25.string(),
|
|
1688
|
+
z25.union([
|
|
1663
1689
|
FunctionSchema.transform((f) => ({
|
|
1664
1690
|
function: f,
|
|
1665
1691
|
lock: false
|
|
1666
1692
|
})),
|
|
1667
|
-
|
|
1693
|
+
z25.object({
|
|
1668
1694
|
function: FunctionSchema.describe("The RPC function to execute."),
|
|
1669
|
-
lock:
|
|
1695
|
+
lock: z25.boolean().describe(
|
|
1670
1696
|
[
|
|
1671
1697
|
"Specify if the function should be locked on the `lockKey` returned from the auth function.",
|
|
1672
1698
|
"An example would be returning the user ID as `lockKey`."
|
|
@@ -1680,8 +1706,8 @@ var RpcSchema = z24.record(
|
|
|
1680
1706
|
// src/feature/instance/schema.ts
|
|
1681
1707
|
import { days as days4, toDays as toDays2 } from "@awsless/duration";
|
|
1682
1708
|
import { toMebibytes } from "@awsless/size";
|
|
1683
|
-
import { z as
|
|
1684
|
-
var CpuSchema =
|
|
1709
|
+
import { z as z26 } from "zod";
|
|
1710
|
+
var CpuSchema = z26.union([z26.literal(0.25), z26.literal(0.5), z26.literal(1), z26.literal(2), z26.literal(4), z26.literal(8), z26.literal(16)]).transform((v) => `${v} vCPU`).describe(
|
|
1685
1711
|
"The number of virtual CPU units (vCPU) used by the instance. Valid values: 0.25, 0.5, 1, 2, 4, 8, 16 vCPU."
|
|
1686
1712
|
);
|
|
1687
1713
|
var validMemorySize = [
|
|
@@ -1721,10 +1747,10 @@ var MemorySizeSchema2 = SizeSchema.refine(
|
|
|
1721
1747
|
(s) => validMemorySize.includes(toMebibytes(s)),
|
|
1722
1748
|
`Invalid memory size. Allowed sizes: ${validMemorySize.join(", ")} MiB`
|
|
1723
1749
|
).describe("The amount of memory (in MiB) used by the instance. Valid memory values depend on the CPU configuration.");
|
|
1724
|
-
var HealthCheckSchema =
|
|
1725
|
-
path:
|
|
1750
|
+
var HealthCheckSchema = z26.object({
|
|
1751
|
+
path: z26.string().describe("The path that the container runs to determine if it is healthy."),
|
|
1726
1752
|
interval: DurationSchema.describe("The time period in seconds between each health check execution."),
|
|
1727
|
-
retries:
|
|
1753
|
+
retries: z26.number().int().min(1).max(10).describe(
|
|
1728
1754
|
"The number of times to retry a failed health check before the container is considered unhealthy."
|
|
1729
1755
|
),
|
|
1730
1756
|
startPeriod: DurationSchema.describe(
|
|
@@ -1734,22 +1760,22 @@ var HealthCheckSchema = z25.object({
|
|
|
1734
1760
|
"The time period in seconds to wait for a health check to succeed before it is considered a failure."
|
|
1735
1761
|
)
|
|
1736
1762
|
}).describe("The health check command and associated configuration parameters for the container.");
|
|
1737
|
-
var EnvironmentSchema2 =
|
|
1738
|
-
var ArchitectureSchema3 =
|
|
1739
|
-
var ActionSchema2 =
|
|
1740
|
-
var ActionsSchema2 =
|
|
1741
|
-
var ArnSchema2 =
|
|
1742
|
-
var WildcardSchema2 =
|
|
1743
|
-
var ResourceSchema2 =
|
|
1744
|
-
var ResourcesSchema2 =
|
|
1745
|
-
var PermissionSchema2 =
|
|
1746
|
-
effect:
|
|
1763
|
+
var EnvironmentSchema2 = z26.record(z26.string(), z26.string()).optional().describe("Environment variable key-value pairs.");
|
|
1764
|
+
var ArchitectureSchema3 = z26.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the instance supports.");
|
|
1765
|
+
var ActionSchema2 = z26.string();
|
|
1766
|
+
var ActionsSchema2 = z26.union([ActionSchema2.transform((v) => [v]), ActionSchema2.array()]);
|
|
1767
|
+
var ArnSchema2 = z26.string().startsWith("arn:");
|
|
1768
|
+
var WildcardSchema2 = z26.literal("*");
|
|
1769
|
+
var ResourceSchema2 = z26.union([ArnSchema2, WildcardSchema2]);
|
|
1770
|
+
var ResourcesSchema2 = z26.union([ResourceSchema2.transform((v) => [v]), ResourceSchema2.array()]);
|
|
1771
|
+
var PermissionSchema2 = z26.object({
|
|
1772
|
+
effect: z26.enum(["allow", "deny"]).default("allow"),
|
|
1747
1773
|
actions: ActionsSchema2,
|
|
1748
1774
|
resources: ResourcesSchema2
|
|
1749
1775
|
});
|
|
1750
|
-
var PermissionsSchema2 =
|
|
1751
|
-
var DescriptionSchema2 =
|
|
1752
|
-
var ImageSchema =
|
|
1776
|
+
var PermissionsSchema2 = z26.union([PermissionSchema2.transform((v) => [v]), PermissionSchema2.array()]).describe("Add IAM permissions to your instance.");
|
|
1777
|
+
var DescriptionSchema2 = z26.string().describe("A description of the instance.");
|
|
1778
|
+
var ImageSchema = z26.string().optional().describe("The URL of the container image to use.");
|
|
1753
1779
|
var validLogRetentionDays2 = [
|
|
1754
1780
|
...[1, 3, 5, 7, 14, 30, 60, 90, 120, 150],
|
|
1755
1781
|
...[180, 365, 400, 545, 731, 1096, 1827, 2192],
|
|
@@ -1764,23 +1790,23 @@ var LogRetentionSchema2 = DurationSchema.refine(
|
|
|
1764
1790
|
},
|
|
1765
1791
|
`Invalid log retention. Valid days are: ${validLogRetentionDays2.map((days8) => `${days8}`).join(", ")}`
|
|
1766
1792
|
).describe("The log retention duration.");
|
|
1767
|
-
var LogSchema2 =
|
|
1768
|
-
|
|
1793
|
+
var LogSchema2 = z26.union([
|
|
1794
|
+
z26.boolean().transform((enabled) => ({ retention: enabled ? days4(7) : days4(0) })),
|
|
1769
1795
|
LogRetentionSchema2.transform((retention) => ({ retention })),
|
|
1770
|
-
|
|
1796
|
+
z26.object({
|
|
1771
1797
|
retention: LogRetentionSchema2.optional()
|
|
1772
1798
|
})
|
|
1773
1799
|
]).describe("Enable logging to a CloudWatch log group. Providing a duration value will set the log retention time.");
|
|
1774
|
-
var FileCodeSchema2 =
|
|
1800
|
+
var FileCodeSchema2 = z26.object({
|
|
1775
1801
|
file: LocalFileSchema.describe("The file path of the instance code.")
|
|
1776
1802
|
});
|
|
1777
|
-
var CodeSchema2 =
|
|
1803
|
+
var CodeSchema2 = z26.union([
|
|
1778
1804
|
LocalFileSchema.transform((file) => ({
|
|
1779
1805
|
file
|
|
1780
1806
|
})).pipe(FileCodeSchema2),
|
|
1781
1807
|
FileCodeSchema2
|
|
1782
1808
|
]).describe("Specify the code of your instance.");
|
|
1783
|
-
var ISchema =
|
|
1809
|
+
var ISchema = z26.object({
|
|
1784
1810
|
code: CodeSchema2,
|
|
1785
1811
|
description: DescriptionSchema2.optional(),
|
|
1786
1812
|
image: ImageSchema.optional(),
|
|
@@ -1793,14 +1819,14 @@ var ISchema = z25.object({
|
|
|
1793
1819
|
healthCheck: HealthCheckSchema.optional()
|
|
1794
1820
|
// restartPolicy: RestartPolicySchema.optional(),
|
|
1795
1821
|
});
|
|
1796
|
-
var InstanceSchema =
|
|
1822
|
+
var InstanceSchema = z26.union([
|
|
1797
1823
|
LocalFileSchema.transform((code) => ({
|
|
1798
1824
|
code
|
|
1799
1825
|
})).pipe(ISchema),
|
|
1800
1826
|
ISchema
|
|
1801
1827
|
]);
|
|
1802
|
-
var InstancesSchema =
|
|
1803
|
-
var InstanceDefaultSchema =
|
|
1828
|
+
var InstancesSchema = z26.record(ResourceIdSchema, InstanceSchema).optional().describe("Define the instances in your stack.");
|
|
1829
|
+
var InstanceDefaultSchema = z26.object({
|
|
1804
1830
|
image: ImageSchema.optional(),
|
|
1805
1831
|
cpu: CpuSchema.default(0.25),
|
|
1806
1832
|
memorySize: MemorySizeSchema2.default("512 MB"),
|
|
@@ -1816,15 +1842,34 @@ var InstanceDefaultSchema = z25.object({
|
|
|
1816
1842
|
|
|
1817
1843
|
// src/feature/topic/schema.ts
|
|
1818
1844
|
import { kebabCase as kebabCase3 } from "change-case";
|
|
1819
|
-
import { z as
|
|
1820
|
-
|
|
1821
|
-
|
|
1845
|
+
import { z as z28 } from "zod";
|
|
1846
|
+
|
|
1847
|
+
// src/feature/task/schema.ts
|
|
1848
|
+
import { z as z27 } from "zod";
|
|
1849
|
+
var RetryAttemptsSchema3 = z27.number().int().min(0).max(2).describe(
|
|
1850
|
+
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
1851
|
+
);
|
|
1852
|
+
var TaskSchema = z27.union([
|
|
1853
|
+
FunctionSchema.transform((consumer) => ({
|
|
1854
|
+
consumer,
|
|
1855
|
+
retryAttempts: 2
|
|
1856
|
+
})),
|
|
1857
|
+
z27.object({
|
|
1858
|
+
consumer: FunctionSchema,
|
|
1859
|
+
retryAttempts: RetryAttemptsSchema3.default(2)
|
|
1860
|
+
})
|
|
1861
|
+
]);
|
|
1862
|
+
var TasksSchema = z27.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
|
|
1863
|
+
|
|
1864
|
+
// src/feature/topic/schema.ts
|
|
1865
|
+
var TopicNameSchema = z28.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => kebabCase3(value)).describe("Define event topic name.");
|
|
1866
|
+
var TopicsDefaultSchema = z28.array(TopicNameSchema).refine((topics) => {
|
|
1822
1867
|
return topics.length === new Set(topics).size;
|
|
1823
1868
|
}, "Must be a list of unique topic names").optional().describe("Define the event topics for your app.");
|
|
1824
|
-
var SubscribersSchema =
|
|
1869
|
+
var SubscribersSchema = z28.record(TopicNameSchema, TaskSchema).optional().describe("Define the event topics to subscribe too in your stack.");
|
|
1825
1870
|
|
|
1826
1871
|
// src/config/schema/region.ts
|
|
1827
|
-
import { z as
|
|
1872
|
+
import { z as z29 } from "zod";
|
|
1828
1873
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
1829
1874
|
var AF = ["af-south-1"];
|
|
1830
1875
|
var AP = [
|
|
@@ -1853,16 +1898,16 @@ var EU = [
|
|
|
1853
1898
|
var ME = ["me-south-1", "me-central-1"];
|
|
1854
1899
|
var SA = ["sa-east-1"];
|
|
1855
1900
|
var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
|
|
1856
|
-
var RegionSchema =
|
|
1901
|
+
var RegionSchema = z29.enum(regions);
|
|
1857
1902
|
|
|
1858
1903
|
// src/config/app.ts
|
|
1859
|
-
var AppSchema =
|
|
1860
|
-
$schema:
|
|
1904
|
+
var AppSchema = z30.object({
|
|
1905
|
+
$schema: z30.string().optional(),
|
|
1861
1906
|
name: ResourceIdSchema.describe("App name."),
|
|
1862
1907
|
region: RegionSchema.describe("The AWS region to deploy to."),
|
|
1863
|
-
profile:
|
|
1864
|
-
protect:
|
|
1865
|
-
removal:
|
|
1908
|
+
profile: z30.string().describe("The AWS profile to deploy to."),
|
|
1909
|
+
protect: z30.boolean().default(false).describe("Protect your app & stacks from being deleted."),
|
|
1910
|
+
removal: z30.enum(["remove", "retain"]).default("remove").describe(
|
|
1866
1911
|
[
|
|
1867
1912
|
"Configure how your resources are handled when they have to be removed.",
|
|
1868
1913
|
"",
|
|
@@ -1876,7 +1921,7 @@ var AppSchema = z28.object({
|
|
|
1876
1921
|
// .default('prod')
|
|
1877
1922
|
// .describe('The deployment stage.'),
|
|
1878
1923
|
// onFailure: OnFailureSchema,
|
|
1879
|
-
defaults:
|
|
1924
|
+
defaults: z30.object({
|
|
1880
1925
|
onFailure: OnFailureDefaultSchema,
|
|
1881
1926
|
onLog: OnLogDefaultSchema,
|
|
1882
1927
|
auth: AuthDefaultSchema,
|
|
@@ -1900,11 +1945,11 @@ var AppSchema = z28.object({
|
|
|
1900
1945
|
});
|
|
1901
1946
|
|
|
1902
1947
|
// src/config/stack.ts
|
|
1903
|
-
import { z as
|
|
1948
|
+
import { z as z45 } from "zod";
|
|
1904
1949
|
|
|
1905
1950
|
// src/feature/cache/schema.ts
|
|
1906
1951
|
import { gibibytes as gibibytes2 } from "@awsless/size";
|
|
1907
|
-
import { z as
|
|
1952
|
+
import { z as z31 } from "zod";
|
|
1908
1953
|
var StorageSchema = SizeSchema.refine(sizeMin(gibibytes2(1)), "Minimum storage size is 1 GB").refine(
|
|
1909
1954
|
sizeMax(gibibytes2(5e3)),
|
|
1910
1955
|
"Maximum storage size is 5000 GB"
|
|
@@ -1915,31 +1960,31 @@ var MinimumStorageSchema = StorageSchema.describe(
|
|
|
1915
1960
|
var MaximumStorageSchema = StorageSchema.describe(
|
|
1916
1961
|
"The upper limit for data storage the cache is set to use. You can specify a size value from 1 GB to 5000 GB."
|
|
1917
1962
|
);
|
|
1918
|
-
var EcpuSchema =
|
|
1963
|
+
var EcpuSchema = z31.number().int().min(1e3).max(15e6);
|
|
1919
1964
|
var MinimumEcpuSchema = EcpuSchema.describe(
|
|
1920
1965
|
"The minimum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1921
1966
|
);
|
|
1922
1967
|
var MaximumEcpuSchema = EcpuSchema.describe(
|
|
1923
1968
|
"The maximum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1924
1969
|
);
|
|
1925
|
-
var CachesSchema =
|
|
1970
|
+
var CachesSchema = z31.record(
|
|
1926
1971
|
ResourceIdSchema,
|
|
1927
|
-
|
|
1972
|
+
z31.object({
|
|
1928
1973
|
minStorage: MinimumStorageSchema.optional(),
|
|
1929
1974
|
maxStorage: MaximumStorageSchema.optional(),
|
|
1930
1975
|
minECPU: MinimumEcpuSchema.optional(),
|
|
1931
1976
|
maxECPU: MaximumEcpuSchema.optional(),
|
|
1932
|
-
snapshotRetentionLimit:
|
|
1977
|
+
snapshotRetentionLimit: z31.number().int().positive().default(1)
|
|
1933
1978
|
})
|
|
1934
1979
|
).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
|
|
1935
1980
|
|
|
1936
1981
|
// src/feature/command/schema.ts
|
|
1937
|
-
import { z as
|
|
1938
|
-
var CommandSchema =
|
|
1939
|
-
|
|
1982
|
+
import { z as z32 } from "zod";
|
|
1983
|
+
var CommandSchema = z32.union([
|
|
1984
|
+
z32.object({
|
|
1940
1985
|
file: LocalFileSchema,
|
|
1941
|
-
handler:
|
|
1942
|
-
description:
|
|
1986
|
+
handler: z32.string().default("default").describe("The name of the handler that needs to run"),
|
|
1987
|
+
description: z32.string().optional().describe("A description of the command")
|
|
1943
1988
|
// options: z.record(ResourceIdSchema, OptionSchema).optional(),
|
|
1944
1989
|
// arguments: z.record(ResourceIdSchema, ArgumentSchema).optional(),
|
|
1945
1990
|
}),
|
|
@@ -1949,22 +1994,22 @@ var CommandSchema = z30.union([
|
|
|
1949
1994
|
description: void 0
|
|
1950
1995
|
}))
|
|
1951
1996
|
]);
|
|
1952
|
-
var CommandsSchema =
|
|
1997
|
+
var CommandsSchema = z32.record(ResourceIdSchema, CommandSchema).optional().describe("Define the custom commands for your stack.");
|
|
1953
1998
|
|
|
1954
1999
|
// src/feature/config/schema.ts
|
|
1955
|
-
import { z as
|
|
1956
|
-
var ConfigNameSchema =
|
|
1957
|
-
var ConfigsSchema =
|
|
2000
|
+
import { z as z33 } from "zod";
|
|
2001
|
+
var ConfigNameSchema = z33.string().regex(/[a-z0-9\-]/g, "Invalid config name");
|
|
2002
|
+
var ConfigsSchema = z33.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
|
|
1958
2003
|
|
|
1959
2004
|
// src/feature/cron/schema/index.ts
|
|
1960
|
-
import { z as
|
|
2005
|
+
import { z as z35 } from "zod";
|
|
1961
2006
|
|
|
1962
2007
|
// src/feature/cron/schema/schedule.ts
|
|
1963
|
-
import { z as
|
|
2008
|
+
import { z as z34 } from "zod";
|
|
1964
2009
|
import { awsCronExpressionValidator } from "aws-cron-expression-validator";
|
|
1965
|
-
var RateExpressionSchema =
|
|
2010
|
+
var RateExpressionSchema = z34.custom(
|
|
1966
2011
|
(value) => {
|
|
1967
|
-
return
|
|
2012
|
+
return z34.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
|
|
1968
2013
|
const [str] = rate.split(" ");
|
|
1969
2014
|
const number = parseInt(str);
|
|
1970
2015
|
return number > 0;
|
|
@@ -1980,9 +2025,9 @@ var RateExpressionSchema = z32.custom(
|
|
|
1980
2025
|
}
|
|
1981
2026
|
return `rate(${rate})`;
|
|
1982
2027
|
});
|
|
1983
|
-
var CronExpressionSchema =
|
|
2028
|
+
var CronExpressionSchema = z34.custom(
|
|
1984
2029
|
(value) => {
|
|
1985
|
-
return
|
|
2030
|
+
return z34.string().safeParse(value).success;
|
|
1986
2031
|
},
|
|
1987
2032
|
{ message: "Invalid cron expression" }
|
|
1988
2033
|
).superRefine((value, ctx) => {
|
|
@@ -1991,12 +2036,12 @@ var CronExpressionSchema = z32.custom(
|
|
|
1991
2036
|
} catch (error) {
|
|
1992
2037
|
if (error instanceof Error) {
|
|
1993
2038
|
ctx.addIssue({
|
|
1994
|
-
code:
|
|
2039
|
+
code: z34.ZodIssueCode.custom,
|
|
1995
2040
|
message: `Invalid cron expression: ${error.message}`
|
|
1996
2041
|
});
|
|
1997
2042
|
} else {
|
|
1998
2043
|
ctx.addIssue({
|
|
1999
|
-
code:
|
|
2044
|
+
code: z34.ZodIssueCode.custom,
|
|
2000
2045
|
message: "Invalid cron expression"
|
|
2001
2046
|
});
|
|
2002
2047
|
}
|
|
@@ -2007,28 +2052,32 @@ var CronExpressionSchema = z32.custom(
|
|
|
2007
2052
|
var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
|
|
2008
2053
|
|
|
2009
2054
|
// src/feature/cron/schema/index.ts
|
|
2010
|
-
var
|
|
2055
|
+
var RetryAttemptsSchema4 = z35.number().int().min(0).max(2).describe(
|
|
2056
|
+
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
2057
|
+
);
|
|
2058
|
+
var CronsSchema = z35.record(
|
|
2011
2059
|
ResourceIdSchema,
|
|
2012
|
-
|
|
2013
|
-
enabled:
|
|
2060
|
+
z35.object({
|
|
2061
|
+
enabled: z35.boolean().default(true).describe("If the cron is enabled."),
|
|
2014
2062
|
consumer: FunctionSchema.describe("The consuming lambda function properties."),
|
|
2015
2063
|
schedule: ScheduleExpressionSchema.describe(
|
|
2016
2064
|
'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
|
|
2017
2065
|
),
|
|
2018
|
-
payload:
|
|
2066
|
+
payload: z35.unknown().optional().describe("The JSON payload that will be passed to the consumer."),
|
|
2067
|
+
retryAttempts: RetryAttemptsSchema4.default(2)
|
|
2019
2068
|
})
|
|
2020
2069
|
).optional().describe(`Define the cron jobs in your stack.`);
|
|
2021
2070
|
|
|
2022
2071
|
// src/feature/search/schema.ts
|
|
2023
2072
|
import { gibibytes as gibibytes3 } from "@awsless/size";
|
|
2024
|
-
import { z as
|
|
2025
|
-
var VersionSchema =
|
|
2073
|
+
import { z as z36 } from "zod";
|
|
2074
|
+
var VersionSchema = z36.union([
|
|
2026
2075
|
//
|
|
2027
|
-
|
|
2028
|
-
|
|
2076
|
+
z36.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]),
|
|
2077
|
+
z36.string()
|
|
2029
2078
|
]).describe("Specify the OpenSearch engine version.");
|
|
2030
|
-
var TypeSchema =
|
|
2031
|
-
|
|
2079
|
+
var TypeSchema = z36.union([
|
|
2080
|
+
z36.enum([
|
|
2032
2081
|
"t3.small",
|
|
2033
2082
|
"t3.medium",
|
|
2034
2083
|
"m3.medium",
|
|
@@ -2102,13 +2151,13 @@ var TypeSchema = z34.union([
|
|
|
2102
2151
|
"r6gd.12xlarge",
|
|
2103
2152
|
"r6gd.16xlarge"
|
|
2104
2153
|
]),
|
|
2105
|
-
|
|
2154
|
+
z36.string()
|
|
2106
2155
|
]).describe("Instance type of data nodes in the cluster.");
|
|
2107
|
-
var CountSchema =
|
|
2156
|
+
var CountSchema = z36.number().int().min(1).describe("Number of instances in the cluster.");
|
|
2108
2157
|
var StorageSizeSchema = SizeSchema.refine(sizeMin(gibibytes3(10)), "Minimum storage size is 10 GB").refine(sizeMax(gibibytes3(100)), "Maximum storage size is 100 GB").describe("The size of the function's /tmp directory. You can specify a size value from 512 MB to 10 GiB.");
|
|
2109
|
-
var SearchsSchema =
|
|
2158
|
+
var SearchsSchema = z36.record(
|
|
2110
2159
|
ResourceIdSchema,
|
|
2111
|
-
|
|
2160
|
+
z36.object({
|
|
2112
2161
|
type: TypeSchema.default("t3.small"),
|
|
2113
2162
|
count: CountSchema.default(1),
|
|
2114
2163
|
version: VersionSchema.default("2.13"),
|
|
@@ -2119,12 +2168,12 @@ var SearchsSchema = z34.record(
|
|
|
2119
2168
|
).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
|
|
2120
2169
|
|
|
2121
2170
|
// src/feature/site/schema.ts
|
|
2122
|
-
import { z as
|
|
2171
|
+
import { z as z38 } from "zod";
|
|
2123
2172
|
|
|
2124
2173
|
// src/config/schema/local-entry.ts
|
|
2125
2174
|
import { stat as stat3 } from "fs/promises";
|
|
2126
|
-
import { z as
|
|
2127
|
-
var LocalEntrySchema =
|
|
2175
|
+
import { z as z37 } from "zod";
|
|
2176
|
+
var LocalEntrySchema = z37.union([
|
|
2128
2177
|
RelativePathSchema.refine(async (path) => {
|
|
2129
2178
|
try {
|
|
2130
2179
|
const s = await stat3(path);
|
|
@@ -2133,7 +2182,7 @@ var LocalEntrySchema = z35.union([
|
|
|
2133
2182
|
return false;
|
|
2134
2183
|
}
|
|
2135
2184
|
}, `File or directory doesn't exist`),
|
|
2136
|
-
|
|
2185
|
+
z37.object({
|
|
2137
2186
|
nocheck: RelativePathSchema.describe(
|
|
2138
2187
|
"Specifies a local file or directory without checking if the file or directory exists."
|
|
2139
2188
|
)
|
|
@@ -2141,21 +2190,21 @@ var LocalEntrySchema = z35.union([
|
|
|
2141
2190
|
]);
|
|
2142
2191
|
|
|
2143
2192
|
// src/feature/site/schema.ts
|
|
2144
|
-
var SitesSchema =
|
|
2193
|
+
var SitesSchema = z38.record(
|
|
2145
2194
|
ResourceIdSchema,
|
|
2146
|
-
|
|
2195
|
+
z38.object({
|
|
2147
2196
|
router: ResourceIdSchema.describe("The router id to link your site with."),
|
|
2148
2197
|
path: RouteSchema2.describe("The path inside the router to link your site to."),
|
|
2149
|
-
build:
|
|
2150
|
-
command:
|
|
2198
|
+
build: z38.object({
|
|
2199
|
+
command: z38.string().describe(
|
|
2151
2200
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2152
2201
|
),
|
|
2153
|
-
cacheKey:
|
|
2202
|
+
cacheKey: z38.union([LocalEntrySchema.transform((v) => [v]), LocalEntrySchema.array()]).describe(
|
|
2154
2203
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2155
2204
|
),
|
|
2156
|
-
configs:
|
|
2205
|
+
configs: z38.string().array().optional().describe("Define the config values for your build command.")
|
|
2157
2206
|
}).optional().describe(`Specifies the build process for sites that need a build step.`),
|
|
2158
|
-
static:
|
|
2207
|
+
static: z38.union([LocalDirectorySchema, z38.boolean()]).optional().describe(
|
|
2159
2208
|
"Specifies the path to the static files directory. Additionally you can also pass `true` when you don't have local static files, but still want to make an S3 bucket."
|
|
2160
2209
|
),
|
|
2161
2210
|
ssr: FunctionSchema.optional().describe("Specifies the file that will render the site on the server.")
|
|
@@ -2163,45 +2212,45 @@ var SitesSchema = z36.record(
|
|
|
2163
2212
|
).optional().describe("Define the sites in your stack.");
|
|
2164
2213
|
|
|
2165
2214
|
// src/feature/store/schema.ts
|
|
2166
|
-
import { z as
|
|
2167
|
-
var StoresSchema =
|
|
2168
|
-
|
|
2215
|
+
import { z as z39 } from "zod";
|
|
2216
|
+
var StoresSchema = z39.union([
|
|
2217
|
+
z39.array(ResourceIdSchema).transform((list3) => {
|
|
2169
2218
|
const stores = {};
|
|
2170
2219
|
for (const key of list3) {
|
|
2171
2220
|
stores[key] = {};
|
|
2172
2221
|
}
|
|
2173
2222
|
return stores;
|
|
2174
2223
|
}),
|
|
2175
|
-
|
|
2224
|
+
z39.record(
|
|
2176
2225
|
ResourceIdSchema,
|
|
2177
|
-
|
|
2226
|
+
z39.object({
|
|
2178
2227
|
static: LocalDirectorySchema.optional().describe("Specifies the path to the static files directory."),
|
|
2179
|
-
versioning:
|
|
2180
|
-
events:
|
|
2228
|
+
versioning: z39.boolean().default(false).describe("Enable versioning of your store."),
|
|
2229
|
+
events: z39.object({
|
|
2181
2230
|
// create
|
|
2182
|
-
"created:*":
|
|
2231
|
+
"created:*": TaskSchema.optional().describe(
|
|
2183
2232
|
"Subscribe to notifications regardless of the API that was used to create an object."
|
|
2184
2233
|
),
|
|
2185
|
-
"created:put":
|
|
2234
|
+
"created:put": TaskSchema.optional().describe(
|
|
2186
2235
|
"Subscribe to notifications when an object is created using the PUT API operation."
|
|
2187
2236
|
),
|
|
2188
|
-
"created:post":
|
|
2237
|
+
"created:post": TaskSchema.optional().describe(
|
|
2189
2238
|
"Subscribe to notifications when an object is created using the POST API operation."
|
|
2190
2239
|
),
|
|
2191
|
-
"created:copy":
|
|
2240
|
+
"created:copy": TaskSchema.optional().describe(
|
|
2192
2241
|
"Subscribe to notifications when an object is created using the COPY API operation."
|
|
2193
2242
|
),
|
|
2194
|
-
"created:upload":
|
|
2243
|
+
"created:upload": TaskSchema.optional().describe(
|
|
2195
2244
|
"Subscribe to notifications when an object multipart upload has been completed."
|
|
2196
2245
|
),
|
|
2197
2246
|
// remove
|
|
2198
|
-
"removed:*":
|
|
2247
|
+
"removed:*": TaskSchema.optional().describe(
|
|
2199
2248
|
"Subscribe to notifications when an object is deleted or a delete marker for a versioned object is created."
|
|
2200
2249
|
),
|
|
2201
|
-
"removed:delete":
|
|
2250
|
+
"removed:delete": TaskSchema.optional().describe(
|
|
2202
2251
|
"Subscribe to notifications when an object is deleted"
|
|
2203
2252
|
),
|
|
2204
|
-
"removed:marker":
|
|
2253
|
+
"removed:marker": TaskSchema.optional().describe(
|
|
2205
2254
|
"Subscribe to notifications when a delete marker for a versioned object is created."
|
|
2206
2255
|
)
|
|
2207
2256
|
}).optional().describe("Describes the store events you want to subscribe too.")
|
|
@@ -2210,30 +2259,30 @@ var StoresSchema = z37.union([
|
|
|
2210
2259
|
]).optional().describe("Define the stores in your stack.");
|
|
2211
2260
|
|
|
2212
2261
|
// src/feature/icon/schema.ts
|
|
2213
|
-
import { z as
|
|
2262
|
+
import { z as z40 } from "zod";
|
|
2214
2263
|
var staticOriginSchema = LocalDirectorySchema.describe(
|
|
2215
2264
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
2216
2265
|
);
|
|
2217
2266
|
var functionOriginSchema = FunctionSchema.describe(
|
|
2218
2267
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2219
2268
|
);
|
|
2220
|
-
var IconsSchema =
|
|
2269
|
+
var IconsSchema = z40.record(
|
|
2221
2270
|
ResourceIdSchema,
|
|
2222
|
-
|
|
2271
|
+
z40.object({
|
|
2223
2272
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2224
2273
|
// subDomain: z.string().optional(),
|
|
2225
2274
|
router: ResourceIdSchema.describe("The router id to link your icon proxy."),
|
|
2226
2275
|
path: RouteSchema2.describe("The path inside the router to link your icon proxy to."),
|
|
2227
2276
|
log: LogSchema.optional(),
|
|
2228
2277
|
cacheDuration: DurationSchema.optional().describe("The cache duration of the cached icons."),
|
|
2229
|
-
preserveIds:
|
|
2230
|
-
symbols:
|
|
2231
|
-
origin:
|
|
2232
|
-
|
|
2278
|
+
preserveIds: z40.boolean().optional().default(false).describe("Preserve the IDs of the icons."),
|
|
2279
|
+
symbols: z40.boolean().optional().default(false).describe(`Convert the SVG's to SVG symbols.`),
|
|
2280
|
+
origin: z40.union([
|
|
2281
|
+
z40.object({
|
|
2233
2282
|
static: staticOriginSchema,
|
|
2234
2283
|
function: functionOriginSchema.optional()
|
|
2235
2284
|
}),
|
|
2236
|
-
|
|
2285
|
+
z40.object({
|
|
2237
2286
|
static: staticOriginSchema.optional(),
|
|
2238
2287
|
function: functionOriginSchema
|
|
2239
2288
|
})
|
|
@@ -2260,13 +2309,13 @@ var IconsSchema = z38.record(
|
|
|
2260
2309
|
).optional().describe("Define an svg icon proxy in your stack. Store, optimize, and deliver svg icons at scale.");
|
|
2261
2310
|
|
|
2262
2311
|
// src/feature/image/schema.ts
|
|
2263
|
-
import { z as
|
|
2264
|
-
var transformationOptionsSchema =
|
|
2265
|
-
width:
|
|
2266
|
-
height:
|
|
2267
|
-
fit:
|
|
2268
|
-
position:
|
|
2269
|
-
quality:
|
|
2312
|
+
import { z as z41 } from "zod";
|
|
2313
|
+
var transformationOptionsSchema = z41.object({
|
|
2314
|
+
width: z41.number().int().positive().optional(),
|
|
2315
|
+
height: z41.number().int().positive().optional(),
|
|
2316
|
+
fit: z41.enum(["cover", "contain", "fill", "inside", "outside"]).optional(),
|
|
2317
|
+
position: z41.enum(["top", "right top", "right", "right bottom", "bottom", "left bottom", "left", "left top", "center"]).optional(),
|
|
2318
|
+
quality: z41.number().int().min(1).max(100).optional()
|
|
2270
2319
|
});
|
|
2271
2320
|
var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
2272
2321
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
@@ -2274,38 +2323,38 @@ var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
|
2274
2323
|
var functionOriginSchema2 = FunctionSchema.describe(
|
|
2275
2324
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2276
2325
|
);
|
|
2277
|
-
var ImagesSchema =
|
|
2326
|
+
var ImagesSchema = z41.record(
|
|
2278
2327
|
ResourceIdSchema,
|
|
2279
|
-
|
|
2328
|
+
z41.object({
|
|
2280
2329
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2281
2330
|
// subDomain: z.string().optional(),
|
|
2282
2331
|
router: ResourceIdSchema.describe("The router id to link your image proxy."),
|
|
2283
2332
|
path: RouteSchema2.describe("The path inside the router to link your image proxy to."),
|
|
2284
2333
|
log: LogSchema.optional(),
|
|
2285
2334
|
cacheDuration: DurationSchema.optional().describe("Cache duration of the cached images."),
|
|
2286
|
-
presets:
|
|
2287
|
-
extensions:
|
|
2288
|
-
jpg:
|
|
2289
|
-
mozjpeg:
|
|
2290
|
-
progressive:
|
|
2335
|
+
presets: z41.record(z41.string(), transformationOptionsSchema).describe("Named presets for image transformations"),
|
|
2336
|
+
extensions: z41.object({
|
|
2337
|
+
jpg: z41.object({
|
|
2338
|
+
mozjpeg: z41.boolean().optional(),
|
|
2339
|
+
progressive: z41.boolean().optional()
|
|
2291
2340
|
}).optional(),
|
|
2292
|
-
webp:
|
|
2293
|
-
effort:
|
|
2294
|
-
lossless:
|
|
2295
|
-
nearLossless:
|
|
2341
|
+
webp: z41.object({
|
|
2342
|
+
effort: z41.number().int().min(1).max(10).default(7).optional(),
|
|
2343
|
+
lossless: z41.boolean().optional(),
|
|
2344
|
+
nearLossless: z41.boolean().optional()
|
|
2296
2345
|
}).optional(),
|
|
2297
|
-
png:
|
|
2298
|
-
compressionLevel:
|
|
2346
|
+
png: z41.object({
|
|
2347
|
+
compressionLevel: z41.number().int().min(0).max(9).default(6).optional()
|
|
2299
2348
|
}).optional()
|
|
2300
2349
|
}).refine((data) => {
|
|
2301
2350
|
return Object.keys(data).length > 0;
|
|
2302
2351
|
}, "At least one extension must be defined.").describe("Specify the allowed extensions."),
|
|
2303
|
-
origin:
|
|
2304
|
-
|
|
2352
|
+
origin: z41.union([
|
|
2353
|
+
z41.object({
|
|
2305
2354
|
static: staticOriginSchema2,
|
|
2306
2355
|
function: functionOriginSchema2.optional()
|
|
2307
2356
|
}),
|
|
2308
|
-
|
|
2357
|
+
z41.object({
|
|
2309
2358
|
static: staticOriginSchema2.optional(),
|
|
2310
2359
|
function: functionOriginSchema2
|
|
2311
2360
|
})
|
|
@@ -2320,7 +2369,7 @@ var ImagesSchema = z39.record(
|
|
|
2320
2369
|
).optional().describe("Define an image proxy in your stack. Store, transform, optimize, and deliver images at scale.");
|
|
2321
2370
|
|
|
2322
2371
|
// src/feature/metric/schema.ts
|
|
2323
|
-
import { z as
|
|
2372
|
+
import { z as z42 } from "zod";
|
|
2324
2373
|
var ops = {
|
|
2325
2374
|
">": "GreaterThanThreshold",
|
|
2326
2375
|
">=": "GreaterThanOrEqualToThreshold",
|
|
@@ -2334,15 +2383,15 @@ var stats = {
|
|
|
2334
2383
|
min: "Minimum",
|
|
2335
2384
|
max: "Maximum"
|
|
2336
2385
|
};
|
|
2337
|
-
var WhereSchema =
|
|
2338
|
-
|
|
2386
|
+
var WhereSchema = z42.union([
|
|
2387
|
+
z42.string().regex(/(count|avg|sum|min|max) (>|>=|<|<=) (\d)/, "Invalid where query").transform((where) => {
|
|
2339
2388
|
const [stat4, op, value] = where.split(" ");
|
|
2340
2389
|
return { stat: stat4, op, value: parseFloat(value) };
|
|
2341
2390
|
}),
|
|
2342
|
-
|
|
2343
|
-
stat:
|
|
2344
|
-
op:
|
|
2345
|
-
value:
|
|
2391
|
+
z42.object({
|
|
2392
|
+
stat: z42.enum(["count", "avg", "sum", "min", "max"]),
|
|
2393
|
+
op: z42.enum([">", ">=", "<", "<="]),
|
|
2394
|
+
value: z42.number()
|
|
2346
2395
|
})
|
|
2347
2396
|
]).transform((where) => {
|
|
2348
2397
|
return {
|
|
@@ -2351,39 +2400,39 @@ var WhereSchema = z40.union([
|
|
|
2351
2400
|
value: where.value
|
|
2352
2401
|
};
|
|
2353
2402
|
});
|
|
2354
|
-
var AlarmSchema =
|
|
2355
|
-
description:
|
|
2403
|
+
var AlarmSchema = z42.object({
|
|
2404
|
+
description: z42.string().optional(),
|
|
2356
2405
|
where: WhereSchema,
|
|
2357
2406
|
period: DurationSchema,
|
|
2358
|
-
minDataPoints:
|
|
2359
|
-
trigger:
|
|
2407
|
+
minDataPoints: z42.number().int().default(1),
|
|
2408
|
+
trigger: z42.union([EmailSchema.transform((v) => [v]), EmailSchema.array(), FunctionSchema])
|
|
2360
2409
|
});
|
|
2361
|
-
var MetricsSchema =
|
|
2410
|
+
var MetricsSchema = z42.record(
|
|
2362
2411
|
ResourceIdSchema,
|
|
2363
|
-
|
|
2364
|
-
type:
|
|
2412
|
+
z42.object({
|
|
2413
|
+
type: z42.enum(["number", "size", "duration"]),
|
|
2365
2414
|
alarms: AlarmSchema.array().optional()
|
|
2366
2415
|
})
|
|
2367
2416
|
).optional().describe("Define the metrics in your stack.");
|
|
2368
2417
|
|
|
2369
2418
|
// src/feature/table/schema.ts
|
|
2370
2419
|
import { minutes as minutes5, seconds as seconds4 } from "@awsless/duration";
|
|
2371
|
-
import { z as
|
|
2372
|
-
var KeySchema =
|
|
2373
|
-
var TablesSchema =
|
|
2420
|
+
import { z as z43 } from "zod";
|
|
2421
|
+
var KeySchema = z43.string().min(1).max(255);
|
|
2422
|
+
var TablesSchema = z43.record(
|
|
2374
2423
|
ResourceIdSchema,
|
|
2375
|
-
|
|
2424
|
+
z43.object({
|
|
2376
2425
|
hash: KeySchema.describe(
|
|
2377
2426
|
"Specifies the name of the partition / hash key that makes up the primary key for the table."
|
|
2378
2427
|
),
|
|
2379
2428
|
sort: KeySchema.optional().describe(
|
|
2380
2429
|
"Specifies the name of the range / sort key that makes up the primary key for the table."
|
|
2381
2430
|
),
|
|
2382
|
-
fields:
|
|
2431
|
+
fields: z43.record(z43.string(), z43.enum(["string", "number", "binary"])).optional().describe(
|
|
2383
2432
|
'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
|
|
2384
2433
|
),
|
|
2385
|
-
class:
|
|
2386
|
-
pointInTimeRecovery:
|
|
2434
|
+
class: z43.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
|
|
2435
|
+
pointInTimeRecovery: z43.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
|
|
2387
2436
|
ttl: KeySchema.optional().describe(
|
|
2388
2437
|
[
|
|
2389
2438
|
"The name of the TTL attribute used to store the expiration time for items in the table.",
|
|
@@ -2391,8 +2440,8 @@ var TablesSchema = z41.record(
|
|
|
2391
2440
|
].join("\n")
|
|
2392
2441
|
),
|
|
2393
2442
|
// deletionProtection: DeletionProtectionSchema.optional(),
|
|
2394
|
-
stream:
|
|
2395
|
-
type:
|
|
2443
|
+
stream: z43.object({
|
|
2444
|
+
type: z43.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
|
|
2396
2445
|
[
|
|
2397
2446
|
"When an item in the table is modified, you can determines what information is written to the stream for this table.",
|
|
2398
2447
|
"Valid values are:",
|
|
@@ -2402,7 +2451,7 @@ var TablesSchema = z41.record(
|
|
|
2402
2451
|
"- new-and-old-images - Both the new and the old item images of the item are written to the stream."
|
|
2403
2452
|
].join("\n")
|
|
2404
2453
|
),
|
|
2405
|
-
batchSize:
|
|
2454
|
+
batchSize: z43.number().min(1).max(1e4).default(1).describe(
|
|
2406
2455
|
[
|
|
2407
2456
|
"The maximum number of records in each batch that Lambda pulls from your stream and sends to your function.",
|
|
2408
2457
|
"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).",
|
|
@@ -2418,29 +2467,26 @@ var TablesSchema = z41.record(
|
|
|
2418
2467
|
"You can specify a duration from 1 seconds to 5 minutes."
|
|
2419
2468
|
].join("\n")
|
|
2420
2469
|
),
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
// 'You can specify a number from -1 to 10000.',
|
|
2433
|
-
// ].join('\n')
|
|
2434
|
-
// ),
|
|
2435
|
-
retryAttempts: z41.number().min(-1).max(1e4).default(-1).describe(
|
|
2470
|
+
maxRecordAge: DurationSchema.refine(
|
|
2471
|
+
durationMin(seconds4(1)),
|
|
2472
|
+
"Minimum record age duration is 1 second"
|
|
2473
|
+
).refine(durationMax(minutes5(1)), "Maximum record age duration is 1 minute").default("60 seconds").describe(
|
|
2474
|
+
[
|
|
2475
|
+
"Discard records older than the specified age.",
|
|
2476
|
+
"The maximum valid value for maximum record age is 60s.",
|
|
2477
|
+
"The default value is 60s"
|
|
2478
|
+
].join("\n")
|
|
2479
|
+
),
|
|
2480
|
+
retryAttempts: z43.number().min(-1).max(1e4).default(2).describe(
|
|
2436
2481
|
[
|
|
2437
2482
|
"Discard records after the specified number of retries.",
|
|
2438
|
-
"
|
|
2483
|
+
"-1 will sets the maximum number of retries to infinite.",
|
|
2439
2484
|
"When maxRetryAttempts is infinite, Lambda retries failed records until the record expires in the event source.",
|
|
2440
|
-
"You can specify a number from -1 to 10000."
|
|
2485
|
+
"You can specify a number from -1 to 10000.",
|
|
2486
|
+
"The default value is 2"
|
|
2441
2487
|
].join("\n")
|
|
2442
2488
|
),
|
|
2443
|
-
concurrencyPerShard:
|
|
2489
|
+
concurrencyPerShard: z43.number().min(1).max(10).default(1).describe(
|
|
2444
2490
|
[
|
|
2445
2491
|
"The number of batches to process concurrently from each shard.",
|
|
2446
2492
|
"You can specify a number from 1 to 10."
|
|
@@ -2450,16 +2496,16 @@ var TablesSchema = z41.record(
|
|
|
2450
2496
|
}).optional().describe(
|
|
2451
2497
|
"The settings for the DynamoDB table stream, which capture changes to items stored in the table."
|
|
2452
2498
|
),
|
|
2453
|
-
indexes:
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
hash:
|
|
2499
|
+
indexes: z43.record(
|
|
2500
|
+
z43.string(),
|
|
2501
|
+
z43.object({
|
|
2502
|
+
hash: z43.union([KeySchema.transform((v) => [v]), KeySchema.array()]).describe(
|
|
2457
2503
|
"Specifies the name of the partition / hash key that makes up the primary key for the global secondary index."
|
|
2458
2504
|
),
|
|
2459
|
-
sort:
|
|
2505
|
+
sort: z43.union([KeySchema.transform((v) => [v]), KeySchema.array()]).optional().describe(
|
|
2460
2506
|
"Specifies the name of the range / sort key that makes up the primary key for the global secondary index."
|
|
2461
2507
|
),
|
|
2462
|
-
projection:
|
|
2508
|
+
projection: z43.enum(["all", "keys-only"]).default("all").describe(
|
|
2463
2509
|
[
|
|
2464
2510
|
"The set of attributes that are projected into the index:",
|
|
2465
2511
|
"- all - All of the table attributes are projected into the index.",
|
|
@@ -2472,36 +2518,13 @@ var TablesSchema = z41.record(
|
|
|
2472
2518
|
})
|
|
2473
2519
|
).optional().describe("Define the tables in your stack.");
|
|
2474
2520
|
|
|
2475
|
-
// src/feature/task/schema.ts
|
|
2476
|
-
import { z as z42 } from "zod";
|
|
2477
|
-
var RetryAttemptsSchema2 = z42.number().int().min(0).max(2).describe(
|
|
2478
|
-
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
2479
|
-
);
|
|
2480
|
-
var TaskSchema = z42.union([
|
|
2481
|
-
LocalFileSchema.transform((file) => ({
|
|
2482
|
-
consumer: {
|
|
2483
|
-
code: {
|
|
2484
|
-
file,
|
|
2485
|
-
minify: true,
|
|
2486
|
-
external: []
|
|
2487
|
-
}
|
|
2488
|
-
},
|
|
2489
|
-
retryAttempts: void 0
|
|
2490
|
-
})),
|
|
2491
|
-
z42.object({
|
|
2492
|
-
consumer: FunctionSchema,
|
|
2493
|
-
retryAttempts: RetryAttemptsSchema2.optional()
|
|
2494
|
-
})
|
|
2495
|
-
]);
|
|
2496
|
-
var TasksSchema = z42.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
|
|
2497
|
-
|
|
2498
2521
|
// src/feature/test/schema.ts
|
|
2499
|
-
import { z as
|
|
2500
|
-
var TestsSchema =
|
|
2522
|
+
import { z as z44 } from "zod";
|
|
2523
|
+
var TestsSchema = z44.union([
|
|
2501
2524
|
//
|
|
2502
2525
|
LocalDirectorySchema.transform((v) => [v]),
|
|
2503
2526
|
LocalDirectorySchema.array(),
|
|
2504
|
-
|
|
2527
|
+
z44.literal(false)
|
|
2505
2528
|
]).describe("Define the location of your tests for your stack.").optional();
|
|
2506
2529
|
|
|
2507
2530
|
// src/config/stack.ts
|
|
@@ -2509,8 +2532,8 @@ var DependsSchema = ResourceIdSchema.array().optional().describe("Define the sta
|
|
|
2509
2532
|
var NameSchema = ResourceIdSchema.refine((name) => !["base", "hostedzones"].includes(name), {
|
|
2510
2533
|
message: `Stack name can't be a reserved name.`
|
|
2511
2534
|
}).describe("Stack name.");
|
|
2512
|
-
var StackSchema =
|
|
2513
|
-
$schema:
|
|
2535
|
+
var StackSchema = z45.object({
|
|
2536
|
+
$schema: z45.string().optional(),
|
|
2514
2537
|
name: NameSchema,
|
|
2515
2538
|
depends: DependsSchema,
|
|
2516
2539
|
commands: CommandsSchema,
|
|
@@ -2547,37 +2570,37 @@ import { basename, dirname as dirname2, extname, join as join4 } from "path";
|
|
|
2547
2570
|
|
|
2548
2571
|
// src/config/stage-patch.ts
|
|
2549
2572
|
import jsonPatch from "fast-json-patch";
|
|
2550
|
-
import { z as
|
|
2551
|
-
var AddOperationSchema =
|
|
2552
|
-
op:
|
|
2553
|
-
path:
|
|
2554
|
-
value:
|
|
2573
|
+
import { z as z46 } from "zod";
|
|
2574
|
+
var AddOperationSchema = z46.object({
|
|
2575
|
+
op: z46.literal("add"),
|
|
2576
|
+
path: z46.string(),
|
|
2577
|
+
value: z46.unknown()
|
|
2555
2578
|
}).strict();
|
|
2556
|
-
var RemoveOperationSchema =
|
|
2557
|
-
op:
|
|
2558
|
-
path:
|
|
2579
|
+
var RemoveOperationSchema = z46.object({
|
|
2580
|
+
op: z46.literal("remove"),
|
|
2581
|
+
path: z46.string()
|
|
2559
2582
|
}).strict();
|
|
2560
|
-
var ReplaceOperationSchema =
|
|
2561
|
-
op:
|
|
2562
|
-
path:
|
|
2563
|
-
value:
|
|
2583
|
+
var ReplaceOperationSchema = z46.object({
|
|
2584
|
+
op: z46.literal("replace"),
|
|
2585
|
+
path: z46.string(),
|
|
2586
|
+
value: z46.unknown()
|
|
2564
2587
|
}).strict();
|
|
2565
|
-
var MoveOperationSchema =
|
|
2566
|
-
op:
|
|
2567
|
-
from:
|
|
2568
|
-
path:
|
|
2588
|
+
var MoveOperationSchema = z46.object({
|
|
2589
|
+
op: z46.literal("move"),
|
|
2590
|
+
from: z46.string(),
|
|
2591
|
+
path: z46.string()
|
|
2569
2592
|
}).strict();
|
|
2570
|
-
var CopyOperationSchema =
|
|
2571
|
-
op:
|
|
2572
|
-
from:
|
|
2573
|
-
path:
|
|
2593
|
+
var CopyOperationSchema = z46.object({
|
|
2594
|
+
op: z46.literal("copy"),
|
|
2595
|
+
from: z46.string(),
|
|
2596
|
+
path: z46.string()
|
|
2574
2597
|
}).strict();
|
|
2575
|
-
var TestOperationSchema =
|
|
2576
|
-
op:
|
|
2577
|
-
path:
|
|
2578
|
-
value:
|
|
2598
|
+
var TestOperationSchema = z46.object({
|
|
2599
|
+
op: z46.literal("test"),
|
|
2600
|
+
path: z46.string(),
|
|
2601
|
+
value: z46.unknown()
|
|
2579
2602
|
}).strict();
|
|
2580
|
-
var JsonPatchOperationSchema =
|
|
2603
|
+
var JsonPatchOperationSchema = z46.discriminatedUnion("op", [
|
|
2581
2604
|
AddOperationSchema,
|
|
2582
2605
|
RemoveOperationSchema,
|
|
2583
2606
|
ReplaceOperationSchema,
|
|
@@ -2585,8 +2608,8 @@ var JsonPatchOperationSchema = z45.discriminatedUnion("op", [
|
|
|
2585
2608
|
CopyOperationSchema,
|
|
2586
2609
|
TestOperationSchema
|
|
2587
2610
|
]);
|
|
2588
|
-
var StagePatchSchema =
|
|
2589
|
-
$schema:
|
|
2611
|
+
var StagePatchSchema = z46.object({
|
|
2612
|
+
$schema: z46.string().optional(),
|
|
2590
2613
|
operations: JsonPatchOperationSchema.array()
|
|
2591
2614
|
}).strict();
|
|
2592
2615
|
var applyStagePatch = (source, patch, file) => {
|
|
@@ -2602,13 +2625,13 @@ var applyStagePatch = (source, patch, file) => {
|
|
|
2602
2625
|
};
|
|
2603
2626
|
|
|
2604
2627
|
// src/config/load/validate.ts
|
|
2605
|
-
import { z as
|
|
2628
|
+
import { z as z47 } from "zod";
|
|
2606
2629
|
var validateConfig = async (schema, file, data) => {
|
|
2607
2630
|
try {
|
|
2608
2631
|
const result = await schema.parseAsync(data);
|
|
2609
2632
|
return result;
|
|
2610
2633
|
} catch (error) {
|
|
2611
|
-
if (error instanceof
|
|
2634
|
+
if (error instanceof z47.ZodError) {
|
|
2612
2635
|
throw new ConfigError(file, error, data);
|
|
2613
2636
|
}
|
|
2614
2637
|
throw error;
|
|
@@ -3419,7 +3442,7 @@ var formatByteSize = (size) => {
|
|
|
3419
3442
|
|
|
3420
3443
|
// src/feature/on-failure/util.ts
|
|
3421
3444
|
var getGlobalOnFailure = (ctx) => {
|
|
3422
|
-
return ctx.shared.get("on-failure", "
|
|
3445
|
+
return ctx.shared.get("on-failure", "bucket-arn");
|
|
3423
3446
|
};
|
|
3424
3447
|
|
|
3425
3448
|
// src/feature/function/build/zip.ts
|
|
@@ -3947,9 +3970,8 @@ var createLambdaFunction = (parentGroup, ctx, ns, id, local) => {
|
|
|
3947
3970
|
}
|
|
3948
3971
|
};
|
|
3949
3972
|
};
|
|
3950
|
-
var createAsyncLambdaFunction = (group, ctx, ns, id,
|
|
3951
|
-
const result = createLambdaFunction(group, ctx, ns, id, { ...
|
|
3952
|
-
const props = deepmerge(ctx.appConfig.defaults.function, local);
|
|
3973
|
+
var createAsyncLambdaFunction = (group, ctx, ns, id, props) => {
|
|
3974
|
+
const result = createLambdaFunction(group, ctx, ns, id, { ...props.consumer, warm: 0 });
|
|
3953
3975
|
result.setEnvironment("THROW_EXPECTED_ERRORS", "1");
|
|
3954
3976
|
const onFailure = getGlobalOnFailure(ctx);
|
|
3955
3977
|
new aws4.lambda.FunctionEventInvokeConfig(
|
|
@@ -3967,8 +3989,15 @@ var createAsyncLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
3967
3989
|
}
|
|
3968
3990
|
);
|
|
3969
3991
|
result.addPermission({
|
|
3970
|
-
actions: ["
|
|
3971
|
-
resources: [onFailure]
|
|
3992
|
+
actions: ["s3:PutObject", "s3:ListBucket"],
|
|
3993
|
+
resources: [onFailure, $interpolate`${onFailure}/*`],
|
|
3994
|
+
conditions: {
|
|
3995
|
+
StringEquals: {
|
|
3996
|
+
// This will protect anyone from taking our bucket name,
|
|
3997
|
+
// and us sending our failed items to the wrong s3 bucket
|
|
3998
|
+
"s3:ResourceAccount": ctx.accountId
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
3972
4001
|
});
|
|
3973
4002
|
return result;
|
|
3974
4003
|
};
|
|
@@ -4042,7 +4071,10 @@ var cronFeature = defineFeature({
|
|
|
4042
4071
|
onStack(ctx) {
|
|
4043
4072
|
for (const [id, props] of Object.entries(ctx.stackConfig.crons ?? {})) {
|
|
4044
4073
|
const group = new Group4(ctx.stack, "cron", id);
|
|
4045
|
-
const { lambda } = createAsyncLambdaFunction(group, ctx, "cron", id,
|
|
4074
|
+
const { lambda } = createAsyncLambdaFunction(group, ctx, "cron", id, {
|
|
4075
|
+
consumer: props.consumer,
|
|
4076
|
+
retryAttempts: props.retryAttempts
|
|
4077
|
+
});
|
|
4046
4078
|
const name = formatLocalResourceName({
|
|
4047
4079
|
appName: ctx.app.name,
|
|
4048
4080
|
stackName: ctx.stack.name,
|
|
@@ -4448,132 +4480,495 @@ var onLogFeature = defineFeature({
|
|
|
4448
4480
|
});
|
|
4449
4481
|
|
|
4450
4482
|
// src/feature/on-failure/index.ts
|
|
4451
|
-
import { Group as
|
|
4483
|
+
import { Group as Group9 } from "@terraforge/core";
|
|
4484
|
+
import { aws as aws10 } from "@terraforge/aws";
|
|
4485
|
+
|
|
4486
|
+
// src/feature/function/prebuild.ts
|
|
4487
|
+
import { days as days5, seconds as seconds5, toDays as toDays5, toSeconds as toSeconds3 } from "@awsless/duration";
|
|
4488
|
+
import { mebibytes as mebibytes2, toMebibytes as toMebibytes3 } from "@awsless/size";
|
|
4452
4489
|
import { aws as aws9 } from "@terraforge/aws";
|
|
4453
|
-
import {
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
messageRetentionSeconds: toSeconds3(days5(14))
|
|
4490
|
+
import { Output as Output4, findInputDeps as findInputDeps2, resolveInputs as resolveInputs2 } from "@terraforge/core";
|
|
4491
|
+
import { pascalCase as pascalCase2 } from "change-case";
|
|
4492
|
+
var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
4493
|
+
let name;
|
|
4494
|
+
let roleName;
|
|
4495
|
+
if ("stack" in ctx) {
|
|
4496
|
+
name = formatLocalResourceName({
|
|
4497
|
+
appName: ctx.app.name,
|
|
4498
|
+
stackName: ctx.stack.name,
|
|
4499
|
+
resourceType: ns,
|
|
4500
|
+
resourceName: id
|
|
4465
4501
|
});
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
redrivePolicy: deadletter.arn.pipe((deadLetterTargetArn) => {
|
|
4473
|
-
return JSON.stringify({
|
|
4474
|
-
deadLetterTargetArn,
|
|
4475
|
-
maxReceiveCount: 100
|
|
4476
|
-
});
|
|
4477
|
-
})
|
|
4502
|
+
roleName = formatLocalResourceName({
|
|
4503
|
+
appName: ctx.app.name,
|
|
4504
|
+
stackName: ctx.stack.name,
|
|
4505
|
+
resourceType: ns,
|
|
4506
|
+
resourceName: id,
|
|
4507
|
+
postfix: ctx.appId
|
|
4478
4508
|
});
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
new aws9.lambda.EventSourceMapping(
|
|
4485
|
-
group,
|
|
4486
|
-
"on-failure",
|
|
4487
|
-
{
|
|
4488
|
-
functionName: result.lambda.functionName,
|
|
4489
|
-
eventSourceArn: queue2.arn,
|
|
4490
|
-
batchSize: 10
|
|
4491
|
-
},
|
|
4492
|
-
{
|
|
4493
|
-
dependsOn: [result.policy]
|
|
4494
|
-
}
|
|
4495
|
-
);
|
|
4496
|
-
result.addPermission({
|
|
4497
|
-
actions: [
|
|
4498
|
-
"sqs:SendMessage",
|
|
4499
|
-
"sqs:DeleteMessage",
|
|
4500
|
-
"sqs:ReceiveMessage",
|
|
4501
|
-
"sqs:GetQueueUrl",
|
|
4502
|
-
"sqs:GetQueueAttributes"
|
|
4503
|
-
],
|
|
4504
|
-
resources: [queue2.arn]
|
|
4509
|
+
} else {
|
|
4510
|
+
name = formatGlobalResourceName({
|
|
4511
|
+
appName: ctx.appConfig.name,
|
|
4512
|
+
resourceType: ns,
|
|
4513
|
+
resourceName: id
|
|
4505
4514
|
});
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4515
|
+
roleName = formatGlobalResourceName({
|
|
4516
|
+
appName: ctx.appConfig.name,
|
|
4517
|
+
resourceType: ns,
|
|
4518
|
+
resourceName: id,
|
|
4519
|
+
postfix: ctx.appId
|
|
4510
4520
|
});
|
|
4511
4521
|
}
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
if (subDomain) {
|
|
4532
|
-
return `${subDomain.replace(/\.$/, "")}.${domain2}`;
|
|
4533
|
-
}
|
|
4534
|
-
return domain2;
|
|
4535
|
-
};
|
|
4536
|
-
|
|
4537
|
-
// src/feature/pubsub/index.ts
|
|
4538
|
-
import { minutes as minutes7, toSeconds as toSeconds4 } from "@awsless/duration";
|
|
4539
|
-
var pubsubFeature = defineFeature({
|
|
4540
|
-
name: "pubsub",
|
|
4541
|
-
onApp(ctx) {
|
|
4542
|
-
ctx.addGlobalPermission({
|
|
4543
|
-
actions: ["iot:Publish"],
|
|
4544
|
-
resources: [
|
|
4545
|
-
// `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`,
|
|
4546
|
-
`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/pubsub/*`
|
|
4522
|
+
const code = new aws9.s3.BucketObject(group, "code", {
|
|
4523
|
+
bucket: ctx.shared.get("function", "bucket-name"),
|
|
4524
|
+
key: `/lambda/${name}.zip`,
|
|
4525
|
+
source: props.bundleFile,
|
|
4526
|
+
sourceHash: $hash(props.bundleFile)
|
|
4527
|
+
// body: Asset.fromFile(props.bundleFile),
|
|
4528
|
+
});
|
|
4529
|
+
const role = new aws9.iam.Role(group, "role", {
|
|
4530
|
+
name: roleName,
|
|
4531
|
+
assumeRolePolicy: JSON.stringify({
|
|
4532
|
+
Version: "2012-10-17",
|
|
4533
|
+
Statement: [
|
|
4534
|
+
{
|
|
4535
|
+
Effect: "Allow",
|
|
4536
|
+
Action: "sts:AssumeRole",
|
|
4537
|
+
Principal: {
|
|
4538
|
+
Service: ["lambda.amazonaws.com"]
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4547
4541
|
]
|
|
4548
|
-
})
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4542
|
+
})
|
|
4543
|
+
});
|
|
4544
|
+
const statements = [];
|
|
4545
|
+
const statementDeps = /* @__PURE__ */ new Set();
|
|
4546
|
+
const addPermission = (...permissions) => {
|
|
4547
|
+
statements.push(...permissions);
|
|
4548
|
+
for (const dep of findInputDeps2(permissions)) {
|
|
4549
|
+
statementDeps.add(dep);
|
|
4550
|
+
}
|
|
4551
|
+
};
|
|
4552
|
+
ctx.onPermission((statement) => {
|
|
4553
|
+
addPermission(statement);
|
|
4554
|
+
});
|
|
4555
|
+
const policy = new aws9.iam.RolePolicy(group, "policy", {
|
|
4556
|
+
role: role.name,
|
|
4557
|
+
name: "lambda-policy",
|
|
4558
|
+
policy: new Output4(statementDeps, async (resolve) => {
|
|
4559
|
+
const list3 = await resolveInputs2(statements);
|
|
4560
|
+
resolve(
|
|
4561
|
+
JSON.stringify({
|
|
4562
|
+
Version: "2012-10-17",
|
|
4563
|
+
Statement: list3.map((statement) => ({
|
|
4564
|
+
Effect: pascalCase2(statement.effect ?? "allow"),
|
|
4565
|
+
Action: statement.actions,
|
|
4566
|
+
Resource: statement.resources
|
|
4567
|
+
}))
|
|
4568
|
+
})
|
|
4569
|
+
);
|
|
4570
|
+
})
|
|
4571
|
+
});
|
|
4572
|
+
const variables = {};
|
|
4573
|
+
const logFormats = {
|
|
4574
|
+
text: "Text",
|
|
4575
|
+
json: "JSON"
|
|
4576
|
+
};
|
|
4577
|
+
const lambda = new aws9.lambda.Function(group, `function`, {
|
|
4578
|
+
functionName: name,
|
|
4579
|
+
role: role.arn,
|
|
4580
|
+
// code,
|
|
4581
|
+
// runtime: props.runtime === 'container' ? undefined : props.runtime,
|
|
4582
|
+
runtime: props.runtime,
|
|
4583
|
+
handler: props.handler,
|
|
4584
|
+
timeout: toSeconds3(props.timeout ?? seconds5(10)),
|
|
4585
|
+
memorySize: toMebibytes3(props.memorySize ?? mebibytes2(128)),
|
|
4586
|
+
architectures: [props.architecture ?? "arm64"],
|
|
4587
|
+
layers: props.layers?.map((id2) => ctx.shared.entry("layer", "arn", id2)),
|
|
4588
|
+
s3Bucket: code.bucket,
|
|
4589
|
+
s3ObjectVersion: code.versionId,
|
|
4590
|
+
s3Key: code.key.pipe((name2) => {
|
|
4591
|
+
if (name2.startsWith("/")) {
|
|
4592
|
+
return name2.substring(1);
|
|
4593
|
+
}
|
|
4594
|
+
return name2;
|
|
4595
|
+
}),
|
|
4596
|
+
sourceCodeHash: $hash(props.bundleFile),
|
|
4597
|
+
environment: {
|
|
4598
|
+
variables
|
|
4599
|
+
},
|
|
4600
|
+
loggingConfig: {
|
|
4601
|
+
logGroup: `/aws/lambda/${name}`,
|
|
4602
|
+
logFormat: logFormats[props.log && "format" in props.log && props.log.format || "json"],
|
|
4603
|
+
applicationLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.level?.toUpperCase() : void 0,
|
|
4604
|
+
systemLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.system?.toUpperCase() : void 0
|
|
4605
|
+
}
|
|
4606
|
+
});
|
|
4607
|
+
ctx.onEnv((name2, value) => {
|
|
4608
|
+
variables[name2] = value;
|
|
4609
|
+
});
|
|
4610
|
+
variables.APP = ctx.appConfig.name;
|
|
4611
|
+
variables.APP_ID = ctx.appId;
|
|
4612
|
+
variables.AWS_ACCOUNT_ID = ctx.accountId;
|
|
4613
|
+
if ("stackConfig" in ctx) {
|
|
4614
|
+
variables.STACK = ctx.stackConfig.name;
|
|
4615
|
+
}
|
|
4616
|
+
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
4617
|
+
const logGroup = new aws9.cloudwatch.LogGroup(group, "log", {
|
|
4618
|
+
name: `/aws/lambda/${name}`,
|
|
4619
|
+
retentionInDays: toDays5(props.log.retention ?? days5(7))
|
|
4620
|
+
});
|
|
4621
|
+
addPermission({
|
|
4622
|
+
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
4623
|
+
resources: [logGroup.arn.pipe((arn) => `${arn}:*`)]
|
|
4624
|
+
});
|
|
4625
|
+
const onLogArn = getGlobalOnLog(ctx);
|
|
4626
|
+
if (onLogArn && ctx.appConfig.defaults.onLog) {
|
|
4627
|
+
const logFilter = ctx.appConfig.defaults.onLog.filter;
|
|
4628
|
+
new aws9.cloudwatch.LogSubscriptionFilter(group, `on-log`, {
|
|
4629
|
+
name: "log-subscription",
|
|
4630
|
+
destinationArn: onLogArn,
|
|
4631
|
+
logGroupName: logGroup.name,
|
|
4632
|
+
filterPattern: formatFilterPattern(logFilter)
|
|
4633
|
+
});
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
if (props.warm) {
|
|
4637
|
+
const rule = new aws9.cloudwatch.EventRule(group, "warm", {
|
|
4638
|
+
name: `${name}--warm`,
|
|
4639
|
+
description: "Lambda Warmer",
|
|
4640
|
+
scheduleExpression: "rate(5 minutes)",
|
|
4641
|
+
isEnabled: true
|
|
4642
|
+
});
|
|
4643
|
+
new aws9.cloudwatch.EventTarget(group, "warm", {
|
|
4644
|
+
rule: rule.name,
|
|
4645
|
+
targetId: "warmer",
|
|
4646
|
+
arn: lambda.arn,
|
|
4647
|
+
input: JSON.stringify({
|
|
4648
|
+
warmer: true,
|
|
4649
|
+
concurrency: props.warm
|
|
4650
|
+
})
|
|
4651
|
+
});
|
|
4652
|
+
new aws9.lambda.Permission(group, `warm`, {
|
|
4653
|
+
action: "lambda:InvokeFunction",
|
|
4654
|
+
principal: "events.amazonaws.com",
|
|
4655
|
+
functionName: lambda.functionName,
|
|
4656
|
+
sourceArn: rule.arn
|
|
4657
|
+
});
|
|
4658
|
+
}
|
|
4659
|
+
return {
|
|
4660
|
+
name,
|
|
4661
|
+
lambda,
|
|
4662
|
+
policy,
|
|
4663
|
+
code,
|
|
4664
|
+
setEnvironment(name2, value) {
|
|
4665
|
+
variables[name2] = value;
|
|
4666
|
+
},
|
|
4667
|
+
addPermission(statement) {
|
|
4668
|
+
addPermission(statement);
|
|
4669
|
+
}
|
|
4670
|
+
};
|
|
4671
|
+
};
|
|
4672
|
+
|
|
4673
|
+
// src/feature/on-failure/index.ts
|
|
4674
|
+
import { join as join10 } from "node:path";
|
|
4675
|
+
import { mebibytes as mebibytes3 } from "@awsless/size";
|
|
4676
|
+
import { days as days6, toSeconds as toSeconds4 } from "@awsless/duration";
|
|
4677
|
+
var onFailureFeature = defineFeature({
|
|
4678
|
+
name: "on-failure",
|
|
4679
|
+
onApp(ctx) {
|
|
4680
|
+
const group = new Group9(ctx.base, "on-failure", "main");
|
|
4681
|
+
const deadletter = new aws10.sqs.Queue(group, "deadletter", {
|
|
4682
|
+
name: formatGlobalResourceName({
|
|
4683
|
+
appName: ctx.app.name,
|
|
4684
|
+
resourceType: "on-failure",
|
|
4685
|
+
resourceName: "deadletter"
|
|
4686
|
+
}),
|
|
4687
|
+
messageRetentionSeconds: toSeconds4(days6(14))
|
|
4688
|
+
});
|
|
4689
|
+
const queue2 = new aws10.sqs.Queue(group, "on-failure", {
|
|
4690
|
+
name: formatGlobalResourceName({
|
|
4691
|
+
appName: ctx.app.name,
|
|
4692
|
+
resourceType: "on-failure",
|
|
4693
|
+
resourceName: "failure"
|
|
4694
|
+
}),
|
|
4695
|
+
redrivePolicy: deadletter.arn.pipe((deadLetterTargetArn) => {
|
|
4696
|
+
return JSON.stringify({
|
|
4697
|
+
deadLetterTargetArn,
|
|
4698
|
+
maxReceiveCount: 3
|
|
4699
|
+
});
|
|
4700
|
+
})
|
|
4701
|
+
});
|
|
4702
|
+
ctx.shared.set("on-failure", "queue-arn", queue2.arn);
|
|
4703
|
+
const bucket = new aws10.s3.Bucket(group, "bucket", {
|
|
4704
|
+
bucket: formatGlobalResourceName({
|
|
4705
|
+
appName: ctx.app.name,
|
|
4706
|
+
resourceType: "on-failure",
|
|
4707
|
+
resourceName: "failure",
|
|
4708
|
+
postfix: ctx.appId
|
|
4709
|
+
}),
|
|
4710
|
+
lifecycleRule: [
|
|
4711
|
+
{
|
|
4712
|
+
id: "ttl",
|
|
4713
|
+
enabled: true,
|
|
4714
|
+
expiration: {
|
|
4715
|
+
days: 14
|
|
4716
|
+
}
|
|
4717
|
+
}
|
|
4718
|
+
]
|
|
4719
|
+
});
|
|
4720
|
+
ctx.shared.set("on-failure", "bucket-arn", bucket.arn);
|
|
4721
|
+
const props = ctx.appConfig.defaults.onFailure;
|
|
4722
|
+
if (props) {
|
|
4723
|
+
if (props.notify) {
|
|
4724
|
+
const topic = new aws10.sns.Topic(group, "deadletter-topic", {
|
|
4725
|
+
name: formatGlobalResourceName({
|
|
4726
|
+
appName: ctx.app.name,
|
|
4727
|
+
resourceType: "on-failure",
|
|
4728
|
+
resourceName: "deadletter"
|
|
4729
|
+
})
|
|
4730
|
+
});
|
|
4731
|
+
for (const email of props.notify) {
|
|
4732
|
+
new aws10.sns.TopicSubscription(group, email, {
|
|
4733
|
+
topicArn: topic.arn,
|
|
4734
|
+
protocol: "email",
|
|
4735
|
+
endpoint: email
|
|
4736
|
+
});
|
|
4737
|
+
}
|
|
4738
|
+
const role = new aws10.iam.Role(group, "deadletter-topic-role", {
|
|
4739
|
+
name: formatGlobalResourceName({
|
|
4740
|
+
appName: ctx.app.name,
|
|
4741
|
+
resourceType: "on-failure",
|
|
4742
|
+
resourceName: "pipe"
|
|
4743
|
+
}),
|
|
4744
|
+
description: `${ctx.app.name} on-failure deadletter notification pipe`,
|
|
4745
|
+
assumeRolePolicy: JSON.stringify({
|
|
4746
|
+
Version: "2012-10-17",
|
|
4747
|
+
Statement: [
|
|
4748
|
+
{
|
|
4749
|
+
Effect: "Allow",
|
|
4750
|
+
Action: "sts:AssumeRole",
|
|
4751
|
+
Principal: {
|
|
4752
|
+
Service: ["pipes.amazonaws.com"]
|
|
4753
|
+
}
|
|
4754
|
+
}
|
|
4755
|
+
]
|
|
4756
|
+
}),
|
|
4757
|
+
inlinePolicy: [
|
|
4758
|
+
{
|
|
4759
|
+
name: "deadletter-topic",
|
|
4760
|
+
policy: topic.arn.pipe(
|
|
4761
|
+
(topicArn) => deadletter.arn.pipe(
|
|
4762
|
+
(queueArn) => JSON.stringify({
|
|
4763
|
+
Version: "2012-10-17",
|
|
4764
|
+
Statement: [
|
|
4765
|
+
{
|
|
4766
|
+
Effect: "Allow",
|
|
4767
|
+
Action: [
|
|
4768
|
+
"sqs:ReceiveMessage",
|
|
4769
|
+
"sqs:DeleteMessage",
|
|
4770
|
+
"sqs:GetQueueAttributes",
|
|
4771
|
+
"sqs:ChangeMessageVisibility"
|
|
4772
|
+
],
|
|
4773
|
+
Resource: queueArn
|
|
4774
|
+
},
|
|
4775
|
+
{
|
|
4776
|
+
Effect: "Allow",
|
|
4777
|
+
Action: ["sns:Publish"],
|
|
4778
|
+
Resource: topicArn
|
|
4779
|
+
}
|
|
4780
|
+
]
|
|
4781
|
+
})
|
|
4782
|
+
)
|
|
4783
|
+
)
|
|
4784
|
+
}
|
|
4785
|
+
]
|
|
4786
|
+
});
|
|
4787
|
+
new aws10.pipes.Pipe(group, "deadletter-topic-pipe", {
|
|
4788
|
+
name: formatGlobalResourceName({
|
|
4789
|
+
appName: ctx.app.name,
|
|
4790
|
+
resourceType: "on-failure",
|
|
4791
|
+
resourceName: "notify"
|
|
4792
|
+
}),
|
|
4793
|
+
roleArn: role.arn,
|
|
4794
|
+
source: deadletter.arn,
|
|
4795
|
+
target: topic.arn,
|
|
4796
|
+
sourceParameters: {
|
|
4797
|
+
sqsQueueParameters: {
|
|
4798
|
+
batchSize: 1
|
|
4799
|
+
}
|
|
4800
|
+
},
|
|
4801
|
+
targetParameters: {
|
|
4802
|
+
inputTemplate: [
|
|
4803
|
+
`Awsless on-failure DLQ message`,
|
|
4804
|
+
`App: ${ctx.app.name}`,
|
|
4805
|
+
`Sent: <$.attributes.SentTimestamp>`,
|
|
4806
|
+
"",
|
|
4807
|
+
`Body:
|
|
4808
|
+
<$.body>`
|
|
4809
|
+
].join("\n")
|
|
4810
|
+
}
|
|
4811
|
+
});
|
|
4812
|
+
}
|
|
4813
|
+
const consumer = createLambdaFunction(group, ctx, "on-failure", "consumer", props.consumer);
|
|
4814
|
+
consumer.addPermission({
|
|
4815
|
+
effect: "deny",
|
|
4816
|
+
actions: [
|
|
4817
|
+
//
|
|
4818
|
+
"lambda:InvokeFunction",
|
|
4819
|
+
"lambda:InvokeAsync",
|
|
4820
|
+
"sqs:SendMessage",
|
|
4821
|
+
"sns:Publish"
|
|
4822
|
+
],
|
|
4823
|
+
resources: ["*"]
|
|
4824
|
+
});
|
|
4825
|
+
const prebuild = createPrebuildLambdaFunction(group, ctx, "on-failure", "normalizer", {
|
|
4826
|
+
bundleFile: join10(__dirname, "/prebuild/on-failure/bundle.zip"),
|
|
4827
|
+
bundleHash: join10(__dirname, "/prebuild/on-failure/HASH"),
|
|
4828
|
+
memorySize: mebibytes3(256),
|
|
4829
|
+
timeout: props.consumer.timeout,
|
|
4830
|
+
handler: "index.default",
|
|
4831
|
+
runtime: "nodejs24.x",
|
|
4832
|
+
log: {
|
|
4833
|
+
format: "json",
|
|
4834
|
+
level: "warn",
|
|
4835
|
+
retention: days6(3),
|
|
4836
|
+
system: "warn"
|
|
4837
|
+
}
|
|
4838
|
+
});
|
|
4839
|
+
prebuild.setEnvironment("CONSUMER", consumer.name);
|
|
4840
|
+
prebuild.addPermission({
|
|
4841
|
+
actions: ["lambda:InvokeFunction"],
|
|
4842
|
+
resources: [consumer.lambda.arn]
|
|
4843
|
+
});
|
|
4844
|
+
prebuild.addPermission({
|
|
4845
|
+
actions: ["s3:GetObject", "s3:DeleteObject"],
|
|
4846
|
+
resources: [bucket.arn, $interpolate`${bucket.arn}/*`]
|
|
4847
|
+
});
|
|
4848
|
+
prebuild.addPermission({
|
|
4849
|
+
actions: ["sqs:SendMessage"],
|
|
4850
|
+
resources: [deadletter.arn]
|
|
4851
|
+
});
|
|
4852
|
+
new aws10.lambda.FunctionEventInvokeConfig(
|
|
4853
|
+
group,
|
|
4854
|
+
"async",
|
|
4855
|
+
{
|
|
4856
|
+
functionName: prebuild.lambda.arn,
|
|
4857
|
+
maximumRetryAttempts: 2,
|
|
4858
|
+
destinationConfig: {
|
|
4859
|
+
onFailure: {
|
|
4860
|
+
destination: deadletter.arn
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4863
|
+
},
|
|
4864
|
+
{
|
|
4865
|
+
dependsOn: [prebuild.policy]
|
|
4866
|
+
}
|
|
4867
|
+
);
|
|
4868
|
+
prebuild.addPermission({
|
|
4869
|
+
actions: [
|
|
4870
|
+
"sqs:SendMessage",
|
|
4871
|
+
"sqs:DeleteMessage",
|
|
4872
|
+
"sqs:ReceiveMessage",
|
|
4873
|
+
"sqs:GetQueueUrl",
|
|
4874
|
+
"sqs:GetQueueAttributes"
|
|
4875
|
+
],
|
|
4876
|
+
resources: [queue2.arn]
|
|
4877
|
+
});
|
|
4878
|
+
new aws10.lambda.EventSourceMapping(
|
|
4879
|
+
group,
|
|
4880
|
+
"on-failure",
|
|
4881
|
+
{
|
|
4882
|
+
functionName: prebuild.lambda.functionName,
|
|
4883
|
+
eventSourceArn: queue2.arn,
|
|
4884
|
+
batchSize: 10
|
|
4885
|
+
},
|
|
4886
|
+
{
|
|
4887
|
+
dependsOn: [prebuild.policy]
|
|
4888
|
+
}
|
|
4889
|
+
);
|
|
4890
|
+
new aws10.lambda.Permission(group, "permission", {
|
|
4891
|
+
action: "lambda:InvokeFunction",
|
|
4892
|
+
principal: "s3.amazonaws.com",
|
|
4893
|
+
functionName: prebuild.lambda.functionName,
|
|
4894
|
+
sourceArn: bucket.arn
|
|
4895
|
+
});
|
|
4896
|
+
new aws10.s3.BucketNotification(group, "notification", {
|
|
4897
|
+
bucket: bucket.bucket,
|
|
4898
|
+
lambdaFunction: [
|
|
4899
|
+
{
|
|
4900
|
+
lambdaFunctionArn: prebuild.lambda.arn,
|
|
4901
|
+
events: ["s3:ObjectCreated:*"]
|
|
4902
|
+
}
|
|
4903
|
+
]
|
|
4904
|
+
});
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4907
|
+
});
|
|
4908
|
+
|
|
4909
|
+
// src/feature/pubsub/index.ts
|
|
4910
|
+
import { Group as Group10 } from "@terraforge/core";
|
|
4911
|
+
import { aws as aws11 } from "@terraforge/aws";
|
|
4912
|
+
import { constantCase as constantCase5 } from "change-case";
|
|
4913
|
+
|
|
4914
|
+
// src/feature/domain/util.ts
|
|
4915
|
+
var getDomainNameById = (config2, id) => {
|
|
4916
|
+
const domains = config2.defaults.domains ?? {};
|
|
4917
|
+
if (id in domains) {
|
|
4918
|
+
if (domains[id]) {
|
|
4919
|
+
return domains[id].domain;
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
throw new TypeError(`No domain registered with id: ${id}`);
|
|
4923
|
+
};
|
|
4924
|
+
var formatFullDomainName = (config2, id, subDomain) => {
|
|
4925
|
+
const domain2 = getDomainNameById(config2, id);
|
|
4926
|
+
if (subDomain) {
|
|
4927
|
+
return `${subDomain.replace(/\.$/, "")}.${domain2}`;
|
|
4928
|
+
}
|
|
4929
|
+
return domain2;
|
|
4930
|
+
};
|
|
4931
|
+
|
|
4932
|
+
// src/feature/pubsub/index.ts
|
|
4933
|
+
import { minutes as minutes7, toSeconds as toSeconds5 } from "@awsless/duration";
|
|
4934
|
+
var pubsubFeature = defineFeature({
|
|
4935
|
+
name: "pubsub",
|
|
4936
|
+
onApp(ctx) {
|
|
4937
|
+
ctx.addGlobalPermission({
|
|
4938
|
+
actions: ["iot:Publish"],
|
|
4939
|
+
resources: [
|
|
4940
|
+
// `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`,
|
|
4941
|
+
`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/pubsub/*`
|
|
4942
|
+
]
|
|
4943
|
+
});
|
|
4944
|
+
for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
|
|
4945
|
+
const group = new Group10(ctx.base, "pubsub", id);
|
|
4946
|
+
const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, props.auth);
|
|
4552
4947
|
const name = formatGlobalResourceName({
|
|
4553
4948
|
appName: ctx.app.name,
|
|
4554
4949
|
resourceType: "pubsub",
|
|
4555
4950
|
resourceName: id
|
|
4556
4951
|
});
|
|
4557
|
-
const authorizer = new
|
|
4952
|
+
const authorizer = new aws11.iot.Authorizer(group, "authorizer", {
|
|
4558
4953
|
name,
|
|
4559
4954
|
authorizerFunctionArn: lambda.arn,
|
|
4560
4955
|
status: "ACTIVE",
|
|
4561
4956
|
signingDisabled: true,
|
|
4562
4957
|
enableCachingForHttp: false
|
|
4563
4958
|
});
|
|
4564
|
-
new
|
|
4959
|
+
new aws11.lambda.Permission(group, "permission", {
|
|
4565
4960
|
functionName: lambda.functionName,
|
|
4566
4961
|
action: "lambda:InvokeFunction",
|
|
4567
4962
|
principal: "iot.amazonaws.com",
|
|
4568
4963
|
sourceArn: authorizer.arn
|
|
4569
4964
|
});
|
|
4570
4965
|
ctx.bind(`PUBSUB_${constantCase5(id)}_AUTHORIZER`, name);
|
|
4571
|
-
const endpoint =
|
|
4966
|
+
const endpoint = aws11.iot.getEndpoint(group, "endpoint", {
|
|
4572
4967
|
endpointType: "iot:Data-ATS"
|
|
4573
4968
|
});
|
|
4574
4969
|
if (props.domain) {
|
|
4575
4970
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
4576
|
-
new
|
|
4971
|
+
new aws11.iot.DomainConfiguration(group, "domain", {
|
|
4577
4972
|
name,
|
|
4578
4973
|
domainName,
|
|
4579
4974
|
serverCertificateArns: [ctx.shared.entry("domain", `certificate-arn`, props.domain)],
|
|
@@ -4582,11 +4977,11 @@ var pubsubFeature = defineFeature({
|
|
|
4582
4977
|
}
|
|
4583
4978
|
// validationCertificate: ctx.shared.get(`global-certificate-${props.domain}-arn`),
|
|
4584
4979
|
});
|
|
4585
|
-
new
|
|
4980
|
+
new aws11.route53.Record(group, "record", {
|
|
4586
4981
|
zoneId: ctx.shared.entry("domain", `zone-id`, props.domain),
|
|
4587
4982
|
name: domainName,
|
|
4588
4983
|
type: "CNAME",
|
|
4589
|
-
ttl:
|
|
4984
|
+
ttl: toSeconds5(minutes7(5)),
|
|
4590
4985
|
records: [endpoint.endpointAddress]
|
|
4591
4986
|
});
|
|
4592
4987
|
ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, domainName);
|
|
@@ -4597,22 +4992,22 @@ var pubsubFeature = defineFeature({
|
|
|
4597
4992
|
},
|
|
4598
4993
|
onStack(ctx) {
|
|
4599
4994
|
for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
|
|
4600
|
-
const group = new
|
|
4601
|
-
const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props
|
|
4995
|
+
const group = new Group10(ctx.stack, "pubsub", id);
|
|
4996
|
+
const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props);
|
|
4602
4997
|
const name = formatLocalResourceName({
|
|
4603
4998
|
appName: ctx.app.name,
|
|
4604
4999
|
stackName: ctx.stack.name,
|
|
4605
5000
|
resourceType: "pubsub",
|
|
4606
5001
|
resourceName: id
|
|
4607
5002
|
});
|
|
4608
|
-
const topic = new
|
|
5003
|
+
const topic = new aws11.iot.TopicRule(group, "rule", {
|
|
4609
5004
|
name: name.replaceAll("-", "_"),
|
|
4610
5005
|
enabled: true,
|
|
4611
5006
|
sql: props.sql,
|
|
4612
5007
|
sqlVersion: props.sqlVersion,
|
|
4613
5008
|
lambda: [{ functionArn: lambda.arn }]
|
|
4614
5009
|
});
|
|
4615
|
-
new
|
|
5010
|
+
new aws11.lambda.Permission(group, "permission", {
|
|
4616
5011
|
action: "lambda:InvokeFunction",
|
|
4617
5012
|
principal: "iot.amazonaws.com",
|
|
4618
5013
|
functionName: lambda.functionName,
|
|
@@ -4623,12 +5018,12 @@ var pubsubFeature = defineFeature({
|
|
|
4623
5018
|
});
|
|
4624
5019
|
|
|
4625
5020
|
// src/feature/queue/index.ts
|
|
4626
|
-
import { Group as
|
|
4627
|
-
import { aws as
|
|
5021
|
+
import { Group as Group11 } from "@terraforge/core";
|
|
5022
|
+
import { aws as aws12 } from "@terraforge/aws";
|
|
4628
5023
|
import { camelCase as camelCase5, constantCase as constantCase6 } from "change-case";
|
|
4629
5024
|
import deepmerge3 from "deepmerge";
|
|
4630
5025
|
import { relative as relative5 } from "path";
|
|
4631
|
-
import { seconds as
|
|
5026
|
+
import { seconds as seconds6, toSeconds as toSeconds6 } from "@awsless/duration";
|
|
4632
5027
|
import { toBytes } from "@awsless/size";
|
|
4633
5028
|
var typeGenCode4 = `
|
|
4634
5029
|
import { SendMessageOptions, SendMessageBatchOptions, BatchItem } from '@awsless/sqs'
|
|
@@ -4688,42 +5083,44 @@ var queueFeature = defineFeature({
|
|
|
4688
5083
|
gen.addInterface("QueueMockResponse", mockResponses);
|
|
4689
5084
|
await ctx.write("queue.d.ts", gen, true);
|
|
4690
5085
|
},
|
|
5086
|
+
onApp(ctx) {
|
|
5087
|
+
},
|
|
4691
5088
|
onStack(ctx) {
|
|
4692
5089
|
for (const [id, local] of Object.entries(ctx.stackConfig.queues || {})) {
|
|
4693
5090
|
const props = deepmerge3(ctx.appConfig.defaults.queue, typeof local === "object" ? local : {});
|
|
4694
|
-
const group = new
|
|
5091
|
+
const group = new Group11(ctx.stack, "queue", id);
|
|
4695
5092
|
const name = formatLocalResourceName({
|
|
4696
5093
|
appName: ctx.app.name,
|
|
4697
5094
|
stackName: ctx.stack.name,
|
|
4698
5095
|
resourceType: "queue",
|
|
4699
5096
|
resourceName: id
|
|
4700
5097
|
});
|
|
4701
|
-
const onFailure =
|
|
4702
|
-
const queue2 = new
|
|
5098
|
+
const onFailure = ctx.shared.get("on-failure", "queue-arn");
|
|
5099
|
+
const queue2 = new aws12.sqs.Queue(group, "queue", {
|
|
4703
5100
|
name,
|
|
4704
|
-
delaySeconds:
|
|
4705
|
-
visibilityTimeoutSeconds:
|
|
4706
|
-
receiveWaitTimeSeconds:
|
|
4707
|
-
messageRetentionSeconds:
|
|
5101
|
+
delaySeconds: toSeconds6(props.deliveryDelay),
|
|
5102
|
+
visibilityTimeoutSeconds: toSeconds6(props.visibilityTimeout),
|
|
5103
|
+
receiveWaitTimeSeconds: toSeconds6(props.receiveMessageWaitTime ?? seconds6(0)),
|
|
5104
|
+
messageRetentionSeconds: toSeconds6(props.retentionPeriod),
|
|
4708
5105
|
maxMessageSize: toBytes(props.maxMessageSize),
|
|
4709
5106
|
redrivePolicy: onFailure.pipe(
|
|
4710
5107
|
(arn) => JSON.stringify({
|
|
4711
5108
|
deadLetterTargetArn: arn,
|
|
4712
|
-
maxReceiveCount:
|
|
5109
|
+
maxReceiveCount: props.retryAttempts + 1
|
|
4713
5110
|
})
|
|
4714
5111
|
)
|
|
4715
5112
|
});
|
|
4716
5113
|
if (local.consumer) {
|
|
4717
5114
|
const lambdaConsumer = createLambdaFunction(group, ctx, `queue`, id, local.consumer);
|
|
4718
5115
|
lambdaConsumer.setEnvironment("THROW_EXPECTED_ERRORS", "1");
|
|
4719
|
-
new
|
|
5116
|
+
new aws12.lambda.EventSourceMapping(
|
|
4720
5117
|
group,
|
|
4721
5118
|
"event",
|
|
4722
5119
|
{
|
|
4723
5120
|
functionName: lambdaConsumer.lambda.functionName,
|
|
4724
5121
|
eventSourceArn: queue2.arn,
|
|
4725
5122
|
batchSize: props.batchSize,
|
|
4726
|
-
maximumBatchingWindowInSeconds: props.maxBatchingWindow &&
|
|
5123
|
+
maximumBatchingWindowInSeconds: props.maxBatchingWindow && toSeconds6(props.maxBatchingWindow),
|
|
4727
5124
|
scalingConfig: {
|
|
4728
5125
|
maximumConcurrency: props.maxConcurrency
|
|
4729
5126
|
}
|
|
@@ -4759,24 +5156,24 @@ var queueFeature = defineFeature({
|
|
|
4759
5156
|
});
|
|
4760
5157
|
|
|
4761
5158
|
// src/feature/rest/index.ts
|
|
4762
|
-
import { Group as
|
|
4763
|
-
import { aws as
|
|
5159
|
+
import { Group as Group12 } from "@terraforge/core";
|
|
5160
|
+
import { aws as aws13 } from "@terraforge/aws";
|
|
4764
5161
|
import { constantCase as constantCase7 } from "change-case";
|
|
4765
5162
|
var restFeature = defineFeature({
|
|
4766
5163
|
name: "rest",
|
|
4767
5164
|
onApp(ctx) {
|
|
4768
5165
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults?.rest ?? {})) {
|
|
4769
|
-
const group = new
|
|
5166
|
+
const group = new Group12(ctx.base, "rest", id);
|
|
4770
5167
|
const name = formatGlobalResourceName({
|
|
4771
5168
|
appName: ctx.app.name,
|
|
4772
5169
|
resourceType: "rest",
|
|
4773
5170
|
resourceName: id
|
|
4774
5171
|
});
|
|
4775
|
-
const api = new
|
|
5172
|
+
const api = new aws13.apigatewayv2.Api(group, "api", {
|
|
4776
5173
|
name,
|
|
4777
5174
|
protocolType: "HTTP"
|
|
4778
5175
|
});
|
|
4779
|
-
const stage = new
|
|
5176
|
+
const stage = new aws13.apigatewayv2.Stage(group, "stage", {
|
|
4780
5177
|
name: "v1",
|
|
4781
5178
|
apiId: api.id,
|
|
4782
5179
|
autoDeploy: true
|
|
@@ -4786,7 +5183,7 @@ var restFeature = defineFeature({
|
|
|
4786
5183
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
4787
5184
|
const zoneId = ctx.shared.entry("domain", `zone-id`, props.domain);
|
|
4788
5185
|
const certificateArn = ctx.shared.entry("domain", `certificate-arn`, props.domain);
|
|
4789
|
-
const domain2 = new
|
|
5186
|
+
const domain2 = new aws13.apigatewayv2.DomainName(group, "domain", {
|
|
4790
5187
|
domainName,
|
|
4791
5188
|
domainNameConfiguration: {
|
|
4792
5189
|
certificateArn,
|
|
@@ -4794,12 +5191,12 @@ var restFeature = defineFeature({
|
|
|
4794
5191
|
securityPolicy: "TLS_1_2"
|
|
4795
5192
|
}
|
|
4796
5193
|
});
|
|
4797
|
-
const mapping = new
|
|
5194
|
+
const mapping = new aws13.apigatewayv2.ApiMapping(group, "mapping", {
|
|
4798
5195
|
apiId: api.id,
|
|
4799
5196
|
domainName: domain2.domainName,
|
|
4800
5197
|
stage: stage.name
|
|
4801
5198
|
});
|
|
4802
|
-
new
|
|
5199
|
+
new aws13.route53.Record(
|
|
4803
5200
|
group,
|
|
4804
5201
|
"record",
|
|
4805
5202
|
{
|
|
@@ -4827,21 +5224,21 @@ var restFeature = defineFeature({
|
|
|
4827
5224
|
},
|
|
4828
5225
|
onStack(ctx) {
|
|
4829
5226
|
for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
|
|
4830
|
-
const restGroup = new
|
|
5227
|
+
const restGroup = new Group12(ctx.stack, "rest", id);
|
|
4831
5228
|
for (const [routeKey, props] of Object.entries(routes)) {
|
|
4832
|
-
const group = new
|
|
5229
|
+
const group = new Group12(restGroup, "route", routeKey);
|
|
4833
5230
|
const apiId = ctx.shared.entry("rest", "id", id);
|
|
4834
5231
|
const routeId = shortId(routeKey);
|
|
4835
5232
|
const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
|
|
4836
5233
|
...props,
|
|
4837
5234
|
description: `${id} ${routeKey}`
|
|
4838
5235
|
});
|
|
4839
|
-
const permission = new
|
|
5236
|
+
const permission = new aws13.lambda.Permission(group, "permission", {
|
|
4840
5237
|
action: "lambda:InvokeFunction",
|
|
4841
5238
|
principal: "apigateway.amazonaws.com",
|
|
4842
5239
|
functionName: lambda.functionName
|
|
4843
5240
|
});
|
|
4844
|
-
const integration = new
|
|
5241
|
+
const integration = new aws13.apigatewayv2.Integration(group, "integration", {
|
|
4845
5242
|
apiId,
|
|
4846
5243
|
description: `${id} ${routeKey}`,
|
|
4847
5244
|
integrationType: "AWS_PROXY",
|
|
@@ -4851,7 +5248,7 @@ var restFeature = defineFeature({
|
|
|
4851
5248
|
return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
|
|
4852
5249
|
})
|
|
4853
5250
|
});
|
|
4854
|
-
new
|
|
5251
|
+
new aws13.apigatewayv2.Route(
|
|
4855
5252
|
group,
|
|
4856
5253
|
"route",
|
|
4857
5254
|
{
|
|
@@ -4872,200 +5269,11 @@ var restFeature = defineFeature({
|
|
|
4872
5269
|
import { camelCase as camelCase6, constantCase as constantCase8, kebabCase as kebabCase6 } from "change-case";
|
|
4873
5270
|
import { Group as Group13 } from "@terraforge/core";
|
|
4874
5271
|
import { aws as aws14 } from "@terraforge/aws";
|
|
4875
|
-
import { mebibytes as
|
|
4876
|
-
import { dirname as dirname5, join as
|
|
5272
|
+
import { mebibytes as mebibytes4 } from "@awsless/size";
|
|
5273
|
+
import { dirname as dirname5, join as join11, relative as relative6 } from "path";
|
|
4877
5274
|
import { fileURLToPath } from "node:url";
|
|
4878
|
-
|
|
4879
|
-
// src/feature/function/prebuild.ts
|
|
4880
|
-
import { days as days6, seconds as seconds6, toDays as toDays5, toSeconds as toSeconds6 } from "@awsless/duration";
|
|
4881
|
-
import { mebibytes as mebibytes2, toMebibytes as toMebibytes3 } from "@awsless/size";
|
|
4882
|
-
import { aws as aws13 } from "@terraforge/aws";
|
|
4883
|
-
import { Output as Output4, findInputDeps as findInputDeps2, resolveInputs as resolveInputs2 } from "@terraforge/core";
|
|
4884
|
-
import { pascalCase as pascalCase2 } from "change-case";
|
|
4885
|
-
var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
4886
|
-
let name;
|
|
4887
|
-
let roleName;
|
|
4888
|
-
if ("stack" in ctx) {
|
|
4889
|
-
name = formatLocalResourceName({
|
|
4890
|
-
appName: ctx.app.name,
|
|
4891
|
-
stackName: ctx.stack.name,
|
|
4892
|
-
resourceType: ns,
|
|
4893
|
-
resourceName: id
|
|
4894
|
-
});
|
|
4895
|
-
roleName = formatLocalResourceName({
|
|
4896
|
-
appName: ctx.app.name,
|
|
4897
|
-
stackName: ctx.stack.name,
|
|
4898
|
-
resourceType: ns,
|
|
4899
|
-
resourceName: id,
|
|
4900
|
-
postfix: ctx.appId
|
|
4901
|
-
});
|
|
4902
|
-
} else {
|
|
4903
|
-
name = formatGlobalResourceName({
|
|
4904
|
-
appName: ctx.appConfig.name,
|
|
4905
|
-
resourceType: ns,
|
|
4906
|
-
resourceName: id
|
|
4907
|
-
});
|
|
4908
|
-
roleName = formatGlobalResourceName({
|
|
4909
|
-
appName: ctx.appConfig.name,
|
|
4910
|
-
resourceType: ns,
|
|
4911
|
-
resourceName: id,
|
|
4912
|
-
postfix: ctx.appId
|
|
4913
|
-
});
|
|
4914
|
-
}
|
|
4915
|
-
const code = new aws13.s3.BucketObject(group, "code", {
|
|
4916
|
-
bucket: ctx.shared.get("function", "bucket-name"),
|
|
4917
|
-
key: `/lambda/${name}.zip`,
|
|
4918
|
-
source: props.bundleFile,
|
|
4919
|
-
sourceHash: $hash(props.bundleFile)
|
|
4920
|
-
// body: Asset.fromFile(props.bundleFile),
|
|
4921
|
-
});
|
|
4922
|
-
const role = new aws13.iam.Role(group, "role", {
|
|
4923
|
-
name: roleName,
|
|
4924
|
-
assumeRolePolicy: JSON.stringify({
|
|
4925
|
-
Version: "2012-10-17",
|
|
4926
|
-
Statement: [
|
|
4927
|
-
{
|
|
4928
|
-
Effect: "Allow",
|
|
4929
|
-
Action: "sts:AssumeRole",
|
|
4930
|
-
Principal: {
|
|
4931
|
-
Service: ["lambda.amazonaws.com"]
|
|
4932
|
-
}
|
|
4933
|
-
}
|
|
4934
|
-
]
|
|
4935
|
-
})
|
|
4936
|
-
});
|
|
4937
|
-
const statements = [];
|
|
4938
|
-
const statementDeps = /* @__PURE__ */ new Set();
|
|
4939
|
-
const addPermission = (...permissions) => {
|
|
4940
|
-
statements.push(...permissions);
|
|
4941
|
-
for (const dep of findInputDeps2(permissions)) {
|
|
4942
|
-
statementDeps.add(dep);
|
|
4943
|
-
}
|
|
4944
|
-
};
|
|
4945
|
-
ctx.onPermission((statement) => {
|
|
4946
|
-
addPermission(statement);
|
|
4947
|
-
});
|
|
4948
|
-
const policy = new aws13.iam.RolePolicy(group, "policy", {
|
|
4949
|
-
role: role.name,
|
|
4950
|
-
name: "lambda-policy",
|
|
4951
|
-
policy: new Output4(statementDeps, async (resolve) => {
|
|
4952
|
-
const list3 = await resolveInputs2(statements);
|
|
4953
|
-
resolve(
|
|
4954
|
-
JSON.stringify({
|
|
4955
|
-
Version: "2012-10-17",
|
|
4956
|
-
Statement: list3.map((statement) => ({
|
|
4957
|
-
Effect: pascalCase2(statement.effect ?? "allow"),
|
|
4958
|
-
Action: statement.actions,
|
|
4959
|
-
Resource: statement.resources
|
|
4960
|
-
}))
|
|
4961
|
-
})
|
|
4962
|
-
);
|
|
4963
|
-
})
|
|
4964
|
-
});
|
|
4965
|
-
const variables = {};
|
|
4966
|
-
const logFormats = {
|
|
4967
|
-
text: "Text",
|
|
4968
|
-
json: "JSON"
|
|
4969
|
-
};
|
|
4970
|
-
const lambda = new aws13.lambda.Function(group, `function`, {
|
|
4971
|
-
functionName: name,
|
|
4972
|
-
role: role.arn,
|
|
4973
|
-
// code,
|
|
4974
|
-
// runtime: props.runtime === 'container' ? undefined : props.runtime,
|
|
4975
|
-
runtime: props.runtime,
|
|
4976
|
-
handler: props.handler,
|
|
4977
|
-
timeout: toSeconds6(props.timeout ?? seconds6(10)),
|
|
4978
|
-
memorySize: toMebibytes3(props.memorySize ?? mebibytes2(128)),
|
|
4979
|
-
architectures: [props.architecture ?? "arm64"],
|
|
4980
|
-
layers: props.layers?.map((id2) => ctx.shared.entry("layer", "arn", id2)),
|
|
4981
|
-
s3Bucket: code.bucket,
|
|
4982
|
-
s3ObjectVersion: code.versionId,
|
|
4983
|
-
s3Key: code.key.pipe((name2) => {
|
|
4984
|
-
if (name2.startsWith("/")) {
|
|
4985
|
-
return name2.substring(1);
|
|
4986
|
-
}
|
|
4987
|
-
return name2;
|
|
4988
|
-
}),
|
|
4989
|
-
sourceCodeHash: $hash(props.bundleFile),
|
|
4990
|
-
environment: {
|
|
4991
|
-
variables
|
|
4992
|
-
},
|
|
4993
|
-
loggingConfig: {
|
|
4994
|
-
logGroup: `/aws/lambda/${name}`,
|
|
4995
|
-
logFormat: logFormats[props.log && "format" in props.log && props.log.format || "json"],
|
|
4996
|
-
applicationLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.level?.toUpperCase() : void 0,
|
|
4997
|
-
systemLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.system?.toUpperCase() : void 0
|
|
4998
|
-
}
|
|
4999
|
-
});
|
|
5000
|
-
ctx.onEnv((name2, value) => {
|
|
5001
|
-
variables[name2] = value;
|
|
5002
|
-
});
|
|
5003
|
-
variables.APP = ctx.appConfig.name;
|
|
5004
|
-
variables.APP_ID = ctx.appId;
|
|
5005
|
-
variables.AWS_ACCOUNT_ID = ctx.accountId;
|
|
5006
|
-
if ("stackConfig" in ctx) {
|
|
5007
|
-
variables.STACK = ctx.stackConfig.name;
|
|
5008
|
-
}
|
|
5009
|
-
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
5010
|
-
const logGroup = new aws13.cloudwatch.LogGroup(group, "log", {
|
|
5011
|
-
name: `/aws/lambda/${name}`,
|
|
5012
|
-
retentionInDays: toDays5(props.log.retention ?? days6(7))
|
|
5013
|
-
});
|
|
5014
|
-
addPermission({
|
|
5015
|
-
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
5016
|
-
resources: [logGroup.arn.pipe((arn) => `${arn}:*`)]
|
|
5017
|
-
});
|
|
5018
|
-
const onLogArn = getGlobalOnLog(ctx);
|
|
5019
|
-
if (onLogArn && ctx.appConfig.defaults.onLog) {
|
|
5020
|
-
const logFilter = ctx.appConfig.defaults.onLog.filter;
|
|
5021
|
-
new aws13.cloudwatch.LogSubscriptionFilter(group, `on-log`, {
|
|
5022
|
-
name: "log-subscription",
|
|
5023
|
-
destinationArn: onLogArn,
|
|
5024
|
-
logGroupName: logGroup.name,
|
|
5025
|
-
filterPattern: formatFilterPattern(logFilter)
|
|
5026
|
-
});
|
|
5027
|
-
}
|
|
5028
|
-
}
|
|
5029
|
-
if (props.warm) {
|
|
5030
|
-
const rule = new aws13.cloudwatch.EventRule(group, "warm", {
|
|
5031
|
-
name: `${name}--warm`,
|
|
5032
|
-
description: "Lambda Warmer",
|
|
5033
|
-
scheduleExpression: "rate(5 minutes)",
|
|
5034
|
-
isEnabled: true
|
|
5035
|
-
});
|
|
5036
|
-
new aws13.cloudwatch.EventTarget(group, "warm", {
|
|
5037
|
-
rule: rule.name,
|
|
5038
|
-
targetId: "warmer",
|
|
5039
|
-
arn: lambda.arn,
|
|
5040
|
-
input: JSON.stringify({
|
|
5041
|
-
warmer: true,
|
|
5042
|
-
concurrency: props.warm
|
|
5043
|
-
})
|
|
5044
|
-
});
|
|
5045
|
-
new aws13.lambda.Permission(group, `warm`, {
|
|
5046
|
-
action: "lambda:InvokeFunction",
|
|
5047
|
-
principal: "events.amazonaws.com",
|
|
5048
|
-
functionName: lambda.functionName,
|
|
5049
|
-
sourceArn: rule.arn
|
|
5050
|
-
});
|
|
5051
|
-
}
|
|
5052
|
-
return {
|
|
5053
|
-
name,
|
|
5054
|
-
lambda,
|
|
5055
|
-
policy,
|
|
5056
|
-
code,
|
|
5057
|
-
setEnvironment(name2, value) {
|
|
5058
|
-
variables[name2] = value;
|
|
5059
|
-
},
|
|
5060
|
-
addPermission(statement) {
|
|
5061
|
-
addPermission(statement);
|
|
5062
|
-
}
|
|
5063
|
-
};
|
|
5064
|
-
};
|
|
5065
|
-
|
|
5066
|
-
// src/feature/rpc/index.ts
|
|
5067
5275
|
import { toSeconds as toSeconds7 } from "@awsless/duration";
|
|
5068
|
-
var
|
|
5276
|
+
var __dirname2 = dirname5(fileURLToPath(import.meta.url));
|
|
5069
5277
|
var rpcFeature = defineFeature({
|
|
5070
5278
|
name: "rpc",
|
|
5071
5279
|
async onTypeGen(ctx) {
|
|
@@ -5125,9 +5333,9 @@ var rpcFeature = defineFeature({
|
|
|
5125
5333
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.rpc ?? {})) {
|
|
5126
5334
|
const group = new Group13(ctx.base, "rpc", id);
|
|
5127
5335
|
const result = createPrebuildLambdaFunction(group, ctx, "rpc", id, {
|
|
5128
|
-
bundleFile:
|
|
5129
|
-
bundleHash:
|
|
5130
|
-
memorySize:
|
|
5336
|
+
bundleFile: join11(__dirname2, "/prebuild/rpc/bundle.zip"),
|
|
5337
|
+
bundleHash: join11(__dirname2, "/prebuild/rpc/HASH"),
|
|
5338
|
+
memorySize: mebibytes4(256),
|
|
5131
5339
|
timeout: props.timeout,
|
|
5132
5340
|
handler: "index.default",
|
|
5133
5341
|
runtime: "nodejs22.x",
|
|
@@ -5394,7 +5602,7 @@ var searchFeature = defineFeature({
|
|
|
5394
5602
|
import { Group as Group15 } from "@terraforge/core";
|
|
5395
5603
|
import { aws as aws16 } from "@terraforge/aws";
|
|
5396
5604
|
import { glob as glob2 } from "glob";
|
|
5397
|
-
import { dirname as dirname6, join as
|
|
5605
|
+
import { dirname as dirname6, join as join12 } from "path";
|
|
5398
5606
|
|
|
5399
5607
|
// src/feature/site/util.ts
|
|
5400
5608
|
import { contentType, lookup } from "mime-types";
|
|
@@ -5440,7 +5648,7 @@ var siteFeature = defineFeature({
|
|
|
5440
5648
|
return build3(fingerprint, async (write) => {
|
|
5441
5649
|
const credentialProvider = await getCredentials(ctx.appConfig.profile);
|
|
5442
5650
|
const credentials = await credentialProvider();
|
|
5443
|
-
const cwd =
|
|
5651
|
+
const cwd = join12(directories.root, dirname6(ctx.stackConfig.file));
|
|
5444
5652
|
const env = {
|
|
5445
5653
|
...process.env,
|
|
5446
5654
|
// Pass the app config name
|
|
@@ -5585,20 +5793,20 @@ var siteFeature = defineFeature({
|
|
|
5585
5793
|
});
|
|
5586
5794
|
const staticRoutes = {};
|
|
5587
5795
|
for (const file of files) {
|
|
5588
|
-
const prefixedFile =
|
|
5796
|
+
const prefixedFile = join12("/", file);
|
|
5589
5797
|
const object = new aws16.s3.BucketObject(group, prefixedFile, {
|
|
5590
5798
|
bucket: bucket.bucket,
|
|
5591
5799
|
key: prefixedFile,
|
|
5592
5800
|
cacheControl: getCacheControl(file),
|
|
5593
5801
|
contentType: getContentType(file),
|
|
5594
|
-
source:
|
|
5595
|
-
sourceHash: $hash(
|
|
5802
|
+
source: join12(props.static, file),
|
|
5803
|
+
sourceHash: $hash(join12(props.static, file))
|
|
5596
5804
|
});
|
|
5597
5805
|
versions.push(object.key);
|
|
5598
5806
|
versions.push(object.sourceHash);
|
|
5599
5807
|
const strippedHtmlFile = file.endsWith("index.html") ? file.slice(0, -11) : file.endsWith(".html") ? file.slice(0, -5) : file;
|
|
5600
5808
|
const urlFriendlyFile = strippedHtmlFile.endsWith("/") ? strippedHtmlFile.slice(0, -1) : strippedHtmlFile;
|
|
5601
|
-
const routeFileKey =
|
|
5809
|
+
const routeFileKey = join12(props.path, urlFriendlyFile);
|
|
5602
5810
|
staticRoutes[routeFileKey] = {
|
|
5603
5811
|
type: "s3",
|
|
5604
5812
|
domainName: bucket.bucketRegionalDomainName,
|
|
@@ -5641,7 +5849,7 @@ var getContentType2 = (file) => {
|
|
|
5641
5849
|
};
|
|
5642
5850
|
|
|
5643
5851
|
// src/feature/store/index.ts
|
|
5644
|
-
import { join as
|
|
5852
|
+
import { join as join13 } from "path";
|
|
5645
5853
|
var typeGenCode6 = `
|
|
5646
5854
|
import { Body, PutObjectProps, BodyStream } from '@awsless/s3'
|
|
5647
5855
|
|
|
@@ -5697,7 +5905,14 @@ var storeFeature = defineFeature({
|
|
|
5697
5905
|
//
|
|
5698
5906
|
`arn:aws:s3:::${name}`,
|
|
5699
5907
|
`arn:aws:s3:::${name}/*`
|
|
5700
|
-
]
|
|
5908
|
+
],
|
|
5909
|
+
conditions: {
|
|
5910
|
+
StringEquals: {
|
|
5911
|
+
// This will protect anyone from taking our bucket name,
|
|
5912
|
+
// and us sending our items to the wrong s3 bucket
|
|
5913
|
+
"s3:ResourceAccount": ctx.accountId
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5701
5916
|
});
|
|
5702
5917
|
},
|
|
5703
5918
|
onStack(ctx) {
|
|
@@ -5746,8 +5961,8 @@ var storeFeature = defineFeature({
|
|
|
5746
5961
|
key: file,
|
|
5747
5962
|
cacheControl: getCacheControl2(file),
|
|
5748
5963
|
contentType: getContentType2(file),
|
|
5749
|
-
source:
|
|
5750
|
-
sourceHash: $hash(
|
|
5964
|
+
source: join13(props.static, file),
|
|
5965
|
+
sourceHash: $hash(join13(props.static, file))
|
|
5751
5966
|
});
|
|
5752
5967
|
}
|
|
5753
5968
|
}
|
|
@@ -5762,12 +5977,15 @@ var storeFeature = defineFeature({
|
|
|
5762
5977
|
"removed:delete": "s3:ObjectRemoved:Delete",
|
|
5763
5978
|
"removed:marker": "s3:ObjectRemoved:DeleteMarkerCreated"
|
|
5764
5979
|
};
|
|
5765
|
-
for (const [event,
|
|
5980
|
+
for (const [event, taskProps] of Object.entries(props.events ?? {})) {
|
|
5766
5981
|
const eventGroup = new Group16(group, "event", event);
|
|
5767
5982
|
const eventId = kebabCase7(`${id}-${shortId(event)}`);
|
|
5768
5983
|
const { lambda } = createAsyncLambdaFunction(eventGroup, ctx, `store`, eventId, {
|
|
5769
|
-
...
|
|
5770
|
-
|
|
5984
|
+
...taskProps,
|
|
5985
|
+
consumer: {
|
|
5986
|
+
...taskProps.consumer,
|
|
5987
|
+
description: `${id} event "${event}"`
|
|
5988
|
+
}
|
|
5771
5989
|
});
|
|
5772
5990
|
new aws17.lambda.Permission(eventGroup, "permission", {
|
|
5773
5991
|
action: "lambda:InvokeFunction",
|
|
@@ -5800,7 +6018,14 @@ var storeFeature = defineFeature({
|
|
|
5800
6018
|
//
|
|
5801
6019
|
bucket.arn,
|
|
5802
6020
|
bucket.arn.pipe((arn) => `${arn}/*`)
|
|
5803
|
-
]
|
|
6021
|
+
],
|
|
6022
|
+
conditions: {
|
|
6023
|
+
StringEquals: {
|
|
6024
|
+
// This will protect anyone from taking our bucket name,
|
|
6025
|
+
// and us sending our items to the wrong s3 bucket
|
|
6026
|
+
"s3:ResourceAccount": ctx.accountId
|
|
6027
|
+
}
|
|
6028
|
+
}
|
|
5804
6029
|
});
|
|
5805
6030
|
}
|
|
5806
6031
|
}
|
|
@@ -5939,7 +6164,7 @@ var tableFeature = defineFeature({
|
|
|
5939
6164
|
functionName: result.lambda.functionName,
|
|
5940
6165
|
eventSourceArn: table.streamArn,
|
|
5941
6166
|
// tumblingWindowInSeconds
|
|
5942
|
-
|
|
6167
|
+
maximumRecordAgeInSeconds: toSeconds8(props.stream.maxRecordAge),
|
|
5943
6168
|
// bisectBatchOnFunctionError: true,
|
|
5944
6169
|
batchSize: props.stream.batchSize,
|
|
5945
6170
|
maximumBatchingWindowInSeconds: props.stream.batchWindow ? toSeconds8(props.stream.batchWindow) : void 0,
|
|
@@ -5955,6 +6180,17 @@ var tableFeature = defineFeature({
|
|
|
5955
6180
|
},
|
|
5956
6181
|
{ dependsOn: [result.policy] }
|
|
5957
6182
|
);
|
|
6183
|
+
result.addPermission({
|
|
6184
|
+
actions: ["s3:PutObject", "s3:ListBucket"],
|
|
6185
|
+
resources: [onFailure, $interpolate`${onFailure}/*`],
|
|
6186
|
+
conditions: {
|
|
6187
|
+
StringEquals: {
|
|
6188
|
+
// This will protect anyone from taking our bucket name,
|
|
6189
|
+
// and us sending our failed items to the wrong s3 bucket
|
|
6190
|
+
"s3:ResourceAccount": ctx.accountId
|
|
6191
|
+
}
|
|
6192
|
+
}
|
|
6193
|
+
});
|
|
5958
6194
|
result.addPermission({
|
|
5959
6195
|
actions: [
|
|
5960
6196
|
"dynamodb:ListStreams",
|
|
@@ -5964,10 +6200,6 @@ var tableFeature = defineFeature({
|
|
|
5964
6200
|
],
|
|
5965
6201
|
resources: [table.streamArn]
|
|
5966
6202
|
});
|
|
5967
|
-
result.addPermission({
|
|
5968
|
-
actions: ["sqs:SendMessage", "sqs:GetQueueUrl"],
|
|
5969
|
-
resources: [onFailure]
|
|
5970
|
-
});
|
|
5971
6203
|
}
|
|
5972
6204
|
ctx.addStackPermission({
|
|
5973
6205
|
actions: [
|
|
@@ -6130,7 +6362,7 @@ var taskFeature = defineFeature({
|
|
|
6130
6362
|
onStack(ctx) {
|
|
6131
6363
|
for (const [id, props] of Object.entries(ctx.stackConfig.tasks ?? {})) {
|
|
6132
6364
|
const group = new Group18(ctx.stack, "task", id);
|
|
6133
|
-
createAsyncLambdaFunction(group, ctx, "task", id, props
|
|
6365
|
+
createAsyncLambdaFunction(group, ctx, "task", id, props);
|
|
6134
6366
|
}
|
|
6135
6367
|
}
|
|
6136
6368
|
});
|
|
@@ -6497,12 +6729,12 @@ var layerFeature = defineFeature({
|
|
|
6497
6729
|
// src/feature/image/index.ts
|
|
6498
6730
|
import { Group as Group23 } from "@terraforge/core";
|
|
6499
6731
|
import { aws as aws24 } from "@terraforge/aws";
|
|
6500
|
-
import { join as
|
|
6501
|
-
import { mebibytes as
|
|
6732
|
+
import { join as join14, dirname as dirname7 } from "path";
|
|
6733
|
+
import { mebibytes as mebibytes5 } from "@awsless/size";
|
|
6502
6734
|
import { seconds as seconds7, toDays as toDays6 } from "@awsless/duration";
|
|
6503
6735
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6504
6736
|
import { glob as glob4 } from "glob";
|
|
6505
|
-
var
|
|
6737
|
+
var __dirname3 = dirname7(fileURLToPath2(import.meta.url));
|
|
6506
6738
|
var imageFeature = defineFeature({
|
|
6507
6739
|
name: "image",
|
|
6508
6740
|
onApp(ctx) {
|
|
@@ -6513,7 +6745,7 @@ var imageFeature = defineFeature({
|
|
|
6513
6745
|
return;
|
|
6514
6746
|
}
|
|
6515
6747
|
const group = new Group23(ctx.base, "image", "layer");
|
|
6516
|
-
const path =
|
|
6748
|
+
const path = join14(__dirname3, "/layers/sharp-arm.zip");
|
|
6517
6749
|
const layerId = formatGlobalResourceName({
|
|
6518
6750
|
appName: ctx.appConfig.name,
|
|
6519
6751
|
resourceType: "layer",
|
|
@@ -6602,9 +6834,9 @@ var imageFeature = defineFeature({
|
|
|
6602
6834
|
resourceName: "sharp"
|
|
6603
6835
|
});
|
|
6604
6836
|
const serverLambda = createPrebuildLambdaFunction(group, ctx, "image", id, {
|
|
6605
|
-
bundleFile:
|
|
6606
|
-
bundleHash:
|
|
6607
|
-
memorySize:
|
|
6837
|
+
bundleFile: join14(__dirname3, "/prebuild/image/bundle.zip"),
|
|
6838
|
+
bundleHash: join14(__dirname3, "/prebuild/image/HASH"),
|
|
6839
|
+
memorySize: mebibytes5(512),
|
|
6608
6840
|
timeout: seconds7(10),
|
|
6609
6841
|
handler: "index.default",
|
|
6610
6842
|
runtime: "nodejs22.x",
|
|
@@ -6678,8 +6910,8 @@ var imageFeature = defineFeature({
|
|
|
6678
6910
|
new aws24.s3.BucketObject(group, `static-${file}`, {
|
|
6679
6911
|
bucket: s3Origin.bucket,
|
|
6680
6912
|
key: file,
|
|
6681
|
-
source:
|
|
6682
|
-
sourceHash: $hash(
|
|
6913
|
+
source: join14(props.origin.static, file),
|
|
6914
|
+
sourceHash: $hash(join14(props.origin.static, file))
|
|
6683
6915
|
});
|
|
6684
6916
|
}
|
|
6685
6917
|
}
|
|
@@ -6694,12 +6926,12 @@ var imageFeature = defineFeature({
|
|
|
6694
6926
|
// src/feature/icon/index.ts
|
|
6695
6927
|
import { Group as Group24 } from "@terraforge/core";
|
|
6696
6928
|
import { aws as aws25 } from "@terraforge/aws";
|
|
6697
|
-
import { join as
|
|
6698
|
-
import { mebibytes as
|
|
6929
|
+
import { join as join15, dirname as dirname8 } from "path";
|
|
6930
|
+
import { mebibytes as mebibytes6 } from "@awsless/size";
|
|
6699
6931
|
import { seconds as seconds8, toDays as toDays7 } from "@awsless/duration";
|
|
6700
6932
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6701
6933
|
import { glob as glob5 } from "glob";
|
|
6702
|
-
var
|
|
6934
|
+
var __dirname4 = dirname8(fileURLToPath3(import.meta.url));
|
|
6703
6935
|
var iconFeature = defineFeature({
|
|
6704
6936
|
name: "icon",
|
|
6705
6937
|
onStack(ctx) {
|
|
@@ -6748,9 +6980,9 @@ var iconFeature = defineFeature({
|
|
|
6748
6980
|
} : {}
|
|
6749
6981
|
});
|
|
6750
6982
|
const serverLambda = createPrebuildLambdaFunction(group, ctx, "icon", id, {
|
|
6751
|
-
bundleFile:
|
|
6752
|
-
bundleHash:
|
|
6753
|
-
memorySize:
|
|
6983
|
+
bundleFile: join15(__dirname4, "/prebuild/icon/bundle.zip"),
|
|
6984
|
+
bundleHash: join15(__dirname4, "/prebuild/icon/HASH"),
|
|
6985
|
+
memorySize: mebibytes6(512),
|
|
6754
6986
|
timeout: seconds8(10),
|
|
6755
6987
|
handler: "index.default",
|
|
6756
6988
|
runtime: "nodejs22.x",
|
|
@@ -6826,8 +7058,8 @@ var iconFeature = defineFeature({
|
|
|
6826
7058
|
new aws25.s3.BucketObject(group, `static-${file}`, {
|
|
6827
7059
|
bucket: s3Origin.bucket,
|
|
6828
7060
|
key: file,
|
|
6829
|
-
source:
|
|
6830
|
-
sourceHash: $hash(
|
|
7061
|
+
source: join15(props.origin.static, file),
|
|
7062
|
+
sourceHash: $hash(join15(props.origin.static, file))
|
|
6831
7063
|
});
|
|
6832
7064
|
}
|
|
6833
7065
|
}
|
|
@@ -6851,14 +7083,14 @@ import { aws as aws26 } from "@terraforge/aws";
|
|
|
6851
7083
|
import { Group as Group25, Output as Output6, findInputDeps as findInputDeps3, resolveInputs as resolveInputs3 } from "@terraforge/core";
|
|
6852
7084
|
import { constantCase as constantCase12, pascalCase as pascalCase3 } from "change-case";
|
|
6853
7085
|
import deepmerge4 from "deepmerge";
|
|
6854
|
-
import { join as
|
|
7086
|
+
import { join as join17 } from "path";
|
|
6855
7087
|
|
|
6856
7088
|
// src/feature/instance/build/executable.ts
|
|
6857
7089
|
import { createHash as createHash3 } from "crypto";
|
|
6858
7090
|
import { readFile as readFile4 } from "fs/promises";
|
|
6859
|
-
import { join as
|
|
7091
|
+
import { join as join16 } from "path";
|
|
6860
7092
|
var buildExecutable = async (input, outputPath, architecture) => {
|
|
6861
|
-
const filePath =
|
|
7093
|
+
const filePath = join16(outputPath, "program");
|
|
6862
7094
|
const target = architecture === "x86_64" ? "bun-linux-x64" : "bun-linux-arm64";
|
|
6863
7095
|
let result;
|
|
6864
7096
|
try {
|
|
@@ -7102,7 +7334,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7102
7334
|
healthCheck: props.healthCheck ? {
|
|
7103
7335
|
command: [
|
|
7104
7336
|
"CMD-SHELL",
|
|
7105
|
-
`curl -f http://${
|
|
7337
|
+
`curl -f http://${join17("localhost", props.healthCheck.path)} || exit 1`
|
|
7106
7338
|
],
|
|
7107
7339
|
interval: toSeconds9(props.healthCheck.interval),
|
|
7108
7340
|
retries: props.healthCheck.retries,
|
|
@@ -7387,7 +7619,13 @@ import { camelCase as camelCase8, constantCase as constantCase14 } from "change-
|
|
|
7387
7619
|
var getViewerRequestFunctionCode = (props) => {
|
|
7388
7620
|
return CODE([
|
|
7389
7621
|
props.blockDirectAccess ? BLOCK_DIRECT_ACCESS_TO_CLOUDFRONT : "",
|
|
7390
|
-
props.
|
|
7622
|
+
props.passwordAuth ?? props.basicAuth ? AUTH_WRAPPER(
|
|
7623
|
+
[
|
|
7624
|
+
//
|
|
7625
|
+
props.basicAuth ? BASIC_AUTH_CHECK(props.basicAuth.username, props.basicAuth.password) : "",
|
|
7626
|
+
props.passwordAuth ? PASSWORD_AUTH_CHECK(props.passwordAuth.password) : ""
|
|
7627
|
+
].join("\n")
|
|
7628
|
+
) : ""
|
|
7391
7629
|
]);
|
|
7392
7630
|
};
|
|
7393
7631
|
var BLOCK_DIRECT_ACCESS_TO_CLOUDFRONT = `
|
|
@@ -7398,13 +7636,36 @@ if (headers.host && headers.host.value.includes('cloudfront.net')) {
|
|
|
7398
7636
|
};
|
|
7399
7637
|
}`;
|
|
7400
7638
|
var BASIC_AUTH_CHECK = (username, password) => `
|
|
7401
|
-
|
|
7402
|
-
|
|
7639
|
+
authMethods.push('Basic realm="Protected"');
|
|
7640
|
+
|
|
7641
|
+
if(!isAuthorized) {
|
|
7642
|
+
if(authHeader && authHeader.startsWith('Basic ') && authHeader.slice(6) === '${Buffer.from(`${username}:${password}`).toString("base64")}') {
|
|
7643
|
+
isAuthorized = true;
|
|
7644
|
+
}
|
|
7645
|
+
}
|
|
7646
|
+
`;
|
|
7647
|
+
var PASSWORD_AUTH_CHECK = (password) => `
|
|
7648
|
+
authMethods.push('Password realm="Protected"');
|
|
7649
|
+
|
|
7650
|
+
if(!isAuthorized) {
|
|
7651
|
+
if(authHeader && authHeader.startsWith('Password ') && authHeader.slice(9) === '${password}') {
|
|
7652
|
+
isAuthorized = true;
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
`;
|
|
7656
|
+
var AUTH_WRAPPER = (code) => `
|
|
7657
|
+
const authHeader = headers.authorization && headers.authorization.value;
|
|
7658
|
+
const authMethods = [];
|
|
7659
|
+
let isAuthorized = false;
|
|
7660
|
+
|
|
7661
|
+
${code}
|
|
7662
|
+
|
|
7663
|
+
if (!isAuthorized) {
|
|
7403
7664
|
return {
|
|
7404
7665
|
statusCode: 401,
|
|
7405
7666
|
headers: {
|
|
7406
7667
|
'www-authenticate': {
|
|
7407
|
-
value: '
|
|
7668
|
+
value: authMethods.join(', ')
|
|
7408
7669
|
}
|
|
7409
7670
|
}
|
|
7410
7671
|
};
|
|
@@ -7723,7 +7984,8 @@ var routerFeature = defineFeature({
|
|
|
7723
7984
|
keyValueStoreAssociations: [routeStore.arn],
|
|
7724
7985
|
code: getViewerRequestFunctionCode({
|
|
7725
7986
|
blockDirectAccess: !!props.domain,
|
|
7726
|
-
basicAuth: props.basicAuth
|
|
7987
|
+
basicAuth: props.basicAuth,
|
|
7988
|
+
passwordAuth: props.passwordAuth
|
|
7727
7989
|
})
|
|
7728
7990
|
});
|
|
7729
7991
|
const wafSettingsConfig = props.waf;
|
|
@@ -9085,20 +9347,20 @@ import wildstring4 from "wildstring";
|
|
|
9085
9347
|
// src/cli/ui/complex/run-tests.ts
|
|
9086
9348
|
import { log as log18 } from "@awsless/clui";
|
|
9087
9349
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
|
|
9088
|
-
import { join as
|
|
9350
|
+
import { join as join19 } from "path";
|
|
9089
9351
|
import wildstring3 from "wildstring";
|
|
9090
9352
|
import { parse as parse4, stringify } from "@awsless/json";
|
|
9091
9353
|
import { generateFolderHash, loadWorkspace as loadWorkspace2 } from "@awsless/ts-file-cache";
|
|
9092
9354
|
|
|
9093
9355
|
// src/test/start.ts
|
|
9094
|
-
import { dirname as dirname9, join as
|
|
9356
|
+
import { dirname as dirname9, join as join18 } from "path";
|
|
9095
9357
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
9096
9358
|
import { configDefaults } from "vitest/config";
|
|
9097
9359
|
import { startVitest } from "vitest/node";
|
|
9098
9360
|
var NullReporter = class {
|
|
9099
9361
|
};
|
|
9100
9362
|
var startTest = async (props) => {
|
|
9101
|
-
const
|
|
9363
|
+
const __dirname5 = dirname9(fileURLToPath4(import.meta.url));
|
|
9102
9364
|
const startTime = process.hrtime.bigint();
|
|
9103
9365
|
process.noDeprecation = true;
|
|
9104
9366
|
const vitest = await startVitest(
|
|
@@ -9129,7 +9391,7 @@ var startTest = async (props) => {
|
|
|
9129
9391
|
// },
|
|
9130
9392
|
setupFiles: [
|
|
9131
9393
|
//
|
|
9132
|
-
|
|
9394
|
+
join18(__dirname5, "test-global-setup.js")
|
|
9133
9395
|
]
|
|
9134
9396
|
// globalSetup: [
|
|
9135
9397
|
// //
|
|
@@ -9323,7 +9585,7 @@ var logTestErrors = (event) => {
|
|
|
9323
9585
|
};
|
|
9324
9586
|
var runTest = async (stack, dir, filters, workspace, opts) => {
|
|
9325
9587
|
await mkdir4(directories.test, { recursive: true });
|
|
9326
|
-
const file =
|
|
9588
|
+
const file = join19(directories.test, `${stack}.json`);
|
|
9327
9589
|
const fingerprint = await generateFolderHash(workspace, dir);
|
|
9328
9590
|
if (!process.env.NO_CACHE) {
|
|
9329
9591
|
const exists = await fileExist(file);
|
|
@@ -10008,7 +10270,7 @@ import { log as log25 } from "@awsless/clui";
|
|
|
10008
10270
|
|
|
10009
10271
|
// src/type-gen/generate.ts
|
|
10010
10272
|
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
10011
|
-
import { dirname as dirname10, join as
|
|
10273
|
+
import { dirname as dirname10, join as join20, relative as relative8 } from "path";
|
|
10012
10274
|
var generateTypes = async (props) => {
|
|
10013
10275
|
const files = [];
|
|
10014
10276
|
await Promise.all(
|
|
@@ -10017,7 +10279,7 @@ var generateTypes = async (props) => {
|
|
|
10017
10279
|
...props,
|
|
10018
10280
|
async write(file, data, include = false) {
|
|
10019
10281
|
const code = data?.toString("utf8");
|
|
10020
|
-
const path =
|
|
10282
|
+
const path = join20(directories.types, file);
|
|
10021
10283
|
if (code) {
|
|
10022
10284
|
if (include) {
|
|
10023
10285
|
files.push(relative8(directories.root, path));
|
|
@@ -10031,7 +10293,7 @@ var generateTypes = async (props) => {
|
|
|
10031
10293
|
);
|
|
10032
10294
|
if (files.length) {
|
|
10033
10295
|
const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
|
|
10034
|
-
await writeFile4(
|
|
10296
|
+
await writeFile4(join20(directories.root, `awsless.d.ts`), code);
|
|
10035
10297
|
}
|
|
10036
10298
|
};
|
|
10037
10299
|
|