@awsless/awsless 0.0.654 → 0.0.656

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