@awsless/awsless 0.0.84 → 0.0.86

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.
Files changed (28) hide show
  1. package/dist/bin.js +746 -380
  2. package/dist/features/cognito-client-secret/HASH +1 -0
  3. package/dist/features/cognito-client-secret/bundle.zip +0 -0
  4. package/dist/features/cognito-client-secret/index.js +61 -0
  5. package/dist/features/cognito-client-secret/index.mjs +59 -0
  6. package/dist/features/delete-bucket/HASH +1 -0
  7. package/dist/features/delete-bucket/bundle.zip +0 -0
  8. package/dist/features/delete-bucket/index.js +88 -0
  9. package/dist/features/{delete-bucket.js → delete-bucket/index.mjs} +2 -2
  10. package/dist/features/delete-hosted-zone/HASH +1 -0
  11. package/dist/features/delete-hosted-zone/bundle.zip +0 -0
  12. package/dist/features/delete-hosted-zone/index.js +130 -0
  13. package/dist/features/{delete-hosted-zone.js → delete-hosted-zone/index.mjs} +2 -2
  14. package/dist/features/global-exports/HASH +1 -0
  15. package/dist/features/global-exports/bundle.zip +0 -0
  16. package/dist/features/global-exports/index.js +63 -0
  17. package/dist/features/{global-exports.js → global-exports/index.mjs} +2 -2
  18. package/dist/features/invalidate-cache/HASH +1 -0
  19. package/dist/features/invalidate-cache/bundle.zip +0 -0
  20. package/dist/features/invalidate-cache/index.js +63 -0
  21. package/dist/features/{invalidate-cache.js → invalidate-cache/index.mjs} +2 -2
  22. package/dist/features/upload-bucket-asset/HASH +1 -0
  23. package/dist/features/upload-bucket-asset/bundle.zip +0 -0
  24. package/dist/features/upload-bucket-asset/index.js +22015 -0
  25. package/dist/features/{upload-bucket-asset.js → upload-bucket-asset/index.mjs} +2 -2
  26. package/dist/index.d.ts +57 -13
  27. package/dist/index.js +24 -9
  28. package/package.json +5 -2
package/dist/bin.js CHANGED
@@ -591,8 +591,8 @@ var Stack = class {
591
591
  return node;
592
592
  };
593
593
  for (const resource of this.resources) {
594
- const json2 = walk(resource.toJSON());
595
- Object.assign(resources, json2);
594
+ const json3 = walk(resource.toJSON());
595
+ Object.assign(resources, json3);
596
596
  }
