@awsless/awsless 0.0.653 → 0.0.655
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 +961 -711
- package/dist/build-json-schema.js +288 -272
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -2
- 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 +12 -12
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 z29 } from "zod";
|
|
943
943
|
|
|
944
944
|
// src/feature/alert/schema.ts
|
|
945
945
|
import { kebabCase } from "change-case";
|
|
@@ -1304,39 +1304,50 @@ var LayerSchema = z17.record(
|
|
|
1304
1304
|
).optional().describe("Define the lambda layers in your stack.");
|
|
1305
1305
|
|
|
1306
1306
|
// src/feature/on-failure/schema.ts
|
|
1307
|
-
|
|
1307
|
+
import { z as z18 } from "zod";
|
|
1308
|
+
var NotifySchema = z18.union([
|
|
1309
|
+
//
|
|
1310
|
+
EmailSchema.transform((v) => [v]),
|
|
1311
|
+
EmailSchema.array()
|
|
1312
|
+
]).describe("Receive an email notification when consuming failure entries goes wrong.");
|
|
1313
|
+
var OnFailureDefaultSchema = z18.object({
|
|
1314
|
+
consumer: FunctionSchema,
|
|
1315
|
+
notify: NotifySchema.optional()
|
|
1316
|
+
}).optional().describe(
|
|
1308
1317
|
[
|
|
1309
1318
|
"Defining a onFailure handler will add a global onFailure handler for the following resources:",
|
|
1310
|
-
"-
|
|
1311
|
-
"-
|
|
1312
|
-
"-
|
|
1313
|
-
"-
|
|
1319
|
+
"- Tasks",
|
|
1320
|
+
"- Crons",
|
|
1321
|
+
"- Queues",
|
|
1322
|
+
"- Topics",
|
|
1323
|
+
"- Pubsub",
|
|
1324
|
+
"- Table streams"
|
|
1314
1325
|
].join("\n")
|
|
1315
1326
|
);
|
|
1316
1327
|
|
|
1317
1328
|
// src/feature/on-log/schema.ts
|
|
1318
|
-
import { z as
|
|
1319
|
-
var FilterSchema =
|
|
1320
|
-
var OnLogDefaultSchema =
|
|
1329
|
+
import { z as z19 } from "zod";
|
|
1330
|
+
var FilterSchema = z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).array().describe("The log level that will gets delivered to the consumer.");
|
|
1331
|
+
var OnLogDefaultSchema = z19.union([
|
|
1321
1332
|
FunctionSchema.transform((consumer) => ({
|
|
1322
1333
|
consumer,
|
|
1323
1334
|
filter: ["error", "fatal"]
|
|
1324
1335
|
})),
|
|
1325
|
-
|
|
1336
|
+
z19.object({
|
|
1326
1337
|
consumer: FunctionSchema,
|
|
1327
1338
|
filter: FilterSchema
|
|
1328
1339
|
})
|
|
1329
1340
|
]).optional().describe("Define a subscription on all Lambda functions logs.");
|
|
1330
1341
|
|
|
1331
1342
|
// src/feature/pubsub/schema.ts
|
|
1332
|
-
import { z as
|
|
1343
|
+
import { z as z20 } from "zod";
|
|
1333
1344
|
var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
|
|
1334
|
-
var PubSubDefaultSchema =
|
|
1345
|
+
var PubSubDefaultSchema = z20.record(
|
|
1335
1346
|
ResourceIdSchema,
|
|
1336
|
-
|
|
1347
|
+
z20.object({
|
|
1337
1348
|
auth: FunctionSchema,
|
|
1338
1349
|
domain: DomainSchema.optional(),
|
|
1339
|
-
subDomain:
|
|
1350
|
+
subDomain: z20.string().optional()
|
|
1340
1351
|
// auth: z.union([
|
|
1341
1352
|
// ResourceIdSchema,
|
|
1342
1353
|
// z.object({
|
|
@@ -1352,11 +1363,11 @@ var PubSubDefaultSchema = z19.record(
|
|
|
1352
1363
|
// .optional(),
|
|
1353
1364
|
})
|
|
1354
1365
|
).optional().describe("Define the pubsub subscriber in your stack.");
|
|
1355
|
-
var PubSubSchema =
|
|
1366
|
+
var PubSubSchema = z20.record(
|
|
1356
1367
|
ResourceIdSchema,
|
|
1357
|
-
|
|
1358
|
-
sql:
|
|
1359
|
-
sqlVersion:
|
|
1368
|
+
z20.object({
|
|
1369
|
+
sql: z20.string().describe("The SQL statement used to query the IOT topic."),
|
|
1370
|
+
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."),
|
|
1360
1371
|
consumer: FunctionSchema.describe("The consuming lambda function properties.")
|
|
1361
1372
|
})
|
|
1362
1373
|
).optional().describe("Define the pubsub subscriber in your stack.");
|
|
@@ -1364,7 +1375,7 @@ var PubSubSchema = z19.record(
|
|
|
1364
1375
|
// src/feature/queue/schema.ts
|
|
1365
1376
|
import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
|
|
1366
1377
|
import { kibibytes } from "@awsless/size";
|
|
1367
|
-
import { z as
|
|
1378
|
+
import { z as z21 } from "zod";
|
|
1368
1379
|
var RetentionPeriodSchema = DurationSchema.refine(
|
|
1369
1380
|
durationMin(minutes2(1)),
|
|
1370
1381
|
"Minimum retention period is 1 minute"
|
|
@@ -1392,10 +1403,10 @@ var ReceiveMessageWaitTimeSchema = DurationSchema.refine(
|
|
|
1392
1403
|
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
1404
|
"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
1405
|
);
|
|
1395
|
-
var BatchSizeSchema =
|
|
1406
|
+
var BatchSizeSchema = z21.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
|
|
1396
1407
|
"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
1408
|
);
|
|
1398
|
-
var MaxConcurrencySchema =
|
|
1409
|
+
var MaxConcurrencySchema = z21.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
|
|
1399
1410
|
"Limits the number of concurrent instances that the queue worker can invoke. You can specify an integer from 2 to 1000."
|
|
1400
1411
|
);
|
|
1401
1412
|
var MaxBatchingWindow = DurationSchema.refine(
|
|
@@ -1404,7 +1415,10 @@ var MaxBatchingWindow = DurationSchema.refine(
|
|
|
1404
1415
|
).describe(
|
|
1405
1416
|
"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
1417
|
);
|
|
1407
|
-
var
|
|
1418
|
+
var RetryAttemptsSchema2 = z21.number().int().min(0).max(999).describe(
|
|
1419
|
+
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 999."
|
|
1420
|
+
);
|
|
1421
|
+
var QueueDefaultSchema = z21.object({
|
|
1408
1422
|
retentionPeriod: RetentionPeriodSchema.default("7 days"),
|
|
1409
1423
|
visibilityTimeout: VisibilityTimeoutSchema.default("30 seconds"),
|
|
1410
1424
|
deliveryDelay: DeliveryDelaySchema.default("0 seconds"),
|
|
@@ -1412,9 +1426,10 @@ var QueueDefaultSchema = z20.object({
|
|
|
1412
1426
|
maxMessageSize: MaxMessageSizeSchema.default("256 KB"),
|
|
1413
1427
|
batchSize: BatchSizeSchema.default(10),
|
|
1414
1428
|
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1415
|
-
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1429
|
+
maxBatchingWindow: MaxBatchingWindow.optional(),
|
|
1430
|
+
retryAttempts: RetryAttemptsSchema2.default(2)
|
|
1416
1431
|
}).default({});
|
|
1417
|
-
var QueueSchema =
|
|
1432
|
+
var QueueSchema = z21.object({
|
|
1418
1433
|
consumer: FunctionSchema.optional().describe("The consuming lambda function properties."),
|
|
1419
1434
|
retentionPeriod: RetentionPeriodSchema.optional(),
|
|
1420
1435
|
visibilityTimeout: VisibilityTimeoutSchema.optional(),
|
|
@@ -1423,11 +1438,12 @@ var QueueSchema = z20.object({
|
|
|
1423
1438
|
maxMessageSize: MaxMessageSizeSchema.optional(),
|
|
1424
1439
|
batchSize: BatchSizeSchema.optional(),
|
|
1425
1440
|
maxConcurrency: MaxConcurrencySchema.optional(),
|
|
1426
|
-
maxBatchingWindow: MaxBatchingWindow.optional()
|
|
1441
|
+
maxBatchingWindow: MaxBatchingWindow.optional(),
|
|
1442
|
+
retryAttempts: RetryAttemptsSchema2.optional()
|
|
1427
1443
|
});
|
|
1428
|
-
var QueuesSchema =
|
|
1444
|
+
var QueuesSchema = z21.record(
|
|
1429
1445
|
ResourceIdSchema,
|
|
1430
|
-
|
|
1446
|
+
z21.union([
|
|
1431
1447
|
LocalFileSchema.transform((consumer) => ({
|
|
1432
1448
|
consumer
|
|
1433
1449
|
})).pipe(QueueSchema),
|
|
@@ -1436,26 +1452,26 @@ var QueuesSchema = z20.record(
|
|
|
1436
1452
|
).optional().describe("Define the queues in your stack.");
|
|
1437
1453
|
|
|
1438
1454
|
// src/feature/rest/schema.ts
|
|
1439
|
-
import { z as
|
|
1455
|
+
import { z as z23 } from "zod";
|
|
1440
1456
|
|
|
1441
1457
|
// src/config/schema/route.ts
|
|
1442
|
-
import { z as
|
|
1443
|
-
var RouteSchema =
|
|
1444
|
-
|
|
1445
|
-
|
|
1458
|
+
import { z as z22 } from "zod";
|
|
1459
|
+
var RouteSchema = z22.union([
|
|
1460
|
+
z22.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS|ANY)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route"),
|
|
1461
|
+
z22.literal("$default")
|
|
1446
1462
|
]);
|
|
1447
1463
|
|
|
1448
1464
|
// src/feature/rest/schema.ts
|
|
1449
|
-
var RestDefaultSchema =
|
|
1465
|
+
var RestDefaultSchema = z23.record(
|
|
1450
1466
|
ResourceIdSchema,
|
|
1451
|
-
|
|
1467
|
+
z23.object({
|
|
1452
1468
|
domain: ResourceIdSchema.describe("The domain id to link your API with.").optional(),
|
|
1453
|
-
subDomain:
|
|
1469
|
+
subDomain: z23.string().optional()
|
|
1454
1470
|
})
|
|
1455
1471
|
).optional().describe("Define your global REST API's.");
|
|
1456
|
-
var RestSchema =
|
|
1472
|
+
var RestSchema = z23.record(
|
|
1457
1473
|
ResourceIdSchema,
|
|
1458
|
-
|
|
1474
|
+
z23.record(
|
|
1459
1475
|
RouteSchema.describe(
|
|
1460
1476
|
[
|
|
1461
1477
|
"The REST API route that is comprised by the http method and http path.",
|
|
@@ -1469,19 +1485,19 @@ var RestSchema = z22.record(
|
|
|
1469
1485
|
|
|
1470
1486
|
// src/feature/rpc/schema.ts
|
|
1471
1487
|
import { minutes as minutes4, seconds as seconds3 } from "@awsless/duration";
|
|
1472
|
-
import { z as
|
|
1488
|
+
import { z as z25 } from "zod";
|
|
1473
1489
|
|
|
1474
1490
|
// src/feature/router/schema.ts
|
|
1475
1491
|
import { days as days3, minutes as minutes3, parse as parse3 } from "@awsless/duration";
|
|
1476
|
-
import { z as
|
|
1477
|
-
var ErrorResponsePathSchema =
|
|
1492
|
+
import { z as z24 } from "zod";
|
|
1493
|
+
var ErrorResponsePathSchema = z24.string().describe(
|
|
1478
1494
|
[
|
|
1479
1495
|
"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
1496
|
"- We recommend that you store custom error pages in an Amazon S3 bucket.",
|
|
1481
1497
|
"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
1498
|
].join("\n")
|
|
1483
1499
|
);
|
|
1484
|
-
var StatusCodeSchema =
|
|
1500
|
+
var StatusCodeSchema = z24.number().int().positive().optional().describe(
|
|
1485
1501
|
[
|
|
1486
1502
|
"The HTTP status code that you want CloudFront to return to the viewer along with the custom error page.",
|
|
1487
1503
|
"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 +1510,26 @@ var StatusCodeSchema = z23.number().int().positive().optional().describe(
|
|
|
1494
1510
|
var MinTTLSchema = DurationSchema.describe(
|
|
1495
1511
|
"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
1512
|
);
|
|
1497
|
-
var ErrorResponseSchema =
|
|
1513
|
+
var ErrorResponseSchema = z24.union([
|
|
1498
1514
|
ErrorResponsePathSchema,
|
|
1499
|
-
|
|
1515
|
+
z24.object({
|
|
1500
1516
|
path: ErrorResponsePathSchema,
|
|
1501
1517
|
statusCode: StatusCodeSchema.optional(),
|
|
1502
1518
|
minTTL: MinTTLSchema.optional()
|
|
1503
1519
|
})
|
|
1504
1520
|
]).optional();
|
|
1505
|
-
var RouteSchema2 =
|
|
1506
|
-
var VisibilitySchema =
|
|
1507
|
-
var WafSettingsSchema =
|
|
1508
|
-
rateLimiter:
|
|
1509
|
-
limit:
|
|
1521
|
+
var RouteSchema2 = z24.string().regex(/^\//, "Route must start with a slash (/)");
|
|
1522
|
+
var VisibilitySchema = z24.boolean().default(false).describe("Whether to enable CloudWatch metrics for the WAF rule.");
|
|
1523
|
+
var WafSettingsSchema = z24.object({
|
|
1524
|
+
rateLimiter: z24.object({
|
|
1525
|
+
limit: z24.number().min(10).max(2e9).default(10).describe(
|
|
1510
1526
|
"The limit on requests during the specified evaluation window for a single aggregation instance for the rate-based rule."
|
|
1511
1527
|
),
|
|
1512
|
-
window:
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1528
|
+
window: z24.union([
|
|
1529
|
+
z24.literal("1 minute"),
|
|
1530
|
+
z24.literal("2 minutes"),
|
|
1531
|
+
z24.literal("5 minutes"),
|
|
1532
|
+
z24.literal("10 minutes")
|
|
1517
1533
|
]).default("5 minutes").transform((v) => parse3(v)).describe(
|
|
1518
1534
|
"The amount of time, in seconds, that AWS WAF should include in its request counts, looking back from the current time."
|
|
1519
1535
|
),
|
|
@@ -1521,18 +1537,18 @@ var WafSettingsSchema = z23.object({
|
|
|
1521
1537
|
}).optional().describe(
|
|
1522
1538
|
"A rate-based rule counts incoming requests and rate limits requests when they are coming at too fast a rate."
|
|
1523
1539
|
),
|
|
1524
|
-
ddosProtection:
|
|
1525
|
-
sensitivity:
|
|
1526
|
-
challenge:
|
|
1527
|
-
block:
|
|
1540
|
+
ddosProtection: z24.object({
|
|
1541
|
+
sensitivity: z24.object({
|
|
1542
|
+
challenge: z24.enum(["low", "medium", "high"]).default("low").transform((v) => v.toUpperCase()).describe("The sensitivity level for challenge requests."),
|
|
1543
|
+
block: z24.enum(["low", "medium", "high"]).default("low").transform((v) => v.toUpperCase()).describe("The sensitivity level for block requests.")
|
|
1528
1544
|
}),
|
|
1529
|
-
exemptUriRegex:
|
|
1545
|
+
exemptUriRegex: z24.string().default("^$"),
|
|
1530
1546
|
visibility: VisibilitySchema
|
|
1531
1547
|
}).optional().describe(
|
|
1532
1548
|
"Provides protection against DDoS attacks targeting the application layer, also known as Layer 7 attacks. Uses 50 WCU."
|
|
1533
1549
|
),
|
|
1534
|
-
botProtection:
|
|
1535
|
-
inspectionLevel:
|
|
1550
|
+
botProtection: z24.object({
|
|
1551
|
+
inspectionLevel: z24.enum(["common", "targeted"]).default("common").transform((v) => v.toUpperCase()),
|
|
1536
1552
|
visibility: VisibilitySchema
|
|
1537
1553
|
}).optional().describe(
|
|
1538
1554
|
"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 +1562,14 @@ var WafSettingsSchema = z23.object({
|
|
|
1546
1562
|
}).describe(
|
|
1547
1563
|
"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
1564
|
);
|
|
1549
|
-
var RouterDefaultSchema =
|
|
1565
|
+
var RouterDefaultSchema = z24.record(
|
|
1550
1566
|
ResourceIdSchema,
|
|
1551
|
-
|
|
1567
|
+
z24.object({
|
|
1552
1568
|
domain: ResourceIdSchema.describe("The domain id to link your Router.").optional(),
|
|
1553
|
-
subDomain:
|
|
1569
|
+
subDomain: z24.string().optional(),
|
|
1554
1570
|
waf: WafSettingsSchema.optional(),
|
|
1555
|
-
geoRestrictions:
|
|
1556
|
-
errors:
|
|
1571
|
+
geoRestrictions: z24.array(z24.string().length(2).toUpperCase()).default([]).describe("Specifies a blacklist of countries that should be blocked."),
|
|
1572
|
+
errors: z24.object({
|
|
1557
1573
|
400: ErrorResponseSchema.describe("Customize a `400 Bad Request` response."),
|
|
1558
1574
|
403: ErrorResponseSchema.describe("Customize a `403 Forbidden` response."),
|
|
1559
1575
|
404: ErrorResponseSchema.describe("Customize a `404 Not Found` response."),
|
|
@@ -1566,19 +1582,22 @@ var RouterDefaultSchema = z23.record(
|
|
|
1566
1582
|
503: ErrorResponseSchema.describe("Customize a `503 Service Unavailable` response."),
|
|
1567
1583
|
504: ErrorResponseSchema.describe("Customize a `504 Gateway Timeout` response.")
|
|
1568
1584
|
}).optional().describe("Customize the error responses for specific HTTP status codes."),
|
|
1569
|
-
cors:
|
|
1570
|
-
override:
|
|
1585
|
+
cors: z24.object({
|
|
1586
|
+
override: z24.boolean().default(false),
|
|
1571
1587
|
maxAge: DurationSchema.default("365 days"),
|
|
1572
|
-
exposeHeaders:
|
|
1573
|
-
credentials:
|
|
1574
|
-
headers:
|
|
1575
|
-
origins:
|
|
1576
|
-
methods:
|
|
1588
|
+
exposeHeaders: z24.string().array().optional(),
|
|
1589
|
+
credentials: z24.boolean().default(false),
|
|
1590
|
+
headers: z24.string().array().default(["*"]),
|
|
1591
|
+
origins: z24.string().array().default(["*"]),
|
|
1592
|
+
methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
|
|
1577
1593
|
}).optional().describe("Specify the cors headers."),
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1594
|
+
passwordAuth: z24.object({
|
|
1595
|
+
password: z24.string().describe("Password.")
|
|
1596
|
+
}).optional().describe("Enable password authentication for the router."),
|
|
1597
|
+
basicAuth: z24.object({
|
|
1598
|
+
username: z24.string().describe("Basic auth username."),
|
|
1599
|
+
password: z24.string().describe("Basic auth password.")
|
|
1600
|
+
}).optional().describe("Enable basic authentication for the router."),
|
|
1582
1601
|
// security: z
|
|
1583
1602
|
// .object({
|
|
1584
1603
|
// contentSecurityPolicy: z.object({
|
|
@@ -1624,10 +1643,10 @@ var RouterDefaultSchema = z23.record(
|
|
|
1624
1643
|
// })
|
|
1625
1644
|
// .optional()
|
|
1626
1645
|
// .describe('Specify the security policy.'),
|
|
1627
|
-
cache:
|
|
1628
|
-
cookies:
|
|
1629
|
-
headers:
|
|
1630
|
-
queries:
|
|
1646
|
+
cache: z24.object({
|
|
1647
|
+
cookies: z24.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
|
|
1648
|
+
headers: z24.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
|
|
1649
|
+
queries: z24.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
|
|
1631
1650
|
}).optional().describe(
|
|
1632
1651
|
"Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
|
|
1633
1652
|
)
|
|
@@ -1642,9 +1661,9 @@ var TimeoutSchema2 = DurationSchema.refine(durationMin(seconds3(10)), "Minimum t
|
|
|
1642
1661
|
"The timeouts of all inner RPC functions will be capped at 80% of this timeout."
|
|
1643
1662
|
].join(" ")
|
|
1644
1663
|
);
|
|
1645
|
-
var RpcDefaultSchema =
|
|
1664
|
+
var RpcDefaultSchema = z25.record(
|
|
1646
1665
|
ResourceIdSchema,
|
|
1647
|
-
|
|
1666
|
+
z25.object({
|
|
1648
1667
|
// domain: ResourceIdSchema.describe('The domain id to link your RPC API with.').optional(),
|
|
1649
1668
|
// subDomain: z.string().optional(),
|
|
1650
1669
|
//
|
|
@@ -1655,18 +1674,18 @@ var RpcDefaultSchema = z24.record(
|
|
|
1655
1674
|
timeout: TimeoutSchema2.default("1 minutes")
|
|
1656
1675
|
})
|
|
1657
1676
|
).describe(`Define the global RPC API's.`).optional();
|
|
1658
|
-
var RpcSchema =
|
|
1677
|
+
var RpcSchema = z25.record(
|
|
1659
1678
|
ResourceIdSchema,
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1679
|
+
z25.record(
|
|
1680
|
+
z25.string(),
|
|
1681
|
+
z25.union([
|
|
1663
1682
|
FunctionSchema.transform((f) => ({
|
|
1664
1683
|
function: f,
|
|
1665
1684
|
lock: false
|
|
1666
1685
|
})),
|
|
1667
|
-
|
|
1686
|
+
z25.object({
|
|
1668
1687
|
function: FunctionSchema.describe("The RPC function to execute."),
|
|
1669
|
-
lock:
|
|
1688
|
+
lock: z25.boolean().describe(
|
|
1670
1689
|
[
|
|
1671
1690
|
"Specify if the function should be locked on the `lockKey` returned from the auth function.",
|
|
1672
1691
|
"An example would be returning the user ID as `lockKey`."
|
|
@@ -1680,8 +1699,8 @@ var RpcSchema = z24.record(
|
|
|
1680
1699
|
// src/feature/instance/schema.ts
|
|
1681
1700
|
import { days as days4, toDays as toDays2 } from "@awsless/duration";
|
|
1682
1701
|
import { toMebibytes } from "@awsless/size";
|
|
1683
|
-
import { z as
|
|
1684
|
-
var CpuSchema =
|
|
1702
|
+
import { z as z26 } from "zod";
|
|
1703
|
+
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
1704
|
"The number of virtual CPU units (vCPU) used by the instance. Valid values: 0.25, 0.5, 1, 2, 4, 8, 16 vCPU."
|
|
1686
1705
|
);
|
|
1687
1706
|
var validMemorySize = [
|
|
@@ -1721,10 +1740,10 @@ var MemorySizeSchema2 = SizeSchema.refine(
|
|
|
1721
1740
|
(s) => validMemorySize.includes(toMebibytes(s)),
|
|
1722
1741
|
`Invalid memory size. Allowed sizes: ${validMemorySize.join(", ")} MiB`
|
|
1723
1742
|
).describe("The amount of memory (in MiB) used by the instance. Valid memory values depend on the CPU configuration.");
|
|
1724
|
-
var HealthCheckSchema =
|
|
1725
|
-
path:
|
|
1743
|
+
var HealthCheckSchema = z26.object({
|
|
1744
|
+
path: z26.string().describe("The path that the container runs to determine if it is healthy."),
|
|
1726
1745
|
interval: DurationSchema.describe("The time period in seconds between each health check execution."),
|
|
1727
|
-
retries:
|
|
1746
|
+
retries: z26.number().int().min(1).max(10).describe(
|
|
1728
1747
|
"The number of times to retry a failed health check before the container is considered unhealthy."
|
|
1729
1748
|
),
|
|
1730
1749
|
startPeriod: DurationSchema.describe(
|
|
@@ -1734,22 +1753,22 @@ var HealthCheckSchema = z25.object({
|
|
|
1734
1753
|
"The time period in seconds to wait for a health check to succeed before it is considered a failure."
|
|
1735
1754
|
)
|
|
1736
1755
|
}).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:
|
|
1756
|
+
var EnvironmentSchema2 = z26.record(z26.string(), z26.string()).optional().describe("Environment variable key-value pairs.");
|
|
1757
|
+
var ArchitectureSchema3 = z26.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the instance supports.");
|
|
1758
|
+
var ActionSchema2 = z26.string();
|
|
1759
|
+
var ActionsSchema2 = z26.union([ActionSchema2.transform((v) => [v]), ActionSchema2.array()]);
|
|
1760
|
+
var ArnSchema2 = z26.string().startsWith("arn:");
|
|
1761
|
+
var WildcardSchema2 = z26.literal("*");
|
|
1762
|
+
var ResourceSchema2 = z26.union([ArnSchema2, WildcardSchema2]);
|
|
1763
|
+
var ResourcesSchema2 = z26.union([ResourceSchema2.transform((v) => [v]), ResourceSchema2.array()]);
|
|
1764
|
+
var PermissionSchema2 = z26.object({
|
|
1765
|
+
effect: z26.enum(["allow", "deny"]).default("allow"),
|
|
1747
1766
|
actions: ActionsSchema2,
|
|
1748
1767
|
resources: ResourcesSchema2
|
|
1749
1768
|
});
|
|
1750
|
-
var PermissionsSchema2 =
|
|
1751
|
-
var DescriptionSchema2 =
|
|
1752
|
-
var ImageSchema =
|
|
1769
|
+
var PermissionsSchema2 = z26.union([PermissionSchema2.transform((v) => [v]), PermissionSchema2.array()]).describe("Add IAM permissions to your instance.");
|
|
1770
|
+
var DescriptionSchema2 = z26.string().describe("A description of the instance.");
|
|
1771
|
+
var ImageSchema = z26.string().optional().describe("The URL of the container image to use.");
|
|
1753
1772
|
var validLogRetentionDays2 = [
|
|
1754
1773
|
...[1, 3, 5, 7, 14, 30, 60, 90, 120, 150],
|
|
1755
1774
|
...[180, 365, 400, 545, 731, 1096, 1827, 2192],
|
|
@@ -1764,23 +1783,23 @@ var LogRetentionSchema2 = DurationSchema.refine(
|
|
|
1764
1783
|
},
|
|
1765
1784
|
`Invalid log retention. Valid days are: ${validLogRetentionDays2.map((days8) => `${days8}`).join(", ")}`
|
|
1766
1785
|
).describe("The log retention duration.");
|
|
1767
|
-
var LogSchema2 =
|
|
1768
|
-
|
|
1786
|
+
var LogSchema2 = z26.union([
|
|
1787
|
+
z26.boolean().transform((enabled) => ({ retention: enabled ? days4(7) : days4(0) })),
|
|
1769
1788
|
LogRetentionSchema2.transform((retention) => ({ retention })),
|
|
1770
|
-
|
|
1789
|
+
z26.object({
|
|
1771
1790
|
retention: LogRetentionSchema2.optional()
|
|
1772
1791
|
})
|
|
1773
1792
|
]).describe("Enable logging to a CloudWatch log group. Providing a duration value will set the log retention time.");
|
|
1774
|
-
var FileCodeSchema2 =
|
|
1793
|
+
var FileCodeSchema2 = z26.object({
|
|
1775
1794
|
file: LocalFileSchema.describe("The file path of the instance code.")
|
|
1776
1795
|
});
|
|
1777
|
-
var CodeSchema2 =
|
|
1796
|
+
var CodeSchema2 = z26.union([
|
|
1778
1797
|
LocalFileSchema.transform((file) => ({
|
|
1779
1798
|
file
|
|
1780
1799
|
})).pipe(FileCodeSchema2),
|
|
1781
1800
|
FileCodeSchema2
|
|
1782
1801
|
]).describe("Specify the code of your instance.");
|
|
1783
|
-
var ISchema =
|
|
1802
|
+
var ISchema = z26.object({
|
|
1784
1803
|
code: CodeSchema2,
|
|
1785
1804
|
description: DescriptionSchema2.optional(),
|
|
1786
1805
|
image: ImageSchema.optional(),
|
|
@@ -1793,14 +1812,14 @@ var ISchema = z25.object({
|
|
|
1793
1812
|
healthCheck: HealthCheckSchema.optional()
|
|
1794
1813
|
// restartPolicy: RestartPolicySchema.optional(),
|
|
1795
1814
|
});
|
|
1796
|
-
var InstanceSchema =
|
|
1815
|
+
var InstanceSchema = z26.union([
|
|
1797
1816
|
LocalFileSchema.transform((code) => ({
|
|
1798
1817
|
code
|
|
1799
1818
|
})).pipe(ISchema),
|
|
1800
1819
|
ISchema
|
|
1801
1820
|
]);
|
|
1802
|
-
var InstancesSchema =
|
|
1803
|
-
var InstanceDefaultSchema =
|
|
1821
|
+
var InstancesSchema = z26.record(ResourceIdSchema, InstanceSchema).optional().describe("Define the instances in your stack.");
|
|
1822
|
+
var InstanceDefaultSchema = z26.object({
|
|
1804
1823
|
image: ImageSchema.optional(),
|
|
1805
1824
|
cpu: CpuSchema.default(0.25),
|
|
1806
1825
|
memorySize: MemorySizeSchema2.default("512 MB"),
|
|
@@ -1816,15 +1835,15 @@ var InstanceDefaultSchema = z25.object({
|
|
|
1816
1835
|
|
|
1817
1836
|
// src/feature/topic/schema.ts
|
|
1818
1837
|
import { kebabCase as kebabCase3 } from "change-case";
|
|
1819
|
-
import { z as
|
|
1820
|
-
var TopicNameSchema =
|
|
1821
|
-
var TopicsDefaultSchema =
|
|
1838
|
+
import { z as z27 } from "zod";
|
|
1839
|
+
var TopicNameSchema = z27.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => kebabCase3(value)).describe("Define event topic name.");
|
|
1840
|
+
var TopicsDefaultSchema = z27.array(TopicNameSchema).refine((topics) => {
|
|
1822
1841
|
return topics.length === new Set(topics).size;
|
|
1823
1842
|
}, "Must be a list of unique topic names").optional().describe("Define the event topics for your app.");
|
|
1824
|
-
var SubscribersSchema =
|
|
1843
|
+
var SubscribersSchema = z27.record(TopicNameSchema, FunctionSchema).optional().describe("Define the event topics to subscribe too in your stack.");
|
|
1825
1844
|
|
|
1826
1845
|
// src/config/schema/region.ts
|
|
1827
|
-
import { z as
|
|
1846
|
+
import { z as z28 } from "zod";
|
|
1828
1847
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
1829
1848
|
var AF = ["af-south-1"];
|
|
1830
1849
|
var AP = [
|
|
@@ -1853,16 +1872,16 @@ var EU = [
|
|
|
1853
1872
|
var ME = ["me-south-1", "me-central-1"];
|
|
1854
1873
|
var SA = ["sa-east-1"];
|
|
1855
1874
|
var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
|
|
1856
|
-
var RegionSchema =
|
|
1875
|
+
var RegionSchema = z28.enum(regions);
|
|
1857
1876
|
|
|
1858
1877
|
// src/config/app.ts
|
|
1859
|
-
var AppSchema =
|
|
1860
|
-
$schema:
|
|
1878
|
+
var AppSchema = z29.object({
|
|
1879
|
+
$schema: z29.string().optional(),
|
|
1861
1880
|
name: ResourceIdSchema.describe("App name."),
|
|
1862
1881
|
region: RegionSchema.describe("The AWS region to deploy to."),
|
|
1863
|
-
profile:
|
|
1864
|
-
protect:
|
|
1865
|
-
removal:
|
|
1882
|
+
profile: z29.string().describe("The AWS profile to deploy to."),
|
|
1883
|
+
protect: z29.boolean().default(false).describe("Protect your app & stacks from being deleted."),
|
|
1884
|
+
removal: z29.enum(["remove", "retain"]).default("remove").describe(
|
|
1866
1885
|
[
|
|
1867
1886
|
"Configure how your resources are handled when they have to be removed.",
|
|
1868
1887
|
"",
|
|
@@ -1876,7 +1895,7 @@ var AppSchema = z28.object({
|
|
|
1876
1895
|
// .default('prod')
|
|
1877
1896
|
// .describe('The deployment stage.'),
|
|
1878
1897
|
// onFailure: OnFailureSchema,
|
|
1879
|
-
defaults:
|
|
1898
|
+
defaults: z29.object({
|
|
1880
1899
|
onFailure: OnFailureDefaultSchema,
|
|
1881
1900
|
onLog: OnLogDefaultSchema,
|
|
1882
1901
|
auth: AuthDefaultSchema,
|
|
@@ -1900,11 +1919,11 @@ var AppSchema = z28.object({
|
|
|
1900
1919
|
});
|
|
1901
1920
|
|
|
1902
1921
|
// src/config/stack.ts
|
|
1903
|
-
import { z as
|
|
1922
|
+
import { z as z45 } from "zod";
|
|
1904
1923
|
|
|
1905
1924
|
// src/feature/cache/schema.ts
|
|
1906
1925
|
import { gibibytes as gibibytes2 } from "@awsless/size";
|
|
1907
|
-
import { z as
|
|
1926
|
+
import { z as z30 } from "zod";
|
|
1908
1927
|
var StorageSchema = SizeSchema.refine(sizeMin(gibibytes2(1)), "Minimum storage size is 1 GB").refine(
|
|
1909
1928
|
sizeMax(gibibytes2(5e3)),
|
|
1910
1929
|
"Maximum storage size is 5000 GB"
|
|
@@ -1915,31 +1934,31 @@ var MinimumStorageSchema = StorageSchema.describe(
|
|
|
1915
1934
|
var MaximumStorageSchema = StorageSchema.describe(
|
|
1916
1935
|
"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
1936
|
);
|
|
1918
|
-
var EcpuSchema =
|
|
1937
|
+
var EcpuSchema = z30.number().int().min(1e3).max(15e6);
|
|
1919
1938
|
var MinimumEcpuSchema = EcpuSchema.describe(
|
|
1920
1939
|
"The minimum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1921
1940
|
);
|
|
1922
1941
|
var MaximumEcpuSchema = EcpuSchema.describe(
|
|
1923
1942
|
"The maximum number of ECPUs the cache can consume per second. You can specify a integer from 1,000 to 15,000,000."
|
|
1924
1943
|
);
|
|
1925
|
-
var CachesSchema =
|
|
1944
|
+
var CachesSchema = z30.record(
|
|
1926
1945
|
ResourceIdSchema,
|
|
1927
|
-
|
|
1946
|
+
z30.object({
|
|
1928
1947
|
minStorage: MinimumStorageSchema.optional(),
|
|
1929
1948
|
maxStorage: MaximumStorageSchema.optional(),
|
|
1930
1949
|
minECPU: MinimumEcpuSchema.optional(),
|
|
1931
1950
|
maxECPU: MaximumEcpuSchema.optional(),
|
|
1932
|
-
snapshotRetentionLimit:
|
|
1951
|
+
snapshotRetentionLimit: z30.number().int().positive().default(1)
|
|
1933
1952
|
})
|
|
1934
1953
|
).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
|
|
1935
1954
|
|
|
1936
1955
|
// src/feature/command/schema.ts
|
|
1937
|
-
import { z as
|
|
1938
|
-
var CommandSchema =
|
|
1939
|
-
|
|
1956
|
+
import { z as z31 } from "zod";
|
|
1957
|
+
var CommandSchema = z31.union([
|
|
1958
|
+
z31.object({
|
|
1940
1959
|
file: LocalFileSchema,
|
|
1941
|
-
handler:
|
|
1942
|
-
description:
|
|
1960
|
+
handler: z31.string().default("default").describe("The name of the handler that needs to run"),
|
|
1961
|
+
description: z31.string().optional().describe("A description of the command")
|
|
1943
1962
|
// options: z.record(ResourceIdSchema, OptionSchema).optional(),
|
|
1944
1963
|
// arguments: z.record(ResourceIdSchema, ArgumentSchema).optional(),
|
|
1945
1964
|
}),
|
|
@@ -1949,22 +1968,22 @@ var CommandSchema = z30.union([
|
|
|
1949
1968
|
description: void 0
|
|
1950
1969
|
}))
|
|
1951
1970
|
]);
|
|
1952
|
-
var CommandsSchema =
|
|
1971
|
+
var CommandsSchema = z31.record(ResourceIdSchema, CommandSchema).optional().describe("Define the custom commands for your stack.");
|
|
1953
1972
|
|
|
1954
1973
|
// src/feature/config/schema.ts
|
|
1955
|
-
import { z as
|
|
1956
|
-
var ConfigNameSchema =
|
|
1957
|
-
var ConfigsSchema =
|
|
1974
|
+
import { z as z32 } from "zod";
|
|
1975
|
+
var ConfigNameSchema = z32.string().regex(/[a-z0-9\-]/g, "Invalid config name");
|
|
1976
|
+
var ConfigsSchema = z32.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
|
|
1958
1977
|
|
|
1959
1978
|
// src/feature/cron/schema/index.ts
|
|
1960
|
-
import { z as
|
|
1979
|
+
import { z as z34 } from "zod";
|
|
1961
1980
|
|
|
1962
1981
|
// src/feature/cron/schema/schedule.ts
|
|
1963
|
-
import { z as
|
|
1982
|
+
import { z as z33 } from "zod";
|
|
1964
1983
|
import { awsCronExpressionValidator } from "aws-cron-expression-validator";
|
|
1965
|
-
var RateExpressionSchema =
|
|
1984
|
+
var RateExpressionSchema = z33.custom(
|
|
1966
1985
|
(value) => {
|
|
1967
|
-
return
|
|
1986
|
+
return z33.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
|
|
1968
1987
|
const [str] = rate.split(" ");
|
|
1969
1988
|
const number = parseInt(str);
|
|
1970
1989
|
return number > 0;
|
|
@@ -1980,9 +1999,9 @@ var RateExpressionSchema = z32.custom(
|
|
|
1980
1999
|
}
|
|
1981
2000
|
return `rate(${rate})`;
|
|
1982
2001
|
});
|
|
1983
|
-
var CronExpressionSchema =
|
|
2002
|
+
var CronExpressionSchema = z33.custom(
|
|
1984
2003
|
(value) => {
|
|
1985
|
-
return
|
|
2004
|
+
return z33.string().safeParse(value).success;
|
|
1986
2005
|
},
|
|
1987
2006
|
{ message: "Invalid cron expression" }
|
|
1988
2007
|
).superRefine((value, ctx) => {
|
|
@@ -1991,12 +2010,12 @@ var CronExpressionSchema = z32.custom(
|
|
|
1991
2010
|
} catch (error) {
|
|
1992
2011
|
if (error instanceof Error) {
|
|
1993
2012
|
ctx.addIssue({
|
|
1994
|
-
code:
|
|
2013
|
+
code: z33.ZodIssueCode.custom,
|
|
1995
2014
|
message: `Invalid cron expression: ${error.message}`
|
|
1996
2015
|
});
|
|
1997
2016
|
} else {
|
|
1998
2017
|
ctx.addIssue({
|
|
1999
|
-
code:
|
|
2018
|
+
code: z33.ZodIssueCode.custom,
|
|
2000
2019
|
message: "Invalid cron expression"
|
|
2001
2020
|
});
|
|
2002
2021
|
}
|
|
@@ -2007,28 +2026,28 @@ var CronExpressionSchema = z32.custom(
|
|
|
2007
2026
|
var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
|
|
2008
2027
|
|
|
2009
2028
|
// src/feature/cron/schema/index.ts
|
|
2010
|
-
var CronsSchema =
|
|
2029
|
+
var CronsSchema = z34.record(
|
|
2011
2030
|
ResourceIdSchema,
|
|
2012
|
-
|
|
2013
|
-
enabled:
|
|
2031
|
+
z34.object({
|
|
2032
|
+
enabled: z34.boolean().default(true).describe("If the cron is enabled."),
|
|
2014
2033
|
consumer: FunctionSchema.describe("The consuming lambda function properties."),
|
|
2015
2034
|
schedule: ScheduleExpressionSchema.describe(
|
|
2016
2035
|
'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
|
|
2017
2036
|
),
|
|
2018
|
-
payload:
|
|
2037
|
+
payload: z34.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
|
|
2019
2038
|
})
|
|
2020
2039
|
).optional().describe(`Define the cron jobs in your stack.`);
|
|
2021
2040
|
|
|
2022
2041
|
// src/feature/search/schema.ts
|
|
2023
2042
|
import { gibibytes as gibibytes3 } from "@awsless/size";
|
|
2024
|
-
import { z as
|
|
2025
|
-
var VersionSchema =
|
|
2043
|
+
import { z as z35 } from "zod";
|
|
2044
|
+
var VersionSchema = z35.union([
|
|
2026
2045
|
//
|
|
2027
|
-
|
|
2028
|
-
|
|
2046
|
+
z35.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]),
|
|
2047
|
+
z35.string()
|
|
2029
2048
|
]).describe("Specify the OpenSearch engine version.");
|
|
2030
|
-
var TypeSchema =
|
|
2031
|
-
|
|
2049
|
+
var TypeSchema = z35.union([
|
|
2050
|
+
z35.enum([
|
|
2032
2051
|
"t3.small",
|
|
2033
2052
|
"t3.medium",
|
|
2034
2053
|
"m3.medium",
|
|
@@ -2102,13 +2121,13 @@ var TypeSchema = z34.union([
|
|
|
2102
2121
|
"r6gd.12xlarge",
|
|
2103
2122
|
"r6gd.16xlarge"
|
|
2104
2123
|
]),
|
|
2105
|
-
|
|
2124
|
+
z35.string()
|
|
2106
2125
|
]).describe("Instance type of data nodes in the cluster.");
|
|
2107
|
-
var CountSchema =
|
|
2126
|
+
var CountSchema = z35.number().int().min(1).describe("Number of instances in the cluster.");
|
|
2108
2127
|
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 =
|
|
2128
|
+
var SearchsSchema = z35.record(
|
|
2110
2129
|
ResourceIdSchema,
|
|
2111
|
-
|
|
2130
|
+
z35.object({
|
|
2112
2131
|
type: TypeSchema.default("t3.small"),
|
|
2113
2132
|
count: CountSchema.default(1),
|
|
2114
2133
|
version: VersionSchema.default("2.13"),
|
|
@@ -2119,12 +2138,12 @@ var SearchsSchema = z34.record(
|
|
|
2119
2138
|
).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
|
|
2120
2139
|
|
|
2121
2140
|
// src/feature/site/schema.ts
|
|
2122
|
-
import { z as
|
|
2141
|
+
import { z as z37 } from "zod";
|
|
2123
2142
|
|
|
2124
2143
|
// src/config/schema/local-entry.ts
|
|
2125
2144
|
import { stat as stat3 } from "fs/promises";
|
|
2126
|
-
import { z as
|
|
2127
|
-
var LocalEntrySchema =
|
|
2145
|
+
import { z as z36 } from "zod";
|
|
2146
|
+
var LocalEntrySchema = z36.union([
|
|
2128
2147
|
RelativePathSchema.refine(async (path) => {
|
|
2129
2148
|
try {
|
|
2130
2149
|
const s = await stat3(path);
|
|
@@ -2133,7 +2152,7 @@ var LocalEntrySchema = z35.union([
|
|
|
2133
2152
|
return false;
|
|
2134
2153
|
}
|
|
2135
2154
|
}, `File or directory doesn't exist`),
|
|
2136
|
-
|
|
2155
|
+
z36.object({
|
|
2137
2156
|
nocheck: RelativePathSchema.describe(
|
|
2138
2157
|
"Specifies a local file or directory without checking if the file or directory exists."
|
|
2139
2158
|
)
|
|
@@ -2141,21 +2160,21 @@ var LocalEntrySchema = z35.union([
|
|
|
2141
2160
|
]);
|
|
2142
2161
|
|
|
2143
2162
|
// src/feature/site/schema.ts
|
|
2144
|
-
var SitesSchema =
|
|
2163
|
+
var SitesSchema = z37.record(
|
|
2145
2164
|
ResourceIdSchema,
|
|
2146
|
-
|
|
2165
|
+
z37.object({
|
|
2147
2166
|
router: ResourceIdSchema.describe("The router id to link your site with."),
|
|
2148
2167
|
path: RouteSchema2.describe("The path inside the router to link your site to."),
|
|
2149
|
-
build:
|
|
2150
|
-
command:
|
|
2168
|
+
build: z37.object({
|
|
2169
|
+
command: z37.string().describe(
|
|
2151
2170
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2152
2171
|
),
|
|
2153
|
-
cacheKey:
|
|
2172
|
+
cacheKey: z37.union([LocalEntrySchema.transform((v) => [v]), LocalEntrySchema.array()]).describe(
|
|
2154
2173
|
`Specifies the files and directories to generate the cache key for your custom build command.`
|
|
2155
2174
|
),
|
|
2156
|
-
configs:
|
|
2175
|
+
configs: z37.string().array().optional().describe("Define the config values for your build command.")
|
|
2157
2176
|
}).optional().describe(`Specifies the build process for sites that need a build step.`),
|
|
2158
|
-
static:
|
|
2177
|
+
static: z37.union([LocalDirectorySchema, z37.boolean()]).optional().describe(
|
|
2159
2178
|
"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
2179
|
),
|
|
2161
2180
|
ssr: FunctionSchema.optional().describe("Specifies the file that will render the site on the server.")
|
|
@@ -2163,21 +2182,21 @@ var SitesSchema = z36.record(
|
|
|
2163
2182
|
).optional().describe("Define the sites in your stack.");
|
|
2164
2183
|
|
|
2165
2184
|
// src/feature/store/schema.ts
|
|
2166
|
-
import { z as
|
|
2167
|
-
var StoresSchema =
|
|
2168
|
-
|
|
2185
|
+
import { z as z38 } from "zod";
|
|
2186
|
+
var StoresSchema = z38.union([
|
|
2187
|
+
z38.array(ResourceIdSchema).transform((list3) => {
|
|
2169
2188
|
const stores = {};
|
|
2170
2189
|
for (const key of list3) {
|
|
2171
2190
|
stores[key] = {};
|
|
2172
2191
|
}
|
|
2173
2192
|
return stores;
|
|
2174
2193
|
}),
|
|
2175
|
-
|
|
2194
|
+
z38.record(
|
|
2176
2195
|
ResourceIdSchema,
|
|
2177
|
-
|
|
2196
|
+
z38.object({
|
|
2178
2197
|
static: LocalDirectorySchema.optional().describe("Specifies the path to the static files directory."),
|
|
2179
|
-
versioning:
|
|
2180
|
-
events:
|
|
2198
|
+
versioning: z38.boolean().default(false).describe("Enable versioning of your store."),
|
|
2199
|
+
events: z38.object({
|
|
2181
2200
|
// create
|
|
2182
2201
|
"created:*": FunctionSchema.optional().describe(
|
|
2183
2202
|
"Subscribe to notifications regardless of the API that was used to create an object."
|
|
@@ -2210,30 +2229,30 @@ var StoresSchema = z37.union([
|
|
|
2210
2229
|
]).optional().describe("Define the stores in your stack.");
|
|
2211
2230
|
|
|
2212
2231
|
// src/feature/icon/schema.ts
|
|
2213
|
-
import { z as
|
|
2232
|
+
import { z as z39 } from "zod";
|
|
2214
2233
|
var staticOriginSchema = LocalDirectorySchema.describe(
|
|
2215
2234
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
2216
2235
|
);
|
|
2217
2236
|
var functionOriginSchema = FunctionSchema.describe(
|
|
2218
2237
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2219
2238
|
);
|
|
2220
|
-
var IconsSchema =
|
|
2239
|
+
var IconsSchema = z39.record(
|
|
2221
2240
|
ResourceIdSchema,
|
|
2222
|
-
|
|
2241
|
+
z39.object({
|
|
2223
2242
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2224
2243
|
// subDomain: z.string().optional(),
|
|
2225
2244
|
router: ResourceIdSchema.describe("The router id to link your icon proxy."),
|
|
2226
2245
|
path: RouteSchema2.describe("The path inside the router to link your icon proxy to."),
|
|
2227
2246
|
log: LogSchema.optional(),
|
|
2228
2247
|
cacheDuration: DurationSchema.optional().describe("The cache duration of the cached icons."),
|
|
2229
|
-
preserveIds:
|
|
2230
|
-
symbols:
|
|
2231
|
-
origin:
|
|
2232
|
-
|
|
2248
|
+
preserveIds: z39.boolean().optional().default(false).describe("Preserve the IDs of the icons."),
|
|
2249
|
+
symbols: z39.boolean().optional().default(false).describe(`Convert the SVG's to SVG symbols.`),
|
|
2250
|
+
origin: z39.union([
|
|
2251
|
+
z39.object({
|
|
2233
2252
|
static: staticOriginSchema,
|
|
2234
2253
|
function: functionOriginSchema.optional()
|
|
2235
2254
|
}),
|
|
2236
|
-
|
|
2255
|
+
z39.object({
|
|
2237
2256
|
static: staticOriginSchema.optional(),
|
|
2238
2257
|
function: functionOriginSchema
|
|
2239
2258
|
})
|
|
@@ -2260,13 +2279,13 @@ var IconsSchema = z38.record(
|
|
|
2260
2279
|
).optional().describe("Define an svg icon proxy in your stack. Store, optimize, and deliver svg icons at scale.");
|
|
2261
2280
|
|
|
2262
2281
|
// src/feature/image/schema.ts
|
|
2263
|
-
import { z as
|
|
2264
|
-
var transformationOptionsSchema =
|
|
2265
|
-
width:
|
|
2266
|
-
height:
|
|
2267
|
-
fit:
|
|
2268
|
-
position:
|
|
2269
|
-
quality:
|
|
2282
|
+
import { z as z40 } from "zod";
|
|
2283
|
+
var transformationOptionsSchema = z40.object({
|
|
2284
|
+
width: z40.number().int().positive().optional(),
|
|
2285
|
+
height: z40.number().int().positive().optional(),
|
|
2286
|
+
fit: z40.enum(["cover", "contain", "fill", "inside", "outside"]).optional(),
|
|
2287
|
+
position: z40.enum(["top", "right top", "right", "right bottom", "bottom", "left bottom", "left", "left top", "center"]).optional(),
|
|
2288
|
+
quality: z40.number().int().min(1).max(100).optional()
|
|
2270
2289
|
});
|
|
2271
2290
|
var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
2272
2291
|
"Specifies the path to a local image directory that will be uploaded in S3."
|
|
@@ -2274,38 +2293,38 @@ var staticOriginSchema2 = LocalDirectorySchema.describe(
|
|
|
2274
2293
|
var functionOriginSchema2 = FunctionSchema.describe(
|
|
2275
2294
|
"Specifies the file that will be called when an image isn't found in the (cache) bucket."
|
|
2276
2295
|
);
|
|
2277
|
-
var ImagesSchema =
|
|
2296
|
+
var ImagesSchema = z40.record(
|
|
2278
2297
|
ResourceIdSchema,
|
|
2279
|
-
|
|
2298
|
+
z40.object({
|
|
2280
2299
|
// domain: ResourceIdSchema.describe('The domain id to link your site with.').optional(),
|
|
2281
2300
|
// subDomain: z.string().optional(),
|
|
2282
2301
|
router: ResourceIdSchema.describe("The router id to link your image proxy."),
|
|
2283
2302
|
path: RouteSchema2.describe("The path inside the router to link your image proxy to."),
|
|
2284
2303
|
log: LogSchema.optional(),
|
|
2285
2304
|
cacheDuration: DurationSchema.optional().describe("Cache duration of the cached images."),
|
|
2286
|
-
presets:
|
|
2287
|
-
extensions:
|
|
2288
|
-
jpg:
|
|
2289
|
-
mozjpeg:
|
|
2290
|
-
progressive:
|
|
2305
|
+
presets: z40.record(z40.string(), transformationOptionsSchema).describe("Named presets for image transformations"),
|
|
2306
|
+
extensions: z40.object({
|
|
2307
|
+
jpg: z40.object({
|
|
2308
|
+
mozjpeg: z40.boolean().optional(),
|
|
2309
|
+
progressive: z40.boolean().optional()
|
|
2291
2310
|
}).optional(),
|
|
2292
|
-
webp:
|
|
2293
|
-
effort:
|
|
2294
|
-
lossless:
|
|
2295
|
-
nearLossless:
|
|
2311
|
+
webp: z40.object({
|
|
2312
|
+
effort: z40.number().int().min(1).max(10).default(7).optional(),
|
|
2313
|
+
lossless: z40.boolean().optional(),
|
|
2314
|
+
nearLossless: z40.boolean().optional()
|
|
2296
2315
|
}).optional(),
|
|
2297
|
-
png:
|
|
2298
|
-
compressionLevel:
|
|
2316
|
+
png: z40.object({
|
|
2317
|
+
compressionLevel: z40.number().int().min(0).max(9).default(6).optional()
|
|
2299
2318
|
}).optional()
|
|
2300
2319
|
}).refine((data) => {
|
|
2301
2320
|
return Object.keys(data).length > 0;
|
|
2302
2321
|
}, "At least one extension must be defined.").describe("Specify the allowed extensions."),
|
|
2303
|
-
origin:
|
|
2304
|
-
|
|
2322
|
+
origin: z40.union([
|
|
2323
|
+
z40.object({
|
|
2305
2324
|
static: staticOriginSchema2,
|
|
2306
2325
|
function: functionOriginSchema2.optional()
|
|
2307
2326
|
}),
|
|
2308
|
-
|
|
2327
|
+
z40.object({
|
|
2309
2328
|
static: staticOriginSchema2.optional(),
|
|
2310
2329
|
function: functionOriginSchema2
|
|
2311
2330
|
})
|
|
@@ -2320,7 +2339,7 @@ var ImagesSchema = z39.record(
|
|
|
2320
2339
|
).optional().describe("Define an image proxy in your stack. Store, transform, optimize, and deliver images at scale.");
|
|
2321
2340
|
|
|
2322
2341
|
// src/feature/metric/schema.ts
|
|
2323
|
-
import { z as
|
|
2342
|
+
import { z as z41 } from "zod";
|
|
2324
2343
|
var ops = {
|
|
2325
2344
|
">": "GreaterThanThreshold",
|
|
2326
2345
|
">=": "GreaterThanOrEqualToThreshold",
|
|
@@ -2334,15 +2353,15 @@ var stats = {
|
|
|
2334
2353
|
min: "Minimum",
|
|
2335
2354
|
max: "Maximum"
|
|
2336
2355
|
};
|
|
2337
|
-
var WhereSchema =
|
|
2338
|
-
|
|
2356
|
+
var WhereSchema = z41.union([
|
|
2357
|
+
z41.string().regex(/(count|avg|sum|min|max) (>|>=|<|<=) (\d)/, "Invalid where query").transform((where) => {
|
|
2339
2358
|
const [stat4, op, value] = where.split(" ");
|
|
2340
2359
|
return { stat: stat4, op, value: parseFloat(value) };
|
|
2341
2360
|
}),
|
|
2342
|
-
|
|
2343
|
-
stat:
|
|
2344
|
-
op:
|
|
2345
|
-
value:
|
|
2361
|
+
z41.object({
|
|
2362
|
+
stat: z41.enum(["count", "avg", "sum", "min", "max"]),
|
|
2363
|
+
op: z41.enum([">", ">=", "<", "<="]),
|
|
2364
|
+
value: z41.number()
|
|
2346
2365
|
})
|
|
2347
2366
|
]).transform((where) => {
|
|
2348
2367
|
return {
|
|
@@ -2351,39 +2370,39 @@ var WhereSchema = z40.union([
|
|
|
2351
2370
|
value: where.value
|
|
2352
2371
|
};
|
|
2353
2372
|
});
|
|
2354
|
-
var AlarmSchema =
|
|
2355
|
-
description:
|
|
2373
|
+
var AlarmSchema = z41.object({
|
|
2374
|
+
description: z41.string().optional(),
|
|
2356
2375
|
where: WhereSchema,
|
|
2357
2376
|
period: DurationSchema,
|
|
2358
|
-
minDataPoints:
|
|
2359
|
-
trigger:
|
|
2377
|
+
minDataPoints: z41.number().int().default(1),
|
|
2378
|
+
trigger: z41.union([EmailSchema.transform((v) => [v]), EmailSchema.array(), FunctionSchema])
|
|
2360
2379
|
});
|
|
2361
|
-
var MetricsSchema =
|
|
2380
|
+
var MetricsSchema = z41.record(
|
|
2362
2381
|
ResourceIdSchema,
|
|
2363
|
-
|
|
2364
|
-
type:
|
|
2382
|
+
z41.object({
|
|
2383
|
+
type: z41.enum(["number", "size", "duration"]),
|
|
2365
2384
|
alarms: AlarmSchema.array().optional()
|
|
2366
2385
|
})
|
|
2367
2386
|
).optional().describe("Define the metrics in your stack.");
|
|
2368
2387
|
|
|
2369
2388
|
// src/feature/table/schema.ts
|
|
2370
2389
|
import { minutes as minutes5, seconds as seconds4 } from "@awsless/duration";
|
|
2371
|
-
import { z as
|
|
2372
|
-
var KeySchema =
|
|
2373
|
-
var TablesSchema =
|
|
2390
|
+
import { z as z42 } from "zod";
|
|
2391
|
+
var KeySchema = z42.string().min(1).max(255);
|
|
2392
|
+
var TablesSchema = z42.record(
|
|
2374
2393
|
ResourceIdSchema,
|
|
2375
|
-
|
|
2394
|
+
z42.object({
|
|
2376
2395
|
hash: KeySchema.describe(
|
|
2377
2396
|
"Specifies the name of the partition / hash key that makes up the primary key for the table."
|
|
2378
2397
|
),
|
|
2379
2398
|
sort: KeySchema.optional().describe(
|
|
2380
2399
|
"Specifies the name of the range / sort key that makes up the primary key for the table."
|
|
2381
2400
|
),
|
|
2382
|
-
fields:
|
|
2401
|
+
fields: z42.record(z42.string(), z42.enum(["string", "number", "binary"])).optional().describe(
|
|
2383
2402
|
'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
2403
|
),
|
|
2385
|
-
class:
|
|
2386
|
-
pointInTimeRecovery:
|
|
2404
|
+
class: z42.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
|
|
2405
|
+
pointInTimeRecovery: z42.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
|
|
2387
2406
|
ttl: KeySchema.optional().describe(
|
|
2388
2407
|
[
|
|
2389
2408
|
"The name of the TTL attribute used to store the expiration time for items in the table.",
|
|
@@ -2391,8 +2410,8 @@ var TablesSchema = z41.record(
|
|
|
2391
2410
|
].join("\n")
|
|
2392
2411
|
),
|
|
2393
2412
|
// deletionProtection: DeletionProtectionSchema.optional(),
|
|
2394
|
-
stream:
|
|
2395
|
-
type:
|
|
2413
|
+
stream: z42.object({
|
|
2414
|
+
type: z42.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
|
|
2396
2415
|
[
|
|
2397
2416
|
"When an item in the table is modified, you can determines what information is written to the stream for this table.",
|
|
2398
2417
|
"Valid values are:",
|
|
@@ -2402,7 +2421,7 @@ var TablesSchema = z41.record(
|
|
|
2402
2421
|
"- new-and-old-images - Both the new and the old item images of the item are written to the stream."
|
|
2403
2422
|
].join("\n")
|
|
2404
2423
|
),
|
|
2405
|
-
batchSize:
|
|
2424
|
+
batchSize: z42.number().min(1).max(1e4).default(1).describe(
|
|
2406
2425
|
[
|
|
2407
2426
|
"The maximum number of records in each batch that Lambda pulls from your stream and sends to your function.",
|
|
2408
2427
|
"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 +2437,26 @@ var TablesSchema = z41.record(
|
|
|
2418
2437
|
"You can specify a duration from 1 seconds to 5 minutes."
|
|
2419
2438
|
].join("\n")
|
|
2420
2439
|
),
|
|
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(
|
|
2440
|
+
maxRecordAge: DurationSchema.refine(
|
|
2441
|
+
durationMin(seconds4(1)),
|
|
2442
|
+
"Minimum record age duration is 1 second"
|
|
2443
|
+
).refine(durationMax(minutes5(1)), "Maximum record age duration is 1 minute").default("60 seconds").describe(
|
|
2444
|
+
[
|
|
2445
|
+
"Discard records older than the specified age.",
|
|
2446
|
+
"The maximum valid value for maximum record age is 60s.",
|
|
2447
|
+
"The default value is 60s"
|
|
2448
|
+
].join("\n")
|
|
2449
|
+
),
|
|
2450
|
+
retryAttempts: z42.number().min(-1).max(1e4).default(2).describe(
|
|
2436
2451
|
[
|
|
2437
2452
|
"Discard records after the specified number of retries.",
|
|
2438
|
-
"
|
|
2453
|
+
"-1 will sets the maximum number of retries to infinite.",
|
|
2439
2454
|
"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."
|
|
2455
|
+
"You can specify a number from -1 to 10000.",
|
|
2456
|
+
"The default value is 2"
|
|
2441
2457
|
].join("\n")
|
|
2442
2458
|
),
|
|
2443
|
-
concurrencyPerShard:
|
|
2459
|
+
concurrencyPerShard: z42.number().min(1).max(10).default(1).describe(
|
|
2444
2460
|
[
|
|
2445
2461
|
"The number of batches to process concurrently from each shard.",
|
|
2446
2462
|
"You can specify a number from 1 to 10."
|
|
@@ -2450,16 +2466,16 @@ var TablesSchema = z41.record(
|
|
|
2450
2466
|
}).optional().describe(
|
|
2451
2467
|
"The settings for the DynamoDB table stream, which capture changes to items stored in the table."
|
|
2452
2468
|
),
|
|
2453
|
-
indexes:
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
hash:
|
|
2469
|
+
indexes: z42.record(
|
|
2470
|
+
z42.string(),
|
|
2471
|
+
z42.object({
|
|
2472
|
+
hash: z42.union([KeySchema.transform((v) => [v]), KeySchema.array()]).describe(
|
|
2457
2473
|
"Specifies the name of the partition / hash key that makes up the primary key for the global secondary index."
|
|
2458
2474
|
),
|
|
2459
|
-
sort:
|
|
2475
|
+
sort: z42.union([KeySchema.transform((v) => [v]), KeySchema.array()]).optional().describe(
|
|
2460
2476
|
"Specifies the name of the range / sort key that makes up the primary key for the global secondary index."
|
|
2461
2477
|
),
|
|
2462
|
-
projection:
|
|
2478
|
+
projection: z42.enum(["all", "keys-only"]).default("all").describe(
|
|
2463
2479
|
[
|
|
2464
2480
|
"The set of attributes that are projected into the index:",
|
|
2465
2481
|
"- all - All of the table attributes are projected into the index.",
|
|
@@ -2473,11 +2489,11 @@ var TablesSchema = z41.record(
|
|
|
2473
2489
|
).optional().describe("Define the tables in your stack.");
|
|
2474
2490
|
|
|
2475
2491
|
// src/feature/task/schema.ts
|
|
2476
|
-
import { z as
|
|
2477
|
-
var
|
|
2492
|
+
import { z as z43 } from "zod";
|
|
2493
|
+
var RetryAttemptsSchema3 = z43.number().int().min(0).max(2).describe(
|
|
2478
2494
|
"The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
|
|
2479
2495
|
);
|
|
2480
|
-
var TaskSchema =
|
|
2496
|
+
var TaskSchema = z43.union([
|
|
2481
2497
|
LocalFileSchema.transform((file) => ({
|
|
2482
2498
|
consumer: {
|
|
2483
2499
|
code: {
|
|
@@ -2488,20 +2504,20 @@ var TaskSchema = z42.union([
|
|
|
2488
2504
|
},
|
|
2489
2505
|
retryAttempts: void 0
|
|
2490
2506
|
})),
|
|
2491
|
-
|
|
2507
|
+
z43.object({
|
|
2492
2508
|
consumer: FunctionSchema,
|
|
2493
|
-
retryAttempts:
|
|
2509
|
+
retryAttempts: RetryAttemptsSchema3.optional()
|
|
2494
2510
|
})
|
|
2495
2511
|
]);
|
|
2496
|
-
var TasksSchema =
|
|
2512
|
+
var TasksSchema = z43.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
|
|
2497
2513
|
|
|
2498
2514
|
// src/feature/test/schema.ts
|
|
2499
|
-
import { z as
|
|
2500
|
-
var TestsSchema =
|
|
2515
|
+
import { z as z44 } from "zod";
|
|
2516
|
+
var TestsSchema = z44.union([
|
|
2501
2517
|
//
|
|
2502
2518
|
LocalDirectorySchema.transform((v) => [v]),
|
|
2503
2519
|
LocalDirectorySchema.array(),
|
|
2504
|
-
|
|
2520
|
+
z44.literal(false)
|
|
2505
2521
|
]).describe("Define the location of your tests for your stack.").optional();
|
|
2506
2522
|
|
|
2507
2523
|
// src/config/stack.ts
|
|
@@ -2509,8 +2525,8 @@ var DependsSchema = ResourceIdSchema.array().optional().describe("Define the sta
|
|
|
2509
2525
|
var NameSchema = ResourceIdSchema.refine((name) => !["base", "hostedzones"].includes(name), {
|
|
2510
2526
|
message: `Stack name can't be a reserved name.`
|
|
2511
2527
|
}).describe("Stack name.");
|
|
2512
|
-
var StackSchema =
|
|
2513
|
-
$schema:
|
|
2528
|
+
var StackSchema = z45.object({
|
|
2529
|
+
$schema: z45.string().optional(),
|
|
2514
2530
|
name: NameSchema,
|
|
2515
2531
|
depends: DependsSchema,
|
|
2516
2532
|
commands: CommandsSchema,
|
|
@@ -2547,37 +2563,37 @@ import { basename, dirname as dirname2, extname, join as join4 } from "path";
|
|
|
2547
2563
|
|
|
2548
2564
|
// src/config/stage-patch.ts
|
|
2549
2565
|
import jsonPatch from "fast-json-patch";
|
|
2550
|
-
import { z as
|
|
2551
|
-
var AddOperationSchema =
|
|
2552
|
-
op:
|
|
2553
|
-
path:
|
|
2554
|
-
value:
|
|
2566
|
+
import { z as z46 } from "zod";
|
|
2567
|
+
var AddOperationSchema = z46.object({
|
|
2568
|
+
op: z46.literal("add"),
|
|
2569
|
+
path: z46.string(),
|
|
2570
|
+
value: z46.unknown()
|
|
2555
2571
|
}).strict();
|
|
2556
|
-
var RemoveOperationSchema =
|
|
2557
|
-
op:
|
|
2558
|
-
path:
|
|
2572
|
+
var RemoveOperationSchema = z46.object({
|
|
2573
|
+
op: z46.literal("remove"),
|
|
2574
|
+
path: z46.string()
|
|
2559
2575
|
}).strict();
|
|
2560
|
-
var ReplaceOperationSchema =
|
|
2561
|
-
op:
|
|
2562
|
-
path:
|
|
2563
|
-
value:
|
|
2576
|
+
var ReplaceOperationSchema = z46.object({
|
|
2577
|
+
op: z46.literal("replace"),
|
|
2578
|
+
path: z46.string(),
|
|
2579
|
+
value: z46.unknown()
|
|
2564
2580
|
}).strict();
|
|
2565
|
-
var MoveOperationSchema =
|
|
2566
|
-
op:
|
|
2567
|
-
from:
|
|
2568
|
-
path:
|
|
2581
|
+
var MoveOperationSchema = z46.object({
|
|
2582
|
+
op: z46.literal("move"),
|
|
2583
|
+
from: z46.string(),
|
|
2584
|
+
path: z46.string()
|
|
2569
2585
|
}).strict();
|
|
2570
|
-
var CopyOperationSchema =
|
|
2571
|
-
op:
|
|
2572
|
-
from:
|
|
2573
|
-
path:
|
|
2586
|
+
var CopyOperationSchema = z46.object({
|
|
2587
|
+
op: z46.literal("copy"),
|
|
2588
|
+
from: z46.string(),
|
|
2589
|
+
path: z46.string()
|
|
2574
2590
|
}).strict();
|
|
2575
|
-
var TestOperationSchema =
|
|
2576
|
-
op:
|
|
2577
|
-
path:
|
|
2578
|
-
value:
|
|
2591
|
+
var TestOperationSchema = z46.object({
|
|
2592
|
+
op: z46.literal("test"),
|
|
2593
|
+
path: z46.string(),
|
|
2594
|
+
value: z46.unknown()
|
|
2579
2595
|
}).strict();
|
|
2580
|
-
var JsonPatchOperationSchema =
|
|
2596
|
+
var JsonPatchOperationSchema = z46.discriminatedUnion("op", [
|
|
2581
2597
|
AddOperationSchema,
|
|
2582
2598
|
RemoveOperationSchema,
|
|
2583
2599
|
ReplaceOperationSchema,
|
|
@@ -2585,8 +2601,8 @@ var JsonPatchOperationSchema = z45.discriminatedUnion("op", [
|
|
|
2585
2601
|
CopyOperationSchema,
|
|
2586
2602
|
TestOperationSchema
|
|
2587
2603
|
]);
|
|
2588
|
-
var StagePatchSchema =
|
|
2589
|
-
$schema:
|
|
2604
|
+
var StagePatchSchema = z46.object({
|
|
2605
|
+
$schema: z46.string().optional(),
|
|
2590
2606
|
operations: JsonPatchOperationSchema.array()
|
|
2591
2607
|
}).strict();
|
|
2592
2608
|
var applyStagePatch = (source, patch, file) => {
|
|
@@ -2602,13 +2618,13 @@ var applyStagePatch = (source, patch, file) => {
|
|
|
2602
2618
|
};
|
|
2603
2619
|
|
|
2604
2620
|
// src/config/load/validate.ts
|
|
2605
|
-
import { z as
|
|
2621
|
+
import { z as z47 } from "zod";
|
|
2606
2622
|
var validateConfig = async (schema, file, data) => {
|
|
2607
2623
|
try {
|
|
2608
2624
|
const result = await schema.parseAsync(data);
|
|
2609
2625
|
return result;
|
|
2610
2626
|
} catch (error) {
|
|
2611
|
-
if (error instanceof
|
|
2627
|
+
if (error instanceof z47.ZodError) {
|
|
2612
2628
|
throw new ConfigError(file, error, data);
|
|
2613
2629
|
}
|
|
2614
2630
|
throw error;
|
|
@@ -3419,7 +3435,7 @@ var formatByteSize = (size) => {
|
|
|
3419
3435
|
|
|
3420
3436
|
// src/feature/on-failure/util.ts
|
|
3421
3437
|
var getGlobalOnFailure = (ctx) => {
|
|
3422
|
-
return ctx.shared.get("on-failure", "
|
|
3438
|
+
return ctx.shared.get("on-failure", "bucket-arn");
|
|
3423
3439
|
};
|
|
3424
3440
|
|
|
3425
3441
|
// src/feature/function/build/zip.ts
|
|
@@ -3967,8 +3983,15 @@ var createAsyncLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
3967
3983
|
}
|
|
3968
3984
|
);
|
|
3969
3985
|
result.addPermission({
|
|
3970
|
-
actions: ["
|
|
3971
|
-
resources: [onFailure]
|
|
3986
|
+
actions: ["s3:PutObject", "s3:ListBucket"],
|
|
3987
|
+
resources: [onFailure, $interpolate`${onFailure}/*`],
|
|
3988
|
+
conditions: {
|
|
3989
|
+
StringEquals: {
|
|
3990
|
+
// This will protect anyone from taking our bucket name,
|
|
3991
|
+
// and us sending our failed items to the wrong s3 bucket
|
|
3992
|
+
"s3:ResourceAccount": ctx.accountId
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3972
3995
|
});
|
|
3973
3996
|
return result;
|
|
3974
3997
|
};
|
|
@@ -4448,146 +4471,509 @@ var onLogFeature = defineFeature({
|
|
|
4448
4471
|
});
|
|
4449
4472
|
|
|
4450
4473
|
// src/feature/on-failure/index.ts
|
|
4451
|
-
import { Group as
|
|
4474
|
+
import { Group as Group9 } from "@terraforge/core";
|
|
4475
|
+
import { aws as aws10 } from "@terraforge/aws";
|
|
4476
|
+
|
|
4477
|
+
// src/feature/function/prebuild.ts
|
|
4478
|
+
import { days as days5, seconds as seconds5, toDays as toDays5, toSeconds as toSeconds3 } from "@awsless/duration";
|
|
4479
|
+
import { mebibytes as mebibytes2, toMebibytes as toMebibytes3 } from "@awsless/size";
|
|
4452
4480
|
import { aws as aws9 } from "@terraforge/aws";
|
|
4453
|
-
import {
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
messageRetentionSeconds: toSeconds3(days5(14))
|
|
4481
|
+
import { Output as Output4, findInputDeps as findInputDeps2, resolveInputs as resolveInputs2 } from "@terraforge/core";
|
|
4482
|
+
import { pascalCase as pascalCase2 } from "change-case";
|
|
4483
|
+
var createPrebuildLambdaFunction = (group, ctx, ns, id, props) => {
|
|
4484
|
+
let name;
|
|
4485
|
+
let roleName;
|
|
4486
|
+
if ("stack" in ctx) {
|
|
4487
|
+
name = formatLocalResourceName({
|
|
4488
|
+
appName: ctx.app.name,
|
|
4489
|
+
stackName: ctx.stack.name,
|
|
4490
|
+
resourceType: ns,
|
|
4491
|
+
resourceName: id
|
|
4465
4492
|
});
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
redrivePolicy: deadletter.arn.pipe((deadLetterTargetArn) => {
|
|
4473
|
-
return JSON.stringify({
|
|
4474
|
-
deadLetterTargetArn,
|
|
4475
|
-
maxReceiveCount: 100
|
|
4476
|
-
});
|
|
4477
|
-
})
|
|
4493
|
+
roleName = formatLocalResourceName({
|
|
4494
|
+
appName: ctx.app.name,
|
|
4495
|
+
stackName: ctx.stack.name,
|
|
4496
|
+
resourceType: ns,
|
|
4497
|
+
resourceName: id,
|
|
4498
|
+
postfix: ctx.appId
|
|
4478
4499
|
});
|
|
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]
|
|
4500
|
+
} else {
|
|
4501
|
+
name = formatGlobalResourceName({
|
|
4502
|
+
appName: ctx.appConfig.name,
|
|
4503
|
+
resourceType: ns,
|
|
4504
|
+
resourceName: id
|
|
4505
4505
|
});
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4506
|
+
roleName = formatGlobalResourceName({
|
|
4507
|
+
appName: ctx.appConfig.name,
|
|
4508
|
+
resourceType: ns,
|
|
4509
|
+
resourceName: id,
|
|
4510
|
+
postfix: ctx.appId
|
|
4510
4511
|
});
|
|
4511
4512
|
}
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
var formatFullDomainName = (config2, id, subDomain) => {
|
|
4530
|
-
const domain2 = getDomainNameById(config2, id);
|
|
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/*`
|
|
4547
|
-
]
|
|
4548
|
-
});
|
|
4549
|
-
for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
|
|
4550
|
-
const group = new Group9(ctx.base, "pubsub", id);
|
|
4551
|
-
const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, props.auth);
|
|
4552
|
-
const name = formatGlobalResourceName({
|
|
4553
|
-
appName: ctx.app.name,
|
|
4554
|
-
resourceType: "pubsub",
|
|
4555
|
-
resourceName: id
|
|
4556
|
-
});
|
|
4557
|
-
const authorizer = new aws10.iot.Authorizer(group, "authorizer", {
|
|
4558
|
-
name,
|
|
4559
|
-
authorizerFunctionArn: lambda.arn,
|
|
4560
|
-
status: "ACTIVE",
|
|
4561
|
-
signingDisabled: true,
|
|
4562
|
-
enableCachingForHttp: false
|
|
4563
|
-
});
|
|
4564
|
-
new aws10.lambda.Permission(group, "permission", {
|
|
4565
|
-
functionName: lambda.functionName,
|
|
4566
|
-
action: "lambda:InvokeFunction",
|
|
4567
|
-
principal: "iot.amazonaws.com",
|
|
4568
|
-
sourceArn: authorizer.arn
|
|
4569
|
-
});
|
|
4570
|
-
ctx.bind(`PUBSUB_${constantCase5(id)}_AUTHORIZER`, name);
|
|
4571
|
-
const endpoint = aws10.iot.getEndpoint(group, "endpoint", {
|
|
4572
|
-
endpointType: "iot:Data-ATS"
|
|
4573
|
-
});
|
|
4574
|
-
if (props.domain) {
|
|
4575
|
-
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
4576
|
-
new aws10.iot.DomainConfiguration(group, "domain", {
|
|
4577
|
-
name,
|
|
4578
|
-
domainName,
|
|
4579
|
-
serverCertificateArns: [ctx.shared.entry("domain", `certificate-arn`, props.domain)],
|
|
4580
|
-
authorizerConfig: {
|
|
4581
|
-
defaultAuthorizerName: authorizer.name
|
|
4513
|
+
const code = new aws9.s3.BucketObject(group, "code", {
|
|
4514
|
+
bucket: ctx.shared.get("function", "bucket-name"),
|
|
4515
|
+
key: `/lambda/${name}.zip`,
|
|
4516
|
+
source: props.bundleFile,
|
|
4517
|
+
sourceHash: $hash(props.bundleFile)
|
|
4518
|
+
// body: Asset.fromFile(props.bundleFile),
|
|
4519
|
+
});
|
|
4520
|
+
const role = new aws9.iam.Role(group, "role", {
|
|
4521
|
+
name: roleName,
|
|
4522
|
+
assumeRolePolicy: JSON.stringify({
|
|
4523
|
+
Version: "2012-10-17",
|
|
4524
|
+
Statement: [
|
|
4525
|
+
{
|
|
4526
|
+
Effect: "Allow",
|
|
4527
|
+
Action: "sts:AssumeRole",
|
|
4528
|
+
Principal: {
|
|
4529
|
+
Service: ["lambda.amazonaws.com"]
|
|
4582
4530
|
}
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4531
|
+
}
|
|
4532
|
+
]
|
|
4533
|
+
})
|
|
4534
|
+
});
|
|
4535
|
+
const statements = [];
|
|
4536
|
+
const statementDeps = /* @__PURE__ */ new Set();
|
|
4537
|
+
const addPermission = (...permissions) => {
|
|
4538
|
+
statements.push(...permissions);
|
|
4539
|
+
for (const dep of findInputDeps2(permissions)) {
|
|
4540
|
+
statementDeps.add(dep);
|
|
4541
|
+
}
|
|
4542
|
+
};
|
|
4543
|
+
ctx.onPermission((statement) => {
|
|
4544
|
+
addPermission(statement);
|
|
4545
|
+
});
|
|
4546
|
+
const policy = new aws9.iam.RolePolicy(group, "policy", {
|
|
4547
|
+
role: role.name,
|
|
4548
|
+
name: "lambda-policy",
|
|
4549
|
+
policy: new Output4(statementDeps, async (resolve) => {
|
|
4550
|
+
const list3 = await resolveInputs2(statements);
|
|
4551
|
+
resolve(
|
|
4552
|
+
JSON.stringify({
|
|
4553
|
+
Version: "2012-10-17",
|
|
4554
|
+
Statement: list3.map((statement) => ({
|
|
4555
|
+
Effect: pascalCase2(statement.effect ?? "allow"),
|
|
4556
|
+
Action: statement.actions,
|
|
4557
|
+
Resource: statement.resources
|
|
4558
|
+
}))
|
|
4559
|
+
})
|
|
4560
|
+
);
|
|
4561
|
+
})
|
|
4562
|
+
});
|
|
4563
|
+
const variables = {};
|
|
4564
|
+
const logFormats = {
|
|
4565
|
+
text: "Text",
|
|
4566
|
+
json: "JSON"
|
|
4567
|
+
};
|
|
4568
|
+
const lambda = new aws9.lambda.Function(group, `function`, {
|
|
4569
|
+
functionName: name,
|
|
4570
|
+
role: role.arn,
|
|
4571
|
+
// code,
|
|
4572
|
+
// runtime: props.runtime === 'container' ? undefined : props.runtime,
|
|
4573
|
+
runtime: props.runtime,
|
|
4574
|
+
handler: props.handler,
|
|
4575
|
+
timeout: toSeconds3(props.timeout ?? seconds5(10)),
|
|
4576
|
+
memorySize: toMebibytes3(props.memorySize ?? mebibytes2(128)),
|
|
4577
|
+
architectures: [props.architecture ?? "arm64"],
|
|
4578
|
+
layers: props.layers?.map((id2) => ctx.shared.entry("layer", "arn", id2)),
|
|
4579
|
+
s3Bucket: code.bucket,
|
|
4580
|
+
s3ObjectVersion: code.versionId,
|
|
4581
|
+
s3Key: code.key.pipe((name2) => {
|
|
4582
|
+
if (name2.startsWith("/")) {
|
|
4583
|
+
return name2.substring(1);
|
|
4584
|
+
}
|
|
4585
|
+
return name2;
|
|
4586
|
+
}),
|
|
4587
|
+
sourceCodeHash: $hash(props.bundleFile),
|
|
4588
|
+
environment: {
|
|
4589
|
+
variables
|
|
4590
|
+
},
|
|
4591
|
+
loggingConfig: {
|
|
4592
|
+
logGroup: `/aws/lambda/${name}`,
|
|
4593
|
+
logFormat: logFormats[props.log && "format" in props.log && props.log.format || "json"],
|
|
4594
|
+
applicationLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.level?.toUpperCase() : void 0,
|
|
4595
|
+
systemLogLevel: props.log && "format" in props.log && props.log.format === "json" ? props.log.system?.toUpperCase() : void 0
|
|
4596
|
+
}
|
|
4597
|
+
});
|
|
4598
|
+
ctx.onEnv((name2, value) => {
|
|
4599
|
+
variables[name2] = value;
|
|
4600
|
+
});
|
|
4601
|
+
variables.APP = ctx.appConfig.name;
|
|
4602
|
+
variables.APP_ID = ctx.appId;
|
|
4603
|
+
variables.AWS_ACCOUNT_ID = ctx.accountId;
|
|
4604
|
+
if ("stackConfig" in ctx) {
|
|
4605
|
+
variables.STACK = ctx.stackConfig.name;
|
|
4606
|
+
}
|
|
4607
|
+
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
4608
|
+
const logGroup = new aws9.cloudwatch.LogGroup(group, "log", {
|
|
4609
|
+
name: `/aws/lambda/${name}`,
|
|
4610
|
+
retentionInDays: toDays5(props.log.retention ?? days5(7))
|
|
4611
|
+
});
|
|
4612
|
+
addPermission({
|
|
4613
|
+
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
|
|
4614
|
+
resources: [logGroup.arn.pipe((arn) => `${arn}:*`)]
|
|
4615
|
+
});
|
|
4616
|
+
const onLogArn = getGlobalOnLog(ctx);
|
|
4617
|
+
if (onLogArn && ctx.appConfig.defaults.onLog) {
|
|
4618
|
+
const logFilter = ctx.appConfig.defaults.onLog.filter;
|
|
4619
|
+
new aws9.cloudwatch.LogSubscriptionFilter(group, `on-log`, {
|
|
4620
|
+
name: "log-subscription",
|
|
4621
|
+
destinationArn: onLogArn,
|
|
4622
|
+
logGroupName: logGroup.name,
|
|
4623
|
+
filterPattern: formatFilterPattern(logFilter)
|
|
4624
|
+
});
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
if (props.warm) {
|
|
4628
|
+
const rule = new aws9.cloudwatch.EventRule(group, "warm", {
|
|
4629
|
+
name: `${name}--warm`,
|
|
4630
|
+
description: "Lambda Warmer",
|
|
4631
|
+
scheduleExpression: "rate(5 minutes)",
|
|
4632
|
+
isEnabled: true
|
|
4633
|
+
});
|
|
4634
|
+
new aws9.cloudwatch.EventTarget(group, "warm", {
|
|
4635
|
+
rule: rule.name,
|
|
4636
|
+
targetId: "warmer",
|
|
4637
|
+
arn: lambda.arn,
|
|
4638
|
+
input: JSON.stringify({
|
|
4639
|
+
warmer: true,
|
|
4640
|
+
concurrency: props.warm
|
|
4641
|
+
})
|
|
4642
|
+
});
|
|
4643
|
+
new aws9.lambda.Permission(group, `warm`, {
|
|
4644
|
+
action: "lambda:InvokeFunction",
|
|
4645
|
+
principal: "events.amazonaws.com",
|
|
4646
|
+
functionName: lambda.functionName,
|
|
4647
|
+
sourceArn: rule.arn
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4650
|
+
return {
|
|
4651
|
+
name,
|
|
4652
|
+
lambda,
|
|
4653
|
+
policy,
|
|
4654
|
+
code,
|
|
4655
|
+
setEnvironment(name2, value) {
|
|
4656
|
+
variables[name2] = value;
|
|
4657
|
+
},
|
|
4658
|
+
addPermission(statement) {
|
|
4659
|
+
addPermission(statement);
|
|
4660
|
+
}
|
|
4661
|
+
};
|
|
4662
|
+
};
|
|
4663
|
+
|
|
4664
|
+
// src/feature/on-failure/index.ts
|
|
4665
|
+
import { join as join10 } from "node:path";
|
|
4666
|
+
import { mebibytes as mebibytes3 } from "@awsless/size";
|
|
4667
|
+
import { days as days6, toSeconds as toSeconds4 } from "@awsless/duration";
|
|
4668
|
+
var onFailureFeature = defineFeature({
|
|
4669
|
+
name: "on-failure",
|
|
4670
|
+
onApp(ctx) {
|
|
4671
|
+
const group = new Group9(ctx.base, "on-failure", "main");
|
|
4672
|
+
const deadletter = new aws10.sqs.Queue(group, "deadletter", {
|
|
4673
|
+
name: formatGlobalResourceName({
|
|
4674
|
+
appName: ctx.app.name,
|
|
4675
|
+
resourceType: "on-failure",
|
|
4676
|
+
resourceName: "deadletter"
|
|
4677
|
+
}),
|
|
4678
|
+
messageRetentionSeconds: toSeconds4(days6(14))
|
|
4679
|
+
});
|
|
4680
|
+
const queue2 = new aws10.sqs.Queue(group, "on-failure", {
|
|
4681
|
+
name: formatGlobalResourceName({
|
|
4682
|
+
appName: ctx.app.name,
|
|
4683
|
+
resourceType: "on-failure",
|
|
4684
|
+
resourceName: "failure"
|
|
4685
|
+
}),
|
|
4686
|
+
redrivePolicy: deadletter.arn.pipe((deadLetterTargetArn) => {
|
|
4687
|
+
return JSON.stringify({
|
|
4688
|
+
deadLetterTargetArn,
|
|
4689
|
+
maxReceiveCount: 3
|
|
4690
|
+
});
|
|
4691
|
+
})
|
|
4692
|
+
});
|
|
4693
|
+
ctx.shared.set("on-failure", "queue-arn", queue2.arn);
|
|
4694
|
+
const bucket = new aws10.s3.Bucket(group, "bucket", {
|
|
4695
|
+
bucket: formatGlobalResourceName({
|
|
4696
|
+
appName: ctx.app.name,
|
|
4697
|
+
resourceType: "on-failure",
|
|
4698
|
+
resourceName: "failure",
|
|
4699
|
+
postfix: ctx.appId
|
|
4700
|
+
}),
|
|
4701
|
+
lifecycleRule: [
|
|
4702
|
+
{
|
|
4703
|
+
id: "ttl",
|
|
4704
|
+
enabled: true,
|
|
4705
|
+
expiration: {
|
|
4706
|
+
days: 14
|
|
4707
|
+
}
|
|
4708
|
+
}
|
|
4709
|
+
]
|
|
4710
|
+
});
|
|
4711
|
+
ctx.shared.set("on-failure", "bucket-arn", bucket.arn);
|
|
4712
|
+
const props = ctx.appConfig.defaults.onFailure;
|
|
4713
|
+
if (props) {
|
|
4714
|
+
if (props.notify) {
|
|
4715
|
+
const topic = new aws10.sns.Topic(group, "deadletter-topic", {
|
|
4716
|
+
name: formatGlobalResourceName({
|
|
4717
|
+
appName: ctx.app.name,
|
|
4718
|
+
resourceType: "on-failure",
|
|
4719
|
+
resourceName: "deadletter"
|
|
4720
|
+
})
|
|
4721
|
+
});
|
|
4722
|
+
for (const email of props.notify) {
|
|
4723
|
+
new aws10.sns.TopicSubscription(group, email, {
|
|
4724
|
+
topicArn: topic.arn,
|
|
4725
|
+
protocol: "email",
|
|
4726
|
+
endpoint: email
|
|
4727
|
+
});
|
|
4728
|
+
}
|
|
4729
|
+
const role = new aws10.iam.Role(group, "deadletter-topic-role", {
|
|
4730
|
+
name: formatGlobalResourceName({
|
|
4731
|
+
appName: ctx.app.name,
|
|
4732
|
+
resourceType: "on-failure",
|
|
4733
|
+
resourceName: "pipe"
|
|
4734
|
+
}),
|
|
4735
|
+
description: `${ctx.app.name} on-failure deadletter notification pipe`,
|
|
4736
|
+
assumeRolePolicy: JSON.stringify({
|
|
4737
|
+
Version: "2012-10-17",
|
|
4738
|
+
Statement: [
|
|
4739
|
+
{
|
|
4740
|
+
Effect: "Allow",
|
|
4741
|
+
Action: "sts:AssumeRole",
|
|
4742
|
+
Principal: {
|
|
4743
|
+
Service: ["pipes.amazonaws.com"]
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
]
|
|
4747
|
+
}),
|
|
4748
|
+
inlinePolicy: [
|
|
4749
|
+
{
|
|
4750
|
+
name: "deadletter-topic",
|
|
4751
|
+
policy: topic.arn.pipe(
|
|
4752
|
+
(topicArn) => deadletter.arn.pipe(
|
|
4753
|
+
(queueArn) => JSON.stringify({
|
|
4754
|
+
Version: "2012-10-17",
|
|
4755
|
+
Statement: [
|
|
4756
|
+
{
|
|
4757
|
+
Effect: "Allow",
|
|
4758
|
+
Action: [
|
|
4759
|
+
"sqs:ReceiveMessage",
|
|
4760
|
+
"sqs:DeleteMessage",
|
|
4761
|
+
"sqs:GetQueueAttributes",
|
|
4762
|
+
"sqs:ChangeMessageVisibility"
|
|
4763
|
+
],
|
|
4764
|
+
Resource: queueArn
|
|
4765
|
+
},
|
|
4766
|
+
{
|
|
4767
|
+
Effect: "Allow",
|
|
4768
|
+
Action: ["sns:Publish"],
|
|
4769
|
+
Resource: topicArn
|
|
4770
|
+
}
|
|
4771
|
+
]
|
|
4772
|
+
})
|
|
4773
|
+
)
|
|
4774
|
+
)
|
|
4775
|
+
}
|
|
4776
|
+
]
|
|
4777
|
+
});
|
|
4778
|
+
new aws10.pipes.Pipe(group, "deadletter-topic-pipe", {
|
|
4779
|
+
name: formatGlobalResourceName({
|
|
4780
|
+
appName: ctx.app.name,
|
|
4781
|
+
resourceType: "on-failure",
|
|
4782
|
+
resourceName: "notify"
|
|
4783
|
+
}),
|
|
4784
|
+
roleArn: role.arn,
|
|
4785
|
+
source: deadletter.arn,
|
|
4786
|
+
target: topic.arn,
|
|
4787
|
+
sourceParameters: {
|
|
4788
|
+
sqsQueueParameters: {
|
|
4789
|
+
batchSize: 1
|
|
4790
|
+
}
|
|
4791
|
+
},
|
|
4792
|
+
targetParameters: {
|
|
4793
|
+
inputTemplate: [
|
|
4794
|
+
`Awsless on-failure DLQ message`,
|
|
4795
|
+
`App: ${ctx.app.name}`,
|
|
4796
|
+
`Sent: <$.attributes.SentTimestamp>`,
|
|
4797
|
+
"",
|
|
4798
|
+
`Body:
|
|
4799
|
+
<$.body>`
|
|
4800
|
+
].join("\n")
|
|
4801
|
+
}
|
|
4802
|
+
});
|
|
4803
|
+
}
|
|
4804
|
+
const consumer = createLambdaFunction(group, ctx, "on-failure", "consumer", props.consumer);
|
|
4805
|
+
consumer.addPermission({
|
|
4806
|
+
effect: "deny",
|
|
4807
|
+
actions: [
|
|
4808
|
+
//
|
|
4809
|
+
"lambda:InvokeFunction",
|
|
4810
|
+
"lambda:InvokeAsync",
|
|
4811
|
+
"sqs:SendMessage",
|
|
4812
|
+
"sns:Publish"
|
|
4813
|
+
],
|
|
4814
|
+
resources: ["*"]
|
|
4815
|
+
});
|
|
4816
|
+
const prebuild = createPrebuildLambdaFunction(group, ctx, "on-failure", "normalizer", {
|
|
4817
|
+
bundleFile: join10(__dirname, "/prebuild/on-failure/bundle.zip"),
|
|
4818
|
+
bundleHash: join10(__dirname, "/prebuild/on-failure/HASH"),
|
|
4819
|
+
memorySize: mebibytes3(256),
|
|
4820
|
+
timeout: props.consumer.timeout,
|
|
4821
|
+
handler: "index.default",
|
|
4822
|
+
runtime: "nodejs24.x",
|
|
4823
|
+
log: {
|
|
4824
|
+
format: "json",
|
|
4825
|
+
level: "warn",
|
|
4826
|
+
retention: days6(3),
|
|
4827
|
+
system: "warn"
|
|
4828
|
+
}
|
|
4829
|
+
});
|
|
4830
|
+
prebuild.setEnvironment("CONSUMER", consumer.name);
|
|
4831
|
+
prebuild.addPermission({
|
|
4832
|
+
actions: ["lambda:InvokeFunction"],
|
|
4833
|
+
resources: [consumer.lambda.arn]
|
|
4834
|
+
});
|
|
4835
|
+
prebuild.addPermission({
|
|
4836
|
+
actions: ["s3:GetObject", "s3:DeleteObject"],
|
|
4837
|
+
resources: [bucket.arn, $interpolate`${bucket.arn}/*`]
|
|
4838
|
+
});
|
|
4839
|
+
prebuild.addPermission({
|
|
4840
|
+
actions: ["sqs:SendMessage"],
|
|
4841
|
+
resources: [deadletter.arn]
|
|
4842
|
+
});
|
|
4843
|
+
new aws10.lambda.FunctionEventInvokeConfig(
|
|
4844
|
+
group,
|
|
4845
|
+
"async",
|
|
4846
|
+
{
|
|
4847
|
+
functionName: prebuild.lambda.arn,
|
|
4848
|
+
maximumRetryAttempts: 2,
|
|
4849
|
+
destinationConfig: {
|
|
4850
|
+
onFailure: {
|
|
4851
|
+
destination: deadletter.arn
|
|
4852
|
+
}
|
|
4853
|
+
}
|
|
4854
|
+
},
|
|
4855
|
+
{
|
|
4856
|
+
dependsOn: [prebuild.policy]
|
|
4857
|
+
}
|
|
4858
|
+
);
|
|
4859
|
+
prebuild.addPermission({
|
|
4860
|
+
actions: [
|
|
4861
|
+
"sqs:SendMessage",
|
|
4862
|
+
"sqs:DeleteMessage",
|
|
4863
|
+
"sqs:ReceiveMessage",
|
|
4864
|
+
"sqs:GetQueueUrl",
|
|
4865
|
+
"sqs:GetQueueAttributes"
|
|
4866
|
+
],
|
|
4867
|
+
resources: [queue2.arn]
|
|
4868
|
+
});
|
|
4869
|
+
new aws10.lambda.EventSourceMapping(
|
|
4870
|
+
group,
|
|
4871
|
+
"on-failure",
|
|
4872
|
+
{
|
|
4873
|
+
functionName: prebuild.lambda.functionName,
|
|
4874
|
+
eventSourceArn: queue2.arn,
|
|
4875
|
+
batchSize: 10
|
|
4876
|
+
},
|
|
4877
|
+
{
|
|
4878
|
+
dependsOn: [prebuild.policy]
|
|
4879
|
+
}
|
|
4880
|
+
);
|
|
4881
|
+
new aws10.lambda.Permission(group, "permission", {
|
|
4882
|
+
action: "lambda:InvokeFunction",
|
|
4883
|
+
principal: "s3.amazonaws.com",
|
|
4884
|
+
functionName: prebuild.lambda.functionName,
|
|
4885
|
+
sourceArn: bucket.arn
|
|
4886
|
+
});
|
|
4887
|
+
new aws10.s3.BucketNotification(group, "notification", {
|
|
4888
|
+
bucket: bucket.bucket,
|
|
4889
|
+
lambdaFunction: [
|
|
4890
|
+
{
|
|
4891
|
+
lambdaFunctionArn: prebuild.lambda.arn,
|
|
4892
|
+
events: ["s3:ObjectCreated:*"]
|
|
4893
|
+
}
|
|
4894
|
+
]
|
|
4895
|
+
});
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
});
|
|
4899
|
+
|
|
4900
|
+
// src/feature/pubsub/index.ts
|
|
4901
|
+
import { Group as Group10 } from "@terraforge/core";
|
|
4902
|
+
import { aws as aws11 } from "@terraforge/aws";
|
|
4903
|
+
import { constantCase as constantCase5 } from "change-case";
|
|
4904
|
+
|
|
4905
|
+
// src/feature/domain/util.ts
|
|
4906
|
+
var getDomainNameById = (config2, id) => {
|
|
4907
|
+
const domains = config2.defaults.domains ?? {};
|
|
4908
|
+
if (id in domains) {
|
|
4909
|
+
if (domains[id]) {
|
|
4910
|
+
return domains[id].domain;
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
throw new TypeError(`No domain registered with id: ${id}`);
|
|
4914
|
+
};
|
|
4915
|
+
var formatFullDomainName = (config2, id, subDomain) => {
|
|
4916
|
+
const domain2 = getDomainNameById(config2, id);
|
|
4917
|
+
if (subDomain) {
|
|
4918
|
+
return `${subDomain.replace(/\.$/, "")}.${domain2}`;
|
|
4919
|
+
}
|
|
4920
|
+
return domain2;
|
|
4921
|
+
};
|
|
4922
|
+
|
|
4923
|
+
// src/feature/pubsub/index.ts
|
|
4924
|
+
import { minutes as minutes7, toSeconds as toSeconds5 } from "@awsless/duration";
|
|
4925
|
+
var pubsubFeature = defineFeature({
|
|
4926
|
+
name: "pubsub",
|
|
4927
|
+
onApp(ctx) {
|
|
4928
|
+
ctx.addGlobalPermission({
|
|
4929
|
+
actions: ["iot:Publish"],
|
|
4930
|
+
resources: [
|
|
4931
|
+
// `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`,
|
|
4932
|
+
`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/pubsub/*`
|
|
4933
|
+
]
|
|
4934
|
+
});
|
|
4935
|
+
for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
|
|
4936
|
+
const group = new Group10(ctx.base, "pubsub", id);
|
|
4937
|
+
const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, props.auth);
|
|
4938
|
+
const name = formatGlobalResourceName({
|
|
4939
|
+
appName: ctx.app.name,
|
|
4940
|
+
resourceType: "pubsub",
|
|
4941
|
+
resourceName: id
|
|
4942
|
+
});
|
|
4943
|
+
const authorizer = new aws11.iot.Authorizer(group, "authorizer", {
|
|
4944
|
+
name,
|
|
4945
|
+
authorizerFunctionArn: lambda.arn,
|
|
4946
|
+
status: "ACTIVE",
|
|
4947
|
+
signingDisabled: true,
|
|
4948
|
+
enableCachingForHttp: false
|
|
4949
|
+
});
|
|
4950
|
+
new aws11.lambda.Permission(group, "permission", {
|
|
4951
|
+
functionName: lambda.functionName,
|
|
4952
|
+
action: "lambda:InvokeFunction",
|
|
4953
|
+
principal: "iot.amazonaws.com",
|
|
4954
|
+
sourceArn: authorizer.arn
|
|
4955
|
+
});
|
|
4956
|
+
ctx.bind(`PUBSUB_${constantCase5(id)}_AUTHORIZER`, name);
|
|
4957
|
+
const endpoint = aws11.iot.getEndpoint(group, "endpoint", {
|
|
4958
|
+
endpointType: "iot:Data-ATS"
|
|
4959
|
+
});
|
|
4960
|
+
if (props.domain) {
|
|
4961
|
+
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
4962
|
+
new aws11.iot.DomainConfiguration(group, "domain", {
|
|
4963
|
+
name,
|
|
4964
|
+
domainName,
|
|
4965
|
+
serverCertificateArns: [ctx.shared.entry("domain", `certificate-arn`, props.domain)],
|
|
4966
|
+
authorizerConfig: {
|
|
4967
|
+
defaultAuthorizerName: authorizer.name
|
|
4968
|
+
}
|
|
4969
|
+
// validationCertificate: ctx.shared.get(`global-certificate-${props.domain}-arn`),
|
|
4970
|
+
});
|
|
4971
|
+
new aws11.route53.Record(group, "record", {
|
|
4972
|
+
zoneId: ctx.shared.entry("domain", `zone-id`, props.domain),
|
|
4973
|
+
name: domainName,
|
|
4974
|
+
type: "CNAME",
|
|
4975
|
+
ttl: toSeconds5(minutes7(5)),
|
|
4976
|
+
records: [endpoint.endpointAddress]
|
|
4591
4977
|
});
|
|
4592
4978
|
ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, domainName);
|
|
4593
4979
|
} else {
|
|
@@ -4597,7 +4983,7 @@ var pubsubFeature = defineFeature({
|
|
|
4597
4983
|
},
|
|
4598
4984
|
onStack(ctx) {
|
|
4599
4985
|
for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
|
|
4600
|
-
const group = new
|
|
4986
|
+
const group = new Group10(ctx.stack, "pubsub", id);
|
|
4601
4987
|
const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
|
|
4602
4988
|
const name = formatLocalResourceName({
|
|
4603
4989
|
appName: ctx.app.name,
|
|
@@ -4605,14 +4991,14 @@ var pubsubFeature = defineFeature({
|
|
|
4605
4991
|
resourceType: "pubsub",
|
|
4606
4992
|
resourceName: id
|
|
4607
4993
|
});
|
|
4608
|
-
const topic = new
|
|
4994
|
+
const topic = new aws11.iot.TopicRule(group, "rule", {
|
|
4609
4995
|
name: name.replaceAll("-", "_"),
|
|
4610
4996
|
enabled: true,
|
|
4611
4997
|
sql: props.sql,
|
|
4612
4998
|
sqlVersion: props.sqlVersion,
|
|
4613
4999
|
lambda: [{ functionArn: lambda.arn }]
|
|
4614
5000
|
});
|
|
4615
|
-
new
|
|
5001
|
+
new aws11.lambda.Permission(group, "permission", {
|
|
4616
5002
|
action: "lambda:InvokeFunction",
|
|
4617
5003
|
principal: "iot.amazonaws.com",
|
|
4618
5004
|
functionName: lambda.functionName,
|
|
@@ -4623,12 +5009,12 @@ var pubsubFeature = defineFeature({
|
|
|
4623
5009
|
});
|
|
4624
5010
|
|
|
4625
5011
|
// src/feature/queue/index.ts
|
|
4626
|
-
import { Group as
|
|
4627
|
-
import { aws as
|
|
5012
|
+
import { Group as Group11 } from "@terraforge/core";
|
|
5013
|
+
import { aws as aws12 } from "@terraforge/aws";
|
|
4628
5014
|
import { camelCase as camelCase5, constantCase as constantCase6 } from "change-case";
|
|
4629
5015
|
import deepmerge3 from "deepmerge";
|
|
4630
5016
|
import { relative as relative5 } from "path";
|
|
4631
|
-
import { seconds as
|
|
5017
|
+
import { seconds as seconds6, toSeconds as toSeconds6 } from "@awsless/duration";
|
|
4632
5018
|
import { toBytes } from "@awsless/size";
|
|
4633
5019
|
var typeGenCode4 = `
|
|
4634
5020
|
import { SendMessageOptions, SendMessageBatchOptions, BatchItem } from '@awsless/sqs'
|
|
@@ -4688,42 +5074,44 @@ var queueFeature = defineFeature({
|
|
|
4688
5074
|
gen.addInterface("QueueMockResponse", mockResponses);
|
|
4689
5075
|
await ctx.write("queue.d.ts", gen, true);
|
|
4690
5076
|
},
|
|
5077
|
+
onApp(ctx) {
|
|
5078
|
+
},
|
|
4691
5079
|
onStack(ctx) {
|
|
4692
5080
|
for (const [id, local] of Object.entries(ctx.stackConfig.queues || {})) {
|
|
4693
5081
|
const props = deepmerge3(ctx.appConfig.defaults.queue, typeof local === "object" ? local : {});
|
|
4694
|
-
const group = new
|
|
5082
|
+
const group = new Group11(ctx.stack, "queue", id);
|
|
4695
5083
|
const name = formatLocalResourceName({
|
|
4696
5084
|
appName: ctx.app.name,
|
|
4697
5085
|
stackName: ctx.stack.name,
|
|
4698
5086
|
resourceType: "queue",
|
|
4699
5087
|
resourceName: id
|
|
4700
5088
|
});
|
|
4701
|
-
const onFailure =
|
|
4702
|
-
const queue2 = new
|
|
5089
|
+
const onFailure = ctx.shared.get("on-failure", "queue-arn");
|
|
5090
|
+
const queue2 = new aws12.sqs.Queue(group, "queue", {
|
|
4703
5091
|
name,
|
|
4704
|
-
delaySeconds:
|
|
4705
|
-
visibilityTimeoutSeconds:
|
|
4706
|
-
receiveWaitTimeSeconds:
|
|
4707
|
-
messageRetentionSeconds:
|
|
5092
|
+
delaySeconds: toSeconds6(props.deliveryDelay),
|
|
5093
|
+
visibilityTimeoutSeconds: toSeconds6(props.visibilityTimeout),
|
|
5094
|
+
receiveWaitTimeSeconds: toSeconds6(props.receiveMessageWaitTime ?? seconds6(0)),
|
|
5095
|
+
messageRetentionSeconds: toSeconds6(props.retentionPeriod),
|
|
4708
5096
|
maxMessageSize: toBytes(props.maxMessageSize),
|
|
4709
5097
|
redrivePolicy: onFailure.pipe(
|
|
4710
5098
|
(arn) => JSON.stringify({
|
|
4711
5099
|
deadLetterTargetArn: arn,
|
|
4712
|
-
maxReceiveCount:
|
|
5100
|
+
maxReceiveCount: props.retryAttempts + 1
|
|
4713
5101
|
})
|
|
4714
5102
|
)
|
|
4715
5103
|
});
|
|
4716
5104
|
if (local.consumer) {
|
|
4717
5105
|
const lambdaConsumer = createLambdaFunction(group, ctx, `queue`, id, local.consumer);
|
|
4718
5106
|
lambdaConsumer.setEnvironment("THROW_EXPECTED_ERRORS", "1");
|
|
4719
|
-
new
|
|
5107
|
+
new aws12.lambda.EventSourceMapping(
|
|
4720
5108
|
group,
|
|
4721
5109
|
"event",
|
|
4722
5110
|
{
|
|
4723
5111
|
functionName: lambdaConsumer.lambda.functionName,
|
|
4724
5112
|
eventSourceArn: queue2.arn,
|
|
4725
5113
|
batchSize: props.batchSize,
|
|
4726
|
-
maximumBatchingWindowInSeconds: props.maxBatchingWindow &&
|
|
5114
|
+
maximumBatchingWindowInSeconds: props.maxBatchingWindow && toSeconds6(props.maxBatchingWindow),
|
|
4727
5115
|
scalingConfig: {
|
|
4728
5116
|
maximumConcurrency: props.maxConcurrency
|
|
4729
5117
|
}
|
|
@@ -4759,24 +5147,24 @@ var queueFeature = defineFeature({
|
|
|
4759
5147
|
});
|
|
4760
5148
|
|
|
4761
5149
|
// src/feature/rest/index.ts
|
|
4762
|
-
import { Group as
|
|
4763
|
-
import { aws as
|
|
5150
|
+
import { Group as Group12 } from "@terraforge/core";
|
|
5151
|
+
import { aws as aws13 } from "@terraforge/aws";
|
|
4764
5152
|
import { constantCase as constantCase7 } from "change-case";
|
|
4765
5153
|
var restFeature = defineFeature({
|
|
4766
5154
|
name: "rest",
|
|
4767
5155
|
onApp(ctx) {
|
|
4768
5156
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults?.rest ?? {})) {
|
|
4769
|
-
const group = new
|
|
5157
|
+
const group = new Group12(ctx.base, "rest", id);
|
|
4770
5158
|
const name = formatGlobalResourceName({
|
|
4771
5159
|
appName: ctx.app.name,
|
|
4772
5160
|
resourceType: "rest",
|
|
4773
5161
|
resourceName: id
|
|
4774
5162
|
});
|
|
4775
|
-
const api = new
|
|
5163
|
+
const api = new aws13.apigatewayv2.Api(group, "api", {
|
|
4776
5164
|
name,
|
|
4777
5165
|
protocolType: "HTTP"
|
|
4778
5166
|
});
|
|
4779
|
-
const stage = new
|
|
5167
|
+
const stage = new aws13.apigatewayv2.Stage(group, "stage", {
|
|
4780
5168
|
name: "v1",
|
|
4781
5169
|
apiId: api.id,
|
|
4782
5170
|
autoDeploy: true
|
|
@@ -4786,7 +5174,7 @@ var restFeature = defineFeature({
|
|
|
4786
5174
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
4787
5175
|
const zoneId = ctx.shared.entry("domain", `zone-id`, props.domain);
|
|
4788
5176
|
const certificateArn = ctx.shared.entry("domain", `certificate-arn`, props.domain);
|
|
4789
|
-
const domain2 = new
|
|
5177
|
+
const domain2 = new aws13.apigatewayv2.DomainName(group, "domain", {
|
|
4790
5178
|
domainName,
|
|
4791
5179
|
domainNameConfiguration: {
|
|
4792
5180
|
certificateArn,
|
|
@@ -4794,12 +5182,12 @@ var restFeature = defineFeature({
|
|
|
4794
5182
|
securityPolicy: "TLS_1_2"
|
|
4795
5183
|
}
|
|
4796
5184
|
});
|
|
4797
|
-
const mapping = new
|
|
5185
|
+
const mapping = new aws13.apigatewayv2.ApiMapping(group, "mapping", {
|
|
4798
5186
|
apiId: api.id,
|
|
4799
5187
|
domainName: domain2.domainName,
|
|
4800
5188
|
stage: stage.name
|
|
4801
5189
|
});
|
|
4802
|
-
new
|
|
5190
|
+
new aws13.route53.Record(
|
|
4803
5191
|
group,
|
|
4804
5192
|
"record",
|
|
4805
5193
|
{
|
|
@@ -4827,21 +5215,21 @@ var restFeature = defineFeature({
|
|
|
4827
5215
|
},
|
|
4828
5216
|
onStack(ctx) {
|
|
4829
5217
|
for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
|
|
4830
|
-
const restGroup = new
|
|
5218
|
+
const restGroup = new Group12(ctx.stack, "rest", id);
|
|
4831
5219
|
for (const [routeKey, props] of Object.entries(routes)) {
|
|
4832
|
-
const group = new
|
|
5220
|
+
const group = new Group12(restGroup, "route", routeKey);
|
|
4833
5221
|
const apiId = ctx.shared.entry("rest", "id", id);
|
|
4834
5222
|
const routeId = shortId(routeKey);
|
|
4835
5223
|
const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
|
|
4836
5224
|
...props,
|
|
4837
5225
|
description: `${id} ${routeKey}`
|
|
4838
5226
|
});
|
|
4839
|
-
const permission = new
|
|
5227
|
+
const permission = new aws13.lambda.Permission(group, "permission", {
|
|
4840
5228
|
action: "lambda:InvokeFunction",
|
|
4841
5229
|
principal: "apigateway.amazonaws.com",
|
|
4842
5230
|
functionName: lambda.functionName
|
|
4843
5231
|
});
|
|
4844
|
-
const integration = new
|
|
5232
|
+
const integration = new aws13.apigatewayv2.Integration(group, "integration", {
|
|
4845
5233
|
apiId,
|
|
4846
5234
|
description: `${id} ${routeKey}`,
|
|
4847
5235
|
integrationType: "AWS_PROXY",
|
|
@@ -4851,7 +5239,7 @@ var restFeature = defineFeature({
|
|
|
4851
5239
|
return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
|
|
4852
5240
|
})
|
|
4853
5241
|
});
|
|
4854
|
-
new
|
|
5242
|
+
new aws13.apigatewayv2.Route(
|
|
4855
5243
|
group,
|
|
4856
5244
|
"route",
|
|
4857
5245
|
{
|
|
@@ -4872,200 +5260,11 @@ var restFeature = defineFeature({
|
|
|
4872
5260
|
import { camelCase as camelCase6, constantCase as constantCase8, kebabCase as kebabCase6 } from "change-case";
|
|
4873
5261
|
import { Group as Group13 } from "@terraforge/core";
|
|
4874
5262
|
import { aws as aws14 } from "@terraforge/aws";
|
|
4875
|
-
import { mebibytes as
|
|
4876
|
-
import { dirname as dirname5, join as
|
|
5263
|
+
import { mebibytes as mebibytes4 } from "@awsless/size";
|
|
5264
|
+
import { dirname as dirname5, join as join11, relative as relative6 } from "path";
|
|
4877
5265
|
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
5266
|
import { toSeconds as toSeconds7 } from "@awsless/duration";
|
|
5068
|
-
var
|
|
5267
|
+
var __dirname2 = dirname5(fileURLToPath(import.meta.url));
|
|
5069
5268
|
var rpcFeature = defineFeature({
|
|
5070
5269
|
name: "rpc",
|
|
5071
5270
|
async onTypeGen(ctx) {
|
|
@@ -5125,9 +5324,9 @@ var rpcFeature = defineFeature({
|
|
|
5125
5324
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.rpc ?? {})) {
|
|
5126
5325
|
const group = new Group13(ctx.base, "rpc", id);
|
|
5127
5326
|
const result = createPrebuildLambdaFunction(group, ctx, "rpc", id, {
|
|
5128
|
-
bundleFile:
|
|
5129
|
-
bundleHash:
|
|
5130
|
-
memorySize:
|
|
5327
|
+
bundleFile: join11(__dirname2, "/prebuild/rpc/bundle.zip"),
|
|
5328
|
+
bundleHash: join11(__dirname2, "/prebuild/rpc/HASH"),
|
|
5329
|
+
memorySize: mebibytes4(256),
|
|
5131
5330
|
timeout: props.timeout,
|
|
5132
5331
|
handler: "index.default",
|
|
5133
5332
|
runtime: "nodejs22.x",
|
|
@@ -5394,7 +5593,7 @@ var searchFeature = defineFeature({
|
|
|
5394
5593
|
import { Group as Group15 } from "@terraforge/core";
|
|
5395
5594
|
import { aws as aws16 } from "@terraforge/aws";
|
|
5396
5595
|
import { glob as glob2 } from "glob";
|
|
5397
|
-
import { dirname as dirname6, join as
|
|
5596
|
+
import { dirname as dirname6, join as join12 } from "path";
|
|
5398
5597
|
|
|
5399
5598
|
// src/feature/site/util.ts
|
|
5400
5599
|
import { contentType, lookup } from "mime-types";
|
|
@@ -5440,7 +5639,7 @@ var siteFeature = defineFeature({
|
|
|
5440
5639
|
return build3(fingerprint, async (write) => {
|
|
5441
5640
|
const credentialProvider = await getCredentials(ctx.appConfig.profile);
|
|
5442
5641
|
const credentials = await credentialProvider();
|
|
5443
|
-
const cwd =
|
|
5642
|
+
const cwd = join12(directories.root, dirname6(ctx.stackConfig.file));
|
|
5444
5643
|
const env = {
|
|
5445
5644
|
...process.env,
|
|
5446
5645
|
// Pass the app config name
|
|
@@ -5585,20 +5784,20 @@ var siteFeature = defineFeature({
|
|
|
5585
5784
|
});
|
|
5586
5785
|
const staticRoutes = {};
|
|
5587
5786
|
for (const file of files) {
|
|
5588
|
-
const prefixedFile =
|
|
5787
|
+
const prefixedFile = join12("/", file);
|
|
5589
5788
|
const object = new aws16.s3.BucketObject(group, prefixedFile, {
|
|
5590
5789
|
bucket: bucket.bucket,
|
|
5591
5790
|
key: prefixedFile,
|
|
5592
5791
|
cacheControl: getCacheControl(file),
|
|
5593
5792
|
contentType: getContentType(file),
|
|
5594
|
-
source:
|
|
5595
|
-
sourceHash: $hash(
|
|
5793
|
+
source: join12(props.static, file),
|
|
5794
|
+
sourceHash: $hash(join12(props.static, file))
|
|
5596
5795
|
});
|
|
5597
5796
|
versions.push(object.key);
|
|
5598
5797
|
versions.push(object.sourceHash);
|
|
5599
5798
|
const strippedHtmlFile = file.endsWith("index.html") ? file.slice(0, -11) : file.endsWith(".html") ? file.slice(0, -5) : file;
|
|
5600
5799
|
const urlFriendlyFile = strippedHtmlFile.endsWith("/") ? strippedHtmlFile.slice(0, -1) : strippedHtmlFile;
|
|
5601
|
-
const routeFileKey =
|
|
5800
|
+
const routeFileKey = join12(props.path, urlFriendlyFile);
|
|
5602
5801
|
staticRoutes[routeFileKey] = {
|
|
5603
5802
|
type: "s3",
|
|
5604
5803
|
domainName: bucket.bucketRegionalDomainName,
|
|
@@ -5641,7 +5840,7 @@ var getContentType2 = (file) => {
|
|
|
5641
5840
|
};
|
|
5642
5841
|
|
|
5643
5842
|
// src/feature/store/index.ts
|
|
5644
|
-
import { join as
|
|
5843
|
+
import { join as join13 } from "path";
|
|
5645
5844
|
var typeGenCode6 = `
|
|
5646
5845
|
import { Body, PutObjectProps, BodyStream } from '@awsless/s3'
|
|
5647
5846
|
|
|
@@ -5697,7 +5896,14 @@ var storeFeature = defineFeature({
|
|
|
5697
5896
|
//
|
|
5698
5897
|
`arn:aws:s3:::${name}`,
|
|
5699
5898
|
`arn:aws:s3:::${name}/*`
|
|
5700
|
-
]
|
|
5899
|
+
],
|
|
5900
|
+
conditions: {
|
|
5901
|
+
StringEquals: {
|
|
5902
|
+
// This will protect anyone from taking our bucket name,
|
|
5903
|
+
// and us sending our items to the wrong s3 bucket
|
|
5904
|
+
"s3:ResourceAccount": ctx.accountId
|
|
5905
|
+
}
|
|
5906
|
+
}
|
|
5701
5907
|
});
|
|
5702
5908
|
},
|
|
5703
5909
|
onStack(ctx) {
|
|
@@ -5746,8 +5952,8 @@ var storeFeature = defineFeature({
|
|
|
5746
5952
|
key: file,
|
|
5747
5953
|
cacheControl: getCacheControl2(file),
|
|
5748
5954
|
contentType: getContentType2(file),
|
|
5749
|
-
source:
|
|
5750
|
-
sourceHash: $hash(
|
|
5955
|
+
source: join13(props.static, file),
|
|
5956
|
+
sourceHash: $hash(join13(props.static, file))
|
|
5751
5957
|
});
|
|
5752
5958
|
}
|
|
5753
5959
|
}
|
|
@@ -5800,7 +6006,14 @@ var storeFeature = defineFeature({
|
|
|
5800
6006
|
//
|
|
5801
6007
|
bucket.arn,
|
|
5802
6008
|
bucket.arn.pipe((arn) => `${arn}/*`)
|
|
5803
|
-
]
|
|
6009
|
+
],
|
|
6010
|
+
conditions: {
|
|
6011
|
+
StringEquals: {
|
|
6012
|
+
// This will protect anyone from taking our bucket name,
|
|
6013
|
+
// and us sending our items to the wrong s3 bucket
|
|
6014
|
+
"s3:ResourceAccount": ctx.accountId
|
|
6015
|
+
}
|
|
6016
|
+
}
|
|
5804
6017
|
});
|
|
5805
6018
|
}
|
|
5806
6019
|
}
|
|
@@ -5939,7 +6152,7 @@ var tableFeature = defineFeature({
|
|
|
5939
6152
|
functionName: result.lambda.functionName,
|
|
5940
6153
|
eventSourceArn: table.streamArn,
|
|
5941
6154
|
// tumblingWindowInSeconds
|
|
5942
|
-
|
|
6155
|
+
maximumRecordAgeInSeconds: toSeconds8(props.stream.maxRecordAge),
|
|
5943
6156
|
// bisectBatchOnFunctionError: true,
|
|
5944
6157
|
batchSize: props.stream.batchSize,
|
|
5945
6158
|
maximumBatchingWindowInSeconds: props.stream.batchWindow ? toSeconds8(props.stream.batchWindow) : void 0,
|
|
@@ -5955,6 +6168,17 @@ var tableFeature = defineFeature({
|
|
|
5955
6168
|
},
|
|
5956
6169
|
{ dependsOn: [result.policy] }
|
|
5957
6170
|
);
|
|
6171
|
+
result.addPermission({
|
|
6172
|
+
actions: ["s3:PutObject", "s3:ListBucket"],
|
|
6173
|
+
resources: [onFailure, $interpolate`${onFailure}/*`],
|
|
6174
|
+
conditions: {
|
|
6175
|
+
StringEquals: {
|
|
6176
|
+
// This will protect anyone from taking our bucket name,
|
|
6177
|
+
// and us sending our failed items to the wrong s3 bucket
|
|
6178
|
+
"s3:ResourceAccount": ctx.accountId
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
});
|
|
5958
6182
|
result.addPermission({
|
|
5959
6183
|
actions: [
|
|
5960
6184
|
"dynamodb:ListStreams",
|
|
@@ -5964,10 +6188,6 @@ var tableFeature = defineFeature({
|
|
|
5964
6188
|
],
|
|
5965
6189
|
resources: [table.streamArn]
|
|
5966
6190
|
});
|
|
5967
|
-
result.addPermission({
|
|
5968
|
-
actions: ["sqs:SendMessage", "sqs:GetQueueUrl"],
|
|
5969
|
-
resources: [onFailure]
|
|
5970
|
-
});
|
|
5971
6191
|
}
|
|
5972
6192
|
ctx.addStackPermission({
|
|
5973
6193
|
actions: [
|
|
@@ -6497,12 +6717,12 @@ var layerFeature = defineFeature({
|
|
|
6497
6717
|
// src/feature/image/index.ts
|
|
6498
6718
|
import { Group as Group23 } from "@terraforge/core";
|
|
6499
6719
|
import { aws as aws24 } from "@terraforge/aws";
|
|
6500
|
-
import { join as
|
|
6501
|
-
import { mebibytes as
|
|
6720
|
+
import { join as join14, dirname as dirname7 } from "path";
|
|
6721
|
+
import { mebibytes as mebibytes5 } from "@awsless/size";
|
|
6502
6722
|
import { seconds as seconds7, toDays as toDays6 } from "@awsless/duration";
|
|
6503
6723
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6504
6724
|
import { glob as glob4 } from "glob";
|
|
6505
|
-
var
|
|
6725
|
+
var __dirname3 = dirname7(fileURLToPath2(import.meta.url));
|
|
6506
6726
|
var imageFeature = defineFeature({
|
|
6507
6727
|
name: "image",
|
|
6508
6728
|
onApp(ctx) {
|
|
@@ -6513,7 +6733,7 @@ var imageFeature = defineFeature({
|
|
|
6513
6733
|
return;
|
|
6514
6734
|
}
|
|
6515
6735
|
const group = new Group23(ctx.base, "image", "layer");
|
|
6516
|
-
const path =
|
|
6736
|
+
const path = join14(__dirname3, "/layers/sharp-arm.zip");
|
|
6517
6737
|
const layerId = formatGlobalResourceName({
|
|
6518
6738
|
appName: ctx.appConfig.name,
|
|
6519
6739
|
resourceType: "layer",
|
|
@@ -6602,9 +6822,9 @@ var imageFeature = defineFeature({
|
|
|
6602
6822
|
resourceName: "sharp"
|
|
6603
6823
|
});
|
|
6604
6824
|
const serverLambda = createPrebuildLambdaFunction(group, ctx, "image", id, {
|
|
6605
|
-
bundleFile:
|
|
6606
|
-
bundleHash:
|
|
6607
|
-
memorySize:
|
|
6825
|
+
bundleFile: join14(__dirname3, "/prebuild/image/bundle.zip"),
|
|
6826
|
+
bundleHash: join14(__dirname3, "/prebuild/image/HASH"),
|
|
6827
|
+
memorySize: mebibytes5(512),
|
|
6608
6828
|
timeout: seconds7(10),
|
|
6609
6829
|
handler: "index.default",
|
|
6610
6830
|
runtime: "nodejs22.x",
|
|
@@ -6678,8 +6898,8 @@ var imageFeature = defineFeature({
|
|
|
6678
6898
|
new aws24.s3.BucketObject(group, `static-${file}`, {
|
|
6679
6899
|
bucket: s3Origin.bucket,
|
|
6680
6900
|
key: file,
|
|
6681
|
-
source:
|
|
6682
|
-
sourceHash: $hash(
|
|
6901
|
+
source: join14(props.origin.static, file),
|
|
6902
|
+
sourceHash: $hash(join14(props.origin.static, file))
|
|
6683
6903
|
});
|
|
6684
6904
|
}
|
|
6685
6905
|
}
|
|
@@ -6694,12 +6914,12 @@ var imageFeature = defineFeature({
|
|
|
6694
6914
|
// src/feature/icon/index.ts
|
|
6695
6915
|
import { Group as Group24 } from "@terraforge/core";
|
|
6696
6916
|
import { aws as aws25 } from "@terraforge/aws";
|
|
6697
|
-
import { join as
|
|
6698
|
-
import { mebibytes as
|
|
6917
|
+
import { join as join15, dirname as dirname8 } from "path";
|
|
6918
|
+
import { mebibytes as mebibytes6 } from "@awsless/size";
|
|
6699
6919
|
import { seconds as seconds8, toDays as toDays7 } from "@awsless/duration";
|
|
6700
6920
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6701
6921
|
import { glob as glob5 } from "glob";
|
|
6702
|
-
var
|
|
6922
|
+
var __dirname4 = dirname8(fileURLToPath3(import.meta.url));
|
|
6703
6923
|
var iconFeature = defineFeature({
|
|
6704
6924
|
name: "icon",
|
|
6705
6925
|
onStack(ctx) {
|
|
@@ -6748,9 +6968,9 @@ var iconFeature = defineFeature({
|
|
|
6748
6968
|
} : {}
|
|
6749
6969
|
});
|
|
6750
6970
|
const serverLambda = createPrebuildLambdaFunction(group, ctx, "icon", id, {
|
|
6751
|
-
bundleFile:
|
|
6752
|
-
bundleHash:
|
|
6753
|
-
memorySize:
|
|
6971
|
+
bundleFile: join15(__dirname4, "/prebuild/icon/bundle.zip"),
|
|
6972
|
+
bundleHash: join15(__dirname4, "/prebuild/icon/HASH"),
|
|
6973
|
+
memorySize: mebibytes6(512),
|
|
6754
6974
|
timeout: seconds8(10),
|
|
6755
6975
|
handler: "index.default",
|
|
6756
6976
|
runtime: "nodejs22.x",
|
|
@@ -6826,8 +7046,8 @@ var iconFeature = defineFeature({
|
|
|
6826
7046
|
new aws25.s3.BucketObject(group, `static-${file}`, {
|
|
6827
7047
|
bucket: s3Origin.bucket,
|
|
6828
7048
|
key: file,
|
|
6829
|
-
source:
|
|
6830
|
-
sourceHash: $hash(
|
|
7049
|
+
source: join15(props.origin.static, file),
|
|
7050
|
+
sourceHash: $hash(join15(props.origin.static, file))
|
|
6831
7051
|
});
|
|
6832
7052
|
}
|
|
6833
7053
|
}
|
|
@@ -6851,14 +7071,14 @@ import { aws as aws26 } from "@terraforge/aws";
|
|
|
6851
7071
|
import { Group as Group25, Output as Output6, findInputDeps as findInputDeps3, resolveInputs as resolveInputs3 } from "@terraforge/core";
|
|
6852
7072
|
import { constantCase as constantCase12, pascalCase as pascalCase3 } from "change-case";
|
|
6853
7073
|
import deepmerge4 from "deepmerge";
|
|
6854
|
-
import { join as
|
|
7074
|
+
import { join as join17 } from "path";
|
|
6855
7075
|
|
|
6856
7076
|
// src/feature/instance/build/executable.ts
|
|
6857
7077
|
import { createHash as createHash3 } from "crypto";
|
|
6858
7078
|
import { readFile as readFile4 } from "fs/promises";
|
|
6859
|
-
import { join as
|
|
7079
|
+
import { join as join16 } from "path";
|
|
6860
7080
|
var buildExecutable = async (input, outputPath, architecture) => {
|
|
6861
|
-
const filePath =
|
|
7081
|
+
const filePath = join16(outputPath, "program");
|
|
6862
7082
|
const target = architecture === "x86_64" ? "bun-linux-x64" : "bun-linux-arm64";
|
|
6863
7083
|
let result;
|
|
6864
7084
|
try {
|
|
@@ -7102,7 +7322,7 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
|
|
|
7102
7322
|
healthCheck: props.healthCheck ? {
|
|
7103
7323
|
command: [
|
|
7104
7324
|
"CMD-SHELL",
|
|
7105
|
-
`curl -f http://${
|
|
7325
|
+
`curl -f http://${join17("localhost", props.healthCheck.path)} || exit 1`
|
|
7106
7326
|
],
|
|
7107
7327
|
interval: toSeconds9(props.healthCheck.interval),
|
|
7108
7328
|
retries: props.healthCheck.retries,
|
|
@@ -7387,7 +7607,13 @@ import { camelCase as camelCase8, constantCase as constantCase14 } from "change-
|
|
|
7387
7607
|
var getViewerRequestFunctionCode = (props) => {
|
|
7388
7608
|
return CODE([
|
|
7389
7609
|
props.blockDirectAccess ? BLOCK_DIRECT_ACCESS_TO_CLOUDFRONT : "",
|
|
7390
|
-
props.
|
|
7610
|
+
props.passwordAuth ?? props.basicAuth ? AUTH_WRAPPER(
|
|
7611
|
+
[
|
|
7612
|
+
//
|
|
7613
|
+
props.basicAuth ? BASIC_AUTH_CHECK(props.basicAuth.username, props.basicAuth.password) : "",
|
|
7614
|
+
props.passwordAuth ? PASSWORD_AUTH_CHECK(props.passwordAuth.password) : ""
|
|
7615
|
+
].join("\n")
|
|
7616
|
+
) : ""
|
|
7391
7617
|
]);
|
|
7392
7618
|
};
|
|
7393
7619
|
var BLOCK_DIRECT_ACCESS_TO_CLOUDFRONT = `
|
|
@@ -7398,13 +7624,36 @@ if (headers.host && headers.host.value.includes('cloudfront.net')) {
|
|
|
7398
7624
|
};
|
|
7399
7625
|
}`;
|
|
7400
7626
|
var BASIC_AUTH_CHECK = (username, password) => `
|
|
7401
|
-
|
|
7402
|
-
|
|
7627
|
+
authMethods.push('Basic realm="Protected"');
|
|
7628
|
+
|
|
7629
|
+
if(!isAuthorized) {
|
|
7630
|
+
if(authHeader && authHeader.startsWith('Basic ') && authHeader.slice(6) === '${Buffer.from(`${username}:${password}`).toString("base64")}') {
|
|
7631
|
+
isAuthorized = true;
|
|
7632
|
+
}
|
|
7633
|
+
}
|
|
7634
|
+
`;
|
|
7635
|
+
var PASSWORD_AUTH_CHECK = (password) => `
|
|
7636
|
+
authMethods.push('Password realm="Protected"');
|
|
7637
|
+
|
|
7638
|
+
if(!isAuthorized) {
|
|
7639
|
+
if(authHeader && authHeader.startsWith('Password ') && authHeader.slice(9) === '${password}') {
|
|
7640
|
+
isAuthorized = true;
|
|
7641
|
+
}
|
|
7642
|
+
}
|
|
7643
|
+
`;
|
|
7644
|
+
var AUTH_WRAPPER = (code) => `
|
|
7645
|
+
const authHeader = headers.authorization && headers.authorization.value;
|
|
7646
|
+
const authMethods = [];
|
|
7647
|
+
let isAuthorized = false;
|
|
7648
|
+
|
|
7649
|
+
${code}
|
|
7650
|
+
|
|
7651
|
+
if (!isAuthorized) {
|
|
7403
7652
|
return {
|
|
7404
7653
|
statusCode: 401,
|
|
7405
7654
|
headers: {
|
|
7406
7655
|
'www-authenticate': {
|
|
7407
|
-
value: '
|
|
7656
|
+
value: authMethods.join(', ')
|
|
7408
7657
|
}
|
|
7409
7658
|
}
|
|
7410
7659
|
};
|
|
@@ -7723,7 +7972,8 @@ var routerFeature = defineFeature({
|
|
|
7723
7972
|
keyValueStoreAssociations: [routeStore.arn],
|
|
7724
7973
|
code: getViewerRequestFunctionCode({
|
|
7725
7974
|
blockDirectAccess: !!props.domain,
|
|
7726
|
-
basicAuth: props.basicAuth
|
|
7975
|
+
basicAuth: props.basicAuth,
|
|
7976
|
+
passwordAuth: props.passwordAuth
|
|
7727
7977
|
})
|
|
7728
7978
|
});
|
|
7729
7979
|
const wafSettingsConfig = props.waf;
|
|
@@ -9085,20 +9335,20 @@ import wildstring4 from "wildstring";
|
|
|
9085
9335
|
// src/cli/ui/complex/run-tests.ts
|
|
9086
9336
|
import { log as log18 } from "@awsless/clui";
|
|
9087
9337
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
|
|
9088
|
-
import { join as
|
|
9338
|
+
import { join as join19 } from "path";
|
|
9089
9339
|
import wildstring3 from "wildstring";
|
|
9090
9340
|
import { parse as parse4, stringify } from "@awsless/json";
|
|
9091
9341
|
import { generateFolderHash, loadWorkspace as loadWorkspace2 } from "@awsless/ts-file-cache";
|
|
9092
9342
|
|
|
9093
9343
|
// src/test/start.ts
|
|
9094
|
-
import { dirname as dirname9, join as
|
|
9344
|
+
import { dirname as dirname9, join as join18 } from "path";
|
|
9095
9345
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
9096
9346
|
import { configDefaults } from "vitest/config";
|
|
9097
9347
|
import { startVitest } from "vitest/node";
|
|
9098
9348
|
var NullReporter = class {
|
|
9099
9349
|
};
|
|
9100
9350
|
var startTest = async (props) => {
|
|
9101
|
-
const
|
|
9351
|
+
const __dirname5 = dirname9(fileURLToPath4(import.meta.url));
|
|
9102
9352
|
const startTime = process.hrtime.bigint();
|
|
9103
9353
|
process.noDeprecation = true;
|
|
9104
9354
|
const vitest = await startVitest(
|
|
@@ -9129,7 +9379,7 @@ var startTest = async (props) => {
|
|
|
9129
9379
|
// },
|
|
9130
9380
|
setupFiles: [
|
|
9131
9381
|
//
|
|
9132
|
-
|
|
9382
|
+
join18(__dirname5, "test-global-setup.js")
|
|
9133
9383
|
]
|
|
9134
9384
|
// globalSetup: [
|
|
9135
9385
|
// //
|
|
@@ -9323,7 +9573,7 @@ var logTestErrors = (event) => {
|
|
|
9323
9573
|
};
|
|
9324
9574
|
var runTest = async (stack, dir, filters, workspace, opts) => {
|
|
9325
9575
|
await mkdir4(directories.test, { recursive: true });
|
|
9326
|
-
const file =
|
|
9576
|
+
const file = join19(directories.test, `${stack}.json`);
|
|
9327
9577
|
const fingerprint = await generateFolderHash(workspace, dir);
|
|
9328
9578
|
if (!process.env.NO_CACHE) {
|
|
9329
9579
|
const exists = await fileExist(file);
|
|
@@ -10008,7 +10258,7 @@ import { log as log25 } from "@awsless/clui";
|
|
|
10008
10258
|
|
|
10009
10259
|
// src/type-gen/generate.ts
|
|
10010
10260
|
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
10011
|
-
import { dirname as dirname10, join as
|
|
10261
|
+
import { dirname as dirname10, join as join20, relative as relative8 } from "path";
|
|
10012
10262
|
var generateTypes = async (props) => {
|
|
10013
10263
|
const files = [];
|
|
10014
10264
|
await Promise.all(
|
|
@@ -10017,7 +10267,7 @@ var generateTypes = async (props) => {
|
|
|
10017
10267
|
...props,
|
|
10018
10268
|
async write(file, data, include = false) {
|
|
10019
10269
|
const code = data?.toString("utf8");
|
|
10020
|
-
const path =
|
|
10270
|
+
const path = join20(directories.types, file);
|
|
10021
10271
|
if (code) {
|
|
10022
10272
|
if (include) {
|
|
10023
10273
|
files.push(relative8(directories.root, path));
|
|
@@ -10031,7 +10281,7 @@ var generateTypes = async (props) => {
|
|
|
10031
10281
|
);
|
|
10032
10282
|
if (files.length) {
|
|
10033
10283
|
const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
|
|
10034
|
-
await writeFile4(
|
|
10284
|
+
await writeFile4(join20(directories.root, `awsless.d.ts`), code);
|
|
10035
10285
|
}
|
|
10036
10286
|
};
|
|
10037
10287
|
|