@awsless/awsless 0.0.85 → 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 +503 -165
  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 +54 -10
  27. package/dist/index.js +18 -3
  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;
@@ -2782,9 +2816,9 @@ var RecordSet = class extends Resource {
2782
2816
  properties() {
2783
2817
  return {
2784
2818
  HostedZoneId: this.props.hostedZoneId,
2785
- Name: this.name + ".",
2819
+ Name: typeof this.name === "string" ? this.name + "." : this.name,
2786
2820
  Type: this.props.type,
2787
- TTL: this.props.ttl,
2821
+ TTL: this.props.ttl?.toSeconds(),
2788
2822
  ...this.props.records ? {
2789
2823
  ResourceRecords: this.props.records
2790
2824
  } : {},
@@ -2800,7 +2834,7 @@ var RecordSet = class extends Resource {
2800
2834
 
2801
2835
  // src/formation/resource/appsync/graphql-schema.ts
2802
2836
  import { print } from "graphql";
2803
- import { readFile } from "fs/promises";
2837
+ import { readFile as readFile2 } from "fs/promises";
2804
2838
  import { mergeTypeDefs } from "@graphql-tools/merge";
2805
2839
  var GraphQLSchema = class extends Resource {
2806
2840
  constructor(logicalId, props) {
@@ -2825,7 +2859,7 @@ var Definition = class extends Asset {
2825
2859
  async build({ write }) {
2826
2860
  const files = [this.files].flat();
2827
2861
  const schemas = await Promise.all(files.map((file) => {
2828
- return readFile(file, "utf8");
2862
+ return readFile2(file, "utf8");
2829
2863
  }));
2830
2864
  const defs = mergeTypeDefs(schemas);
2831
2865
  const schema2 = print(defs);
@@ -2844,8 +2878,69 @@ var Definition = class extends Asset {
2844
2878
  }
2845
2879
  };
2846
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
+
2847
2943
  // src/formation/resource/appsync/code.ts
2848
- import { readFile as readFile2 } from "fs/promises";
2849
2944
  var Code2 = class {
2850
2945
  static fromFile(id, file) {
2851
2946
  return new FileCode2(id, file);
@@ -2872,7 +2967,7 @@ var FileCode2 = class extends Asset {
2872
2967
  }
2873
2968
  code;
2874
2969
  async build() {
2875
- const code = await readFile2(this.file);
2970
+ const code = await rollupResolver({ minify: false })(this.file);
2876
2971
  this.code = code.toString("utf8");
2877
2972
  return {
2878
2973
  size: formatByteSize(code.byteLength)
@@ -2934,9 +3029,7 @@ var DataSource = class _DataSource extends Resource {
2934
3029
  import { snakeCase as snakeCase3 } from "change-case";
2935
3030
  var FunctionConfiguration = class extends Resource {
2936
3031
  constructor(logicalId, props) {
2937
- super("AWS::AppSync::FunctionConfiguration", logicalId, [
2938
- props.code
2939
- ]);
3032
+ super("AWS::AppSync::FunctionConfiguration", logicalId);
2940
3033
  this.props = props;
2941
3034
  this.name = snakeCase3(this.props.name || logicalId);
2942
3035
  }
@@ -3055,7 +3148,10 @@ var DomainNameApiAssociation = class extends Resource {
3055
3148
  };
3056
3149
 
3057
3150
  // src/plugins/graphql.ts
3058
- var defaultResolver = `
3151
+ import { basename } from "path";
3152
+ var defaultResolver = Code2.fromInline(
3153
+ "graphql-default-resolver",
3154
+ `
3059
3155
  export function request(ctx) {
3060
3156
  return {
3061
3157
  operation: 'Invoke',
@@ -3066,7 +3162,9 @@ export function request(ctx) {
3066
3162
  export function response(ctx) {
3067
3163
  return ctx.result
3068
3164
  }
3069
- `;
3165
+ `
3166
+ );
3167
+ var resolverCache = /* @__PURE__ */ new Map();
3070
3168
  var graphqlPlugin = definePlugin({
3071
3169
  name: "graphql",
3072
3170
  schema: z15.object({
@@ -3100,7 +3198,7 @@ var graphqlPlugin = definePlugin({
3100
3198
  FunctionSchema,
3101
3199
  z15.object({
3102
3200
  consumer: FunctionSchema,
3103
- resolver: LocalFileSchema
3201
+ resolver: LocalFileSchema.optional()
3104
3202
  })
3105
3203
  ])
3106
3204
  )
@@ -3171,19 +3269,30 @@ var graphqlPlugin = definePlugin({
3171
3269
  }
3172
3270
  },
3173
3271
  onStack(ctx) {
3174
- const { stack, stackConfig, bootstrap: bootstrap2 } = ctx;
3272
+ const { config, stack, stackConfig, bootstrap: bootstrap2 } = ctx;
3175
3273
  for (const [id, props] of Object.entries(stackConfig.graphql || {})) {
3176
3274
  const apiId = bootstrap2.import(`graphql-${id}`);
3275
+ const defaultProps = config.defaults.graphql?.[id];
3177
3276
  for (const [typeName, fields] of Object.entries(props.resolvers || {})) {
3178
3277
  for (const [fieldName, resolverProps] of Object.entries(fields || {})) {
3179
3278
  const props2 = isFunctionProps(resolverProps) ? { consumer: resolverProps } : resolverProps;
3180
3279
  const entryId = paramCase4(`${id}-${typeName}-${fieldName}`);
3181
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
+ }
3182
3291
  const source = new AppsyncEventSource(entryId, lambda, {
3183
3292
  apiId,
3184
3293
  typeName,
3185
3294
  fieldName,
3186
- code: Code2.fromInline(entryId, props2.resolver || defaultResolver)
3295
+ code
3187
3296
  });
3188
3297
  stack.add(lambda, source);
3189
3298
  }
@@ -3247,9 +3356,9 @@ var RecordSetGroup = class extends Resource {
3247
3356
  return {
3248
3357
  HostedZoneId: this.props.hostedZoneId,
3249
3358
  RecordSets: this.props.records.map((props) => ({
3250
- Name: props.name + ".",
3359
+ Name: typeof props.name === "string" ? props.name + "." : props.name,
3251
3360
  Type: props.type,
3252
- TTL: props.ttl,
3361
+ TTL: props.ttl?.toSeconds(),
3253
3362
  ...props.records ? {
3254
3363
  ResourceRecords: props.records
3255
3364
  } : {},
@@ -3292,6 +3401,108 @@ var GlobalExports = class extends Group {
3292
3401
  }
3293
3402
  };
3294
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
+
3295
3506
  // src/plugins/domain.ts
3296
3507
  var DomainNameSchema = z16.string().regex(/[a-z\-\_\.]/g, "Invalid domain name");
3297
3508
  var domainPlugin = definePlugin({
@@ -3344,7 +3555,7 @@ var domainPlugin = definePlugin({
3344
3555
  ).optional()
3345
3556
  }).default({})
3346
3557
  }),
3347
- onApp({ config, bootstrap: bootstrap2, usEastBootstrap }) {
3558
+ onApp({ config, bootstrap: bootstrap2, usEastBootstrap, bind }) {
3348
3559
  const domains = Object.entries(config.defaults.domains || {});
3349
3560
  if (domains.length === 0) {
3350
3561
  return;
@@ -3361,6 +3572,12 @@ var domainPlugin = definePlugin({
3361
3572
  region: usEastBootstrap.region
3362
3573
  });
3363
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);
3364
3581
  for (const [domain, records] of domains) {
3365
3582
  const hostedZone = new HostedZone(domain);
3366
3583
  const usEastCertificate = new Certificate(domain, {
@@ -3378,7 +3595,18 @@ var domainPlugin = definePlugin({
3378
3595
  hostedZoneId: usEastExports.import(`hosted-zone-${domain}-id`),
3379
3596
  alternativeNames: [`*.${domain}`]
3380
3597
  });
3381
- 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`));
3382
3610
  if (records.length > 0) {
3383
3611
  const group = new RecordSetGroup(domain, {
3384
3612
  hostedZoneId: hostedZone.id,
@@ -3387,6 +3615,12 @@ var domainPlugin = definePlugin({
3387
3615
  usEastBootstrap.add(group);
3388
3616
  }
3389
3617
  }
3618
+ bind(
3619
+ (lambda) => lambda.addPermissions({
3620
+ actions: ["ses:*"],
3621
+ resources: ["*"]
3622
+ })
3623
+ );
3390
3624
  }
3391
3625
  });
3392
3626
 
@@ -3775,7 +4009,7 @@ var LoadBalancer = class extends Resource {
3775
4009
  };
3776
4010
 
3777
4011
  // src/formation/resource/elb/listener.ts
3778
- import { constantCase as constantCase7 } from "change-case";
4012
+ import { constantCase as constantCase8 } from "change-case";
3779
4013
  var Listener = class extends Resource {
3780
4014
  constructor(logicalId, props) {
3781
4015
  super("AWS::ElasticLoadBalancingV2::Listener", logicalId);
@@ -3791,7 +4025,7 @@ var Listener = class extends Resource {
3791
4025
  return {
3792
4026
  LoadBalancerArn: this.props.loadBalancerArn,
3793
4027
  Port: this.props.port,
3794
- Protocol: constantCase7(this.props.protocol),
4028
+ Protocol: constantCase8(this.props.protocol),
3795
4029
  Certificates: this.props.certificates.map((arn) => ({
3796
4030
  CertificateArn: arn
3797
4031
  })),
@@ -4274,7 +4508,7 @@ var SubnetGroup = class extends Resource {
4274
4508
  };
4275
4509
 
4276
4510
  // src/plugins/cache.ts
4277
- import { constantCase as constantCase8 } from "change-case";
4511
+ import { constantCase as constantCase9 } from "change-case";
4278
4512
  var TypeSchema = z20.enum([
4279
4513
  "t4g.small",
4280
4514
  "t4g.medium",
@@ -4294,6 +4528,17 @@ var PortSchema = z20.number().int().min(1).max(5e4);
4294
4528
  var ShardsSchema = z20.number().int().min(0).max(100);
4295
4529
  var ReplicasPerShardSchema = z20.number().int().min(0).max(5);
4296
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
+ }`;
4297
4542
  var cachePlugin = definePlugin({
4298
4543
  name: "cache",
4299
4544
  schema: z20.object({
@@ -4324,10 +4569,11 @@ var cachePlugin = definePlugin({
4324
4569
  }),
4325
4570
  onTypeGen({ config }) {
4326
4571
  const gen = new TypeGen("@awsless/awsless", "CacheResources");
4572
+ gen.addCode(typeGenCode4);
4327
4573
  for (const stack of config.stacks) {
4328
4574
  const list3 = new TypeObject();
4329
4575
  for (const name of Object.keys(stack.caches || {})) {
4330
- list3.addType(name, `{ readonly host: string, readonly port: number }`);
4576
+ list3.addType(name, `Command`);
4331
4577
  }
4332
4578
  gen.addType(stack.name, list3.toString());
4333
4579
  }
@@ -4357,8 +4603,8 @@ var cachePlugin = definePlugin({
4357
4603
  }).dependsOn(subnetGroup, securityGroup);
4358
4604
  stack.add(subnetGroup, securityGroup, cluster);
4359
4605
  bind((lambda) => {
4360
- lambda.addEnvironment(`CACHE_${constantCase8(stack.name)}_${constantCase8(id)}_HOST`, cluster.address).addEnvironment(
4361
- `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`,
4362
4608
  props.port.toString()
4363
4609
  );
4364
4610
  });
@@ -5528,7 +5774,7 @@ var featurePlugin = definePlugin({
5528
5774
  import { z as z26 } from "zod";
5529
5775
 
5530
5776
  // src/formation/resource/cognito/user-pool.ts
5531
- import { constantCase as constantCase9 } from "change-case";
5777
+ import { constantCase as constantCase10 } from "change-case";
5532
5778
 
5533
5779
  // src/formation/resource/cognito/user-pool-client.ts
5534
5780
  var UserPoolClient = class extends Resource {
@@ -5699,25 +5945,26 @@ var UserPool = class extends Resource {
5699
5945
  AliasAttributes: ["email"],
5700
5946
  // UsernameAttributes: [ 'email' ],
5701
5947
  AutoVerifiedAttributes: ["email"],
5702
- Schema: [{
5703
- AttributeDataType: "String",
5704
- Name: "email",
5705
- Required: true,
5706
- Mutable: false,
5707
- StringAttributeConstraints: {
5708
- MinLength: 5,
5709
- 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
+ }
5710
5958
  }
5711
- }]
5959
+ ]
5712
5960
  } : {},
5713
5961
  UsernameConfiguration: {
5714
5962
  CaseSensitive: this.props.username?.caseSensitive ?? false
5715
5963
  },
5716
5964
  ...this.attr("EmailConfiguration", this.props.email?.toJSON()),
5717
- // DeviceConfiguration: {
5718
- // ChallengeRequiredOnNewDevice: {},
5719
- // DeviceOnlyRememberedOnUserPrompt: {},
5720
- // },
5965
+ DeviceConfiguration: {
5966
+ DeviceOnlyRememberedOnUserPrompt: false
5967
+ },
5721
5968
  AdminCreateUserConfig: {
5722
5969
  AllowAdminCreateUserOnly: !(this.props.allowUserRegistration ?? true)
5723
5970
  },
@@ -5741,14 +5988,41 @@ var UserPool = class extends Resource {
5741
5988
  ...this.attr("UserMigration", this.props.triggers?.userMigration),
5742
5989
  ...this.attr("DefineAuthChallenge", this.props.triggers?.defineChallange),
5743
5990
  ...this.attr("CreateAuthChallenge", this.props.triggers?.createChallange),
5744
- ...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
+ } : {}
5745
5998
  }
5746
5999
  };
5747
6000
  }
5748
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
+ };
5749
6023
 
5750
6024
  // src/plugins/auth.ts
5751
- import { constantCase as constantCase10 } from "change-case";
6025
+ import { constantCase as constantCase11 } from "change-case";
5752
6026
  var TriggersSchema = z26.object({
5753
6027
  /** A pre jwt token generation AWS Lambda trigger. */
5754
6028
  beforeToken: FunctionSchema.optional(),
@@ -5762,6 +6036,8 @@ var TriggersSchema = z26.object({
5762
6036
  afterRegister: FunctionSchema.optional(),
5763
6037
  /** A custom message AWS Lambda trigger. */
5764
6038
  customMessage: FunctionSchema.optional(),
6039
+ // /** A custom email sender AWS Lambda trigger */
6040
+ // emailSender: FunctionSchema.optional(),
5765
6041
  /** Defines the authentication challenge. */
5766
6042
  defineChallenge: FunctionSchema.optional(),
5767
6043
  /** Creates an authentication challenge. */
@@ -5795,6 +6071,16 @@ var authPlugin = definePlugin({
5795
6071
  * @default true
5796
6072
  */
5797
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(),
5798
6084
  /** The username policy. */
5799
6085
  username: z26.object({
5800
6086
  /** Allow the user email to be used as username.
@@ -5811,9 +6097,9 @@ var authPlugin = definePlugin({
5811
6097
  /** The password policy. */
5812
6098
  password: z26.object({
5813
6099
  /** Required users to have at least the minimum password length.
5814
- * @default 8
6100
+ * @default 12
5815
6101
  */
5816
- minLength: z26.number().int().min(6).max(99).default(8),
6102
+ minLength: z26.number().int().min(6).max(99).default(12),
5817
6103
  /** Required users to use at least one uppercase letter in their password.
5818
6104
  * @default true
5819
6105
  */
@@ -5900,11 +6186,13 @@ var authPlugin = definePlugin({
5900
6186
  for (const [id, props] of Object.entries(stackConfig.auth ?? {})) {
5901
6187
  if (props.access) {
5902
6188
  const userPoolId = bootstrap2.import(`auth-${id}-user-pool-id`);
5903
- const clientId = bootstrap2.import(`auth-${id}-user-pool-id`);
5904
- 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);
5905
6192
  bind((lambda) => {
5906
6193
  lambda.addEnvironment(`AUTH_${name}_USER_POOL_ID`, userPoolId);
5907
6194
  lambda.addEnvironment(`AUTH_${name}_CLIENT_ID`, clientId);
6195
+ lambda.addEnvironment(`AUTH_${name}_CLIENT_SECRET`, clientSecret);
5908
6196
  lambda.addPermissions({
5909
6197
  actions: ["cognito:*"],
5910
6198
  resources: ["*"]
@@ -5915,6 +6203,18 @@ var authPlugin = definePlugin({
5915
6203
  },
5916
6204
  onApp(ctx) {
5917
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);
5918
6218
  for (const [id, props] of Object.entries(config.defaults.auth)) {
5919
6219
  const functions = /* @__PURE__ */ new Map();
5920
6220
  const triggers = {};
@@ -5935,12 +6235,26 @@ var authPlugin = definePlugin({
5935
6235
  triggers[trigger] = lambda.arn;
5936
6236
  }
5937
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
+ }
5938
6251
  const userPool = new UserPool(id, {
5939
6252
  name: `${config.name}-${id}`,
5940
6253
  allowUserRegistration: props.allowUserRegistration,
5941
6254
  username: props.username,
5942
6255
  password: props.password,
5943
- triggers
6256
+ triggers,
6257
+ email: emailConfig
5944
6258
  });
5945
6259
  const client = userPool.addClient({
5946
6260
  name: `${config.name}-${id}`,
@@ -5954,7 +6268,14 @@ var authPlugin = definePlugin({
5954
6268
  const domain = userPool.addDomain({
5955
6269
  domain: `${config.name}-${id}`
5956
6270
  });
5957
- 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);
5958
6279
  for (const [event, lambda] of functions) {
5959
6280
  const permission = new Permission(`auth-${id}-${event}`, {
5960
6281
  action: "lambda:InvokeFunction",
@@ -6207,27 +6528,28 @@ var AppSchema = z30.object({
6207
6528
  });
6208
6529
 
6209
6530
  // src/util/import.ts
6210
- import { rollup as rollup2, watch } from "rollup";
6211
- 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";
6212
6533
  import replace from "rollup-plugin-replace";
6213
6534
  import { EventIterator } from "event-iterator";
6214
- import { dirname as dirname2, join as join5 } from "path";
6535
+ import { dirname as dirname3, join as join5 } from "path";
6215
6536
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
6216
6537
  var importFile = async (path) => {
6217
- const bundle = await rollup2({
6538
+ const bundle = await rollup3({
6218
6539
  input: path,
6219
6540
  onwarn: (error) => {
6220
6541
  debugError(error.message);
6221
6542
  },
6222
6543
  plugins: [
6544
+ // @ts-ignore
6223
6545
  replace({
6224
- __dirname: (id) => `'${dirname2(id)}'`,
6225
- "defineStackConfig({": (id) => `defineStackConfig({ cwd: '${dirname2(id)}',`
6546
+ __dirname: (id) => `'${dirname3(id)}'`
6547
+ // 'defineStackConfig({': id => `defineStackConfig({ cwd: '${dirname(id)}',`,
6226
6548
  }),
6227
- swc2({
6549
+ swc3({
6228
6550
  minify: false,
6229
6551
  jsc: {
6230
- baseUrl: dirname2(path)
6552
+ baseUrl: dirname3(path)
6231
6553
  }
6232
6554
  })
6233
6555
  ]
@@ -6256,14 +6578,15 @@ var watchFile = (path) => {
6256
6578
  debugError(error.message);
6257
6579
  },
6258
6580
  plugins: [
6581
+ // @ts-ignore
6259
6582
  replace({
6260
- __dirname: (id) => `'${dirname2(id)}'`,
6261
- "defineStackConfig({": (id) => `defineStackConfig({ cwd: '${dirname2(id)}',`
6583
+ __dirname: (id) => `'${dirname3(id)}'`
6584
+ // 'defineStackConfig({': id => `defineStackConfig({ cwd: '${dirname(id)}',`,
6262
6585
  }),
6263
- swc2({
6586
+ swc3({
6264
6587
  minify: false,
6265
6588
  jsc: {
6266
- baseUrl: dirname2(path)
6589
+ baseUrl: dirname3(path)
6267
6590
  }
6268
6591
  })
6269
6592
  ]
@@ -6979,7 +7302,7 @@ var flexLine = (term, left, right, reserveSpace = 0) => {
6979
7302
  };
6980
7303
 
6981
7304
  // src/cli/ui/complex/builder.ts
6982
- import { dirname as dirname3, join as join7 } from "path";
7305
+ import { dirname as dirname4, join as join7 } from "path";
6983
7306
  var assetBuilder = (app) => {
6984
7307
  return async (term) => {
6985
7308
  const assets = [];
@@ -7043,7 +7366,7 @@ var assetBuilder = (app) => {
7043
7366
  const data = await asset.build({
7044
7367
  async write(file, data2) {
7045
7368
  const fullpath = join7(directories.asset, asset.type, app.name, stack.name, asset.id, file);
7046
- const basepath = dirname3(fullpath);
7369
+ const basepath = dirname4(fullpath);
7047
7370
  await mkdir3(basepath, { recursive: true });
7048
7371
  await writeFile3(fullpath, data2);
7049
7372
  }
@@ -7632,55 +7955,70 @@ var assetPublisher = (config, app) => {
7632
7955
  });
7633
7956
  return async (term) => {
7634
7957
  const done = term.out.write(loadingDialog("Publishing stack assets to AWS..."));
7635
- await Promise.all(app.stacks.map(async (stack) => {
7636
- await Promise.all([...stack.assets].map(async (asset) => {
7637
- await asset.publish?.({
7638
- async read(file) {
7639
- const path = join9(directories.asset, asset.type, app.name, stack.name, asset.id, file);
7640
- const data = await readFile3(path);
7641
- return data;
7642
- },
7643
- async publish(name, data, hash) {
7644
- const key = `${app.name}/${stack.name}/${asset.type}/${name}`;
7645
- const bucket = assetBucketName(config.account, config.region);
7646
- let getResult;
7647
- try {
7648
- getResult = await client.send(new GetObjectCommand({
7649
- Bucket: bucket,
7650
- Key: key
7651
- }));
7652
- } catch (error) {
7653
- if (error instanceof Error && error.name === "NoSuchKey") {
7654
- } else {
7655
- 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
+ };
7656
8016
  }
7657
- }
7658
- if (getResult?.Metadata?.hash === hash) {
7659
- return {
7660
- bucket,
7661
- key,
7662
- version: getResult.VersionId
7663
- };
7664
- }
7665
- const putResult = await client.send(new PutObjectCommand2({
7666
- Bucket: bucket,
7667
- Key: key,
7668
- Body: data,
7669
- ACL: ObjectCannedACL2.private,
7670
- StorageClass: StorageClass2.STANDARD,
7671
- Metadata: {
7672
- hash
7673
- }
7674
- }));
7675
- return {
7676
- bucket,
7677
- key,
7678
- version: putResult.VersionId
7679
- };
7680
- }
7681
- });
7682
- }));
7683
- }));
8017
+ });
8018
+ })
8019
+ );
8020
+ })
8021
+ );
7684
8022
  done("Done publishing stack assets to AWS");
7685
8023
  };
7686
8024
  };