@awsless/awsless 0.0.366 → 0.0.368

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -596,9 +596,9 @@ var require_Alias = __commonJS({
596
596
  var anchors = require_anchors();
597
597
  var visit = require_visit();
598
598
  var identity = require_identity();
599
- var Node22 = require_Node();
599
+ var Node25 = require_Node();
600
600
  var toJS = require_toJS();
601
- var Alias = class extends Node22.NodeBase {
601
+ var Alias = class extends Node25.NodeBase {
602
602
  constructor(source) {
603
603
  super(identity.ALIAS);
604
604
  this.source = source;
@@ -696,10 +696,10 @@ var require_Scalar = __commonJS({
696
696
  "../../node_modules/.pnpm/yaml@2.5.0/node_modules/yaml/dist/nodes/Scalar.js"(exports) {
697
697
  "use strict";
698
698
  var identity = require_identity();
699
- var Node22 = require_Node();
699
+ var Node25 = require_Node();
700
700
  var toJS = require_toJS();
701
701
  var isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
702
- var Scalar = class extends Node22.NodeBase {
702
+ var Scalar = class extends Node25.NodeBase {
703
703
  constructor(value) {
704
704
  super(identity.SCALAR);
705
705
  this.value = value;
@@ -803,7 +803,7 @@ var require_Collection = __commonJS({
803
803
  "use strict";
804
804
  var createNode = require_createNode();
805
805
  var identity = require_identity();
806
- var Node22 = require_Node();
806
+ var Node25 = require_Node();
807
807
  function collectionFromPath(schema, path, value) {
808
808
  let v = value;
809
809
  for (let i = path.length - 1; i >= 0; --i) {
@@ -827,7 +827,7 @@ var require_Collection = __commonJS({
827
827
  });
828
828
  }
829
829
  var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
830
- var Collection = class extends Node22.NodeBase {
830
+ var Collection = class extends Node25.NodeBase {
831
831
  constructor(type, schema) {
832
832
  super(type);
833
833
  Object.defineProperty(this, "schema", {
@@ -7560,7 +7560,7 @@ var debug = (...parts) => {
7560
7560
  };
7561
7561
 
7562
7562
  // src/config/app.ts
7563
- import { z as z20 } from "zod";
7563
+ import { z as z21 } from "zod";
7564
7564
 
7565
7565
  // src/feature/auth/schema.ts
7566
7566
  import { z as z7 } from "zod";
@@ -7678,12 +7678,24 @@ var LogRetentionSchema = DurationSchema.refine(
7678
7678
  (duration) => {
7679
7679
  return validLogRetentionDays.includes(toDays(duration));
7680
7680
  },
7681
- `Invalid log retention. Valid days are: ${validLogRetentionDays.map((days6) => `${days6}`).join(", ")}`
7681
+ `Invalid log retention. Valid days are: ${validLogRetentionDays.map((days7) => `${days7}`).join(", ")}`
7682
7682
  ).describe("The log retention duration.");
7683
+ var LogSubscriptionSchema = z5.union([
7684
+ LocalFileSchema.transform((file) => ({
7685
+ file
7686
+ })),
7687
+ z5.object({
7688
+ subscriber: LocalFileSchema,
7689
+ filter: z5.string().optional()
7690
+ })
7691
+ ]).describe(
7692
+ "Log Subscription allow you to subscribe to a real-time stream of log events and have them delivered to a specific destination"
7693
+ );
7683
7694
  var LogSchema = z5.union([
7684
7695
  z5.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
7685
7696
  LogRetentionSchema.transform((retention) => ({ retention })),
7686
7697
  z5.object({
7698
+ subscription: LogSubscriptionSchema.optional(),
7687
7699
  retention: LogRetentionSchema.optional(),
7688
7700
  format: z5.enum(["text", "json"]).describe(
7689
7701
  `The format in which Lambda sends your function's application and system logs to CloudWatch. Select between plain text and structured JSON.`
@@ -7703,32 +7715,33 @@ var BuildSchema = z5.object({
7703
7715
  minify: MinifySchema.default(true),
7704
7716
  external: z5.string().array().optional().describe(`A list of external packages that won't be included in the bundle.`)
7705
7717
  }).describe(`Options for the function bundler`);
7718
+ var FnSchema = z5.object({
7719
+ file: FileSchema,
7720
+ // node
7721
+ handler: HandlerSchema.optional(),
7722
+ build: BuildSchema.optional(),
7723
+ // container
7724
+ // ...
7725
+ runtime: RuntimeSchema.optional(),
7726
+ description: DescriptionSchema.optional(),
7727
+ warm: WarmSchema.optional(),
7728
+ vpc: VPCSchema.optional(),
7729
+ log: LogSchema.optional(),
7730
+ timeout: TimeoutSchema.optional(),
7731
+ memorySize: MemorySizeSchema.optional(),
7732
+ architecture: ArchitectureSchema.optional(),
7733
+ ephemeralStorageSize: EphemeralStorageSizeSchema.optional(),
7734
+ retryAttempts: RetryAttemptsSchema.optional(),
7735
+ reserved: ReservedConcurrentExecutionsSchema.optional(),
7736
+ layers: LayersSchema.optional(),
7737
+ environment: EnvironmentSchema.optional(),
7738
+ permissions: PermissionsSchema.optional()
7739
+ });
7706
7740
  var FunctionSchema = z5.union([
7707
7741
  LocalFileSchema.transform((file) => ({
7708
7742
  file
7709
7743
  })),
7710
- z5.object({
7711
- file: FileSchema,
7712
- // node
7713
- handler: HandlerSchema.optional(),
7714
- build: BuildSchema.optional(),
7715
- // container
7716
- // ...
7717
- runtime: RuntimeSchema.optional(),
7718
- description: DescriptionSchema.optional(),
7719
- warm: WarmSchema.optional(),
7720
- vpc: VPCSchema.optional(),
7721
- log: LogSchema.optional(),
7722
- timeout: TimeoutSchema.optional(),
7723
- memorySize: MemorySizeSchema.optional(),
7724
- architecture: ArchitectureSchema.optional(),
7725
- ephemeralStorageSize: EphemeralStorageSizeSchema.optional(),
7726
- retryAttempts: RetryAttemptsSchema.optional(),
7727
- reserved: ReservedConcurrentExecutionsSchema.optional(),
7728
- layers: LayersSchema.optional(),
7729
- environment: EnvironmentSchema.optional(),
7730
- permissions: PermissionsSchema.optional()
7731
- })
7744
+ FnSchema
7732
7745
  ]);
7733
7746
  var FunctionsSchema = z5.record(ResourceIdSchema, FunctionSchema).optional().describe("Define the functions in your stack.");
7734
7747
  var FunctionDefaultSchema = z5.object({
@@ -7980,6 +7993,11 @@ var InstancesSchema = z12.record(
7980
7993
  })
7981
7994
  ).optional().describe("Define the instances in your stack.");
7982
7995
 
7996
+ // src/feature/log-subscription/schema.ts
7997
+ var LogSubscriptionSchema2 = FunctionSchema.optional().describe(
7998
+ "Log Subscription allow you to subscribe to a real-time stream of log events and have them delivered to a specific destination."
7999
+ );
8000
+
7983
8001
  // src/feature/pubsub/schema.ts
7984
8002
  import { z as z13 } from "zod";
7985
8003
  var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
@@ -8011,9 +8029,9 @@ var PubSubSchema = z13.record(
8011
8029
  ).optional().describe("Define the pubsub subscriber in your stack.");
8012
8030
 
8013
8031
  // src/feature/queue/schema.ts
8014
- import { z as z14 } from "zod";
8015
8032
  import { days as days2, hours, minutes as minutes3, seconds as seconds2 } from "@awsless/duration";
8016
8033
  import { kibibytes } from "@awsless/size";
8034
+ import { z as z14 } from "zod";
8017
8035
  var RetentionPeriodSchema = DurationSchema.refine(
8018
8036
  durationMin(minutes3(1)),
8019
8037
  "Minimum retention period is 1 minute"
@@ -8072,7 +8090,7 @@ var QueuesSchema = z14.record(
8072
8090
  }
8073
8091
  })),
8074
8092
  z14.object({
8075
- consumer: FunctionSchema.describe("he consuming lambda function properties."),
8093
+ consumer: FunctionSchema.describe("The consuming lambda function properties."),
8076
8094
  retentionPeriod: RetentionPeriodSchema.optional(),
8077
8095
  visibilityTimeout: VisibilityTimeoutSchema.optional(),
8078
8096
  deliveryDelay: DeliveryDelaySchema.optional(),
@@ -8105,27 +8123,39 @@ var RestDefaultSchema = z16.record(
8105
8123
  ).optional().describe("Define your global REST API's.");
8106
8124
  var RestSchema = z16.record(ResourceIdSchema, z16.record(RouteSchema2, FunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
8107
8125
 
8108
- // src/feature/store/schema.ts
8126
+ // src/feature/rpc/schema.ts
8109
8127
  import { z as z17 } from "zod";
8110
- var DeletionProtectionSchema = z17.boolean().describe("Specifies if you want to protect the store from being deleted by awsless.");
8111
- var StoreDefaultSchema = z17.object({
8128
+ var RpcDefaultSchema = z17.record(
8129
+ ResourceIdSchema,
8130
+ z17.object({
8131
+ domain: ResourceIdSchema.describe("The domain id to link your RPC API with.").optional(),
8132
+ subDomain: z17.string().optional(),
8133
+ auth: FunctionSchema.optional()
8134
+ })
8135
+ ).describe(`Define the global RPC API's.`).optional();
8136
+ var RpcSchema = z17.record(ResourceIdSchema, z17.record(z17.string(), FunctionSchema).describe("The queries for your global RPC API.")).describe("Define the schema in your stack for your global RPC API.").optional();
8137
+
8138
+ // src/feature/store/schema.ts
8139
+ import { z as z18 } from "zod";
8140
+ var DeletionProtectionSchema = z18.boolean().describe("Specifies if you want to protect the store from being deleted by awsless.");
8141
+ var StoreDefaultSchema = z18.object({
8112
8142
  deletionProtection: DeletionProtectionSchema.optional()
8113
8143
  }).optional();
8114
- var StoresSchema = z17.union([
8115
- z17.array(ResourceIdSchema).transform((list4) => {
8144
+ var StoresSchema = z18.union([
8145
+ z18.array(ResourceIdSchema).transform((list4) => {
8116
8146
  const stores = {};
8117
8147
  for (const key of list4) {
8118
8148
  stores[key] = {};
8119
8149
  }
8120
8150
  return stores;
8121
8151
  }),
8122
- z17.record(
8152
+ z18.record(
8123
8153
  ResourceIdSchema,
8124
- z17.object({
8154
+ z18.object({
8125
8155
  // cors: CorsSchema,
8126
8156
  deletionProtection: DeletionProtectionSchema.optional(),
8127
- versioning: z17.boolean().default(false).describe("Enable versioning of your store."),
8128
- events: z17.object({
8157
+ versioning: z18.boolean().default(false).describe("Enable versioning of your store."),
8158
+ events: z18.object({
8129
8159
  // create
8130
8160
  "created:*": FunctionSchema.optional().describe(
8131
8161
  "Subscribe to notifications regardless of the API that was used to create an object."
@@ -8158,41 +8188,41 @@ var StoresSchema = z17.union([
8158
8188
  ]).optional().describe("Define the stores in your stack.");
8159
8189
 
8160
8190
  // src/feature/table/schema.ts
8161
- import { z as z18 } from "zod";
8162
- var KeySchema = z18.string().min(1).max(255);
8163
- var DeletionProtectionSchema2 = z18.boolean().describe("Specifies if you want to protect the table from being deleted by awsless.");
8164
- var TableDefaultSchema = z18.object({
8191
+ import { z as z19 } from "zod";
8192
+ var KeySchema = z19.string().min(1).max(255);
8193
+ var DeletionProtectionSchema2 = z19.boolean().describe("Specifies if you want to protect the table from being deleted by awsless.");
8194
+ var TableDefaultSchema = z19.object({
8165
8195
  deletionProtection: DeletionProtectionSchema2.optional()
8166
8196
  }).optional();
8167
- var TablesSchema = z18.record(
8197
+ var TablesSchema = z19.record(
8168
8198
  ResourceIdSchema,
8169
- z18.object({
8199
+ z19.object({
8170
8200
  hash: KeySchema.describe(
8171
8201
  "Specifies the name of the partition / hash key that makes up the primary key for the table."
8172
8202
  ),
8173
8203
  sort: KeySchema.optional().describe(
8174
8204
  "Specifies the name of the range / sort key that makes up the primary key for the table."
8175
8205
  ),
8176
- fields: z18.record(z18.string(), z18.enum(["string", "number", "binary"])).optional().describe(
8206
+ fields: z19.record(z19.string(), z19.enum(["string", "number", "binary"])).optional().describe(
8177
8207
  'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
8178
8208
  ),
8179
- class: z18.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
8180
- pointInTimeRecovery: z18.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
8209
+ class: z19.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
8210
+ pointInTimeRecovery: z19.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
8181
8211
  timeToLiveAttribute: KeySchema.optional().describe(
8182
8212
  "The name of the TTL attribute used to store the expiration time for items in the table. To update this property, you must first disable TTL and then enable TTL with the new attribute name."
8183
8213
  ),
8184
8214
  deletionProtection: DeletionProtectionSchema2.optional(),
8185
- stream: z18.object({
8186
- type: z18.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
8215
+ stream: z19.object({
8216
+ type: z19.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
8187
8217
  "When an item in the table is modified, stream.type determines what information is written to the stream for this table. Valid values are:\n- keys-only - Only the key attributes of the modified item are written to the stream.\n- new-image - The entire item, as it appears after it was modified, is written to the stream.\n- old-image - The entire item, as it appeared before it was modified, is written to the stream.\n- new-and-old-images - Both the new and the old item images of the item are written to the stream."
8188
8218
  ),
8189
8219
  consumer: FunctionSchema.describe("The consuming lambda function for the stream")
8190
8220
  }).optional().describe(
8191
8221
  "The settings for the DynamoDB table stream, which capture changes to items stored in the table."
8192
8222
  ),
8193
- indexes: z18.record(
8194
- z18.string(),
8195
- z18.object({
8223
+ indexes: z19.record(
8224
+ z19.string(),
8225
+ z19.object({
8196
8226
  /** Specifies the name of the partition / hash key that makes up the primary key for the global secondary index. */
8197
8227
  hash: KeySchema,
8198
8228
  /** Specifies the name of the range / sort key that makes up the primary key for the global secondary index. */
@@ -8202,14 +8232,14 @@ var TablesSchema = z18.record(
8202
8232
  * - keys-only - Only the index and primary keys are projected into the index.
8203
8233
  * @default 'all'
8204
8234
  */
8205
- projection: z18.enum(["all", "keys-only"]).default("all")
8235
+ projection: z19.enum(["all", "keys-only"]).default("all")
8206
8236
  })
8207
8237
  ).optional().describe("Specifies the global secondary indexes to be created on the table.")
8208
8238
  })
8209
8239
  ).optional().describe("Define the tables in your stack.");
8210
8240
 
8211
8241
  // src/config/schema/region.ts
8212
- import { z as z19 } from "zod";
8242
+ import { z as z20 } from "zod";
8213
8243
  var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
8214
8244
  var AF = ["af-south-1"];
8215
8245
  var AP = [
@@ -8238,20 +8268,22 @@ var EU = [
8238
8268
  var ME = ["me-south-1", "me-central-1"];
8239
8269
  var SA = ["sa-east-1"];
8240
8270
  var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
8241
- var RegionSchema = z19.enum(regions);
8271
+ var RegionSchema = z20.enum(regions);
8242
8272
 
8243
8273
  // src/config/app.ts
8244
- var AppSchema = z20.object({
8245
- $schema: z20.string().optional(),
8274
+ var AppSchema = z21.object({
8275
+ $schema: z21.string().optional(),
8246
8276
  name: ResourceIdSchema.describe("App name."),
8247
8277
  region: RegionSchema.describe("The AWS region to deploy to."),
8248
- profile: z20.string().describe("The AWS profile to deploy to."),
8278
+ profile: z21.string().describe("The AWS profile to deploy to."),
8249
8279
  // stage: z
8250
8280
  // .string()
8251
8281
  // .regex(/^[a-z]+$/)
8252
8282
  // .default('prod')
8253
8283
  // .describe('The deployment stage.'),
8254
- defaults: z20.object({
8284
+ // onFailure: OnFailureSchema,
8285
+ logSubscription: LogSubscriptionSchema2,
8286
+ defaults: z21.object({
8255
8287
  auth: AuthDefaultSchema,
8256
8288
  domains: DomainsDefaultSchema,
8257
8289
  function: FunctionDefaultSchema,
@@ -8260,6 +8292,7 @@ var AppSchema = z20.object({
8260
8292
  graphql: GraphQLDefaultSchema,
8261
8293
  http: HttpDefaultSchema,
8262
8294
  rest: RestDefaultSchema,
8295
+ rpc: RpcDefaultSchema,
8263
8296
  pubsub: PubSubDefaultSchema,
8264
8297
  table: TableDefaultSchema,
8265
8298
  store: StoreDefaultSchema
@@ -8268,11 +8301,11 @@ var AppSchema = z20.object({
8268
8301
  });
8269
8302
 
8270
8303
  // src/config/stack.ts
8271
- import { z as z32 } from "zod";
8304
+ import { z as z33 } from "zod";
8272
8305
 
8273
8306
  // src/feature/cache/schema.ts
8274
- import { z as z21 } from "zod";
8275
- var TypeSchema2 = z21.enum([
8307
+ import { z as z22 } from "zod";
8308
+ var TypeSchema2 = z22.enum([
8276
8309
  "t4g.small",
8277
8310
  "t4g.medium",
8278
8311
  "r6g.large",
@@ -8287,29 +8320,29 @@ var TypeSchema2 = z21.enum([
8287
8320
  "r6gd.4xlarge",
8288
8321
  "r6gd.8xlarge"
8289
8322
  ]);
8290
- var PortSchema = z21.number().int().min(1).max(5e4);
8291
- var ShardsSchema = z21.number().int().min(0).max(100);
8292
- var ReplicasPerShardSchema = z21.number().int().min(0).max(5);
8293
- var EngineSchema = z21.enum(["7.0", "6.2"]);
8294
- var CachesSchema = z21.record(
8323
+ var PortSchema = z22.number().int().min(1).max(5e4);
8324
+ var ShardsSchema = z22.number().int().min(0).max(100);
8325
+ var ReplicasPerShardSchema = z22.number().int().min(0).max(5);
8326
+ var EngineSchema = z22.enum(["7.0", "6.2"]);
8327
+ var CachesSchema = z22.record(
8295
8328
  ResourceIdSchema,
8296
- z21.object({
8329
+ z22.object({
8297
8330
  type: TypeSchema2.default("t4g.small"),
8298
8331
  port: PortSchema.default(6379),
8299
8332
  shards: ShardsSchema.default(1),
8300
8333
  replicasPerShard: ReplicasPerShardSchema.default(1),
8301
8334
  engine: EngineSchema.default("7.0"),
8302
- dataTiering: z21.boolean().default(false)
8335
+ dataTiering: z22.boolean().default(false)
8303
8336
  })
8304
8337
  ).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
8305
8338
 
8306
8339
  // src/feature/command/schema.ts
8307
- import { z as z22 } from "zod";
8308
- var CommandSchema2 = z22.union([
8309
- z22.object({
8340
+ import { z as z23 } from "zod";
8341
+ var CommandSchema2 = z23.union([
8342
+ z23.object({
8310
8343
  file: LocalFileSchema,
8311
- handler: z22.string().default("default").describe("The name of the handler that needs to run"),
8312
- description: z22.string().optional().describe("A description of the command")
8344
+ handler: z23.string().default("default").describe("The name of the handler that needs to run"),
8345
+ description: z23.string().optional().describe("A description of the command")
8313
8346
  // options: z.record(ResourceIdSchema, OptionSchema).optional(),
8314
8347
  // arguments: z.record(ResourceIdSchema, ArgumentSchema).optional(),
8315
8348
  }),
@@ -8319,22 +8352,22 @@ var CommandSchema2 = z22.union([
8319
8352
  description: void 0
8320
8353
  }))
8321
8354
  ]);
8322
- var CommandsSchema = z22.record(ResourceIdSchema, CommandSchema2).optional().describe("Define the custom commands for your stack.");
8355
+ var CommandsSchema = z23.record(ResourceIdSchema, CommandSchema2).optional().describe("Define the custom commands for your stack.");
8323
8356
 
8324
8357
  // src/feature/config/schema.ts
8325
- import { z as z23 } from "zod";
8326
- var ConfigNameSchema = z23.string().regex(/[a-z0-9\-]/g, "Invalid config name");
8327
- var ConfigsSchema = z23.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
8358
+ import { z as z24 } from "zod";
8359
+ var ConfigNameSchema = z24.string().regex(/[a-z0-9\-]/g, "Invalid config name");
8360
+ var ConfigsSchema = z24.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
8328
8361
 
8329
8362
  // src/feature/cron/schema/index.ts
8330
- import { z as z25 } from "zod";
8363
+ import { z as z26 } from "zod";
8331
8364
 
8332
8365
  // src/feature/cron/schema/schedule.ts
8333
- import { z as z24 } from "zod";
8366
+ import { z as z25 } from "zod";
8334
8367
  import { awsCronExpressionValidator } from "aws-cron-expression-validator";
8335
- var RateExpressionSchema = z24.custom(
8368
+ var RateExpressionSchema = z25.custom(
8336
8369
  (value) => {
8337
- return z24.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
8370
+ return z25.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
8338
8371
  const [str] = rate.split(" ");
8339
8372
  const number = parseInt(str);
8340
8373
  return number > 0;
@@ -8350,9 +8383,9 @@ var RateExpressionSchema = z24.custom(
8350
8383
  }
8351
8384
  return `rate(${rate})`;
8352
8385
  });
8353
- var CronExpressionSchema = z24.custom(
8386
+ var CronExpressionSchema = z25.custom(
8354
8387
  (value) => {
8355
- return z24.string().safeParse(value).success;
8388
+ return z25.string().safeParse(value).success;
8356
8389
  },
8357
8390
  { message: "Invalid cron expression" }
8358
8391
  ).superRefine((value, ctx) => {
@@ -8361,12 +8394,12 @@ var CronExpressionSchema = z24.custom(
8361
8394
  } catch (error) {
8362
8395
  if (error instanceof Error) {
8363
8396
  ctx.addIssue({
8364
- code: z24.ZodIssueCode.custom,
8397
+ code: z25.ZodIssueCode.custom,
8365
8398
  message: `Invalid cron expression: ${error.message}`
8366
8399
  });
8367
8400
  } else {
8368
8401
  ctx.addIssue({
8369
- code: z24.ZodIssueCode.custom,
8402
+ code: z25.ZodIssueCode.custom,
8370
8403
  message: "Invalid cron expression"
8371
8404
  });
8372
8405
  }
@@ -8377,15 +8410,15 @@ var CronExpressionSchema = z24.custom(
8377
8410
  var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
8378
8411
 
8379
8412
  // src/feature/cron/schema/index.ts
8380
- var CronsSchema = z25.record(
8413
+ var CronsSchema = z26.record(
8381
8414
  ResourceIdSchema,
8382
- z25.object({
8383
- enabled: z25.boolean().default(true).describe("If the cron is enabled."),
8415
+ z26.object({
8416
+ enabled: z26.boolean().default(true).describe("If the cron is enabled."),
8384
8417
  consumer: FunctionSchema.describe("The consuming lambda function properties."),
8385
8418
  schedule: ScheduleExpressionSchema.describe(
8386
8419
  'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
8387
8420
  ),
8388
- payload: z25.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
8421
+ payload: z26.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
8389
8422
  })
8390
8423
  ).optional().describe(`Define the cron jobs in your stack.`);
8391
8424
 
@@ -8396,9 +8429,9 @@ var OnFailureSchema = FunctionSchema.optional().describe(
8396
8429
 
8397
8430
  // src/feature/search/schema.ts
8398
8431
  import { gibibytes as gibibytes2 } from "@awsless/size";
8399
- import { z as z26 } from "zod";
8400
- var VersionSchema = z26.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]);
8401
- var TypeSchema3 = z26.enum([
8432
+ import { z as z27 } from "zod";
8433
+ var VersionSchema = z27.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]);
8434
+ var TypeSchema3 = z27.enum([
8402
8435
  "t3.small",
8403
8436
  "t3.medium",
8404
8437
  "m3.medium",
@@ -8473,41 +8506,41 @@ var TypeSchema3 = z26.enum([
8473
8506
  "r6gd.16xlarge"
8474
8507
  ]);
8475
8508
  var StorageSizeSchema = SizeSchema.refine(sizeMin(gibibytes2(10)), "Minimum storage size is 10 GB").refine(sizeMax(gibibytes2(100)), "Maximum storage size is 100 GB").describe("The size of the function's /tmp directory. You can specify a size value from 512 MB to 10 GiB.");
8476
- var SearchsSchema = z26.record(
8509
+ var SearchsSchema = z27.record(
8477
8510
  ResourceIdSchema,
8478
- z26.object({
8511
+ z27.object({
8479
8512
  type: TypeSchema3.default("t3.small"),
8480
- count: z26.number().int().min(1).default(1),
8513
+ count: z27.number().int().min(1).default(1),
8481
8514
  version: VersionSchema.default("2.13"),
8482
8515
  storage: StorageSizeSchema.default("10 GB"),
8483
- vpc: z26.boolean().default(false)
8516
+ vpc: z27.boolean().default(false)
8484
8517
  })
8485
8518
  ).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
8486
8519
 
8487
8520
  // src/feature/site/schema.ts
8488
- import { z as z27 } from "zod";
8489
- var ErrorResponsePathSchema = z27.string().describe(
8521
+ import { z as z28 } from "zod";
8522
+ var ErrorResponsePathSchema = z28.string().describe(
8490
8523
  "The path to the custom error page that you want to return to the viewer when your origin returns the HTTP status code specified.\n - We recommend that you store custom error pages in an Amazon S3 bucket. If you store custom error pages on an HTTP server and the server starts to return 5xx errors, CloudFront can't get the files that you want to return to viewers because the origin server is unavailable."
8491
8524
  );
8492
- var StatusCodeSchema = z27.number().int().positive().optional().describe(
8525
+ var StatusCodeSchema = z28.number().int().positive().optional().describe(
8493
8526
  "The HTTP status code that you want CloudFront to return to the viewer along with the custom error page. 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:\n- 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. If you substitute 200, the response typically won't be intercepted.\n- 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.\n- You might want to return a 200 status code (OK) and static website so your customers don't know that your website is down."
8494
8527
  );
8495
8528
  var MinTTLSchema = DurationSchema.describe(
8496
8529
  "The minimum amount of time, that you want to cache the error response. When this time period has elapsed, CloudFront queries your origin to see whether the problem that caused the error has been resolved and the requested object is now available."
8497
8530
  );
8498
- var ErrorResponseSchema = z27.union([
8531
+ var ErrorResponseSchema = z28.union([
8499
8532
  ErrorResponsePathSchema,
8500
- z27.object({
8533
+ z28.object({
8501
8534
  path: ErrorResponsePathSchema,
8502
8535
  statusCode: StatusCodeSchema.optional(),
8503
8536
  minTTL: MinTTLSchema.optional()
8504
8537
  })
8505
8538
  ]).optional();
8506
- var SitesSchema = z27.record(
8539
+ var SitesSchema = z28.record(
8507
8540
  ResourceIdSchema,
8508
- z27.object({
8541
+ z28.object({
8509
8542
  domain: ResourceIdSchema.describe("The domain id to link your site with.").optional(),
8510
- subDomain: z27.string().optional(),
8543
+ subDomain: z28.string().optional(),
8511
8544
  // bind: z
8512
8545
  // .object({
8513
8546
  // auth: z.array(ResourceIdSchema),
@@ -8530,7 +8563,7 @@ var SitesSchema = z27.record(
8530
8563
  // build: z.string().optional(),
8531
8564
  // }),
8532
8565
  // ]),
8533
- errors: z27.object({
8566
+ errors: z28.object({
8534
8567
  400: ErrorResponseSchema.describe("Customize a `400 Bad Request` response."),
8535
8568
  403: ErrorResponseSchema.describe("Customize a `403 Forbidden` response."),
8536
8569
  404: ErrorResponseSchema.describe("Customize a `404 Not Found` response."),
@@ -8543,16 +8576,16 @@ var SitesSchema = z27.record(
8543
8576
  503: ErrorResponseSchema.describe("Customize a `503 Service Unavailable` response."),
8544
8577
  504: ErrorResponseSchema.describe("Customize a `504 Gateway Timeout` response.")
8545
8578
  }).optional().describe("Customize the error responses for specific HTTP status codes."),
8546
- cors: z27.object({
8547
- override: z27.boolean().default(false),
8579
+ cors: z28.object({
8580
+ override: z28.boolean().default(false),
8548
8581
  maxAge: DurationSchema.default("365 days"),
8549
- exposeHeaders: z27.string().array().optional(),
8550
- credentials: z27.boolean().default(false),
8551
- headers: z27.string().array().default(["*"]),
8552
- origins: z27.string().array().default(["*"]),
8553
- methods: z27.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
8582
+ exposeHeaders: z28.string().array().optional(),
8583
+ credentials: z28.boolean().default(false),
8584
+ headers: z28.string().array().default(["*"]),
8585
+ origins: z28.string().array().default(["*"]),
8586
+ methods: z28.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
8554
8587
  }).optional().describe("Define the cors headers."),
8555
- security: z27.object({
8588
+ security: z28.object({
8556
8589
  // contentSecurityPolicy: z.object({
8557
8590
  // override: z.boolean().default(false),
8558
8591
  // policy: z.string(),
@@ -8594,10 +8627,10 @@ var SitesSchema = z27.record(
8594
8627
  // reportUri?: string
8595
8628
  // }
8596
8629
  }).optional().describe("Define the security policy."),
8597
- cache: z27.object({
8598
- cookies: z27.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
8599
- headers: z27.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
8600
- queries: z27.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
8630
+ cache: z28.object({
8631
+ cookies: z28.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
8632
+ headers: z28.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
8633
+ queries: z28.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
8601
8634
  }).optional().describe(
8602
8635
  "Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
8603
8636
  )
@@ -8605,22 +8638,22 @@ var SitesSchema = z27.record(
8605
8638
  ).optional().describe("Define the sites in your stack.");
8606
8639
 
8607
8640
  // src/feature/stream/schema.ts
8608
- import { z as z28 } from "zod";
8609
- var LatencyModeSchema = z28.enum(["low", "normal"]).describe(
8641
+ import { z as z29 } from "zod";
8642
+ var LatencyModeSchema = z29.enum(["low", "normal"]).describe(
8610
8643
  `Channel latency mode. Valid values:
8611
8644
  - normal: Use "normal" to broadcast and deliver live video up to Full HD.
8612
8645
  - low: Use "low" for near real-time interactions with viewers.`
8613
8646
  );
8614
- var TypeSchema4 = z28.enum(["standard", "basic", "advanced-sd", "advanced-hd"]).describe(`The channel type, which determines the allowable resolution and bitrate.
8647
+ var TypeSchema4 = z29.enum(["standard", "basic", "advanced-sd", "advanced-hd"]).describe(`The channel type, which determines the allowable resolution and bitrate.
8615
8648
  If you exceed the allowable resolution or bitrate, the stream probably will disconnect immediately. Valid values:
8616
8649
  - standard: Video is transcoded: multiple qualities are generated from the original input to automatically give viewers the best experience for their devices and network conditions. Transcoding allows higher playback quality across a range of download speeds. Resolution can be up to 1080p and bitrate can be up to 8.5 Mbps. Audio is transcoded only for renditions 360p and below; above that, audio is passed through.
8617
8650
  - basic: Video is transmuxed: Amazon IVS delivers the original input to viewers. The viewer's video-quality choice is limited to the original input. Resolution can be up to 1080p and bitrate can be up to 1.5 Mbps for 480p and up to 3.5 Mbps for resolutions between 480p and 1080p.
8618
8651
  - advanced-sd: Video is transcoded; multiple qualities are generated from the original input, to automatically give viewers the best experience for their devices and network conditions. Input resolution can be up to 1080p and bitrate can be up to 8.5 Mbps; output is capped at SD quality (480p). You can select an optional transcode preset (see below). Audio for all renditions is transcoded, and an audio-only rendition is available.
8619
8652
  - advanced-hd: Video is transcoded; multiple qualities are generated from the original input, to automatically give viewers the best experience for their devices and network conditions. Input resolution can be up to 1080p and bitrate can be up to 8.5 Mbps; output is capped at HD quality (720p). You can select an optional transcode preset (see below). Audio for all renditions is transcoded, and an audio-only rendition is available.
8620
8653
  `);
8621
- var StreamsSchema = z28.record(
8654
+ var StreamsSchema = z29.record(
8622
8655
  ResourceIdSchema,
8623
- z28.object({
8656
+ z29.object({
8624
8657
  type: TypeSchema4.default("standard"),
8625
8658
  // preset: PresetSchema.optional(),
8626
8659
  latencyMode: LatencyModeSchema.default("low")
@@ -8628,42 +8661,42 @@ var StreamsSchema = z28.record(
8628
8661
  ).optional().describe("Define the streams in your stack.");
8629
8662
 
8630
8663
  // src/feature/task/schema.ts
8631
- import { z as z29 } from "zod";
8632
- var RetryAttemptsSchema2 = z29.number().int().min(0).max(2).describe(
8664
+ import { z as z30 } from "zod";
8665
+ var RetryAttemptsSchema2 = z30.number().int().min(0).max(2).describe(
8633
8666
  "The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
8634
8667
  );
8635
- var TaskSchema = z29.union([
8668
+ var TaskSchema = z30.union([
8636
8669
  LocalFileSchema.transform((file) => ({
8637
8670
  consumer: { file },
8638
8671
  retryAttempts: void 0
8639
8672
  })),
8640
- z29.object({
8673
+ z30.object({
8641
8674
  consumer: FunctionSchema,
8642
8675
  retryAttempts: RetryAttemptsSchema2.optional()
8643
8676
  })
8644
8677
  ]);
8645
- var TasksSchema = z29.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
8678
+ var TasksSchema = z30.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
8646
8679
 
8647
8680
  // src/feature/test/schema.ts
8648
- import { z as z30 } from "zod";
8649
- var TestsSchema = z30.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
8681
+ import { z as z31 } from "zod";
8682
+ var TestsSchema = z31.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
8650
8683
 
8651
8684
  // src/feature/topic/schema.ts
8652
8685
  import { paramCase as paramCase2 } from "change-case";
8653
- import { z as z31 } from "zod";
8654
- var TopicNameSchema = z31.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => paramCase2(value)).describe("Define event topic name.");
8655
- var TopicsSchema = z31.array(TopicNameSchema).refine((topics) => {
8686
+ import { z as z32 } from "zod";
8687
+ var TopicNameSchema = z32.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => paramCase2(value)).describe("Define event topic name.");
8688
+ var TopicsSchema = z32.array(TopicNameSchema).refine((topics) => {
8656
8689
  return topics.length === new Set(topics).size;
8657
8690
  }, "Must be a list of unique topic names").optional().describe("Define the event topics to publish too in your stack.");
8658
- var SubscribersSchema = z31.record(TopicNameSchema, z31.union([EmailSchema, FunctionSchema])).optional().describe("Define the event topics to subscribe too in your stack.");
8691
+ var SubscribersSchema = z32.record(TopicNameSchema, z32.union([EmailSchema, FunctionSchema])).optional().describe("Define the event topics to subscribe too in your stack.");
8659
8692
 
8660
8693
  // src/config/stack.ts
8661
8694
  var DependsSchema = ResourceIdSchema.array().optional().describe("Define the stacks that this stack is depended on.");
8662
8695
  var NameSchema = ResourceIdSchema.refine((name) => !["base"].includes(name), {
8663
8696
  message: `Stack name can't be a reserved name.`
8664
8697
  }).describe("Stack name.");
8665
- var StackSchema = z32.object({
8666
- $schema: z32.string().optional(),
8698
+ var StackSchema = z33.object({
8699
+ $schema: z33.string().optional(),
8667
8700
  name: NameSchema,
8668
8701
  depends: DependsSchema,
8669
8702
  commands: CommandsSchema,
@@ -8672,6 +8705,7 @@ var StackSchema = z32.object({
8672
8705
  graphql: GraphQLSchema,
8673
8706
  http: HttpSchema,
8674
8707
  rest: RestSchema,
8708
+ rpc: RpcSchema,
8675
8709
  configs: ConfigsSchema,
8676
8710
  crons: CronsSchema,
8677
8711
  caches: CachesSchema,
@@ -8729,13 +8763,13 @@ var readConfigWithStage = async (file, stage) => {
8729
8763
  };
8730
8764
 
8731
8765
  // src/config/load/validate.ts
8732
- import { z as z33 } from "zod";
8766
+ import { z as z34 } from "zod";
8733
8767
  var validateConfig = async (schema, file, data) => {
8734
8768
  try {
8735
8769
  const result = await schema.parseAsync(data);
8736
8770
  return result;
8737
8771
  } catch (error) {
8738
- if (error instanceof z33.ZodError) {
8772
+ if (error instanceof z34.ZodError) {
8739
8773
  throw new ConfigError(file, error, data);
8740
8774
  }
8741
8775
  throw error;
@@ -10672,7 +10706,7 @@ import nodeResolve from "@rollup/plugin-node-resolve";
10672
10706
  import { createHash as createHash2 } from "crypto";
10673
10707
  import { dirname as dirname6 } from "path";
10674
10708
  import { rollup } from "rollup";
10675
- import { minify as swcMinify, swc } from "rollup-plugin-swc3";
10709
+ import { swc, minify as swcMinify } from "rollup-plugin-swc3";
10676
10710
  var bundleTypeScript = async ({ format: format2 = "esm", minify = true, file, external }) => {
10677
10711
  const bundle = await rollup({
10678
10712
  input: file,
@@ -10802,7 +10836,7 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
10802
10836
  let code;
10803
10837
  if (props.runtime === "container") {
10804
10838
  ctx.registerBuild("function", name, async (build3) => {
10805
- const cwd = dirname7(props.file);
10839
+ const cwd = dirname7(local2.file);
10806
10840
  const version = await hashElement(cwd, {
10807
10841
  files: {
10808
10842
  exclude: ["stack.json"]
@@ -10831,10 +10865,10 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
10831
10865
  };
10832
10866
  } else {
10833
10867
  ctx.registerBuild("function", name, async (build3, { workspace }) => {
10834
- const version = await generateFileHash(workspace, props.file);
10868
+ const version = await generateFileHash(workspace, local2.file);
10835
10869
  return build3(version, async (write) => {
10836
10870
  const bundle = await bundleTypeScript({
10837
- file: props.file,
10871
+ file: local2.file,
10838
10872
  external: props.build.external,
10839
10873
  minify: props.build.minify
10840
10874
  });
@@ -10914,6 +10948,14 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
10914
10948
  resources: [logGroup.arn.apply((arn) => `${arn}:*`)]
10915
10949
  }
10916
10950
  );
10951
+ const logSubscriptionArn = ctx.shared.get("log-subscription-destination-arn");
10952
+ if (logSubscriptionArn) {
10953
+ new aws2.cloudWatch.SubscriptionFilter(group, `log-subscription`, {
10954
+ destinationArn: logSubscriptionArn,
10955
+ logGroupName: logGroup.name,
10956
+ filterPattern: "{$.level = ERROR}"
10957
+ });
10958
+ }
10917
10959
  }
10918
10960
  if (ctx.appConfig.defaults.function.permissions) {
10919
10961
  policy.addStatement(...ctx.appConfig.defaults.function.permissions);
@@ -10972,6 +11014,7 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
10972
11014
  lambda.dependsOn(vpcPolicy);
10973
11015
  }
10974
11016
  return {
11017
+ name,
10975
11018
  lambda,
10976
11019
  policy,
10977
11020
  code
@@ -12286,8 +12329,75 @@ var instanceFeature = defineFeature({
12286
12329
  }
12287
12330
  });
12288
12331
 
12289
- // src/feature/on-failure/index.ts
12332
+ // src/feature/log-subscription/index.ts
12290
12333
  import { Node as Node10, aws as aws11 } from "@awsless/formation";
12334
+ var logSubscriptionFeature = defineFeature({
12335
+ name: "log-subscription",
12336
+ onApp(ctx) {
12337
+ if (!ctx.appConfig.logSubscription) {
12338
+ return;
12339
+ }
12340
+ const group = new Node10(ctx.base, "log-subscription", "main");
12341
+ const { lambda, policy } = createLambdaFunction(
12342
+ group,
12343
+ ctx,
12344
+ "log-subscription",
12345
+ "main",
12346
+ ctx.appConfig.logSubscription
12347
+ );
12348
+ new aws11.lambda.Permission(group, "log-subscription-permission", {
12349
+ action: "lambda:InvokeFunction",
12350
+ principal: "logs.amazonaws.com",
12351
+ functionArn: lambda.arn,
12352
+ sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/lambda/app-kennedy--*`
12353
+ });
12354
+ ctx.shared.set("log-subscription-destination-arn", lambda.arn);
12355
+ for (const stack of ctx.stackConfigs) {
12356
+ for (const id of stack.topics ?? []) {
12357
+ policy.addStatement({
12358
+ actions: ["sns:Publish"],
12359
+ resources: [ctx.shared.get(`topic-${id}-arn`)]
12360
+ });
12361
+ }
12362
+ for (const [id, props] of Object.entries(stack.tables ?? {})) {
12363
+ const tableName = formatLocalResourceName({
12364
+ appName: ctx.app.name,
12365
+ stackName: stack.name,
12366
+ resourceType: "table",
12367
+ resourceName: id
12368
+ });
12369
+ policy.addStatement({
12370
+ actions: [
12371
+ "dynamodb:DescribeTable",
12372
+ "dynamodb:PutItem",
12373
+ "dynamodb:GetItem",
12374
+ "dynamodb:UpdateItem",
12375
+ "dynamodb:DeleteItem",
12376
+ "dynamodb:TransactWrite",
12377
+ "dynamodb:BatchWriteItem",
12378
+ "dynamodb:BatchGetItem",
12379
+ "dynamodb:ConditionCheckItem",
12380
+ "dynamodb:Query",
12381
+ "dynamodb:Scan"
12382
+ ],
12383
+ resources: [`arn:aws:dynamodb:${ctx.appConfig.region}:${ctx.accountId}:table/${tableName}`]
12384
+ });
12385
+ const indexes = Object.keys(props.indexes ?? {});
12386
+ if (indexes.length) {
12387
+ policy.addStatement({
12388
+ actions: ["dynamodb:Query"],
12389
+ resources: indexes.map(
12390
+ (indexName) => `arn:aws:dynamodb:${ctx.appConfig.region}:${ctx.accountId}:table/${tableName}/index/${indexName}`
12391
+ )
12392
+ });
12393
+ }
12394
+ }
12395
+ }
12396
+ }
12397
+ });
12398
+
12399
+ // src/feature/on-failure/index.ts
12400
+ import { Node as Node11, aws as aws12 } from "@awsless/formation";
12291
12401
  var onFailureFeature = defineFeature({
12292
12402
  name: "on-failure",
12293
12403
  onApp(ctx) {
@@ -12298,7 +12408,7 @@ var onFailureFeature = defineFeature({
12298
12408
  if (count > 1) {
12299
12409
  throw new TypeError("Only 1 onFailure configuration is allowed in your app.");
12300
12410
  }
12301
- const queue2 = new aws11.sqs.Queue(ctx.base, "on-failure", {
12411
+ const queue2 = new aws12.sqs.Queue(ctx.base, "on-failure", {
12302
12412
  name: formatGlobalResourceName({
12303
12413
  appName: ctx.app.name,
12304
12414
  resourceType: "on-failure",
@@ -12313,9 +12423,9 @@ var onFailureFeature = defineFeature({
12313
12423
  return;
12314
12424
  }
12315
12425
  const queueArn = ctx.shared.get("on-failure-queue-arn");
12316
- const group = new Node10(ctx.stack, "on-failure", "failure");
12426
+ const group = new Node11(ctx.stack, "on-failure", "failure");
12317
12427
  const { lambda, policy } = createLambdaFunction(group, ctx, "on-failure", "failure", onFailure);
12318
- const source = new aws11.lambda.EventSourceMapping(group, "on-failure", {
12428
+ const source = new aws12.lambda.EventSourceMapping(group, "on-failure", {
12319
12429
  functionArn: lambda.arn,
12320
12430
  sourceArn: queueArn,
12321
12431
  batchSize: 10
@@ -12335,13 +12445,13 @@ var onFailureFeature = defineFeature({
12335
12445
  });
12336
12446
 
12337
12447
  // src/feature/pubsub/index.ts
12338
- import { aws as aws12, Node as Node11 } from "@awsless/formation";
12448
+ import { aws as aws13, Node as Node12 } from "@awsless/formation";
12339
12449
  import { constantCase as constantCase6 } from "change-case";
12340
12450
  var pubsubFeature = defineFeature({
12341
12451
  name: "pubsub",
12342
12452
  onApp(ctx) {
12343
12453
  for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
12344
- const group = new Node11(ctx.base, "pubsub", id);
12454
+ const group = new Node12(ctx.base, "pubsub", id);
12345
12455
  const functionProps = typeof props.auth === "string" ? { file: "" } : props.auth.authorizer;
12346
12456
  const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, functionProps);
12347
12457
  lambda.addEnvironment("PUBSUB_POLICY", JSON.stringify(props.policy));
@@ -12351,23 +12461,23 @@ var pubsubFeature = defineFeature({
12351
12461
  resourceType: "pubsub",
12352
12462
  resourceName: id
12353
12463
  });
12354
- const authorizer = new aws12.iot.Authorizer(group, "authorizer", {
12464
+ const authorizer = new aws13.iot.Authorizer(group, "authorizer", {
12355
12465
  name,
12356
12466
  functionArn: lambda.arn
12357
12467
  });
12358
- new aws12.lambda.Permission(group, "permission", {
12468
+ new aws13.lambda.Permission(group, "permission", {
12359
12469
  functionArn: lambda.arn,
12360
12470
  principal: "iot.amazonaws.com",
12361
12471
  sourceArn: authorizer.arn,
12362
12472
  action: "lambda:InvokeFunction"
12363
12473
  });
12364
12474
  ctx.bind(`PUBSUB_${constantCase6(id)}_AUTHORIZER`, name);
12365
- const endpoint = new aws12.iot.Endpoint(group, "endpoint", {
12475
+ const endpoint = new aws13.iot.Endpoint(group, "endpoint", {
12366
12476
  type: "data-ats"
12367
12477
  });
12368
12478
  if (props.domain) {
12369
12479
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
12370
- new aws12.iot.DomainConfiguration(group, "domain", {
12480
+ new aws13.iot.DomainConfiguration(group, "domain", {
12371
12481
  name,
12372
12482
  domainName,
12373
12483
  certificates: [ctx.shared.get(`local-certificate-${props.domain}-arn`)],
@@ -12376,7 +12486,7 @@ var pubsubFeature = defineFeature({
12376
12486
  }
12377
12487
  // validationCertificate: ctx.shared.get(`global-certificate-${props.domain}-arn`),
12378
12488
  });
12379
- new aws12.route53.RecordSet(group, "record", {
12489
+ new aws13.route53.RecordSet(group, "record", {
12380
12490
  hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
12381
12491
  name: domainName,
12382
12492
  type: "CNAME",
@@ -12397,7 +12507,7 @@ var pubsubFeature = defineFeature({
12397
12507
  },
12398
12508
  onStack(ctx) {
12399
12509
  for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
12400
- const group = new Node11(ctx.stack, "pubsub", id);
12510
+ const group = new Node12(ctx.stack, "pubsub", id);
12401
12511
  const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
12402
12512
  const name = formatLocalResourceName({
12403
12513
  appName: ctx.app.name,
@@ -12405,13 +12515,13 @@ var pubsubFeature = defineFeature({
12405
12515
  resourceType: "pubsub",
12406
12516
  resourceName: id
12407
12517
  });
12408
- const topic = new aws12.iot.TopicRule(group, "rule", {
12518
+ const topic = new aws13.iot.TopicRule(group, "rule", {
12409
12519
  name: name.replaceAll("-", "_"),
12410
12520
  sql: props.sql,
12411
12521
  sqlVersion: props.sqlVersion,
12412
12522
  actions: [{ lambda: { functionArn: lambda.arn } }]
12413
12523
  });
12414
- new aws12.lambda.Permission(group, "permission", {
12524
+ new aws13.lambda.Permission(group, "permission", {
12415
12525
  action: "lambda:InvokeFunction",
12416
12526
  principal: "iot.amazonaws.com",
12417
12527
  functionArn: lambda.arn,
@@ -12422,7 +12532,7 @@ var pubsubFeature = defineFeature({
12422
12532
  });
12423
12533
 
12424
12534
  // src/feature/queue/index.ts
12425
- import { aws as aws13, Node as Node12 } from "@awsless/formation";
12535
+ import { aws as aws14, Node as Node13 } from "@awsless/formation";
12426
12536
  import { camelCase as camelCase5, constantCase as constantCase7 } from "change-case";
12427
12537
  import deepmerge3 from "deepmerge";
12428
12538
  import { relative as relative4 } from "path";
@@ -12482,21 +12592,21 @@ var queueFeature = defineFeature({
12482
12592
  onStack(ctx) {
12483
12593
  for (const [id, local2] of Object.entries(ctx.stackConfig.queues || {})) {
12484
12594
  const props = deepmerge3(ctx.appConfig.defaults.queue, local2);
12485
- const group = new Node12(ctx.stack, "queue", id);
12595
+ const group = new Node13(ctx.stack, "queue", id);
12486
12596
  const name = formatLocalResourceName({
12487
12597
  appName: ctx.app.name,
12488
12598
  stackName: ctx.stack.name,
12489
12599
  resourceType: "queue",
12490
12600
  resourceName: id
12491
12601
  });
12492
- const queue2 = new aws13.sqs.Queue(group, "queue", {
12602
+ const queue2 = new aws14.sqs.Queue(group, "queue", {
12493
12603
  name,
12494
12604
  deadLetterArn: getGlobalOnFailure(ctx),
12495
12605
  ...props
12496
12606
  });
12497
12607
  const { lambda, policy } = createLambdaFunction(group, ctx, `queue`, id, props.consumer);
12498
12608
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
12499
- new aws13.lambda.EventSourceMapping(group, "event", {
12609
+ new aws14.lambda.EventSourceMapping(group, "event", {
12500
12610
  functionArn: lambda.arn,
12501
12611
  sourceArn: queue2.arn,
12502
12612
  batchSize: props.batchSize,
@@ -12516,23 +12626,23 @@ var queueFeature = defineFeature({
12516
12626
  });
12517
12627
 
12518
12628
  // src/feature/rest/index.ts
12519
- import { aws as aws14, Node as Node13 } from "@awsless/formation";
12629
+ import { aws as aws15, Node as Node14 } from "@awsless/formation";
12520
12630
  import { constantCase as constantCase8 } from "change-case";
12521
12631
  var restFeature = defineFeature({
12522
12632
  name: "rest",
12523
12633
  onApp(ctx) {
12524
12634
  for (const [id, props] of Object.entries(ctx.appConfig.defaults?.rest ?? {})) {
12525
- const group = new Node13(ctx.base, "rest", id);
12635
+ const group = new Node14(ctx.base, "rest", id);
12526
12636
  const name = formatGlobalResourceName({
12527
12637
  appName: ctx.app.name,
12528
12638
  resourceType: "rest",
12529
12639
  resourceName: id
12530
12640
  });
12531
- const api = new aws14.apiGatewayV2.Api(group, "api", {
12641
+ const api = new aws15.apiGatewayV2.Api(group, "api", {
12532
12642
  name,
12533
12643
  protocolType: "HTTP"
12534
12644
  });
12535
- const stage = new aws14.apiGatewayV2.Stage(group, "stage", {
12645
+ const stage = new aws15.apiGatewayV2.Stage(group, "stage", {
12536
12646
  name: "v1",
12537
12647
  apiId: api.id
12538
12648
  });
@@ -12541,7 +12651,7 @@ var restFeature = defineFeature({
12541
12651
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
12542
12652
  const hostedZoneId = ctx.shared.get(`hosted-zone-${props.domain}-id`);
12543
12653
  const certificateArn = ctx.shared.get(`certificate-${props.domain}-arn`);
12544
- const domain = new aws14.apiGatewayV2.DomainName(group, "domain", {
12654
+ const domain = new aws15.apiGatewayV2.DomainName(group, "domain", {
12545
12655
  name: domainName,
12546
12656
  certificates: [
12547
12657
  {
@@ -12549,12 +12659,12 @@ var restFeature = defineFeature({
12549
12659
  }
12550
12660
  ]
12551
12661
  });
12552
- const mapping = new aws14.apiGatewayV2.ApiMapping(group, "mapping", {
12662
+ const mapping = new aws15.apiGatewayV2.ApiMapping(group, "mapping", {
12553
12663
  apiId: api.id,
12554
12664
  domainName: domain.name,
12555
12665
  stage: stage.name
12556
12666
  });
12557
- const record = new aws14.route53.RecordSet(group, "record", {
12667
+ const record = new aws15.route53.RecordSet(group, "record", {
12558
12668
  hostedZoneId,
12559
12669
  type: "A",
12560
12670
  name: domainName,
@@ -12572,21 +12682,21 @@ var restFeature = defineFeature({
12572
12682
  },
12573
12683
  onStack(ctx) {
12574
12684
  for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
12575
- const restGroup = new Node13(ctx.stack, "rest", id);
12685
+ const restGroup = new Node14(ctx.stack, "rest", id);
12576
12686
  for (const [routeKey, props] of Object.entries(routes)) {
12577
- const group = new Node13(restGroup, "route", routeKey);
12687
+ const group = new Node14(restGroup, "route", routeKey);
12578
12688
  const apiId = ctx.shared.get(`rest-${id}-id`);
12579
12689
  const routeId = shortId(routeKey);
12580
12690
  const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
12581
12691
  ...props,
12582
12692
  description: `${id} ${routeKey}`
12583
12693
  });
12584
- const permission = new aws14.lambda.Permission(group, "permission", {
12694
+ const permission = new aws15.lambda.Permission(group, "permission", {
12585
12695
  action: "lambda:InvokeFunction",
12586
12696
  principal: "apigateway.amazonaws.com",
12587
12697
  functionArn: lambda.arn
12588
12698
  });
12589
- const integration = new aws14.apiGatewayV2.Integration(group, "integration", {
12699
+ const integration = new aws15.apiGatewayV2.Integration(group, "integration", {
12590
12700
  apiId,
12591
12701
  description: `${id} ${routeKey}`,
12592
12702
  method: "POST",
@@ -12596,7 +12706,7 @@ var restFeature = defineFeature({
12596
12706
  return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
12597
12707
  })
12598
12708
  });
12599
- const route = new aws14.apiGatewayV2.Route(group, "route", {
12709
+ const route = new aws15.apiGatewayV2.Route(group, "route", {
12600
12710
  apiId,
12601
12711
  routeKey,
12602
12712
  target: integration.id.apply((id2) => `integrations/${id2}`)
@@ -12607,9 +12717,296 @@ var restFeature = defineFeature({
12607
12717
  }
12608
12718
  });
12609
12719
 
12720
+ // src/feature/rpc/index.ts
12721
+ import { camelCase as camelCase6, constantCase as constantCase9, paramCase as paramCase6 } from "change-case";
12722
+ import { aws as aws17, Node as Node16, Output as Output3 } from "@awsless/formation";
12723
+ import { mebibytes as mebibytes2 } from "@awsless/size";
12724
+ import { dirname as dirname10, join as join8, relative as relative5 } from "path";
12725
+ import { fileURLToPath } from "node:url";
12726
+
12727
+ // src/feature/function/prebuild.ts
12728
+ import { Asset as Asset4, aws as aws16 } from "@awsless/formation";
12729
+ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
12730
+ let name;
12731
+ if ("stack" in ctx) {
12732
+ name = formatLocalResourceName({
12733
+ appName: ctx.app.name,
12734
+ stackName: ctx.stack.name,
12735
+ resourceType: ns,
12736
+ resourceName: id
12737
+ });
12738
+ } else {
12739
+ name = formatGlobalResourceName({
12740
+ appName: ctx.appConfig.name,
12741
+ resourceType: ns,
12742
+ resourceName: id
12743
+ });
12744
+ }
12745
+ const props = {
12746
+ architecture: "arm64",
12747
+ runtime: "nodejs20.x",
12748
+ ...local2
12749
+ };
12750
+ const code = new aws16.s3.BucketObject(group, "code", {
12751
+ bucket: ctx.shared.get("function-bucket-name"),
12752
+ key: `/lambda/${name}.zip`,
12753
+ body: Asset4.fromFile(props.bundleFile)
12754
+ });
12755
+ const role = new aws16.iam.Role(group, "role", {
12756
+ name,
12757
+ assumedBy: "lambda.amazonaws.com"
12758
+ });
12759
+ const policy = new aws16.iam.RolePolicy(group, "policy", {
12760
+ role: role.name,
12761
+ name: "lambda-policy",
12762
+ version: "2012-10-17"
12763
+ });
12764
+ const lambda = new aws16.lambda.Function(group, `function`, {
12765
+ ...props,
12766
+ name,
12767
+ role: role.arn,
12768
+ code,
12769
+ runtime: props.runtime === "container" ? void 0 : props.runtime,
12770
+ // Remove conflicting props.
12771
+ vpc: void 0,
12772
+ log: props.log
12773
+ });
12774
+ new aws16.lambda.SourceCodeUpdate(group, "update", {
12775
+ functionName: lambda.name,
12776
+ version: Asset4.fromFile(props.bundleHash),
12777
+ architecture: props.architecture,
12778
+ code
12779
+ });
12780
+ ctx.onEnv((name2, value) => {
12781
+ lambda.addEnvironment(name2, value);
12782
+ });
12783
+ ctx.registerPolicy(policy);
12784
+ lambda.addEnvironment("APP", ctx.appConfig.name);
12785
+ lambda.addEnvironment("APP_ID", ctx.appId);
12786
+ if ("stackConfig" in ctx) {
12787
+ lambda.addEnvironment("STACK", ctx.stackConfig.name);
12788
+ }
12789
+ if (props.log?.retention && props.log?.retention?.value > 0n) {
12790
+ const logGroup = new aws16.cloudWatch.LogGroup(group, "log", {
12791
+ name: lambda.name.apply((name2) => `/aws/lambda/${name2}`),
12792
+ retention: props.log.retention
12793
+ });
12794
+ policy.addStatement(
12795
+ {
12796
+ actions: ["logs:CreateLogStream"],
12797
+ resources: [logGroup.arn]
12798
+ },
12799
+ {
12800
+ actions: ["logs:PutLogEvents"],
12801
+ resources: [logGroup.arn.apply((arn) => `${arn}:*`)]
12802
+ }
12803
+ );
12804
+ }
12805
+ if ("permissions" in local2 && local2.permissions) {
12806
+ policy.addStatement(...local2.permissions);
12807
+ }
12808
+ if (props.warm) {
12809
+ const rule = new aws16.events.Rule(group, "warm", {
12810
+ name: `${name}--warm`,
12811
+ schedule: "rate(5 minutes)",
12812
+ enabled: true,
12813
+ targets: [
12814
+ {
12815
+ id: "warmer",
12816
+ arn: lambda.arn,
12817
+ input: {
12818
+ warmer: true,
12819
+ concurrency: props.warm
12820
+ }
12821
+ }
12822
+ ]
12823
+ });
12824
+ new aws16.lambda.Permission(group, `warm`, {
12825
+ action: "lambda:InvokeFunction",
12826
+ principal: "events.amazonaws.com",
12827
+ functionArn: lambda.arn,
12828
+ sourceArn: rule.arn
12829
+ });
12830
+ }
12831
+ if (props.vpc) {
12832
+ lambda.setVpc({
12833
+ securityGroupIds: [ctx.shared.get(`vpc-security-group-id`)],
12834
+ subnetIds: [
12835
+ ctx.shared.get(`vpc-public-subnet-id-1`),
12836
+ ctx.shared.get(`vpc-public-subnet-id-2`)
12837
+ ]
12838
+ });
12839
+ const vpcPolicy = new aws16.iam.RolePolicy(group, "vpc-policy", {
12840
+ role: role.name,
12841
+ name: "lambda-vpc-policy",
12842
+ version: "2012-10-17",
12843
+ statements: [
12844
+ {
12845
+ actions: [
12846
+ "ec2:CreateNetworkInterface",
12847
+ "ec2:DescribeNetworkInterfaces",
12848
+ "ec2:DeleteNetworkInterface",
12849
+ "ec2:AssignPrivateIpAddresses",
12850
+ "ec2:UnassignPrivateIpAddresses"
12851
+ ],
12852
+ resources: ["*"]
12853
+ }
12854
+ ]
12855
+ });
12856
+ lambda.dependsOn(vpcPolicy);
12857
+ }
12858
+ return {
12859
+ name,
12860
+ lambda,
12861
+ policy,
12862
+ code
12863
+ };
12864
+ };
12865
+
12866
+ // src/feature/rpc/index.ts
12867
+ import { days as days5, seconds as seconds3 } from "@awsless/duration";
12868
+ var __dirname = dirname10(fileURLToPath(import.meta.url));
12869
+ var rpcFeature = defineFeature({
12870
+ name: "rpc",
12871
+ async onTypeGen(ctx) {
12872
+ const types2 = new TypeFile("@awsless/awsless/client");
12873
+ types2.addCode(`type Input<T> = Parameters<T>[0]`);
12874
+ types2.addCode(`type Output<T> = Promise<ReturnType<T>>`);
12875
+ types2.addCode(`type Handle<T> = (input:Input<T>) => Output<T>`);
12876
+ const schemas = new TypeObject(1);
12877
+ for (const id of Object.keys(ctx.appConfig.defaults.rpc ?? {})) {
12878
+ const schema = new TypeObject(2);
12879
+ for (const stack of ctx.stackConfigs) {
12880
+ for (const [name, props] of Object.entries(stack.rpc?.[id] ?? {})) {
12881
+ const relFile = relative5(directories.types, props.file);
12882
+ const varName = camelCase6(`${stack.name}-${name}`);
12883
+ types2.addImport(varName, relFile);
12884
+ schema.addType(name, `Handle<typeof ${varName}>`);
12885
+ }
12886
+ }
12887
+ schemas.addType(id, schema);
12888
+ }
12889
+ types2.addInterface("RpcSchema", schemas);
12890
+ await ctx.write("rpc.d.ts", types2, true);
12891
+ },
12892
+ onApp(ctx) {
12893
+ for (const [id, props] of Object.entries(ctx.appConfig.defaults.rpc ?? {})) {
12894
+ const group = new Node16(ctx.base, "rpc", id);
12895
+ const name = formatGlobalResourceName({
12896
+ appName: ctx.app.name,
12897
+ resourceType: "rpc",
12898
+ resourceName: id
12899
+ });
12900
+ const { lambda } = createPrebuildLambdaFunction(group, ctx, "rpc", id, {
12901
+ bundleFile: join8(__dirname, "/prebuild/rpc/bundle.zip"),
12902
+ bundleHash: join8(__dirname, "/prebuild/rpc/HASH"),
12903
+ memorySize: mebibytes2(256),
12904
+ warm: 3
12905
+ });
12906
+ const schema = {};
12907
+ lambda.addEnvironment(
12908
+ "SCHEMA",
12909
+ new Output3([], (resolve2) => {
12910
+ ctx.onReady(() => {
12911
+ resolve2(JSON.stringify(schema));
12912
+ });
12913
+ })
12914
+ );
12915
+ ctx.shared.set(`rpc-${id}-schema`, schema);
12916
+ if (props.auth) {
12917
+ const authGroup = new Node16(group, "auth", "authorizer");
12918
+ const auth2 = createLambdaFunction(authGroup, ctx, "rpc", `${id}-auth`, props.auth);
12919
+ lambda.addEnvironment("AUTH", auth2.lambda.name);
12920
+ }
12921
+ const permission = new aws17.lambda.Permission(group, "permission", {
12922
+ principal: "*",
12923
+ action: "lambda:InvokeFunctionUrl",
12924
+ functionArn: lambda.arn,
12925
+ urlAuthType: "none"
12926
+ });
12927
+ const url = new aws17.lambda.Url(group, "url-2", {
12928
+ targetArn: lambda.arn,
12929
+ authType: "none",
12930
+ cors: {
12931
+ allow: {
12932
+ origins: ["*"],
12933
+ methods: ["*"],
12934
+ headers: ["Authentication", "Content-Type"]
12935
+ // credentials: true,
12936
+ }
12937
+ }
12938
+ }).dependsOn(permission);
12939
+ const domainName = props.domain ? formatFullDomainName(ctx.appConfig, props.domain, props.subDomain) : void 0;
12940
+ const certificateArn = props.domain ? ctx.shared.get(`global-certificate-${props.domain}-arn`) : void 0;
12941
+ const cache = new aws17.cloudFront.CachePolicy(group, "cache", {
12942
+ name,
12943
+ minTtl: seconds3(1),
12944
+ maxTtl: days5(365),
12945
+ defaultTtl: days5(1)
12946
+ });
12947
+ const originRequest = new aws17.cloudFront.OriginRequestPolicy(group, "request", {
12948
+ name,
12949
+ header: {
12950
+ behavior: "all-except",
12951
+ values: ["Host"]
12952
+ }
12953
+ });
12954
+ const cdn = new aws17.cloudFront.Distribution(group, "cdn-2", {
12955
+ name,
12956
+ compress: true,
12957
+ certificateArn,
12958
+ viewerProtocol: "https-only",
12959
+ allowMethod: ["GET", "HEAD", "OPTIONS", "PUT", "PATCH", "POST", "DELETE"],
12960
+ aliases: domainName ? [domainName] : void 0,
12961
+ origins: [
12962
+ {
12963
+ id: "default",
12964
+ domainName: url.url.apply((url2) => url2.split("/")[2]),
12965
+ protocol: "https-only"
12966
+ }
12967
+ ],
12968
+ targetOriginId: "default",
12969
+ cachePolicyId: cache.id,
12970
+ originRequestPolicyId: originRequest.id
12971
+ });
12972
+ if (props.domain) {
12973
+ const fullDomainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
12974
+ new aws17.route53.RecordSet(group, "record", {
12975
+ hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
12976
+ type: "A",
12977
+ name: fullDomainName,
12978
+ alias: cdn.aliasTarget
12979
+ });
12980
+ ctx.bind(`RPC_${constantCase9(id)}_ENDPOINT`, fullDomainName);
12981
+ } else {
12982
+ ctx.bind(`RPC_${constantCase9(id)}_ENDPOINT`, cdn.aliasTarget.dnsName);
12983
+ }
12984
+ }
12985
+ },
12986
+ onStack(ctx) {
12987
+ for (const [id, queries] of Object.entries(ctx.stackConfig.rpc ?? {})) {
12988
+ const defaultProps = ctx.appConfig.defaults.rpc?.[id];
12989
+ if (!defaultProps) {
12990
+ throw new FileError(ctx.stackConfig.file, `RPC definition is not defined on app level for "${id}"`);
12991
+ }
12992
+ const schema = ctx.shared.get(`rpc-${id}-schema`);
12993
+ const group = new Node16(ctx.stack, "rpc", id);
12994
+ for (const [name, props] of Object.entries(queries ?? {})) {
12995
+ const queryGroup = new Node16(group, "query", name);
12996
+ const entryId = paramCase6(`${id}-${shortId(name)}`);
12997
+ const lambda = createLambdaFunction(queryGroup, ctx, `rpc`, entryId, {
12998
+ ...props,
12999
+ description: `${id} ${name}`
13000
+ });
13001
+ schema[name] = lambda.name;
13002
+ }
13003
+ }
13004
+ }
13005
+ });
13006
+
12610
13007
  // src/feature/search/index.ts
12611
- import { aws as aws15, Node as Node14 } from "@awsless/formation";
12612
- import { constantCase as constantCase9 } from "change-case";
13008
+ import { aws as aws18, Node as Node17 } from "@awsless/formation";
13009
+ import { constantCase as constantCase10 } from "change-case";
12613
13010
  var typeGenCode4 = `
12614
13011
  import { AnyStruct, Table } from '@awsless/open-search'
12615
13012
 
@@ -12636,9 +13033,9 @@ var searchFeature = defineFeature({
12636
13033
  },
12637
13034
  onStack(ctx) {
12638
13035
  for (const [id, props] of Object.entries(ctx.stackConfig.searchs ?? {})) {
12639
- const group = new Node14(ctx.stack, "search", id);
13036
+ const group = new Node17(ctx.stack, "search", id);
12640
13037
  const name = `${id}-${shortId([ctx.app.name, ctx.stack.name, this.name, id].join("--"))}`;
12641
- const openSearch = new aws15.openSearch.Domain(group, "domain", {
13038
+ const openSearch = new aws18.openSearch.Domain(group, "domain", {
12642
13039
  name,
12643
13040
  version: props.version,
12644
13041
  storageSize: props.storage,
@@ -12665,7 +13062,7 @@ var searchFeature = defineFeature({
12665
13062
  ]
12666
13063
  });
12667
13064
  }
12668
- ctx.addEnv(`SEARCH_${constantCase9(ctx.stack.name)}_${constantCase9(id)}_DOMAIN`, openSearch.domainEndpoint);
13065
+ ctx.addEnv(`SEARCH_${constantCase10(ctx.stack.name)}_${constantCase10(id)}_DOMAIN`, openSearch.domainEndpoint);
12669
13066
  ctx.onPolicy((policy) => {
12670
13067
  policy.addStatement({
12671
13068
  actions: ["es:ESHttp*"],
@@ -12677,10 +13074,10 @@ var searchFeature = defineFeature({
12677
13074
  });
12678
13075
 
12679
13076
  // src/feature/site/index.ts
12680
- import { days as days5, seconds as seconds3 } from "@awsless/duration";
12681
- import { Asset as Asset4, aws as aws16, Node as Node15 } from "@awsless/formation";
13077
+ import { days as days6, seconds as seconds4 } from "@awsless/duration";
13078
+ import { Asset as Asset5, aws as aws19, Node as Node18 } from "@awsless/formation";
12682
13079
  import { glob as glob2 } from "glob";
12683
- import { join as join8 } from "path";
13080
+ import { join as join9 } from "path";
12684
13081
 
12685
13082
  // src/feature/site/util.ts
12686
13083
  import { lookup, contentType } from "mime-types";
@@ -12703,12 +13100,12 @@ var getContentType = (file) => {
12703
13100
  };
12704
13101
 
12705
13102
  // src/feature/site/index.ts
12706
- import { constantCase as constantCase10 } from "change-case";
13103
+ import { constantCase as constantCase11 } from "change-case";
12707
13104
  var siteFeature = defineFeature({
12708
13105
  name: "site",
12709
13106
  onStack(ctx) {
12710
13107
  for (const [id, props] of Object.entries(ctx.stackConfig.sites ?? {})) {
12711
- const group = new Node15(ctx.stack, "site", id);
13108
+ const group = new Node18(ctx.stack, "site", id);
12712
13109
  const name = formatLocalResourceName({
12713
13110
  appName: ctx.app.name,
12714
13111
  stackName: ctx.stack.name,
@@ -12727,7 +13124,7 @@ var siteFeature = defineFeature({
12727
13124
  ctx.onBind((name2, value) => {
12728
13125
  lambda.addEnvironment(name2, value);
12729
13126
  });
12730
- new aws16.lambda.Permission(group, "permission", {
13127
+ new aws19.lambda.Permission(group, "permission", {
12731
13128
  principal: "*",
12732
13129
  // principal: 'cloudfront.amazonaws.com',
12733
13130
  action: "lambda:InvokeFunctionUrl",
@@ -12736,7 +13133,7 @@ var siteFeature = defineFeature({
12736
13133
  // urlAuthType: 'aws-iam',
12737
13134
  // sourceArn: distribution.arn,
12738
13135
  });
12739
- const url = new aws16.lambda.Url(group, "url", {
13136
+ const url = new aws19.lambda.Url(group, "url", {
12740
13137
  targetArn: lambda.arn,
12741
13138
  authType: "none"
12742
13139
  // authType: 'aws-iam',
@@ -12748,7 +13145,7 @@ var siteFeature = defineFeature({
12748
13145
  });
12749
13146
  }
12750
13147
  if (props.static) {
12751
- bucket = new aws16.s3.Bucket(group, "bucket", {
13148
+ bucket = new aws19.s3.Bucket(group, "bucket", {
12752
13149
  name: formatLocalResourceName({
12753
13150
  appName: ctx.app.name,
12754
13151
  stackName: ctx.stack.name,
@@ -12774,7 +13171,7 @@ var siteFeature = defineFeature({
12774
13171
  policy.addStatement(bucket.permissions);
12775
13172
  });
12776
13173
  bucket.deletionPolicy = "after-deployment";
12777
- const accessControl = new aws16.cloudFront.OriginAccessControl(group, `access`, {
13174
+ const accessControl = new aws19.cloudFront.OriginAccessControl(group, `access`, {
12778
13175
  name,
12779
13176
  type: "s3",
12780
13177
  behavior: "always",
@@ -12786,10 +13183,10 @@ var siteFeature = defineFeature({
12786
13183
  nodir: true
12787
13184
  });
12788
13185
  for (const file of files) {
12789
- const object = new aws16.s3.BucketObject(group, file, {
13186
+ const object = new aws19.s3.BucketObject(group, file, {
12790
13187
  bucket: bucket.name,
12791
13188
  key: file,
12792
- body: Asset4.fromFile(join8(props.static, file)),
13189
+ body: Asset5.fromFile(join9(props.static, file)),
12793
13190
  cacheControl: getCacheControl(file),
12794
13191
  contentType: getContentType(file)
12795
13192
  });
@@ -12809,21 +13206,21 @@ var siteFeature = defineFeature({
12809
13206
  statusCodes: [403, 404]
12810
13207
  });
12811
13208
  }
12812
- const cache = new aws16.cloudFront.CachePolicy(group, "cache", {
13209
+ const cache = new aws19.cloudFront.CachePolicy(group, "cache", {
12813
13210
  name,
12814
- minTtl: seconds3(1),
12815
- maxTtl: days5(365),
12816
- defaultTtl: days5(1),
13211
+ minTtl: seconds4(1),
13212
+ maxTtl: days6(365),
13213
+ defaultTtl: days6(1),
12817
13214
  ...props.cache
12818
13215
  });
12819
- const originRequest = new aws16.cloudFront.OriginRequestPolicy(group, "request", {
13216
+ const originRequest = new aws19.cloudFront.OriginRequestPolicy(group, "request", {
12820
13217
  name,
12821
13218
  header: {
12822
13219
  behavior: "all-except",
12823
13220
  values: ["host", "authorization"]
12824
13221
  }
12825
13222
  });
12826
- const responseHeaders = new aws16.cloudFront.ResponseHeadersPolicy(group, "response", {
13223
+ const responseHeaders = new aws19.cloudFront.ResponseHeadersPolicy(group, "response", {
12827
13224
  name,
12828
13225
  cors: props.cors,
12829
13226
  remove: ["server"]
@@ -12833,7 +13230,7 @@ var siteFeature = defineFeature({
12833
13230
  });
12834
13231
  const domainName = props.domain ? formatFullDomainName(ctx.appConfig, props.domain, props.subDomain) : void 0;
12835
13232
  const certificateArn = props.domain ? ctx.shared.get(`global-certificate-${props.domain}-arn`) : void 0;
12836
- const distribution = new aws16.cloudFront.Distribution(group, "distribution", {
13233
+ const distribution = new aws19.cloudFront.Distribution(group, "distribution", {
12837
13234
  name,
12838
13235
  compress: true,
12839
13236
  certificateArn,
@@ -12861,13 +13258,13 @@ var siteFeature = defineFeature({
12861
13258
  };
12862
13259
  })
12863
13260
  });
12864
- new aws16.cloudFront.InvalidateCache(group, "invalidate", {
13261
+ new aws19.cloudFront.InvalidateCache(group, "invalidate", {
12865
13262
  distributionId: distribution.id,
12866
13263
  paths: ["/*"],
12867
13264
  versions
12868
13265
  });
12869
13266
  if (props.static) {
12870
- new aws16.s3.BucketPolicy(group, `policy`, {
13267
+ new aws19.s3.BucketPolicy(group, `policy`, {
12871
13268
  bucketName: bucket.name,
12872
13269
  statements: [
12873
13270
  {
@@ -12894,7 +13291,7 @@ var siteFeature = defineFeature({
12894
13291
  });
12895
13292
  }
12896
13293
  if (domainName) {
12897
- new aws16.route53.RecordSet(group, `record`, {
13294
+ new aws19.route53.RecordSet(group, `record`, {
12898
13295
  hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
12899
13296
  type: "A",
12900
13297
  name: domainName,
@@ -12902,7 +13299,7 @@ var siteFeature = defineFeature({
12902
13299
  });
12903
13300
  }
12904
13301
  ctx.bind(
12905
- `SITE_${constantCase10(ctx.stack.name)}_${constantCase10(id)}_ENDPOINT`,
13302
+ `SITE_${constantCase11(ctx.stack.name)}_${constantCase11(id)}_ENDPOINT`,
12906
13303
  domainName ? domainName : distribution.domainName
12907
13304
  );
12908
13305
  }
@@ -12910,8 +13307,8 @@ var siteFeature = defineFeature({
12910
13307
  });
12911
13308
 
12912
13309
  // src/feature/store/index.ts
12913
- import { aws as aws17, Node as Node16 } from "@awsless/formation";
12914
- import { paramCase as paramCase6 } from "change-case";
13310
+ import { aws as aws20, Node as Node19 } from "@awsless/formation";
13311
+ import { paramCase as paramCase7 } from "change-case";
12915
13312
  var typeGenCode5 = `
12916
13313
  import { Body, PutObjectProps, BodyStream } from '@awsless/s3'
12917
13314
 
@@ -12947,7 +13344,7 @@ var storeFeature = defineFeature({
12947
13344
  },
12948
13345
  onStack(ctx) {
12949
13346
  for (const [id, props] of Object.entries(ctx.stackConfig.stores ?? {})) {
12950
- const group = new Node16(ctx.stack, "store", id);
13347
+ const group = new Node19(ctx.stack, "store", id);
12951
13348
  const name = formatLocalResourceName({
12952
13349
  appName: ctx.app.name,
12953
13350
  stackName: ctx.stack.name,
@@ -12967,13 +13364,13 @@ var storeFeature = defineFeature({
12967
13364
  "removed:marker": "s3:ObjectRemoved:DeleteMarkerCreated"
12968
13365
  };
12969
13366
  for (const [event, funcProps] of Object.entries(props.events ?? {})) {
12970
- const eventGroup = new Node16(group, "event", event);
12971
- const eventId = paramCase6(`${id}-${shortId(event)}`);
13367
+ const eventGroup = new Node19(group, "event", event);
13368
+ const eventId = paramCase7(`${id}-${shortId(event)}`);
12972
13369
  const { lambda } = createAsyncLambdaFunction(eventGroup, ctx, `store`, eventId, {
12973
13370
  ...funcProps,
12974
13371
  description: `${id} event "${event}"`
12975
13372
  });
12976
- new aws17.lambda.Permission(eventGroup, "permission", {
13373
+ new aws20.lambda.Permission(eventGroup, "permission", {
12977
13374
  action: "lambda:InvokeFunction",
12978
13375
  principal: "s3.amazonaws.com",
12979
13376
  functionArn: lambda.arn,
@@ -12984,7 +13381,7 @@ var storeFeature = defineFeature({
12984
13381
  function: lambda.arn
12985
13382
  });
12986
13383
  }
12987
- const bucket = new aws17.s3.Bucket(group, "store", {
13384
+ const bucket = new aws20.s3.Bucket(group, "store", {
12988
13385
  name,
12989
13386
  versioning: props.versioning,
12990
13387
  forceDelete: true,
@@ -13012,27 +13409,27 @@ var storeFeature = defineFeature({
13012
13409
  });
13013
13410
 
13014
13411
  // src/feature/stream/index.ts
13015
- import { aws as aws18, Node as Node17 } from "@awsless/formation";
13016
- import { constantCase as constantCase11 } from "change-case";
13412
+ import { aws as aws21, Node as Node20 } from "@awsless/formation";
13413
+ import { constantCase as constantCase12 } from "change-case";
13017
13414
  var streamFeature = defineFeature({
13018
13415
  name: "stream",
13019
13416
  onStack(ctx) {
13020
13417
  for (const [id, props] of Object.entries(ctx.stackConfig.streams ?? {})) {
13021
- const group = new Node17(ctx.stack, "stream", id);
13418
+ const group = new Node20(ctx.stack, "stream", id);
13022
13419
  const name = formatLocalResourceName({
13023
13420
  appName: ctx.app.name,
13024
13421
  stackName: ctx.stack.name,
13025
13422
  resourceType: "stream",
13026
13423
  resourceName: id
13027
13424
  });
13028
- const channel = new aws18.ivs.Channel(group, "channel", {
13425
+ const channel = new aws21.ivs.Channel(group, "channel", {
13029
13426
  name,
13030
13427
  ...props
13031
13428
  });
13032
- const streamKey = new aws18.ivs.StreamKey(group, "key", {
13429
+ const streamKey = new aws21.ivs.StreamKey(group, "key", {
13033
13430
  channel: channel.arn
13034
13431
  });
13035
- const prefix = `STREAM_${constantCase11(ctx.stack.name)}_${constantCase11(id)}`;
13432
+ const prefix = `STREAM_${constantCase12(ctx.stack.name)}_${constantCase12(id)}`;
13036
13433
  ctx.bind(`${prefix}_ENDPOINT`, channel.playbackUrl);
13037
13434
  ctx.addEnv(`${prefix}_INGEST_ENDPOINT`, channel.ingestEndpoint);
13038
13435
  ctx.addEnv(`${prefix}_STREAM_KEY`, streamKey.value);
@@ -13041,7 +13438,7 @@ var streamFeature = defineFeature({
13041
13438
  });
13042
13439
 
13043
13440
  // src/feature/table/index.ts
13044
- import { aws as aws19, Node as Node18 } from "@awsless/formation";
13441
+ import { aws as aws22, Node as Node21 } from "@awsless/formation";
13045
13442
  var tableFeature = defineFeature({
13046
13443
  name: "table",
13047
13444
  async onTypeGen(ctx) {
@@ -13065,7 +13462,7 @@ var tableFeature = defineFeature({
13065
13462
  },
13066
13463
  onStack(ctx) {
13067
13464
  for (const [id, props] of Object.entries(ctx.stackConfig.tables ?? {})) {
13068
- const group = new Node18(ctx.stack, "table", id);
13465
+ const group = new Node21(ctx.stack, "table", id);
13069
13466
  const name = formatLocalResourceName({
13070
13467
  appName: ctx.app.name,
13071
13468
  stackName: ctx.stack.name,
@@ -13073,7 +13470,7 @@ var tableFeature = defineFeature({
13073
13470
  resourceName: id
13074
13471
  });
13075
13472
  const deletionProtection = props.deletionProtection ?? ctx.appConfig.defaults.table?.deletionProtection;
13076
- const table2 = new aws19.dynamodb.Table(group, "table", {
13473
+ const table2 = new aws22.dynamodb.Table(group, "table", {
13077
13474
  ...props,
13078
13475
  name,
13079
13476
  stream: props.stream?.type,
@@ -13086,7 +13483,7 @@ var tableFeature = defineFeature({
13086
13483
  const { lambda, policy } = createLambdaFunction(group, ctx, "table", id, props.stream.consumer);
13087
13484
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
13088
13485
  const onFailure = getGlobalOnFailure(ctx);
13089
- const source = new aws19.lambda.EventSourceMapping(group, id, {
13486
+ const source = new aws22.lambda.EventSourceMapping(group, id, {
13090
13487
  functionArn: lambda.arn,
13091
13488
  sourceArn: table2.streamArn,
13092
13489
  batchSize: 100,
@@ -13113,9 +13510,9 @@ var tableFeature = defineFeature({
13113
13510
  });
13114
13511
 
13115
13512
  // src/feature/task/index.ts
13116
- import { Node as Node19 } from "@awsless/formation";
13117
- import { camelCase as camelCase6 } from "change-case";
13118
- import { relative as relative5 } from "path";
13513
+ import { Node as Node22 } from "@awsless/formation";
13514
+ import { camelCase as camelCase7 } from "change-case";
13515
+ import { relative as relative6 } from "path";
13119
13516
  var typeGenCode6 = `
13120
13517
  import { InvokeOptions } from '@awsless/lambda'
13121
13518
  import type { Mock } from 'vitest'
@@ -13150,14 +13547,14 @@ var taskFeature = defineFeature({
13150
13547
  const mock = new TypeObject(2);
13151
13548
  const mockResponse = new TypeObject(2);
13152
13549
  for (const [name, props] of Object.entries(stack.tasks || {})) {
13153
- const varName = camelCase6(`${stack.name}-${name}`);
13550
+ const varName = camelCase7(`${stack.name}-${name}`);
13154
13551
  const funcName = formatLocalResourceName({
13155
13552
  appName: ctx.appConfig.name,
13156
13553
  stackName: stack.name,
13157
13554
  resourceType: "task",
13158
13555
  resourceName: name
13159
13556
  });
13160
- const relFile = relative5(directories.types, props.consumer.file);
13557
+ const relFile = relative6(directories.types, props.consumer.file);
13161
13558
  types2.addImport(varName, relFile);
13162
13559
  resource2.addType(name, `Invoke<'${funcName}', typeof ${varName}>`);
13163
13560
  mock.addType(name, `MockBuilder<typeof ${varName}>`);
@@ -13175,7 +13572,7 @@ var taskFeature = defineFeature({
13175
13572
  },
13176
13573
  onStack(ctx) {
13177
13574
  for (const [id, props] of Object.entries(ctx.stackConfig.tasks ?? {})) {
13178
- const group = new Node19(ctx.stack, "task", id);
13575
+ const group = new Node22(ctx.stack, "task", id);
13179
13576
  createAsyncLambdaFunction(group, ctx, "task", id, props.consumer);
13180
13577
  }
13181
13578
  }
@@ -13192,7 +13589,7 @@ var testFeature = defineFeature({
13192
13589
  });
13193
13590
 
13194
13591
  // src/feature/topic/index.ts
13195
- import { aws as aws20, Node as Node20 } from "@awsless/formation";
13592
+ import { aws as aws23, Node as Node23 } from "@awsless/formation";
13196
13593
  var typeGenCode7 = `
13197
13594
  import type { PublishOptions } from '@awsless/sns'
13198
13595
  import type { Mock } from 'vitest'
@@ -13233,13 +13630,13 @@ var topicFeature = defineFeature({
13233
13630
  onApp(ctx) {
13234
13631
  for (const stack of ctx.stackConfigs) {
13235
13632
  for (const id of stack.topics ?? []) {
13236
- const group = new Node20(ctx.base, "topic", id);
13633
+ const group = new Node23(ctx.base, "topic", id);
13237
13634
  const name = formatGlobalResourceName({
13238
13635
  appName: ctx.appConfig.name,
13239
13636
  resourceType: "topic",
13240
13637
  resourceName: id
13241
13638
  });
13242
- const topic = new aws20.sns.Topic(group, "topic", {
13639
+ const topic = new aws23.sns.Topic(group, "topic", {
13243
13640
  name
13244
13641
  });
13245
13642
  ctx.shared.set(`topic-${id}-arn`, topic.arn);
@@ -13256,22 +13653,22 @@ var topicFeature = defineFeature({
13256
13653
  });
13257
13654
  }
13258
13655
  for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
13259
- const group = new Node20(ctx.stack, "topic", id);
13656
+ const group = new Node23(ctx.stack, "topic", id);
13260
13657
  const topicArn = ctx.shared.get(`topic-${id}-arn`);
13261
13658
  if (typeof props === "string" && isEmail(props)) {
13262
- new aws20.sns.Subscription(group, id, {
13659
+ new aws23.sns.Subscription(group, id, {
13263
13660
  topicArn,
13264
13661
  protocol: "email",
13265
13662
  endpoint: props
13266
13663
  });
13267
13664
  } else if (typeof props === "object") {
13268
13665
  const { lambda } = createAsyncLambdaFunction(group, ctx, `topic`, id, props);
13269
- new aws20.sns.Subscription(group, id, {
13666
+ new aws23.sns.Subscription(group, id, {
13270
13667
  topicArn,
13271
13668
  protocol: "lambda",
13272
13669
  endpoint: lambda.arn
13273
13670
  });
13274
- new aws20.lambda.Permission(group, id, {
13671
+ new aws23.lambda.Permission(group, id, {
13275
13672
  action: "lambda:InvokeFunction",
13276
13673
  principal: "sns.amazonaws.com",
13277
13674
  functionArn: lambda.arn,
@@ -13283,36 +13680,36 @@ var topicFeature = defineFeature({
13283
13680
  });
13284
13681
 
13285
13682
  // src/feature/vpc/index.ts
13286
- import { aws as aws21, combine as combine2, Node as Node21 } from "@awsless/formation";
13683
+ import { aws as aws24, combine as combine2, Node as Node24 } from "@awsless/formation";
13287
13684
  var vpcFeature = defineFeature({
13288
13685
  name: "vpc",
13289
13686
  onApp(ctx) {
13290
- const group = new Node21(ctx.base, "vpc", "main");
13291
- const vpc = new aws21.ec2.Vpc(group, "vpc", {
13687
+ const group = new Node24(ctx.base, "vpc", "main");
13688
+ const vpc = new aws24.ec2.Vpc(group, "vpc", {
13292
13689
  name: ctx.app.name,
13293
- cidrBlock: aws21.ec2.Peer.ipv4("10.0.0.0/16")
13690
+ cidrBlock: aws24.ec2.Peer.ipv4("10.0.0.0/16")
13294
13691
  // cidrBlock: aws.ec2.Peer.ipv6('fd00:10:20::/48'),
13295
13692
  // cidrBlock: aws.ec2.Peer.ipv6('2a05:d018:c69:6600::/56'),
13296
13693
  // enableDnsSupport: true,
13297
13694
  // enableDnsHostnames: true,
13298
13695
  });
13299
- const privateRouteTable = new aws21.ec2.RouteTable(group, "private", {
13696
+ const privateRouteTable = new aws24.ec2.RouteTable(group, "private", {
13300
13697
  vpcId: vpc.id,
13301
13698
  name: "private"
13302
13699
  });
13303
- const publicRouteTable = new aws21.ec2.RouteTable(group, "public", {
13700
+ const publicRouteTable = new aws24.ec2.RouteTable(group, "public", {
13304
13701
  vpcId: vpc.id,
13305
13702
  name: "public"
13306
13703
  });
13307
- const gateway = new aws21.ec2.InternetGateway(group, "gateway");
13308
- const attachment = new aws21.ec2.VPCGatewayAttachment(group, "attachment", {
13704
+ const gateway = new aws24.ec2.InternetGateway(group, "gateway");
13705
+ const attachment = new aws24.ec2.VPCGatewayAttachment(group, "attachment", {
13309
13706
  vpcId: vpc.id,
13310
13707
  internetGatewayId: gateway.id
13311
13708
  });
13312
- new aws21.ec2.Route(group, "route", {
13709
+ new aws24.ec2.Route(group, "route", {
13313
13710
  gatewayId: gateway.id,
13314
13711
  routeTableId: publicRouteTable.id,
13315
- destination: aws21.ec2.Peer.anyIpv4()
13712
+ destination: aws24.ec2.Peer.anyIpv4()
13316
13713
  // destination: aws.ec2.Peer.anyIpv6(),
13317
13714
  });
13318
13715
  ctx.shared.set(
@@ -13328,10 +13725,10 @@ var vpcFeature = defineFeature({
13328
13725
  for (const i in zones) {
13329
13726
  const index = Number(i) + 1;
13330
13727
  const id = `${table2.identifier}-${index}`;
13331
- const subnet = new aws21.ec2.Subnet(group, id, {
13728
+ const subnet = new aws24.ec2.Subnet(group, id, {
13332
13729
  name: `${ctx.app.name}--${table2.identifier}-${index}`,
13333
13730
  vpcId: vpc.id,
13334
- cidrBlock: aws21.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
13731
+ cidrBlock: aws24.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
13335
13732
  // ipv6CidrBlock: aws.ec2.Peer.ipv6(`fd00:10:20:${++block}::/64`),
13336
13733
  // ipv6CidrBlock: aws.ec2.Peer.ipv6(`2a05:d018:c69:660${++block}::/64`),
13337
13734
  // ipv6CidrBlock: ipv6CidrBlock.ipv6CidrBlock.apply(ip => ),
@@ -13341,7 +13738,7 @@ var vpcFeature = defineFeature({
13341
13738
  mapPublicIpOnLaunch: table2.identifier === "public",
13342
13739
  availabilityZone: ctx.appConfig.region + zones[i]
13343
13740
  });
13344
- new aws21.ec2.SubnetRouteTableAssociation(group, id, {
13741
+ new aws24.ec2.SubnetRouteTableAssociation(group, id, {
13345
13742
  routeTableId: table2.id,
13346
13743
  subnetId: subnet.id
13347
13744
  });
@@ -13378,7 +13775,11 @@ var features = [
13378
13775
  cronFeature,
13379
13776
  httpFeature,
13380
13777
  restFeature,
13381
- siteFeature
13778
+ siteFeature,
13779
+ // 4
13780
+ logSubscriptionFeature,
13781
+ // I think needs to be after s3 feature
13782
+ rpcFeature
13382
13783
  ];
13383
13784
 
13384
13785
  // src/shared.ts
@@ -13853,12 +14254,12 @@ import { confirm as confirm4, isCancel as isCancel5 } from "@clack/prompts";
13853
14254
  import { log as log8 } from "@clack/prompts";
13854
14255
  import chalk6 from "chalk";
13855
14256
  import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
13856
- import { join as join11 } from "path";
14257
+ import { join as join12 } from "path";
13857
14258
 
13858
14259
  // src/build/__fingerprint.ts
13859
14260
  import { createHash as createHash5 } from "crypto";
13860
14261
  import { readdir, readFile as readFile6, stat as stat4 } from "fs/promises";
13861
- import { basename as basename4, dirname as dirname10, extname as extname3, join as join9 } from "path";
14262
+ import { basename as basename4, dirname as dirname11, extname as extname3, join as join10 } from "path";
13862
14263
  import parseStaticImports from "parse-static-imports";
13863
14264
  var extensions = ["js", "mjs", "jsx", "ts", "mts", "tsx"];
13864
14265
  var generateFileHashes = async (file, hashes) => {
@@ -13880,7 +14281,7 @@ var fingerprintFromDirectory = async (dir) => {
13880
14281
  const files = await readdir(dir, { recursive: true });
13881
14282
  for (const file of files) {
13882
14283
  if (extensions.includes(extname3(file).substring(1)) && file.at(0) !== "_") {
13883
- await generateFileHashes(join9(dir, file), hashes);
14284
+ await generateFileHashes(join10(dir, file), hashes);
13884
14285
  }
13885
14286
  }
13886
14287
  const merge2 = Buffer.concat(Array.from(hashes.values()).sort());
@@ -13894,7 +14295,7 @@ var readModuleFile = (file) => {
13894
14295
  return readFiles([
13895
14296
  file,
13896
14297
  ...extensions.map((exp) => `${file}.${exp}`),
13897
- ...extensions.map((exp) => join9(file, `/index.${exp}`))
14298
+ ...extensions.map((exp) => join10(file, `/index.${exp}`))
13898
14299
  ]);
13899
14300
  }
13900
14301
  return readFile6(file, "utf8");
@@ -13914,7 +14315,7 @@ var readFiles = async (files) => {
13914
14315
  };
13915
14316
  var findDependencies = async (file, code) => {
13916
14317
  const imports = await parseStaticImports(code);
13917
- return imports.map((entry) => entry.moduleName).filter(Boolean).map((value) => value?.startsWith(".") ? join9(dirname10(file), value) : value);
14318
+ return imports.map((entry) => entry.moduleName).filter(Boolean).map((value) => value?.startsWith(".") ? join10(dirname11(file), value) : value);
13918
14319
  };
13919
14320
 
13920
14321
  // src/test/reporter.ts
@@ -13997,10 +14398,10 @@ import { startVitest } from "vitest/node";
13997
14398
  import commonjs3 from "@rollup/plugin-commonjs";
13998
14399
  import nodeResolve3 from "@rollup/plugin-node-resolve";
13999
14400
  import json3 from "@rollup/plugin-json";
14000
- import { dirname as dirname11, join as join10 } from "path";
14001
- import { fileURLToPath } from "url";
14401
+ import { dirname as dirname12, join as join11 } from "path";
14402
+ import { fileURLToPath as fileURLToPath2 } from "url";
14002
14403
  var startTest = async (props) => {
14003
- const __dirname = dirname11(fileURLToPath(import.meta.url));
14404
+ const __dirname2 = dirname12(fileURLToPath2(import.meta.url));
14004
14405
  const result = await startVitest(
14005
14406
  "test",
14006
14407
  props.filters,
@@ -14014,7 +14415,7 @@ var startTest = async (props) => {
14014
14415
  exclude: ["**/_*", "**/_*/**", ...configDefaults.exclude],
14015
14416
  globals: true,
14016
14417
  reporters: props.reporter,
14017
- globalSetup: join10(__dirname, "test-global-setup.js")
14418
+ globalSetup: join11(__dirname2, "test-global-setup.js")
14018
14419
  // env: {
14019
14420
  // TZ: 'UTC',
14020
14421
  // },
@@ -14108,7 +14509,7 @@ var logTestErrors = (event) => {
14108
14509
  var runTest = async (stack, dir, filters) => {
14109
14510
  await mkdir4(directories.test, { recursive: true });
14110
14511
  const fingerprint = await fingerprintFromDirectory(dir);
14111
- const file = join11(directories.test, `${stack}.json`);
14512
+ const file = join12(directories.test, `${stack}.json`);
14112
14513
  const exists = await fileExist(file);
14113
14514
  if (exists && !process.env.NO_CACHE) {
14114
14515
  const raw = await readFile7(file, { encoding: "utf8" });
@@ -14418,7 +14819,7 @@ import { log as log10 } from "@clack/prompts";
14418
14819
 
14419
14820
  // src/type-gen/generate.ts
14420
14821
  import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
14421
- import { dirname as dirname12, join as join12, relative as relative6 } from "path";
14822
+ import { dirname as dirname13, join as join13, relative as relative7 } from "path";
14422
14823
  var generateTypes = async (props) => {
14423
14824
  const files = [];
14424
14825
  await Promise.all(
@@ -14427,12 +14828,12 @@ var generateTypes = async (props) => {
14427
14828
  ...props,
14428
14829
  async write(file, data, include = false) {
14429
14830
  const code = data?.toString("utf8");
14430
- const path = join12(directories.types, file);
14831
+ const path = join13(directories.types, file);
14431
14832
  if (code) {
14432
14833
  if (include) {
14433
- files.push(relative6(directories.root, path));
14834
+ files.push(relative7(directories.root, path));
14434
14835
  }
14435
- await mkdir5(dirname12(path), { recursive: true });
14836
+ await mkdir5(dirname13(path), { recursive: true });
14436
14837
  await writeFile4(path, code);
14437
14838
  }
14438
14839
  }
@@ -14441,7 +14842,7 @@ var generateTypes = async (props) => {
14441
14842
  );
14442
14843
  if (files.length) {
14443
14844
  const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
14444
- await writeFile4(join12(directories.root, `awsless.d.ts`), code);
14845
+ await writeFile4(join13(directories.root, `awsless.d.ts`), code);
14445
14846
  }
14446
14847
  };
14447
14848