597
597
  for (let [name, value] of this.exports.entries()) {
598
598
  Object.assign(outputs, {
@@ -892,7 +892,11 @@ import json from "@rollup/plugin-json";
892
892
  import commonjs from "@rollup/plugin-commonjs";
893
893
  import nodeResolve from "@rollup/plugin-node-resolve";
894
894
  import { dirname } from "path";
895
- var rollupBundle = ({ format: format2 = "esm", minify = true, handler = "default" } = {}) => {
895
+ var rollupBundle = ({
896
+ format: format2 = "esm",
897
+ minify = true,
898
+ handler = "default"
899
+ } = {}) => {
896
900
  return async (input) => {
897
901
  const bundle = await rollup({
898
902
  input,
@@ -977,6 +981,7 @@ var zipFiles = (files) => {
977
981
  };
978
982
 
979
983
  // src/formation/resource/lambda/code.ts
984
+ import { readFile } from "fs/promises";
980
985
  import { fileURLToPath } from "url";
981
986
  import { join } from "path";
982
987
  var Code = class {
@@ -993,21 +998,10 @@ var Code = class {
993
998
  // return new ZipFileCode(id, file, hash, handler)
994
999
  // }
995
1000
  static fromFeature(id) {
996
- const root2 = fileURLToPath(new URL(".", import.meta.url));
997
- const file = join(root2, `features/${id}.js`);
998
- return new FileCode(id, file, rollupBundle({
999
- minify: false,
1000
- handler: "handler"
1001
- }));
1001
+ return new FeatureCode(id);
1002
1002
  }
1003
1003
  static fromInlineFeature(id) {
1004
- const root2 = fileURLToPath(new URL(".", import.meta.url));
1005
- const file = join(root2, `features/${id}.js`);
1006
- return new InlineFileCode(id, file, rollupBundle({
1007
- format: "cjs",
1008
- minify: false,
1009
- handler: "handler"
1010
- }));
1004
+ return new InlineFeatureCode(id);
1011
1005
  }
1012
1006
  };
1013
1007
  var InlineCode = class {
@@ -1034,11 +1028,12 @@ var InlineFileCode = class extends Asset {
1034
1028
  handler;
1035
1029
  async build({ write }) {
1036
1030
  const bundler = this.bundler ?? rollupBundle();
1037
- const { hash, files: [file], handler } = await bundler(this.file);
1038
- await Promise.all([
1039
- write("HASH", hash),
1040
- write("file.js", file.code)
1041
- ]);
1031
+ const {
1032
+ hash,
1033
+ files: [file],
1034
+ handler
1035
+ } = await bundler(this.file);
1036
+ await Promise.all([write("HASH", hash), write("file.js", file.code)]);
1042
1037
  this.handler = handler;
1043
1038
  this.code = file.code.toString("utf8");
1044
1039
  return {
@@ -1082,11 +1077,7 @@ var FileCode = class extends Asset {
1082
1077
  };
1083
1078
  }
1084
1079
  async publish({ publish }) {
1085
- this.s3 = await publish(
1086
- `${this.id}.zip`,
1087
- this.bundle,
1088
- this.hash
1089
- );
1080
+ this.s3 = await publish(`${this.id}.zip`, this.bundle, this.hash);
1090
1081
  }
1091
1082
  toCodeJson() {
1092
1083
  return {
@@ -1099,6 +1090,49 @@ var FileCode = class extends Asset {
1099
1090
  };
1100
1091
  }
1101
1092
  };
1093
+ var FeatureCode = class extends Asset {
1094
+ s3;
1095
+ constructor(id) {
1096
+ super("function", id);
1097
+ }
1098
+ async publish({ publish }) {
1099
+ const root2 = fileURLToPath(new URL(".", import.meta.url));
1100
+ const path = join(root2, `features/${this.id}`);
1101
+ const bundle = await readFile(join(path, "bundle.zip"));
1102
+ const hash = await readFile(join(path, "HASH"));
1103
+ this.s3 = await publish(`${this.id}.zip`, bundle, hash.toString("utf8"));
1104
+ }
1105
+ toCodeJson() {
1106
+ return {
1107
+ Handler: "index.handler",
1108
+ Code: {
1109
+ S3Bucket: this.s3?.bucket ?? "",
1110
+ S3Key: this.s3?.key ?? "",
1111
+ S3ObjectVersion: this.s3?.version ?? ""
1112
+ }
1113
+ };
1114
+ }
1115
+ };
1116
+ var InlineFeatureCode = class extends Asset {
1117
+ code;
1118
+ constructor(id) {
1119
+ super("function", id);
1120
+ }
1121
+ async publish() {
1122
+ const root2 = fileURLToPath(new URL(".", import.meta.url));
1123
+ const path = join(root2, `features/${this.id}`);
1124
+ const file = await readFile(join(path, "index.js"));
1125
+ this.code = file.toString("utf8");
1126
+ }
1127
+ toCodeJson() {
1128
+ return {
1129
+ Handler: "index.handler",
1130
+ Code: {
1131
+ ZipFile: this.code ?? ""
1132
+ }
1133
+ };
1134
+ }
1135
+ };
1102
1136
 
1103
1137
  // src/formation/resource/lambda/event-invoke-config.ts
1104
1138
  var EventInvokeConfig = class extends Resource {
@@ -1321,16 +1355,23 @@ var TypeObject = class {
1321
1355
  };
1322
1356
 
1323
1357
  // src/plugins/function.ts
1324
- var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum memory size is 10 GB");
1325
- var TimeoutSchema = DurationSchema.refine(durationMin(Duration.seconds(10)), "Minimum timeout duration is 10 seconds").refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
1326
- var EphemeralStorageSizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(512)), "Minimum ephemeral storage size is 512 MB").refine(sizeMax(Size.gigaBytes(10)), "Minimum ephemeral storage size is 10 GB");
1358
+ var MemorySizeSchema = SizeSchema.refine(sizeMin(Size.megaBytes(128)), "Minimum memory size is 128 MB").refine(
1359
+ sizeMax(Size.gigaBytes(10)),
1360
+ "Minimum memory size is 10 GB"
1361
+ );
1362
+ var TimeoutSchema = DurationSchema.refine(
1363
+ durationMin(Duration.seconds(10)),
1364
+ "Minimum timeout duration is 10 seconds"
1365
+ ).refine(durationMax(Duration.minutes(15)), "Maximum timeout duration is 15 minutes");
1366
+ var EphemeralStorageSizeSchema = SizeSchema.refine(
1367
+ sizeMin(Size.megaBytes(512)),
1368
+ "Minimum ephemeral storage size is 512 MB"
1369
+ ).refine(sizeMax(Size.gigaBytes(10)), "Minimum ephemeral storage size is 10 GB");
1327
1370
  var ReservedConcurrentExecutionsSchema = z6.number().int().min(0);
1328
1371
  var EnvironmentSchema = z6.record(z6.string(), z6.string()).optional();
1329
1372
  var ArchitectureSchema = z6.enum(["x86_64", "arm64"]);
1330
1373
  var RetryAttemptsSchema = z6.number().int().min(0).max(2);
1331
- var RuntimeSchema = z6.enum([
1332
- "nodejs18.x"
1333
- ]);
1374
+ var RuntimeSchema = z6.enum(["nodejs18.x"]);
1334
1375
  var PermissionSchema = z6.object({
1335
1376
  effect: z6.enum(["allow", "deny"]).default("allow"),
1336
1377
  actions: z6.string().array(),
@@ -1392,12 +1433,12 @@ var FunctionSchema = z6.union([
1392
1433
  /** The size of the function's /tmp directory.
1393
1434
  * You can specify a size value from 512 MB to 10 GB.
1394
1435
  * @default 512 MB
1395
- */
1436
+ */
1396
1437
  ephemeralStorageSize: EphemeralStorageSizeSchema.optional(),
1397
1438
  /** The maximum number of times to retry when the function returns an error.
1398
1439
  * You can specify a number from 0 to 2.
1399
1440
  * @default 2
1400
- */
1441
+ */
1401
1442
  retryAttempts: RetryAttemptsSchema.optional(),
1402
1443
  /** The number of simultaneous executions to reserve for the function.
1403
1444
  * You can specify a number from 0.
@@ -1432,7 +1473,7 @@ var schema = z6.object({
1432
1473
  function: z6.object({
1433
1474
  /** The name of the exported method within your code that Lambda calls to run your function.
1434
1475
  * @default 'default'
1435
- */
1476
+ */
1436
1477
  handler: z6.string().default("default"),
1437
1478
  /** Minify the function code.
1438
1479
  * @default true
@@ -1474,12 +1515,12 @@ var schema = z6.object({
1474
1515
  /** The size of the function's /tmp directory.
1475
1516
  * You can specify a size value from 512 MB to 10 GB.
1476
1517
  * @default 512 MB
1477
- */
1518
+ */
1478
1519
  ephemeralStorageSize: EphemeralStorageSizeSchema.default("512 MB"),
1479
1520
  /** The maximum number of times to retry when the function returns an error.
1480
1521
  * You can specify a number from 0 to 2.
1481
1522
  * @default 2
1482
- */
1523
+ */
1483
1524
  retryAttempts: RetryAttemptsSchema.default(2),
1484
1525
  /** The number of simultaneous executions to reserve for the function.
1485
1526
  * You can specify a number from 0.
@@ -1515,10 +1556,7 @@ var schema = z6.object({
1515
1556
  * }
1516
1557
  * }
1517
1558
  */
1518
- functions: z6.record(
1519
- ResourceIdSchema,
1520
- FunctionSchema
1521
- ).optional()
1559
+ functions: z6.record(ResourceIdSchema, FunctionSchema).optional()
1522
1560
  }).array()
1523
1561
  });
1524
1562
  var typeGenCode = `
@@ -1571,15 +1609,19 @@ var functionPlugin = definePlugin({
1571
1609
  });
1572
1610
  var toLambdaFunction = (ctx, id, fileOrProps) => {
1573
1611
  const config = ctx.config;
1574
- const stack = ctx.stack;
1612
+ const stack = ctx.stack ?? ctx.bootstrap;
1575
1613
  const bootstrap2 = ctx.bootstrap;
1576
1614
  const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
1577
1615
  const lambda = new Function(id, {
1578
1616
  name: `${config.name}-${stack.name}-${id}`,
1579
- code: Code.fromFile(id, props.file, rollupBundle({
1580
- handler: props.handler,
1581
- minify: props.minify
1582
- })),
1617
+ code: Code.fromFile(
1618
+ id,
1619
+ props.file,
1620
+ rollupBundle({
1621
+ handler: props.handler,
1622
+ minify: props.minify
1623
+ })
1624
+ ),
1583
1625
  ...props,
1584
1626
  vpc: void 0
1585
1627
  });
@@ -1598,13 +1640,8 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
1598
1640
  }
1599
1641
  if (props.vpc) {
1600
1642
  lambda.setVpc({
1601
- securityGroupIds: [
1602
- bootstrap2.import(`vpc-security-group-id`)
1603
- ],
1604
- subnetIds: [
1605
- bootstrap2.import(`public-subnet-1`),
1606
- bootstrap2.import(`public-subnet-2`)
1607
- ]
1643
+ securityGroupIds: [bootstrap2.import(`vpc-security-group-id`)],
1644
+ subnetIds: [bootstrap2.import(`public-subnet-1`), bootstrap2.import(`public-subnet-2`)]
1608
1645
  }).addPermissions({
1609
1646
  actions: [
1610
1647
  "ec2:CreateNetworkInterface",
@@ -1617,10 +1654,7 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
1617
1654
  });
1618
1655
  }
1619
1656
  lambda.addPermissions({
1620
- actions: [
1621
- "lambda:InvokeFunction",
1622
- "lambda:InvokeAsync"
1623
- ],
1657
+ actions: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
1624
1658
  resources: ["*"]
1625
1659
  });
1626
1660
  return lambda;
@@ -2363,7 +2397,7 @@ var storePlugin = definePlugin({
2363
2397
  });
2364
2398
 
2365
2399
  // src/plugins/topic.ts
2366
- import { z as z11 } from "zod";
2400
+ import { z as z12 } from "zod";
2367
2401
 
2368
2402
  // src/formation/resource/sns/topic.ts
2369
2403
  var Topic = class extends Resource {
@@ -2430,6 +2464,15 @@ var SnsEventSource = class extends Group {
2430
2464
  }
2431
2465
  };
2432
2466
 
2467
+ // src/schema/email.ts
2468
+ import { z as z11 } from "zod";
2469
+ var EmailSchema = z11.custom((value) => {
2470
+ return z11.string().email().safeParse(value).success;
2471
+ });
2472
+ var isEmail = (value) => {
2473
+ return z11.string().email().safeParse(value).success;
2474
+ };
2475
+
2433
2476
  // src/plugins/topic.ts
2434
2477
  var typeGenCode3 = `
2435
2478
  import { PublishOptions } from '@awsless/sns'
@@ -2440,26 +2483,30 @@ type Publish<Name extends string> = {
2440
2483
  }`;
2441
2484
  var topicPlugin = definePlugin({
2442
2485
  name: "topic",
2443
- schema: z11.object({
2444
- stacks: z11.object({
2486
+ schema: z12.object({
2487
+ stacks: z12.object({
2445
2488
  /** Define the events to publish too in your stack.
2446
2489
  * @example
2447
2490
  * {
2448
2491
  * topics: [ 'TOPIC_NAME' ]
2449
2492
  * }
2450
2493
  */
2451
- topics: z11.array(ResourceIdSchema).refine((topics) => {
2494
+ topics: z12.array(ResourceIdSchema).refine((topics) => {
2452
2495
  return topics.length === new Set(topics).size;
2453
2496
  }, "Must be a list of unique topic names").optional(),
2454
2497
  /** Define the events to subscribe too in your stack.
2455
2498
  * @example
2456
2499
  * {
2457
- * subscribers: {
2458
- * TOPIC_NAME: 'function.ts'
2500
+ * subscribers: {
2501
+ * // Subscribe to a lambda function.
2502
+ * TOPIC_NAME: 'function.ts',
2503
+ *
2504
+ * // Subscribe to an email address.
2505
+ * TOPIC_NAME: 'example@gmail.com',
2459
2506
  * }
2460
2507
  * }
2461
2508
  */
2462
- subscribers: z11.record(ResourceIdSchema, FunctionSchema).optional()
2509
+ subscribers: z12.record(ResourceIdSchema, z12.union([EmailSchema, FunctionSchema])).optional()
2463
2510
  }).array().superRefine((stacks, ctx) => {
2464
2511
  const topics = [];
2465
2512
  for (const stack of stacks) {
@@ -2470,7 +2517,7 @@ var topicPlugin = definePlugin({
2470
2517
  for (const sub2 of Object.keys(stack.subscribers || {})) {
2471
2518
  if (!topics.includes(sub2)) {
2472
2519
  ctx.addIssue({
2473
- code: z11.ZodIssueCode.custom,
2520
+ code: z12.ZodIssueCode.custom,
2474
2521
  message: `Topic subscription to "${sub2}" is undefined`,
2475
2522
  path: [Number(index), "subscribers"]
2476
2523
  });
@@ -2517,25 +2564,34 @@ var topicPlugin = definePlugin({
2517
2564
  });
2518
2565
  }
2519
2566
  for (const [id, props] of Object.entries(stackConfig.subscribers || {})) {
2520
- const lambda = toLambdaFunction(ctx, `topic-${id}`, props);
2521
- const source = new SnsEventSource(id, lambda, {
2522
- topicArn: bootstrap2.import(`topic-${id}-arn`)
2523
- });
2524
- stack.add(lambda, source);
2567
+ if (typeof props === "string" && isEmail(props)) {
2568
+ const subscription = new Subscription(id, {
2569
+ topicArn: bootstrap2.import(`topic-${id}-arn`),
2570
+ protocol: "email",
2571
+ endpoint: props
2572
+ });
2573
+ stack.add(subscription);
2574
+ } else {
2575
+ const lambda = toLambdaFunction(ctx, `topic-${id}`, props);
2576
+ const source = new SnsEventSource(id, lambda, {
2577
+ topicArn: bootstrap2.import(`topic-${id}-arn`)
2578
+ });
2579
+ stack.add(lambda, source);
2580
+ }
2525
2581
  }
2526
2582
  }
2527
2583
  });
2528
2584
 
2529
2585
  // src/plugins/extend.ts
2530
- import { z as z12 } from "zod";
2586
+ import { z as z13 } from "zod";
2531
2587
  var extendPlugin = definePlugin({
2532
2588
  name: "extend",
2533
- schema: z12.object({
2589
+ schema: z13.object({
2534
2590
  /** Extend your app with custom resources. */
2535
- extend: z12.custom().optional(),
2536
- stacks: z12.object({
2591
+ extend: z13.custom().optional(),
2592
+ stacks: z13.object({
2537
2593
  /** Extend your stack with custom resources. */
2538
- extend: z12.custom().optional()
2594
+ extend: z13.custom().optional()
2539
2595
  }).array()
2540
2596
  }),
2541
2597
  onApp(ctx) {
@@ -2547,7 +2603,7 @@ var extendPlugin = definePlugin({
2547
2603
  });
2548
2604
 
2549
2605
  // src/plugins/pubsub.ts
2550
- import { z as z13 } from "zod";
2606
+ import { z as z14 } from "zod";
2551
2607
 
2552
2608
  // src/formation/resource/iot/topic-rule.ts
2553
2609
  import { snakeCase } from "change-case";
@@ -2598,8 +2654,8 @@ var IotEventSource = class extends Group {
2598
2654
  // src/plugins/pubsub.ts
2599
2655
  var pubsubPlugin = definePlugin({
2600
2656
  name: "pubsub",
2601
- schema: z13.object({
2602
- stacks: z13.object({
2657
+ schema: z14.object({
2658
+ stacks: z14.object({
2603
2659
  /** Define the pubsub subscriber in your stack.
2604
2660
  * @example
2605
2661
  * {
@@ -2611,13 +2667,13 @@ var pubsubPlugin = definePlugin({
2611
2667
  * }
2612
2668
  * }
2613
2669
  */
2614
- pubsub: z13.record(
2670
+ pubsub: z14.record(
2615
2671
  ResourceIdSchema,
2616
- z13.object({
2672
+ z14.object({
2617
2673
  /** The SQL statement used to query the IOT topic. */
2618
- sql: z13.string(),
2674
+ sql: z14.string(),
2619
2675
  /** The version of the SQL rules engine to use when evaluating the rule. */
2620
- sqlVersion: z13.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23"),
2676
+ sqlVersion: z14.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23"),
2621
2677
  /** The consuming lambda function properties. */
2622
2678
  consumer: FunctionSchema
2623
2679
  })
@@ -2647,7 +2703,7 @@ var pubsubPlugin = definePlugin({
2647
2703
  });
2648
2704
 
2649
2705
  // src/plugins/graphql.ts
2650
- import { z as z14 } from "zod";
2706
+ import { z as z15 } from "zod";
2651
2707
 
2652
2708
  // src/util/array.ts
2653
2709
  var toArray = (value) => {
@@ -2760,9 +2816,9 @@ var RecordSet = class extends Resource {
2760
2816
  properties() {
2761
2817
  return {
2762
2818
  HostedZoneId: this.props.hostedZoneId,
2763
- Name: this.name + ".",
2819
+ Name: typeof this.name === "string" ? this.name + "." : this.name,
2764
2820
  Type: this.props.type,
2765
- TTL: this.props.ttl,
2821
+ TTL: this.props.ttl?.toSeconds(),
2766
2822
  ...this.props.records ? {
2767
2823
  ResourceRecords: this.props.records
2768
2824
  } : {},
@@ -2778,7 +2834,7 @@ var RecordSet = class extends Resource {
2778
2834
 
2779
2835
  // src/formation/resource/appsync/graphql-schema.ts
2780
2836
  import { print } from "graphql";
2781
- import { readFile } from "fs/promises";
2837
+ import { readFile as readFile2 } from "fs/promises";
2782
2838
  import { mergeTypeDefs } from "@graphql-tools/merge";
2783
2839
  var GraphQLSchema = class extends Resource {
2784
2840
  constructor(logicalId, props) {
@@ -2803,7 +2859,7 @@ var Definition = class extends Asset {
2803
2859
  async build({ write }) {
2804
2860
  const files = [this.files].flat();
2805
2861
  const schemas = await Promise.all(files.map((file) => {
2806
- return readFile(file, "utf8");
2862
+ return readFile2(file, "utf8");
2807
2863
  }));
2808
2864
  const defs = mergeTypeDefs(schemas);
2809
2865
  const schema2 = print(defs);
@@ -2822,8 +2878,69 @@ var Definition = class extends Asset {
2822
2878
  }
2823
2879
  };
2824
2880
 
2881
+ // src/formation/resource/appsync/util/rollup.ts
2882
+ import { rollup as rollup2 } from "rollup";
2883
+ import { swc as swc2, minify as swcMinify2 } from "rollup-plugin-swc3";
2884
+ import json2 from "@rollup/plugin-json";
2885
+ import commonjs2 from "@rollup/plugin-commonjs";
2886
+ import nodeResolve2 from "@rollup/plugin-node-resolve";
2887
+ import { dirname as dirname2 } from "path";
2888
+ var rollupResolver = ({ minify = true } = {}) => {
2889
+ return async (input) => {
2890
+ const bundle = await rollup2({
2891
+ input,
2892
+ external: (importee) => {
2893
+ return importee.startsWith("@aws-sdk") || importee.startsWith("aws-sdk") || importee.startsWith("@aws-appsync/utils");
2894
+ },
2895
+ onwarn: (error) => {
2896
+ debugError(error.message);
2897
+ },
2898
+ treeshake: {
2899
+ moduleSideEffects: (id) => input === id
2900
+ },
2901
+ plugins: [
2902
+ // @ts-ignore
2903
+ commonjs2({ sourceMap: true }),
2904
+ // @ts-ignore
2905
+ nodeResolve2({ preferBuiltins: true }),
2906
+ swc2({
2907
+ // minify,
2908
+ // module: true,
2909
+ jsc: {
2910
+ baseUrl: dirname2(input),
2911
+ minify: { sourceMap: true }
2912
+ },
2913
+ sourceMaps: true
2914
+ }),
2915
+ minify ? swcMinify2({
2916
+ module: true,
2917
+ sourceMap: true,
2918
+ compress: true
2919
+ }) : void 0,
2920
+ // @ts-ignore
2921
+ json2()
2922
+ ]
2923
+ });
2924
+ const result = await bundle.generate({
2925
+ format: "esm",
2926
+ sourcemap: "hidden",
2927
+ exports: "auto",
2928
+ manualChunks: {},
2929
+ entryFileNames: `index.mjs`,
2930
+ chunkFileNames: `[name].mjs`
2931
+ });
2932
+ let code;
2933
+ for (const item of result.output) {
2934
+ if (item.type !== "chunk") {
2935
+ continue;
2936
+ }
2937
+ code = item.code;
2938
+ }
2939
+ return Buffer.from(code, "utf8");
2940
+ };
2941
+ };
2942
+
2825
2943
  // src/formation/resource/appsync/code.ts
2826
- import { readFile as readFile2 } from "fs/promises";
2827
2944
  var Code2 = class {
2828
2945
  static fromFile(id, file) {
2829
2946
  return new FileCode2(id, file);
@@ -2850,7 +2967,7 @@ var FileCode2 = class extends Asset {
2850
2967
  }
2851
2968
  code;
2852
2969
  async build() {
2853
- const code = await readFile2(this.file);
2970
+ const code = await rollupResolver({ minify: false })(this.file);
2854
2971
  this.code = code.toString("utf8");
2855
2972
  return {
2856
2973
  size: formatByteSize(code.byteLength)
@@ -2912,9 +3029,7 @@ var DataSource = class _DataSource extends Resource {
2912
3029
  import { snakeCase as snakeCase3 } from "change-case";
2913
3030
  var FunctionConfiguration = class extends Resource {
2914
3031
  constructor(logicalId, props) {
2915
- super("AWS::AppSync::FunctionConfiguration", logicalId, [
2916
- props.code
2917
- ]);
3032
+ super("AWS::AppSync::FunctionConfiguration", logicalId);
2918
3033
  this.props = props;
2919
3034
  this.name = snakeCase3(this.props.name || logicalId);
2920
3035
  }
@@ -3033,7 +3148,10 @@ var DomainNameApiAssociation = class extends Resource {
3033
3148
  };
3034
3149
 
3035
3150
  // src/plugins/graphql.ts
3036
- var defaultResolver = `
3151
+ import { basename } from "path";
3152
+ var defaultResolver = Code2.fromInline(
3153
+ "graphql-default-resolver",
3154
+ `
3037
3155
  export function request(ctx) {
3038
3156
  return {
3039
3157
  operation: 'Invoke',
@@ -3044,16 +3162,18 @@ export function request(ctx) {
3044
3162
  export function response(ctx) {
3045
3163
  return ctx.result
3046
3164
  }
3047
- `;
3165
+ `
3166
+ );
3167
+ var resolverCache = /* @__PURE__ */ new Map();
3048
3168
  var graphqlPlugin = definePlugin({
3049
3169
  name: "graphql",
3050
- schema: z14.object({
3051
- defaults: z14.object({
3052
- graphql: z14.record(
3170
+ schema: z15.object({
3171
+ defaults: z15.object({
3172
+ graphql: z15.record(
3053
3173
  ResourceIdSchema,
3054
- z14.object({
3055
- domain: z14.string().optional(),
3056
- subDomain: z14.string().optional(),
3174
+ z15.object({
3175
+ domain: z15.string().optional(),
3176
+ subDomain: z15.string().optional(),
3057
3177
  auth: ResourceIdSchema.optional(),
3058
3178
  // authorization: z.object({
3059
3179
  // authorizer: FunctionSchema,
@@ -3063,22 +3183,22 @@ var graphqlPlugin = definePlugin({
3063
3183
  })
3064
3184
  ).optional()
3065
3185
  }).default({}),
3066
- stacks: z14.object({
3067
- graphql: z14.record(
3186
+ stacks: z15.object({
3187
+ graphql: z15.record(
3068
3188
  ResourceIdSchema,
3069
- z14.object({
3070
- schema: z14.union([LocalFileSchema, z14.array(LocalFileSchema).min(1)]).optional(),
3071
- resolvers: z14.record(
3189
+ z15.object({
3190
+ schema: z15.union([LocalFileSchema, z15.array(LocalFileSchema).min(1)]).optional(),
3191
+ resolvers: z15.record(
3072
3192
  // TypeName
3073
- z14.string(),
3074
- z14.record(
3193
+ z15.string(),
3194
+ z15.record(
3075
3195
  // FieldName
3076
- z14.string(),
3077
- z14.union([
3196
+ z15.string(),
3197
+ z15.union([
3078
3198
  FunctionSchema,
3079
- z14.object({
3199
+ z15.object({
3080
3200
  consumer: FunctionSchema,
3081
- resolver: LocalFileSchema
3201
+ resolver: LocalFileSchema.optional()
3082
3202
  })
3083
3203
  ])
3084
3204
  )
@@ -3149,19 +3269,30 @@ var graphqlPlugin = definePlugin({
3149
3269
  }
3150
3270
  },
3151
3271
  onStack(ctx) {
3152
- const { stack, stackConfig, bootstrap: bootstrap2 } = ctx;
3272
+ const { config, stack, stackConfig, bootstrap: bootstrap2 } = ctx;
3153
3273
  for (const [id, props] of Object.entries(stackConfig.graphql || {})) {
3154
3274
  const apiId = bootstrap2.import(`graphql-${id}`);
3275
+ const defaultProps = config.defaults.graphql?.[id];
3155
3276
  for (const [typeName, fields] of Object.entries(props.resolvers || {})) {
3156
3277
  for (const [fieldName, resolverProps] of Object.entries(fields || {})) {
3157
3278
  const props2 = isFunctionProps(resolverProps) ? { consumer: resolverProps } : resolverProps;
3158
3279
  const entryId = paramCase4(`${id}-${typeName}-${fieldName}`);
3159
3280
  const lambda = toLambdaFunction(ctx, `graphql-${entryId}`, props2.consumer);
3281
+ const resolver = props2.resolver ?? defaultProps?.resolver;
3282
+ let code = defaultResolver;
3283
+ if (resolver) {
3284
+ if (!resolverCache.has(resolver)) {
3285
+ const fileCode = Code2.fromFile(basename(resolver), resolver);
3286
+ resolverCache.set(resolver, fileCode);
3287
+ stack.add(fileCode);
3288
+ }
3289
+ code = resolverCache.get(resolver);
3290
+ }
3160
3291
  const source = new AppsyncEventSource(entryId, lambda, {
3161
3292
  apiId,
3162
3293
  typeName,
3163
3294
  fieldName,
3164
- code: Code2.fromInline(entryId, props2.resolver || defaultResolver)
3295
+ code
3165
3296
  });
3166
3297
  stack.add(lambda, source);
3167
3298
  }
@@ -3171,7 +3302,7 @@ var graphqlPlugin = definePlugin({
3171
3302
  });
3172
3303
 
3173
3304
  // src/plugins/domain.ts
3174
- import { z as z15 } from "zod";
3305
+ import { z as z16 } from "zod";
3175
3306
 
3176
3307
  // src/formation/resource/route53/hosted-zone.ts
3177
3308
  var HostedZone = class extends Resource {
@@ -3225,9 +3356,9 @@ var RecordSetGroup = class extends Resource {
3225
3356
  return {
3226
3357
  HostedZoneId: this.props.hostedZoneId,
3227
3358
  RecordSets: this.props.records.map((props) => ({
3228
- Name: props.name + ".",
3359
+ Name: typeof props.name === "string" ? props.name + "." : props.name,
3229
3360
  Type: props.type,
3230
- TTL: props.ttl,
3361
+ TTL: props.ttl?.toSeconds(),
3231
3362
  ...props.records ? {
3232
3363
  ResourceRecords: props.records
3233
3364
  } : {},
@@ -3270,12 +3401,114 @@ var GlobalExports = class extends Group {
3270
3401
  }
3271
3402
  };
3272
3403
 
3404
+ // src/formation/resource/ses/configuration-set.ts
3405
+ var ConfigurationSet = class extends Resource {
3406
+ constructor(logicalId, props) {
3407
+ super("AWS::SES::ConfigurationSet", logicalId);
3408
+ this.props = props;
3409
+ this.name = formatName(this.props.name || logicalId);
3410
+ }
3411
+ name;
3412
+ properties() {
3413
+ return {
3414
+ Name: this.name,
3415
+ VdmOptions: {
3416
+ DashboardOptions: {
3417
+ EngagementMetrics: this.props.engagementMetrics ?? false ? "ENABLED" : "DISABLED"
3418
+ }
3419
+ },
3420
+ ReputationOptions: {
3421
+ ReputationMetricsEnabled: this.props.reputationMetrics ?? false
3422
+ },
3423
+ SendingOptions: {
3424
+ SendingEnabled: this.props.sending ?? true
3425
+ }
3426
+ };
3427
+ }
3428
+ };
3429
+
3430
+ // src/formation/resource/ses/email-identity.ts
3431
+ import { constantCase as constantCase7 } from "change-case";
3432
+ var EmailIdentity = class extends Resource {
3433
+ constructor(logicalId, props) {
3434
+ super("AWS::SES::EmailIdentity", logicalId);
3435
+ this.props = props;
3436
+ }
3437
+ getDnsToken(index) {
3438
+ return {
3439
+ name: getAtt(this.logicalId, "DkimDNSTokenName" + index),
3440
+ value: getAtt(this.logicalId, "DkimDNSTokenValue" + index)
3441
+ };
3442
+ }
3443
+ get fullDomain() {
3444
+ return `${this.props.subDomain}.${this.props.domain}`;
3445
+ }
3446
+ get dkimDnsToken1() {
3447
+ return this.getDnsToken(1);
3448
+ }
3449
+ get dkimDnsToken2() {
3450
+ return this.getDnsToken(2);
3451
+ }
3452
+ get dkimDnsToken3() {
3453
+ return this.getDnsToken(3);
3454
+ }
3455
+ get records() {
3456
+ const tokens = [this.dkimDnsToken1, this.dkimDnsToken2, this.dkimDnsToken3];
3457
+ const ttl = Duration.minutes(5);
3458
+ return [
3459
+ ...tokens.map((token) => ({
3460
+ name: token.name,
3461
+ type: "CNAME",
3462
+ ttl,
3463
+ records: [token.value]
3464
+ })),
3465
+ {
3466
+ name: this.fullDomain,
3467
+ type: "TXT",
3468
+ ttl,
3469
+ records: ['"v=spf1 include:amazonses.com -all"']
3470
+ },
3471
+ {
3472
+ name: this.fullDomain,
3473
+ type: "MX",
3474
+ ttl,
3475
+ records: [sub("10 feedback-smtp.${AWS::Region}.amazonses.com.")]
3476
+ }
3477
+ ];
3478
+ }
3479
+ properties() {
3480
+ return {
3481
+ EmailIdentity: this.props.domain,
3482
+ ...this.props.configurationSetName ? {
3483
+ ConfigurationSetAttributes: {
3484
+ ConfigurationSetName: this.props.configurationSetName
3485
+ }
3486
+ } : {},
3487
+ ...this.props.dkim ? {
3488
+ DkimAttributes: {
3489
+ SigningEnabled: true
3490
+ },
3491
+ DkimSigningAttributes: {
3492
+ NextSigningKeyLength: constantCase7(this.props.dkim)
3493
+ }
3494
+ } : {},
3495
+ FeedbackAttributes: {
3496
+ EmailForwardingEnabled: this.props.feedback ?? false
3497
+ },
3498
+ MailFromAttributes: {
3499
+ BehaviorOnMxFailure: this.props.rejectOnMxFailure ?? true ? "REJECT_MESSAGE" : "USE_DEFAULT_VALUE",
3500
+ MailFromDomain: this.fullDomain
3501
+ }
3502
+ };
3503
+ }
3504
+ };
3505
+
3273
3506
  // src/plugins/domain.ts
3274
- var DomainNameSchema = z15.string().regex(/[a-z\-\_\.]/g, "Invalid domain name");
3507
+ var DomainNameSchema = z16.string().regex(/[a-z\-\_\.]/g, "Invalid domain name");
3275
3508
  var domainPlugin = definePlugin({
3276
3509
  name: "domain",
3277
- schema: z15.object({
3278
- defaults: z15.object({
3510
+ schema: z16.object({
3511
+ defaults: z16.object({
3279
3512
  /** Define the domains for your application.
3280
3513
  * @example
3281
3514
  * {
@@ -3289,9 +3522,9 @@ var domainPlugin = definePlugin({
3289
3522
  * }
3290
3523
  * }
3291
3524
  */
3292
- domains: z15.record(
3525
+ domains: z16.record(
3293
3526
  DomainNameSchema,
3294
- z15.object({
3527
+ z16.object({
3295
3528
  /** Enter a fully qualified domain name, for example, www.example.com.
3296
3529
  * You can optionally include a trailing dot.
3297
3530
  * If you omit the trailing dot, Amazon Route 53 assumes that the domain name that you specify is fully qualified.
@@ -3299,7 +3532,7 @@ var domainPlugin = definePlugin({
3299
3532
  */
3300
3533
  name: DomainNameSchema.optional(),
3301
3534
  /** The DNS record type. */
3302
- type: z15.enum([
3535
+ type: z16.enum([
3303
3536
  "A",
3304
3537
  "AAAA",
3305
3538
  "CAA",
@@ -3317,12 +3550,12 @@ var domainPlugin = definePlugin({
3317
3550
  /** The resource record cache time to live (TTL). */
3318
3551
  ttl: DurationSchema,
3319
3552
  /** One or more values that correspond with the value that you specified for the Type property. */
3320
- records: z15.string().array()
3553
+ records: z16.string().array()
3321
3554
  }).array()
3322
3555
  ).optional()
3323
3556
  }).default({})
3324
3557
  }),
3325
- onApp({ config, bootstrap: bootstrap2, usEastBootstrap }) {
3558
+ onApp({ config, bootstrap: bootstrap2, usEastBootstrap, bind }) {
3326
3559
  const domains = Object.entries(config.defaults.domains || {});
3327
3560
  if (domains.length === 0) {
3328
3561
  return;
@@ -3339,6 +3572,12 @@ var domainPlugin = definePlugin({
3339
3572
  region: usEastBootstrap.region
3340
3573
  });
3341
3574
  bootstrap2.add(usEastExports);
3575
+ const configurationSet = new ConfigurationSet("default", {
3576
+ name: config.name,
3577
+ engagementMetrics: true,
3578
+ reputationMetrics: true
3579
+ });
3580
+ bootstrap2.add(configurationSet);
3342
3581
  for (const [domain, records] of domains) {
3343
3582
  const hostedZone = new HostedZone(domain);
3344
3583
  const usEastCertificate = new Certificate(domain, {
@@ -3356,7 +3595,18 @@ var domainPlugin = definePlugin({
3356
3595
  hostedZoneId: usEastExports.import(`hosted-zone-${domain}-id`),
3357
3596
  alternativeNames: [`*.${domain}`]
3358
3597
  });
3359
- bootstrap2.add(certificate).export(`certificate-${domain}-arn`, certificate.arn).export(`hosted-zone-${domain}-id`, usEastExports.import(`hosted-zone-${domain}-id`)).export(`us-east-certificate-${domain}-arn`, usEastExports.import(`certificate-${domain}-arn`));
3598
+ const emailIdentity = new EmailIdentity(domain, {
3599
+ domain,
3600
+ subDomain: "mailer",
3601
+ configurationSetName: configurationSet.name,
3602
+ feedback: true,
3603
+ rejectOnMxFailure: true
3604
+ }).dependsOn(configurationSet);
3605
+ const emailRecordGroup = new RecordSetGroup(`${domain}-mail`, {
3606
+ hostedZoneId: usEastExports.import(`hosted-zone-${domain}-id`),
3607
+ records: emailIdentity.records
3608
+ }).dependsOn(emailIdentity);
3609
+ bootstrap2.add(certificate).add(emailIdentity).add(emailRecordGroup).export(`certificate-${domain}-arn`, certificate.arn).export(`hosted-zone-${domain}-id`, usEastExports.import(`hosted-zone-${domain}-id`)).export(`us-east-certificate-${domain}-arn`, usEastExports.import(`certificate-${domain}-arn`));
3360
3610
  if (records.length > 0) {
3361
3611
  const group = new RecordSetGroup(domain, {
3362
3612
  hostedZoneId: hostedZone.id,
@@ -3365,15 +3615,21 @@ var domainPlugin = definePlugin({
3365
3615
  usEastBootstrap.add(group);
3366
3616
  }
3367
3617
  }
3618
+ bind(
3619
+ (lambda) => lambda.addPermissions({
3620
+ actions: ["ses:*"],
3621
+ resources: ["*"]
3622
+ })
3623
+ );
3368
3624
  }
3369
3625
  });
3370
3626
 
3371
3627
  // src/plugins/on-failure/index.ts
3372
- import { z as z16 } from "zod";
3628
+ import { z as z17 } from "zod";
3373
3629
  var onFailurePlugin = definePlugin({
3374
3630
  name: "on-failure",
3375
- schema: z16.object({
3376
- stacks: z16.object({
3631
+ schema: z17.object({
3632
+ stacks: z17.object({
3377
3633
  /** Defining a onFailure handler will add a global onFailure handler for the following resources:
3378
3634
  * - Async lambda functions
3379
3635
  * - SQS queues
@@ -3629,7 +3885,7 @@ var vpcPlugin = definePlugin({
3629
3885
  });
3630
3886
 
3631
3887
  // src/plugins/http.ts
3632
- import { z as z17 } from "zod";
3888
+ import { z as z18 } from "zod";
3633
3889
 
3634
3890
  // src/formation/resource/ec2/security-group.ts
3635
3891
  var SecurityGroup = class extends Resource {
@@ -3753,7 +4009,7 @@ var LoadBalancer = class extends Resource {
3753
4009
  };
3754
4010
 
3755
4011
  // src/formation/resource/elb/listener.ts
3756
- import { constantCase as constantCase7 } from "change-case";
4012
+ import { constantCase as constantCase8 } from "change-case";
3757
4013
  var Listener = class extends Resource {
3758
4014
  constructor(logicalId, props) {
3759
4015
  super("AWS::ElasticLoadBalancingV2::Listener", logicalId);
@@ -3769,7 +4025,7 @@ var Listener = class extends Resource {
3769
4025
  return {
3770
4026
  LoadBalancerArn: this.props.loadBalancerArn,
3771
4027
  Port: this.props.port,
3772
- Protocol: constantCase7(this.props.protocol),
4028
+ Protocol: constantCase8(this.props.protocol),
3773
4029
  Certificates: this.props.certificates.map((arn) => ({
3774
4030
  CertificateArn: arn
3775
4031
  })),
@@ -3969,8 +4225,8 @@ var ElbEventSource = class extends Group {
3969
4225
  };
3970
4226
 
3971
4227
  // src/plugins/http.ts
3972
- var RouteSchema = z17.custom((route) => {
3973
- return z17.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/]*)$/ig).safeParse(route).success;
4228
+ var RouteSchema = z18.custom((route) => {
4229
+ return z18.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/]*)$/ig).safeParse(route).success;
3974
4230
  }, "Invalid route");
3975
4231
  var parseRoute = (route) => {
3976
4232
  const [method, ...paths] = route.split(" ");
@@ -3988,8 +4244,8 @@ var generatePriority = (stackName, route) => {
3988
4244
  };
3989
4245
  var httpPlugin = definePlugin({
3990
4246
  name: "http",
3991
- schema: z17.object({
3992
- defaults: z17.object({
4247
+ schema: z18.object({
4248
+ defaults: z18.object({
3993
4249
  /** Define your global http api's.
3994
4250
  * @example
3995
4251
  * {
@@ -4001,17 +4257,17 @@ var httpPlugin = definePlugin({
4001
4257
  * }
4002
4258
  * }
4003
4259
  */
4004
- http: z17.record(
4260
+ http: z18.record(
4005
4261
  ResourceIdSchema,
4006
- z17.object({
4262
+ z18.object({
4007
4263
  /** The domain to link your api with. */
4008
- domain: z17.string(),
4009
- subDomain: z17.string().optional(),
4264
+ domain: z18.string(),
4265
+ subDomain: z18.string().optional(),
4010
4266
  auth: ResourceIdSchema.optional()
4011
4267
  })
4012
4268
  ).optional()
4013
4269
  }).default({}),
4014
- stacks: z17.object({
4270
+ stacks: z18.object({
4015
4271
  /** Define routes in your stack for your global http api.
4016
4272
  * @example
4017
4273
  * {
@@ -4023,9 +4279,9 @@ var httpPlugin = definePlugin({
4023
4279
  * }
4024
4280
  * }
4025
4281
  */
4026
- http: z17.record(
4282
+ http: z18.record(
4027
4283
  ResourceIdSchema,
4028
- z17.record(RouteSchema, FunctionSchema)
4284
+ z18.record(RouteSchema, FunctionSchema)
4029
4285
  ).optional()
4030
4286
  }).array()
4031
4287
  }),
@@ -4110,7 +4366,7 @@ var httpPlugin = definePlugin({
4110
4366
  });
4111
4367
 
4112
4368
  // src/plugins/search.ts
4113
- import { z as z18 } from "zod";
4369
+ import { z as z19 } from "zod";
4114
4370
 
4115
4371
  // src/formation/resource/open-search-serverless/collection.ts
4116
4372
  var Collection = class extends Resource {
@@ -4154,9 +4410,9 @@ var Collection = class extends Resource {
4154
4410
  // src/plugins/search.ts
4155
4411
  var searchPlugin = definePlugin({
4156
4412
  name: "search",
4157
- schema: z18.object({
4158
- stacks: z18.object({
4159
- searchs: z18.array(ResourceIdSchema).optional()
4413
+ schema: z19.object({
4414
+ stacks: z19.object({
4415
+ searchs: z19.array(ResourceIdSchema).optional()
4160
4416
  }).array()
4161
4417
  }),
4162
4418
  onTypeGen({ config }) {
@@ -4185,7 +4441,7 @@ var searchPlugin = definePlugin({
4185
4441
  });
4186
4442
 
4187
4443
  // src/plugins/cache.ts
4188
- import { z as z19 } from "zod";
4444
+ import { z as z20 } from "zod";
4189
4445
 
4190
4446
  // src/formation/resource/memorydb/cluster.ts
4191
4447
  var Cluster = class extends Resource {
@@ -4252,8 +4508,8 @@ var SubnetGroup = class extends Resource {
4252
4508
  };
4253
4509
 
4254
4510
  // src/plugins/cache.ts
4255
- import { constantCase as constantCase8 } from "change-case";
4256
- var TypeSchema = z19.enum([
4511
+ import { constantCase as constantCase9 } from "change-case";
4512
+ var TypeSchema = z20.enum([
4257
4513
  "t4g.small",
4258
4514
  "t4g.medium",
4259
4515
  "r6g.large",
@@ -4268,14 +4524,25 @@ var TypeSchema = z19.enum([
4268
4524
  "r6gd.4xlarge",
4269
4525
  "r6gd.8xlarge"
4270
4526
  ]);
4271
- var PortSchema = z19.number().int().min(1).max(5e4);
4272
- var ShardsSchema = z19.number().int().min(0).max(100);
4273
- var ReplicasPerShardSchema = z19.number().int().min(0).max(5);
4274
- var EngineSchema = z19.enum(["7.0", "6.2"]);
4527
+ var PortSchema = z20.number().int().min(1).max(5e4);
4528
+ var ShardsSchema = z20.number().int().min(0).max(100);
4529
+ var ReplicasPerShardSchema = z20.number().int().min(0).max(5);
4530
+ var EngineSchema = z20.enum(["7.0", "6.2"]);
4531
+ var typeGenCode4 = `
4532
+ import { Cluster, CommandOptions } from '@awsless/redis'
4533
+
4534
+ type Callback<T> = (redis: Cluster) => T
4535
+
4536
+ type Command = {
4537
+ readonly host: string
4538
+ readonly port: number
4539
+ <T>(callback: Callback<T>): T
4540
+ <T>(options:Omit<CommandOptions, 'cluster'>, callback: Callback<T>): T
4541
+ }`;
4275
4542
  var cachePlugin = definePlugin({
4276
4543
  name: "cache",
4277
- schema: z19.object({
4278
- stacks: z19.object({
4544
+ schema: z20.object({
4545
+ stacks: z20.object({
4279
4546
  /** Define the caches in your stack.
4280
4547
  * For access to the cache put your functions inside the global VPC.
4281
4548
  * @example
@@ -4287,25 +4554,26 @@ var cachePlugin = definePlugin({
4287
4554
  * }
4288
4555
  * }
4289
4556
  */
4290
- caches: z19.record(
4557
+ caches: z20.record(
4291
4558
  ResourceIdSchema,
4292
- z19.object({
4559
+ z20.object({
4293
4560
  type: TypeSchema.default("t4g.small"),
4294
4561
  port: PortSchema.default(6379),
4295
4562
  shards: ShardsSchema.default(1),
4296
4563
  replicasPerShard: ReplicasPerShardSchema.default(1),
4297
4564
  engine: EngineSchema.default("7.0"),
4298
- dataTiering: z19.boolean().default(false)
4565
+ dataTiering: z20.boolean().default(false)
4299
4566
  })
4300
4567
  ).optional()
4301
4568
  }).array()
4302
4569
  }),
4303
4570
  onTypeGen({ config }) {
4304
4571
  const gen = new TypeGen("@awsless/awsless", "CacheResources");
4572
+ gen.addCode(typeGenCode4);
4305
4573
  for (const stack of config.stacks) {
4306
4574
  const list3 = new TypeObject();
4307
4575
  for (const name of Object.keys(stack.caches || {})) {
4308
- list3.addType(name, `{ readonly host: string, readonly port: number }`);
4576
+ list3.addType(name, `Command`);
4309
4577
  }
4310
4578
  gen.addType(stack.name, list3.toString());
4311
4579
  }
@@ -4335,8 +4603,8 @@ var cachePlugin = definePlugin({
4335
4603
  }).dependsOn(subnetGroup, securityGroup);
4336
4604
  stack.add(subnetGroup, securityGroup, cluster);
4337
4605
  bind((lambda) => {
4338
- lambda.addEnvironment(`CACHE_${constantCase8(stack.name)}_${constantCase8(id)}_HOST`, cluster.address).addEnvironment(
4339
- `CACHE_${constantCase8(stack.name)}_${constantCase8(id)}_PORT`,
4606
+ lambda.addEnvironment(`CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_HOST`, cluster.address).addEnvironment(
4607
+ `CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_PORT`,
4340
4608
  props.port.toString()
4341
4609
  );
4342
4610
  });
@@ -4345,12 +4613,12 @@ var cachePlugin = definePlugin({
4345
4613
  });
4346
4614
 
4347
4615
  // src/plugins/rest.ts
4348
- import { z as z21 } from "zod";
4616
+ import { z as z22 } from "zod";
4349
4617
 
4350
4618
  // src/schema/route.ts
4351
- import { z as z20 } from "zod";
4352
- var RouteSchema2 = z20.custom((route) => {
4353
- return z20.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/ig).safeParse(route).success;
4619
+ import { z as z21 } from "zod";
4620
+ var RouteSchema2 = z21.custom((route) => {
4621
+ return z21.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/ig).safeParse(route).success;
4354
4622
  }, "Invalid route");
4355
4623
 
4356
4624
  // src/formation/resource/api-gateway-v2/api.ts
@@ -4516,8 +4784,8 @@ var ApiMapping = class extends Resource {
4516
4784
  // src/plugins/rest.ts
4517
4785
  var restPlugin = definePlugin({
4518
4786
  name: "rest",
4519
- schema: z21.object({
4520
- defaults: z21.object({
4787
+ schema: z22.object({
4788
+ defaults: z22.object({
4521
4789
  /** Define your global REST API's.
4522
4790
  * @example
4523
4791
  * {
@@ -4529,16 +4797,16 @@ var restPlugin = definePlugin({
4529
4797
  * }
4530
4798
  * }
4531
4799
  */
4532
- rest: z21.record(
4800
+ rest: z22.record(
4533
4801
  ResourceIdSchema,
4534
- z21.object({
4802
+ z22.object({
4535
4803
  /** The domain to link your API with. */
4536
- domain: z21.string(),
4537
- subDomain: z21.string().optional()
4804
+ domain: z22.string(),
4805
+ subDomain: z22.string().optional()
4538
4806
  })
4539
4807
  ).optional()
4540
4808
  }).default({}),
4541
- stacks: z21.object({
4809
+ stacks: z22.object({
4542
4810
  /** Define routes in your stack for your global REST API.
4543
4811
  * @example
4544
4812
  * {
@@ -4550,9 +4818,9 @@ var restPlugin = definePlugin({
4550
4818
  * }
4551
4819
  * }
4552
4820
  */
4553
- rest: z21.record(
4821
+ rest: z22.record(
4554
4822
  ResourceIdSchema,
4555
- z21.record(RouteSchema2, FunctionSchema)
4823
+ z22.record(RouteSchema2, FunctionSchema)
4556
4824
  ).optional()
4557
4825
  }).array()
4558
4826
  }),
@@ -4609,7 +4877,7 @@ var restPlugin = definePlugin({
4609
4877
  });
4610
4878
 
4611
4879
  // src/plugins/config.ts
4612
- import { z as z22 } from "zod";
4880
+ import { z as z23 } from "zod";
4613
4881
 
4614
4882
  // src/util/param.ts
4615
4883
  import { DeleteParameterCommand, GetParameterCommand, GetParametersByPathCommand, ParameterType, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
@@ -4697,11 +4965,11 @@ var Params = class {
4697
4965
 
4698
4966
  // src/plugins/config.ts
4699
4967
  import { paramCase as paramCase5 } from "change-case";
4700
- var ConfigNameSchema = z22.string().regex(/[a-z0-9\-]/g, "Invalid config name");
4968
+ var ConfigNameSchema = z23.string().regex(/[a-z0-9\-]/g, "Invalid config name");
4701
4969
  var configPlugin = definePlugin({
4702
4970
  name: "config",
4703
- schema: z22.object({
4704
- stacks: z22.object({
4971
+ schema: z23.object({
4972
+ stacks: z23.object({
4705
4973
  /** Define the config values for your stack.
4706
4974
  * @example
4707
4975
  * ```
@@ -4718,7 +4986,7 @@ var configPlugin = definePlugin({
4718
4986
  * Config.YOUR_SECRET
4719
4987
  * ```
4720
4988
  */
4721
- configs: z22.array(ConfigNameSchema).optional()
4989
+ configs: z23.array(ConfigNameSchema).optional()
4722
4990
  }).array()
4723
4991
  }),
4724
4992
  onTypeGen({ config }) {
@@ -4752,7 +5020,7 @@ var configPlugin = definePlugin({
4752
5020
  });
4753
5021
 
4754
5022
  // src/plugins/site.ts
4755
- import { z as z24 } from "zod";
5023
+ import { z as z25 } from "zod";
4756
5024
 
4757
5025
  // src/formation/resource/cloud-front/distribution.ts
4758
5026
  var Distribution = class extends Resource {
@@ -4879,8 +5147,8 @@ var OriginGroup = class {
4879
5147
 
4880
5148
  // src/schema/local-directory.ts
4881
5149
  import { stat as stat2 } from "fs/promises";
4882
- import { z as z23 } from "zod";
4883
- var LocalDirectorySchema = z23.string().refine(async (path) => {
5150
+ import { z as z24 } from "zod";
5151
+ var LocalDirectorySchema = z24.string().refine(async (path) => {
4884
5152
  try {
4885
5153
  const s = await stat2(path);
4886
5154
  return s.isDirectory();
@@ -5156,9 +5424,9 @@ var ResponseHeadersPolicy = class extends Resource {
5156
5424
  };
5157
5425
 
5158
5426
  // src/plugins/site.ts
5159
- var ErrorResponseSchema = z24.union([
5160
- z24.string(),
5161
- z24.object({
5427
+ var ErrorResponseSchema = z25.union([
5428
+ z25.string(),
5429
+ z25.object({
5162
5430
  /** The path to the custom error page that you want to return to the viewer when your origin returns the HTTP status code specified.
5163
5431
  * @example ```
5164
5432
  * "/404.html"
@@ -5168,7 +5436,7 @@ var ErrorResponseSchema = z24.union([
5168
5436
  * If you store custom error pages on an HTTP server and the server starts to return 5xx errors,
5169
5437
  * CloudFront can't get the files that you want to return to viewers because the origin server is unavailable.
5170
5438
  */
5171
- path: z24.string(),
5439
+ path: z25.string(),
5172
5440
  /** The HTTP status code that you want CloudFront to return to the viewer along with the custom error page.
5173
5441
  * 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:
5174
5442
  * - Some Internet devices (some firewalls and corporate proxies, for example) intercept HTTP 4xx and 5xx and prevent the response from being returned to the viewer.
@@ -5176,7 +5444,7 @@ var ErrorResponseSchema = z24.union([
5176
5444
  * - If you don't care about distinguishing among different client errors or server errors, you can specify 400 or 500 as the ResponseCode for all 4xx or 5xx errors.
5177
5445
  * - You might want to return a 200 status code (OK) and static website so your customers don't know that your website is down.
5178
5446
  */
5179
- statusCode: z24.number().int().positive().optional(),
5447
+ statusCode: z25.number().int().positive().optional(),
5180
5448
  /** The minimum amount of time, that you want to cache the error response.
5181
5449
  * 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.
5182
5450
  * @example
@@ -5187,8 +5455,8 @@ var ErrorResponseSchema = z24.union([
5187
5455
  ]).optional();
5188
5456
  var sitePlugin = definePlugin({
5189
5457
  name: "site",
5190
- schema: z24.object({
5191
- stacks: z24.object({
5458
+ schema: z25.object({
5459
+ stacks: z25.object({
5192
5460
  /** Define the sites in your stack.
5193
5461
  * @example
5194
5462
  * {
@@ -5201,18 +5469,18 @@ var sitePlugin = definePlugin({
5201
5469
  * }
5202
5470
  * }
5203
5471
  */
5204
- sites: z24.record(
5472
+ sites: z25.record(
5205
5473
  ResourceIdSchema,
5206
- z24.object({
5474
+ z25.object({
5207
5475
  /** The domain to link your site with. */
5208
- domain: z24.string(),
5209
- subDomain: z24.string().optional(),
5476
+ domain: z25.string(),
5477
+ subDomain: z25.string().optional(),
5210
5478
  /** Specifies the path to the static files directory. */
5211
5479
  static: LocalDirectorySchema.optional(),
5212
5480
  /** Specifies the ssr file. */
5213
5481
  ssr: FunctionSchema.optional(),
5214
5482
  /** Customize the error responses for specific HTTP status codes. */
5215
- errors: z24.object({
5483
+ errors: z25.object({
5216
5484
  /** Customize a `400 Bad Request` response */
5217
5485
  400: ErrorResponseSchema,
5218
5486
  /** Customize a `403 Forbidden` response. */
@@ -5237,17 +5505,17 @@ var sitePlugin = definePlugin({
5237
5505
  504: ErrorResponseSchema
5238
5506
  }).optional(),
5239
5507
  /** Define the cors headers. */
5240
- cors: z24.object({
5241
- override: z24.boolean().default(false),
5508
+ cors: z25.object({
5509
+ override: z25.boolean().default(false),
5242
5510
  maxAge: DurationSchema.default("365 days"),
5243
- exposeHeaders: z24.string().array().optional(),
5244
- credentials: z24.boolean().default(false),
5245
- headers: z24.string().array().default(["*"]),
5246
- origins: z24.string().array().default(["*"]),
5247
- methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
5511
+ exposeHeaders: z25.string().array().optional(),
5512
+ credentials: z25.boolean().default(false),
5513
+ headers: z25.string().array().default(["*"]),
5514
+ origins: z25.string().array().default(["*"]),
5515
+ methods: z25.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
5248
5516
  }).optional(),
5249
5517
  /** Define the cors headers. */
5250
- security: z24.object({
5518
+ security: z25.object({
5251
5519
  // contentSecurityPolicy: z.object({
5252
5520
  // override: z.boolean().default(false),
5253
5521
  // policy: z.string(),
@@ -5290,13 +5558,13 @@ var sitePlugin = definePlugin({
5290
5558
  // }
5291
5559
  }).optional(),
5292
5560
  /** Specifies the cookies, headers, and query values that CloudFront includes in the cache key. */
5293
- cache: z24.object({
5561
+ cache: z25.object({
5294
5562
  /** Specifies the cookies that CloudFront includes in the cache key. */
5295
- cookies: z24.string().array().optional(),
5563
+ cookies: z25.string().array().optional(),
5296
5564
  /** Specifies the headers that CloudFront includes in the cache key. */
5297
- headers: z24.string().array().optional(),
5565
+ headers: z25.string().array().optional(),
5298
5566
  /** Specifies the query values that CloudFront includes in the cache key. */
5299
- queries: z24.string().array().optional()
5567
+ queries: z25.string().array().optional()
5300
5568
  }).optional()
5301
5569
  })
5302
5570
  ).optional()
@@ -5503,10 +5771,10 @@ var featurePlugin = definePlugin({
5503
5771
  });
5504
5772
 
5505
5773
  // src/plugins/auth.ts
5506
- import { z as z25 } from "zod";
5774
+ import { z as z26 } from "zod";
5507
5775
 
5508
5776
  // src/formation/resource/cognito/user-pool.ts
5509
- import { constantCase as constantCase9 } from "change-case";
5777
+ import { constantCase as constantCase10 } from "change-case";
5510
5778
 
5511
5779
  // src/formation/resource/cognito/user-pool-client.ts
5512
5780
  var UserPoolClient = class extends Resource {
@@ -5677,25 +5945,26 @@ var UserPool = class extends Resource {
5677
5945
  AliasAttributes: ["email"],
5678
5946
  // UsernameAttributes: [ 'email' ],
5679
5947
  AutoVerifiedAttributes: ["email"],
5680
- Schema: [{
5681
- AttributeDataType: "String",
5682
- Name: "email",
5683
- Required: true,
5684
- Mutable: false,
5685
- StringAttributeConstraints: {
5686
- MinLength: 5,
5687
- MaxLength: 100
5948
+ Schema: [
5949
+ {
5950
+ AttributeDataType: "String",
5951
+ Name: "email",
5952
+ Required: true,
5953
+ Mutable: false,
5954
+ StringAttributeConstraints: {
5955
+ MinLength: 5,
5956
+ MaxLength: 100
5957
+ }
5688
5958
  }
5689
- }]
5959
+ ]
5690
5960
  } : {},
5691
5961
  UsernameConfiguration: {
5692
5962
  CaseSensitive: this.props.username?.caseSensitive ?? false
5693
5963
  },
5694
5964
  ...this.attr("EmailConfiguration", this.props.email?.toJSON()),
5695
- // DeviceConfiguration: {
5696
- // ChallengeRequiredOnNewDevice: {},
5697
- // DeviceOnlyRememberedOnUserPrompt: {},
5698
- // },
5965
+ DeviceConfiguration: {
5966
+ DeviceOnlyRememberedOnUserPrompt: false
5967
+ },
5699
5968
  AdminCreateUserConfig: {
5700
5969
  AllowAdminCreateUserOnly: !(this.props.allowUserRegistration ?? true)
5701
5970
  },
@@ -5719,15 +5988,42 @@ var UserPool = class extends Resource {
5719
5988
  ...this.attr("UserMigration", this.props.triggers?.userMigration),
5720
5989
  ...this.attr("DefineAuthChallenge", this.props.triggers?.defineChallange),
5721
5990
  ...this.attr("CreateAuthChallenge", this.props.triggers?.createChallange),
5722
- ...this.attr("VerifyAuthChallengeResponse", this.props.triggers?.verifyChallange)
5991
+ ...this.attr("VerifyAuthChallengeResponse", this.props.triggers?.verifyChallange),
5992
+ ...this.props.triggers?.emailSender ? {
5993
+ CustomEmailSender: {
5994
+ LambdaArn: this.props.triggers.emailSender,
5995
+ LambdaVersion: "V1_0"
5996
+ }
5997
+ } : {}
5723
5998
  }
5724
5999
  };
5725
6000
  }
5726
6001
  };
6002
+ var UserPoolEmail = class _UserPoolEmail {
6003
+ constructor(props) {
6004
+ this.props = props;
6005
+ }
6006
+ static withSES(props) {
6007
+ return new _UserPoolEmail({
6008
+ type: "developer",
6009
+ replyTo: props.replyTo,
6010
+ from: props.fromName ? `${props.fromName} <${props.fromEmail}>` : props.fromEmail,
6011
+ sourceArn: props.sourceArn
6012
+ });
6013
+ }
6014
+ toJSON() {
6015
+ return {
6016
+ ...this.props.type ? { EmailSendingAccount: constantCase10(this.props.type) } : {},
6017
+ ...this.props.from ? { From: this.props.from } : {},
6018
+ ...this.props.replyTo ? { ReplyToEmailAddress: this.props.replyTo } : {},
6019
+ ...this.props.sourceArn ? { SourceArn: this.props.sourceArn } : {}
6020
+ };
6021
+ }
6022
+ };
5727
6023
 
5728
6024
  // src/plugins/auth.ts
5729
- import { constantCase as constantCase10 } from "change-case";
5730
- var TriggersSchema = z25.object({
6025
+ import { constantCase as constantCase11 } from "change-case";
6026
+ var TriggersSchema = z26.object({
5731
6027
  /** A pre jwt token generation AWS Lambda trigger. */
5732
6028
  beforeToken: FunctionSchema.optional(),
5733
6029
  /** A pre user login AWS Lambda trigger. */
@@ -5740,6 +6036,8 @@ var TriggersSchema = z25.object({
5740
6036
  afterRegister: FunctionSchema.optional(),
5741
6037
  /** A custom message AWS Lambda trigger. */
5742
6038
  customMessage: FunctionSchema.optional(),
6039
+ // /** A custom email sender AWS Lambda trigger */
6040
+ // emailSender: FunctionSchema.optional(),
5743
6041
  /** Defines the authentication challenge. */
5744
6042
  defineChallenge: FunctionSchema.optional(),
5745
6043
  /** Creates an authentication challenge. */
@@ -5749,8 +6047,8 @@ var TriggersSchema = z25.object({
5749
6047
  });
5750
6048
  var authPlugin = definePlugin({
5751
6049
  name: "auth",
5752
- schema: z25.object({
5753
- defaults: z25.object({
6050
+ schema: z26.object({
6051
+ defaults: z26.object({
5754
6052
  /** Define the authenticatable users in your app.
5755
6053
  * @example
5756
6054
  * {
@@ -5766,48 +6064,58 @@ var authPlugin = definePlugin({
5766
6064
  * }
5767
6065
  * }
5768
6066
  */
5769
- auth: z25.record(
6067
+ auth: z26.record(
5770
6068
  ResourceIdSchema,
5771
- z25.object({
6069
+ z26.object({
5772
6070
  /** Specifies whether users can create an user account or if only the administrator can.
5773
6071
  * @default true
5774
6072
  */
5775
- allowUserRegistration: z25.boolean().default(true),
6073
+ allowUserRegistration: z26.boolean().default(true),
6074
+ /** The email configuration for sending messages.
6075
+ */
6076
+ messaging: z26.object({
6077
+ // Specifies the sender's email address.
6078
+ fromEmail: EmailSchema,
6079
+ // Specifies the sender's name.
6080
+ fromName: z26.string().optional(),
6081
+ // The destination to which the receiver of the email should reply.
6082
+ replyTo: EmailSchema.optional()
6083
+ }).optional(),
5776
6084
  /** The username policy. */
5777
- username: z25.object({
6085
+ username: z26.object({
5778
6086
  /** Allow the user email to be used as username.
5779
6087
  * @default true
5780
6088
  */
5781
- emailAlias: z25.boolean().default(true),
6089
+ emailAlias: z26.boolean().default(true),
5782
6090
  /** Specifies whether username case sensitivity will be enabled.
5783
6091
  * When usernames and email addresses are case insensitive,
5784
6092
  * users can sign in as the same user when they enter a different capitalization of their user name.
5785
6093
  * @default false
5786
6094
  */
5787
- caseSensitive: z25.boolean().default(false)
6095
+ caseSensitive: z26.boolean().default(false)
5788
6096
  }).default({}),
5789
6097
  /** The password policy. */
5790
- password: z25.object({
6098
+ password: z26.object({
5791
6099
  /** Required users to have at least the minimum password length.
5792
- * @default 8
6100
+ * @default 12
5793
6101
  */
5794
- minLength: z25.number().int().min(6).max(99).default(8),
6102
+ minLength: z26.number().int().min(6).max(99).default(12),
5795
6103
  /** Required users to use at least one uppercase letter in their password.
5796
6104
  * @default true
5797
6105
  */
5798
- uppercase: z25.boolean().default(true),
6106
+ uppercase: z26.boolean().default(true),
5799
6107
  /** Required users to use at least one lowercase letter in their password.
5800
6108
  * @default true
5801
6109
  */
5802
- lowercase: z25.boolean().default(true),
6110
+ lowercase: z26.boolean().default(true),
5803
6111
  /** Required users to use at least one number in their password.
5804
6112
  * @default true
5805
6113
  */
5806
- numbers: z25.boolean().default(true),
6114
+ numbers: z26.boolean().default(true),
5807
6115
  /** Required users to use at least one symbol in their password.
5808
6116
  * @default true
5809
6117
  */
5810
- symbols: z25.boolean().default(true),
6118
+ symbols: z26.boolean().default(true),
5811
6119
  /** The duration a temporary password is valid.
5812
6120
  * If the user doesn't sign in during this time, an administrator must reset their password.
5813
6121
  * @default '7 days'
@@ -5815,7 +6123,7 @@ var authPlugin = definePlugin({
5815
6123
  temporaryPasswordValidity: DurationSchema.default("7 days")
5816
6124
  }).default({}),
5817
6125
  /** Specifies the validity duration for every JWT token. */
5818
- validity: z25.object({
6126
+ validity: z26.object({
5819
6127
  /** The ID token time limit.
5820
6128
  * After this limit expires, your user can't use their ID token.
5821
6129
  * @default '1 hour'
@@ -5837,7 +6145,7 @@ var authPlugin = definePlugin({
5837
6145
  })
5838
6146
  ).default({})
5839
6147
  }).default({}),
5840
- stacks: z25.object({
6148
+ stacks: z26.object({
5841
6149
  /** Define the auth triggers in your stack.
5842
6150
  * @example
5843
6151
  * {
@@ -5850,13 +6158,13 @@ var authPlugin = definePlugin({
5850
6158
  * }
5851
6159
  * }
5852
6160
  */
5853
- auth: z25.record(
6161
+ auth: z26.record(
5854
6162
  ResourceIdSchema,
5855
- z25.object({
6163
+ z26.object({
5856
6164
  /** Give access to every function in this stack to your cognito instance.
5857
6165
  * @default false
5858
6166
  */
5859
- access: z25.boolean().default(false),
6167
+ access: z26.boolean().default(false),
5860
6168
  /** Specifies the configuration for AWS Lambda triggers. */
5861
6169
  triggers: TriggersSchema.optional()
5862
6170
  })
@@ -5878,11 +6186,13 @@ var authPlugin = definePlugin({
5878
6186
  for (const [id, props] of Object.entries(stackConfig.auth ?? {})) {
5879
6187
  if (props.access) {
5880
6188
  const userPoolId = bootstrap2.import(`auth-${id}-user-pool-id`);
5881
- const clientId = bootstrap2.import(`auth-${id}-user-pool-id`);
5882
- const name = constantCase10(id);
6189
+ const clientId = bootstrap2.import(`auth-${id}-client-id`);
6190
+ const clientSecret = bootstrap2.import(`auth-${id}-client-secret`);
6191
+ const name = constantCase11(id);
5883
6192
  bind((lambda) => {
5884
6193
  lambda.addEnvironment(`AUTH_${name}_USER_POOL_ID`, userPoolId);
5885
6194
  lambda.addEnvironment(`AUTH_${name}_CLIENT_ID`, clientId);
6195
+ lambda.addEnvironment(`AUTH_${name}_CLIENT_SECRET`, clientSecret);
5886
6196
  lambda.addPermissions({
5887
6197
  actions: ["cognito:*"],
5888
6198
  resources: ["*"]
@@ -5893,6 +6203,18 @@ var authPlugin = definePlugin({
5893
6203
  },
5894
6204
  onApp(ctx) {
5895
6205
  const { config, bootstrap: bootstrap2 } = ctx;
6206
+ if (Object.keys(config.defaults.auth).length === 0) {
6207
+ return;
6208
+ }
6209
+ const clientSecretLambda = new Function(`auth-client-secret`, {
6210
+ name: `${config.name}-auth-client-secret`,
6211
+ code: Code.fromFeature("cognito-client-secret")
6212
+ });
6213
+ clientSecretLambda.addPermissions({
6214
+ actions: ["cognito-idp:DescribeUserPoolClient"],
6215
+ resources: ["*"]
6216
+ });
6217
+ bootstrap2.add(clientSecretLambda);
5896
6218
  for (const [id, props] of Object.entries(config.defaults.auth)) {
5897
6219
  const functions = /* @__PURE__ */ new Map();
5898
6220
  const triggers = {};
@@ -5913,12 +6235,26 @@ var authPlugin = definePlugin({
5913
6235
  triggers[trigger] = lambda.arn;
5914
6236
  }
5915
6237
  }
6238
+ let emailConfig;
6239
+ if (props.messaging) {
6240
+ const [_, ...parts] = props.messaging.fromEmail.split("@");
6241
+ const domainName = parts.join("@");
6242
+ emailConfig = UserPoolEmail.withSES({
6243
+ ...props.messaging,
6244
+ sourceArn: formatArn({
6245
+ service: "ses",
6246
+ resource: "identity",
6247
+ resourceName: domainName
6248
+ })
6249
+ });
6250
+ }
5916
6251
  const userPool = new UserPool(id, {
5917
6252
  name: `${config.name}-${id}`,
5918
6253
  allowUserRegistration: props.allowUserRegistration,
5919
6254
  username: props.username,
5920
6255
  password: props.password,
5921
- triggers
6256
+ triggers,
6257
+ email: emailConfig
5922
6258
  });
5923
6259
  const client = userPool.addClient({
5924
6260
  name: `${config.name}-${id}`,
@@ -5932,7 +6268,14 @@ var authPlugin = definePlugin({
5932
6268
  const domain = userPool.addDomain({
5933
6269
  domain: `${config.name}-${id}`
5934
6270
  });
5935
- bootstrap2.add(userPool).export(`auth-${id}-user-pool-arn`, userPool.arn).export(`auth-${id}-user-pool-id`, userPool.id).export(`auth-${id}-client-id`, client.id).export(`auth-${id}-domain`, domain.domain);
6271
+ const clientSecret = new CustomResource(`${id}-client-secret`, {
6272
+ serviceToken: clientSecretLambda.arn,
6273
+ properties: {
6274
+ userPoolId: userPool.id,
6275
+ clientId: client.id
6276
+ }
6277
+ }).dependsOn(client, userPool);
6278
+ bootstrap2.add(userPool).add(clientSecret).export(`auth-${id}-user-pool-arn`, userPool.arn).export(`auth-${id}-user-pool-id`, userPool.id).export(`auth-${id}-client-id`, client.id).export(`auth-${id}-client-secret`, clientSecret.getAtt("secret")).export(`auth-${id}-domain`, domain.domain);
5936
6279
  for (const [event, lambda] of functions) {
5937
6280
  const permission = new Permission(`auth-${id}-${event}`, {
5938
6281
  action: "lambda:InvokeFunction",
@@ -5959,6 +6302,7 @@ var defaultPlugins = [
5959
6302
  queuePlugin,
5960
6303
  tablePlugin,
5961
6304
  storePlugin,
6305
+ // alertPlugin,
5962
6306
  topicPlugin,
5963
6307
  pubsubPlugin,
5964
6308
  searchPlugin,
@@ -6119,17 +6463,17 @@ var getCredentials = (profile) => {
6119
6463
  };
6120
6464
 
6121
6465
  // src/schema/app.ts
6122
- import { z as z29 } from "zod";
6466
+ import { z as z30 } from "zod";
6123
6467
 
6124
6468
  // src/schema/stack.ts
6125
- import { z as z26 } from "zod";
6126
- var StackSchema = z26.object({
6469
+ import { z as z27 } from "zod";
6470
+ var StackSchema = z27.object({
6127
6471
  name: ResourceIdSchema,
6128
- depends: z26.array(z26.lazy(() => StackSchema)).optional()
6472
+ depends: z27.array(z27.lazy(() => StackSchema)).optional()
6129
6473
  });
6130
6474
 
6131
6475
  // src/schema/region.ts
6132
- import { z as z27 } from "zod";
6476
+ import { z as z28 } from "zod";
6133
6477
  var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
6134
6478
  var AF = ["af-south-1"];
6135
6479
  var AP = ["ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-4", "ap-south-1", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1"];
@@ -6146,64 +6490,66 @@ var regions = [
6146
6490
  ...ME,
6147
6491
  ...SA
6148
6492
  ];
6149
- var RegionSchema = z27.enum(regions);
6493
+ var RegionSchema = z28.enum(regions);
6150
6494
 
6151
6495
  // src/schema/plugin.ts
6152
- import { z as z28 } from "zod";
6153
- var PluginSchema = z28.object({
6154
- name: z28.string(),
6155
- schema: z28.custom().optional(),
6496
+ import { z as z29 } from "zod";
6497
+ var PluginSchema = z29.object({
6498
+ name: z29.string(),
6499
+ schema: z29.custom().optional(),
6156
6500
  // depends: z.array(z.lazy(() => PluginSchema)).optional(),
6157
- onApp: z28.function().returns(z28.void()).optional(),
6158
- onStack: z28.function().returns(z28.any()).optional(),
6159
- onResource: z28.function().returns(z28.any()).optional()
6501
+ onApp: z29.function().returns(z29.void()).optional(),
6502
+ onStack: z29.function().returns(z29.any()).optional(),
6503
+ onResource: z29.function().returns(z29.any()).optional()
6160
6504
  // bind: z.function().optional(),
6161
6505
  });
6162
6506
 
6163
6507
  // src/schema/app.ts
6164
- var AppSchema = z29.object({
6508
+ var AppSchema = z30.object({
6165
6509
  /** App name */
6166
6510
  name: ResourceIdSchema,
6167
6511
  /** The AWS region to deploy to. */
6168
6512
  region: RegionSchema,
6169
6513
  /** The AWS profile to deploy to. */
6170
- profile: z29.string(),
6514
+ profile: z30.string(),
6171
6515
  /** The deployment stage.
6172
6516
  * @default 'prod'
6173
6517
  */
6174
- stage: z29.string().regex(/^[a-z]+$/).default("prod"),
6518
+ stage: z30.string().regex(/^[a-z]+$/).default("prod"),
6175
6519
  /** Default properties. */
6176
- defaults: z29.object({}).default({}),
6520
+ defaults: z30.object({}).default({}),
6177
6521
  /** The application stacks. */
6178
- stacks: z29.array(StackSchema).min(1).refine((stacks) => {
6522
+ stacks: z30.array(StackSchema).min(1).refine((stacks) => {
6179
6523
  const unique = new Set(stacks.map((stack) => stack.name));
6180
6524
  return unique.size === stacks.length;
6181
6525
  }, "Must be an array of unique stacks"),
6182
6526
  /** Custom plugins. */
6183
- plugins: z29.array(PluginSchema).optional()
6527
+ plugins: z30.array(PluginSchema).optional()
6184
6528
  });
6185
6529
 
6186
6530
  // src/util/import.ts
6187
- import { rollup as rollup2, watch } from "rollup";
6188
- import { swc as swc2 } from "rollup-plugin-swc3";
6531
+ import { rollup as rollup3, watch } from "rollup";
6532
+ import { swc as swc3 } from "rollup-plugin-swc3";
6189
6533
  import replace from "rollup-plugin-replace";
6190
6534
  import { EventIterator } from "event-iterator";
6191
- import { dirname as dirname2, join as join5 } from "path";
6535
+ import { dirname as dirname3, join as join5 } from "path";
6192
6536
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
6193
6537
  var importFile = async (path) => {
6194
- const bundle = await rollup2({
6538
+ const bundle = await rollup3({
6195
6539
  input: path,
6196
6540
  onwarn: (error) => {
6197
6541
  debugError(error.message);
6198
6542
  },
6199
6543
  plugins: [
6544
+ // @ts-ignore
6200
6545
  replace({
6201
- __dirname: (id) => `'${dirname2(id)}'`
6546
+ __dirname: (id) => `'${dirname3(id)}'`
6547
+ // 'defineStackConfig({': id => `defineStackConfig({ cwd: '${dirname(id)}',`,
6202
6548
  }),
6203
- swc2({
6549
+ swc3({
6204
6550
  minify: false,
6205
6551
  jsc: {
6206
- baseUrl: dirname2(path)
6552
+ baseUrl: dirname3(path)
6207
6553
  }
6208
6554
  })
6209
6555
  ]
@@ -6221,63 +6567,68 @@ var importFile = async (path) => {
6221
6567
  return import(outputFile);
6222
6568
  };
6223
6569
  var watchFile = (path) => {
6224
- return new EventIterator((queue2) => {
6225
- const watcher = watch({
6226
- watch: {
6227
- skipWrite: true
6228
- },
6229
- input: path,
6230
- onwarn: (error) => {
6231
- debugError(error.message);
6232
- },
6233
- plugins: [
6234
- replace({
6235
- __dirname: (id) => `'${dirname2(id)}'`
6236
- }),
6237
- swc2({
6238
- minify: false,
6239
- jsc: {
6240
- baseUrl: dirname2(path)
6241
- }
6242
- })
6243
- ]
6244
- });
6245
- let resume;
6246
- queue2.on("lowWater", () => {
6247
- resume?.(true);
6248
- });
6249
- watcher.on("close", queue2.stop);
6250
- watcher.on("event", async (event) => {
6251
- if (event.code === "ERROR") {
6252
- queue2.fail(new Error(event.error.message));
6253
- }
6254
- if (event.code === "BUNDLE_END") {
6255
- const result = await event.result.generate({
6256
- format: "esm",
6257
- exports: "default"
6258
- });
6259
- event.result.close();
6260
- const output = result.output[0];
6261
- const code = output.code;
6262
- const outputFile = join5(directories.cache, "config.js");
6263
- await mkdir2(directories.cache, { recursive: true });
6264
- await writeFile2(outputFile, code);
6265
- debug("Save config file:", style.info(outputFile));
6266
- const config = await import(`${outputFile}?${Date.now()}`);
6267
- queue2.push(config);
6268
- }
6269
- });
6270
- return () => {
6271
- watcher.close();
6272
- };
6273
- }, {
6274
- highWaterMark: 1,
6275
- lowWaterMark: 0
6276
- });
6570
+ return new EventIterator(
6571
+ (queue2) => {
6572
+ const watcher = watch({
6573
+ watch: {
6574
+ skipWrite: true
6575
+ },
6576
+ input: path,
6577
+ onwarn: (error) => {
6578
+ debugError(error.message);
6579
+ },
6580
+ plugins: [
6581
+ // @ts-ignore
6582
+ replace({
6583
+ __dirname: (id) => `'${dirname3(id)}'`
6584
+ // 'defineStackConfig({': id => `defineStackConfig({ cwd: '${dirname(id)}',`,
6585
+ }),
6586
+ swc3({
6587
+ minify: false,
6588
+ jsc: {
6589
+ baseUrl: dirname3(path)
6590
+ }
6591
+ })
6592
+ ]
6593
+ });
6594
+ let resume;
6595
+ queue2.on("lowWater", () => {
6596
+ resume?.(true);
6597
+ });
6598
+ watcher.on("close", queue2.stop);
6599
+ watcher.on("event", async (event) => {
6600
+ if (event.code === "ERROR") {
6601
+ queue2.fail(new Error(event.error.message));
6602
+ }
6603
+ if (event.code === "BUNDLE_END") {
6604
+ const result = await event.result.generate({
6605
+ format: "esm",
6606
+ exports: "default"
6607
+ });
6608
+ event.result.close();
6609
+ const output = result.output[0];
6610
+ const code = output.code;
6611
+ const outputFile = join5(directories.cache, "config.js");
6612
+ await mkdir2(directories.cache, { recursive: true });
6613
+ await writeFile2(outputFile, code);
6614
+ debug("Save config file:", style.info(outputFile));
6615
+ const config = await import(`${outputFile}?${Date.now()}`);
6616
+ queue2.push(config);
6617
+ }
6618
+ });
6619
+ return () => {
6620
+ watcher.close();
6621
+ };
6622
+ },
6623
+ {
6624
+ highWaterMark: 1,
6625
+ lowWaterMark: 0
6626
+ }
6627
+ );
6277
6628
  };
6278
6629
 
6279
6630
  // src/config.ts
6280
- import { z as z30 } from "zod";
6631
+ import { z as z31 } from "zod";
6281
6632
  var ConfigError = class extends Error {
6282
6633
  constructor(error, data) {
6283
6634
  super(error.message);
@@ -6310,7 +6661,7 @@ var importConfig = async (options) => {
6310
6661
  try {
6311
6662
  config = await schema2.parseAsync(appConfig);
6312
6663
  } catch (error) {
6313
- if (error instanceof z30.ZodError) {
6664
+ if (error instanceof z31.ZodError) {
6314
6665
  throw new ConfigError(error, appConfig);
6315
6666
  }
6316
6667
  throw error;
@@ -6351,7 +6702,7 @@ var watchConfig = async (options, resolve, reject) => {
6351
6702
  try {
6352
6703
  config = await schema2.parseAsync(appConfig);
6353
6704
  } catch (error) {
6354
- if (error instanceof z30.ZodError) {
6705
+ if (error instanceof z31.ZodError) {
6355
6706
  reject(new ConfigError(error, appConfig));
6356
6707
  continue;
6357
6708
  }
@@ -6951,7 +7302,7 @@ var flexLine = (term, left, right, reserveSpace = 0) => {
6951
7302
  };
6952
7303
 
6953
7304
  // src/cli/ui/complex/builder.ts
6954
- import { dirname as dirname3, join as join7 } from "path";
7305
+ import { dirname as dirname4, join as join7 } from "path";
6955
7306
  var assetBuilder = (app) => {
6956
7307
  return async (term) => {
6957
7308
  const assets = [];
@@ -7015,7 +7366,7 @@ var assetBuilder = (app) => {
7015
7366
  const data = await asset.build({
7016
7367
  async write(file, data2) {
7017
7368
  const fullpath = join7(directories.asset, asset.type, app.name, stack.name, asset.id, file);
7018
- const basepath = dirname3(fullpath);
7369
+ const basepath = dirname4(fullpath);
7019
7370
  await mkdir3(basepath, { recursive: true });
7020
7371
  await writeFile3(fullpath, data2);
7021
7372
  }
@@ -7604,55 +7955,70 @@ var assetPublisher = (config, app) => {
7604
7955
  });
7605
7956
  return async (term) => {
7606
7957
  const done = term.out.write(loadingDialog("Publishing stack assets to AWS..."));
7607
- await Promise.all(app.stacks.map(async (stack) => {
7608
- await Promise.all([...stack.assets].map(async (asset) => {
7609
- await asset.publish?.({
7610
- async read(file) {
7611
- const path = join9(directories.asset, asset.type, app.name, stack.name, asset.id, file);
7612
- const data = await readFile3(path);
7613
- return data;
7614
- },
7615
- async publish(name, data, hash) {
7616
- const key = `${app.name}/${stack.name}/${asset.type}/${name}`;
7617
- const bucket = assetBucketName(config.account, config.region);
7618
- let getResult;
7619
- try {
7620
- getResult = await client.send(new GetObjectCommand({
7621
- Bucket: bucket,
7622
- Key: key
7623
- }));
7624
- } catch (error) {
7625
- if (error instanceof Error && error.name === "NoSuchKey") {
7626
- } else {
7627
- throw error;
7958
+ await Promise.all(
7959
+ app.stacks.map(async (stack) => {
7960
+ await Promise.all(
7961
+ [...stack.assets].map(async (asset) => {
7962
+ await asset.publish?.({
7963
+ async read(file) {
7964
+ const path = join9(
7965
+ directories.asset,
7966
+ asset.type,
7967
+ app.name,
7968
+ stack.name,
7969
+ asset.id,
7970
+ file
7971
+ );
7972
+ const data = await readFile3(path);
7973
+ return data;
7974
+ },
7975
+ async publish(name, data, hash) {
7976
+ const key = `${app.name}/${stack.name}/${asset.type}/${name}`;
7977
+ const bucket = assetBucketName(config.account, config.region);
7978
+ let getResult;
7979
+ try {
7980
+ getResult = await client.send(
7981
+ new GetObjectCommand({
7982
+ Bucket: bucket,
7983
+ Key: key
7984
+ })
7985
+ );
7986
+ } catch (error) {
7987
+ if (error instanceof Error && error.name === "NoSuchKey") {
7988
+ } else {
7989
+ throw error;
7990
+ }
7991
+ }
7992
+ if (getResult?.Metadata?.hash === hash) {
7993
+ return {
7994
+ bucket,
7995
+ key,
7996
+ version: getResult.VersionId
7997
+ };
7998
+ }
7999
+ const putResult = await client.send(
8000
+ new PutObjectCommand2({
8001
+ Bucket: bucket,
8002
+ Key: key,
8003
+ Body: data,
8004
+ ACL: ObjectCannedACL2.private,
8005
+ StorageClass: StorageClass2.STANDARD,
8006
+ Metadata: {
8007
+ hash
8008
+ }
8009
+ })
8010
+ );
8011
+ return {
8012
+ bucket,
8013
+ key,
8014
+ version: putResult.VersionId
8015
+ };
7628
8016
  }
7629
- }
7630
- if (getResult?.Metadata?.hash === hash) {
7631
- return {
7632
- bucket,
7633
- key,
7634
- version: getResult.VersionId
7635
- };
7636
- }
7637
- const putResult = await client.send(new PutObjectCommand2({
7638
- Bucket: bucket,
7639
- Key: key,
7640
- Body: data,
7641
- ACL: ObjectCannedACL2.private,
7642
- StorageClass: StorageClass2.STANDARD,
7643
- Metadata: {
7644
- hash
7645
- }
7646
- }));
7647
- return {
7648
- bucket,
7649
- key,
7650
- version: putResult.VersionId
7651
- };
7652
- }
7653
- });
7654
- }));
7655
- }));
8017
+ });
8018
+ })
8019
+ );
8020
+ })
8021
+ );
7656
8022
  done("Done publishing stack assets to AWS");
7657
8023
  };
7658
8024
  };