@awsless/cli 0.0.46-next.33 → 0.0.46-next.35

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
@@ -82626,7 +82626,7 @@ var require_readdirp = __commonJS((exports, module) => {
82626
82626
  var sysPath = __require("path");
82627
82627
  var { promisify: promisify4 } = __require("util");
82628
82628
  var picomatch = require_picomatch3();
82629
- var readdir5 = promisify4(fs3.readdir);
82629
+ var readdir6 = promisify4(fs3.readdir);
82630
82630
  var stat5 = promisify4(fs3.stat);
82631
82631
  var lstat4 = promisify4(fs3.lstat);
82632
82632
  var realpath2 = promisify4(fs3.realpath);
@@ -82759,7 +82759,7 @@ var require_readdirp = __commonJS((exports, module) => {
82759
82759
  async _exploreDir(path2, depth) {
82760
82760
  let files;
82761
82761
  try {
82762
- files = await readdir5(path2, this._rdOptions);
82762
+ files = await readdir6(path2, this._rdOptions);
82763
82763
  } catch (error3) {
82764
82764
  this._onError(error3);
82765
82765
  }
@@ -143766,6 +143766,7 @@ var stageRoutes = async (kvs, state2) => {
143766
143766
  var createCloudFrontKvsProvider = ({ credentials: credentials2, region }) => {
143767
143767
  const kvs = new CloudFrontKeyValueStoreClient({ credentials: credentials2, region });
143768
143768
  return createCustomProvider("cloudfront-kvs", {
143769
+ "import-keys": {},
143769
143770
  "route-deployment": {
143770
143771
  async createResource(props) {
143771
143772
  return stageRoutes(kvs, routeDeploymentInputSchema.parse(props.state));
@@ -149549,7 +149550,7 @@ var createLambdaProvider = ({ credentials: credentials3, region }) => {
149549
149550
  deploymentId: exports_external.string(),
149550
149551
  functionName: exports_external.string(),
149551
149552
  functionVersion: exports_external.string(),
149552
- onFailureArn: exports_external.string(),
149553
+ onFailureArn: exports_external.string().optional(),
149553
149554
  sourceAccount: exports_external.string().optional()
149554
149555
  });
149555
149556
  const bundleDeploymentStateSchema = bundleDeploymentInputSchema.extend({
@@ -149578,11 +149579,11 @@ var createLambdaProvider = ({ credentials: credentials3, region }) => {
149578
149579
  FunctionName: state2.functionName,
149579
149580
  Qualifier: state2.functionVersion,
149580
149581
  MaximumRetryAttempts: 2,
149581
- DestinationConfig: {
149582
+ DestinationConfig: state2.onFailureArn ? {
149582
149583
  OnFailure: {
149583
149584
  Destination: state2.onFailureArn
149584
149585
  }
149585
- }
149586
+ } : undefined
149586
149587
  }));
149587
149588
  };
149588
149589
  const createDeploymentUrl = async (functionName, alias, sourceAccount) => {
@@ -160729,6 +160730,9 @@ var createWorkSpace = async (props) => {
160729
160730
  createCloudFrontKvsProvider(props),
160730
160731
  createS3Provider(props),
160731
160732
  createNameServersProvider(props),
160733
+ createCustomProvider("cloudfront", {
160734
+ invalidation: {}
160735
+ }),
160732
160736
  aws3({
160733
160737
  accessKey: cred.accessKeyId,
160734
160738
  secretKey: cred.secretAccessKey,
@@ -161495,10 +161499,28 @@ var CodeSchema = exports_external.union([
161495
161499
  })).pipe(FileCodeSchema),
161496
161500
  FileCodeSchema
161497
161501
  ]).describe("Specify the code of your function.");
161498
- var FnSchema = exports_external.object({
161502
+ var BundledFnSchema = exports_external.object({
161499
161503
  code: CodeSchema,
161500
161504
  handler: HandlerSchema.optional()
161501
161505
  }).strict();
161506
+ var BundledFunctionSchema = exports_external.union([
161507
+ LocalFileSchema.transform((code) => ({
161508
+ code
161509
+ })).pipe(BundledFnSchema),
161510
+ BundledFnSchema
161511
+ ]);
161512
+ var FnSchema = BundledFnSchema.extend({
161513
+ timeout: TimeoutSchema.optional(),
161514
+ memorySize: MemorySizeSchema.optional(),
161515
+ architecture: ArchitectureSchema.optional(),
161516
+ vpc: VPCSchema.optional(),
161517
+ log: LogSchema.transform((log) => ({
161518
+ retention: log.retention,
161519
+ format: "format" in log ? log.format : undefined,
161520
+ level: "level" in log ? log.level : undefined,
161521
+ system: "system" in log ? log.system : undefined
161522
+ })).optional()
161523
+ });
161502
161524
  var FunctionSchema = exports_external.union([
161503
161525
  LocalFileSchema.transform((code) => ({
161504
161526
  code
@@ -161543,7 +161565,7 @@ var FunctionDefaultSchema = exports_external.object({
161543
161565
  timeout: TimeoutSchema.default("15 minutes"),
161544
161566
  memorySize: MemorySizeSchema.default("1024 MB"),
161545
161567
  architecture: ArchitectureSchema.default("arm64"),
161546
- vpc: VPCSchema.default(false),
161568
+ vpc: VPCSchema.default(true),
161547
161569
  ephemeralStorageSize: EphemeralStorageSizeSchema.default("512 MB"),
161548
161570
  reserved: ReservedConcurrentExecutionsSchema.optional(),
161549
161571
  layers: LayersSchema.optional(),
@@ -161570,32 +161592,36 @@ var LayerSchema = exports_external.record(exports_external.string(), exports_ext
161570
161592
  Schema
161571
161593
  ])).optional().describe("Define the lambda layers in your stack.");
161572
161594
 
161573
- // src/feature/task/schema.ts
161574
- var TaskSchema = exports_external.union([
161575
- FunctionSchema.transform((consumer) => ({
161595
+ // src/feature/on-error-log/schema.ts
161596
+ var ConsumerSchema = FunctionSchema.transform((consumer) => ({
161597
+ ...consumer,
161598
+ vpc: consumer.vpc ?? false
161599
+ }));
161600
+ var OnErrorLogDefaultSchema = exports_external.union([
161601
+ ConsumerSchema.transform((consumer) => ({
161576
161602
  consumer
161577
161603
  })),
161578
161604
  exports_external.object({
161579
- consumer: FunctionSchema
161605
+ consumer: ConsumerSchema
161580
161606
  })
161581
- ]);
161582
- var TasksSchema = exports_external.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
161583
-
161584
- // src/feature/on-error-log/schema.ts
161585
- var OnErrorLogDefaultSchema = TaskSchema.optional().describe("Define a subscription on all Lambda functions logs.");
161607
+ ]).optional().describe("Define a subscription on all Lambda functions logs.");
161586
161608
 
161587
161609
  // src/feature/on-failure/schema.ts
161588
161610
  var NotifySchema = exports_external.union([
161589
161611
  EmailSchema.transform((v7) => [v7]),
161590
161612
  EmailSchema.array()
161591
161613
  ]).describe("Receive an email notification when consuming failure entries goes wrong.");
161614
+ var ConsumerSchema2 = FunctionSchema.transform((consumer) => ({
161615
+ ...consumer,
161616
+ vpc: consumer.vpc ?? false
161617
+ }));
161592
161618
  var OnFailureDefaultSchema = exports_external.union([
161593
- FunctionSchema.transform((consumer) => ({
161619
+ ConsumerSchema2.transform((consumer) => ({
161594
161620
  consumer,
161595
161621
  notify: []
161596
161622
  })),
161597
161623
  exports_external.object({
161598
- consumer: FunctionSchema,
161624
+ consumer: ConsumerSchema2,
161599
161625
  notify: NotifySchema.optional()
161600
161626
  })
161601
161627
  ]).optional().describe([
@@ -161809,7 +161835,7 @@ var ErrorResponseSchema = exports_external.union([
161809
161835
  })
161810
161836
  ]).optional();
161811
161837
  var RouteSchema = exports_external.string().regex(/^\//, "Route must start with a slash (/)").regex(/^\/([^/*.]+)?$/, 'Router paths mount a single segment without dots, like "/api".');
161812
- var RoutesSchema = exports_external.record(ResourceIdSchema.describe("The router id to add your routes to."), exports_external.record(exports_external.string().regex(/^\//, "Route must start with a slash (/)"), FunctionSchema).superRefine((routes, ctx) => {
161838
+ var RoutesSchema = exports_external.record(ResourceIdSchema.describe("The router id to add your routes to."), exports_external.record(exports_external.string().regex(/^\//, "Route must start with a slash (/)"), BundledFunctionSchema).superRefine((routes, ctx) => {
161813
161839
  for (const pattern of Object.keys(routes)) {
161814
161840
  try {
161815
161841
  compileRoutePattern(pattern);
@@ -161917,7 +161943,7 @@ var RouterDefaultSchema = exports_external.record(ResourceIdSchema, exports_exte
161917
161943
 
161918
161944
  // src/feature/pubsub/schema.ts
161919
161945
  var PubSubDefaultSchema = exports_external.record(ResourceIdSchema, exports_external.object({
161920
- auth: FunctionSchema.describe("The authorizer that validates the client auth token and returns the allowed topics."),
161946
+ auth: BundledFunctionSchema.describe("The authorizer that validates the client auth token and returns the allowed topics."),
161921
161947
  router: ResourceIdSchema.describe("The router id to route pubsub traffic through."),
161922
161948
  path: RouteSchema.default("/ws").describe("The base path on the router that exposes the pubsub endpoint."),
161923
161949
  log: LogSchema2.default(true).transform((log) => ({
@@ -161925,10 +161951,10 @@ var PubSubDefaultSchema = exports_external.record(ResourceIdSchema, exports_exte
161925
161951
  }))
161926
161952
  })).optional().describe("Define the pubsub API for your app. Backed by a websocket server on AWS Fargate.");
161927
161953
  var PubSubSchema = exports_external.record(ResourceIdSchema, exports_external.object({
161928
- connected: FunctionSchema.optional().describe("Subscribe to the event when a client connects."),
161929
- disconnected: FunctionSchema.optional().describe("Subscribe to the event when a client disconnects."),
161930
- subscribed: FunctionSchema.optional().describe("Subscribe to the event when a client subscribes to topics."),
161931
- unsubscribed: FunctionSchema.optional().describe("Subscribe to the event when a client unsubscribes from topics.")
161954
+ connected: BundledFunctionSchema.optional().describe("Subscribe to the event when a client connects."),
161955
+ disconnected: BundledFunctionSchema.optional().describe("Subscribe to the event when a client disconnects."),
161956
+ subscribed: BundledFunctionSchema.optional().describe("Subscribe to the event when a client subscribes to topics."),
161957
+ unsubscribed: BundledFunctionSchema.optional().describe("Subscribe to the event when a client unsubscribes from topics.")
161932
161958
  })).optional().describe("Define the pubsub event listeners in your stack.");
161933
161959
  var pubsubEventTypes = ["connected", "disconnected", "subscribed", "unsubscribed"];
161934
161960
 
@@ -161945,7 +161971,7 @@ var QueueDefaultSchema = exports_external.object({
161945
161971
  batchSize: BatchSizeSchema.default(10)
161946
161972
  }).default({});
161947
161973
  var QueueSchema = exports_external.object({
161948
- consumer: FunctionSchema.optional().describe("The consuming lambda function properties."),
161974
+ consumer: BundledFunctionSchema.optional().describe("The consuming lambda function properties."),
161949
161975
  retentionPeriod: RetentionPeriodSchema.optional(),
161950
161976
  receiveMessageWaitTime: ReceiveMessageWaitTimeSchema.optional(),
161951
161977
  maxMessageSize: MaxMessageSizeSchema.optional(),
@@ -161974,21 +162000,21 @@ var RestSchema = exports_external.record(ResourceIdSchema, exports_external.reco
161974
162000
  "The possible http methods are POST, GET,PUT, DELETE, HEAD, OPTIONS, ANY.",
161975
162001
  "Example: GET /posts/{id}"
161976
162002
  ].join(`
161977
- `)), FunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
162003
+ `)), BundledFunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
161978
162004
 
161979
162005
  // src/feature/rpc/schema.ts
161980
162006
  var RpcDefaultSchema = exports_external.record(ResourceIdSchema, exports_external.object({
161981
162007
  router: ResourceIdSchema.describe("The router id to link your RPC API with."),
161982
162008
  path: RouteSchema.describe("The path inside the router to link your RPC API to."),
161983
- auth: FunctionSchema.optional().describe("The authentication handler for your RPC API.")
162009
+ auth: BundledFunctionSchema.optional().describe("The authentication handler for your RPC API.")
161984
162010
  })).describe(`Define the global RPC API's.`).optional();
161985
162011
  var RpcSchema = exports_external.record(ResourceIdSchema, exports_external.record(exports_external.string(), exports_external.union([
161986
- FunctionSchema.transform((f11) => ({
162012
+ BundledFunctionSchema.transform((f11) => ({
161987
162013
  function: f11,
161988
162014
  lock: false
161989
162015
  })),
161990
162016
  exports_external.object({
161991
- function: FunctionSchema.describe("The RPC function to execute."),
162017
+ function: BundledFunctionSchema.describe("The RPC function to execute."),
161992
162018
  lock: exports_external.boolean().describe([
161993
162019
  "Specify if the function should be locked on the `lockKey` returned from the auth function.",
161994
162020
  "An example would be returning the user ID as `lockKey`."
@@ -162106,6 +162132,17 @@ var JobDefaultSchema = exports_external.object({
162106
162132
  }))
162107
162133
  }).default({});
162108
162134
 
162135
+ // src/feature/task/schema.ts
162136
+ var TaskSchema = exports_external.union([
162137
+ BundledFunctionSchema.transform((consumer) => ({
162138
+ consumer
162139
+ })),
162140
+ exports_external.object({
162141
+ consumer: BundledFunctionSchema
162142
+ })
162143
+ ]);
162144
+ var TasksSchema = exports_external.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
162145
+
162109
162146
  // src/feature/topic/schema.ts
162110
162147
  var TopicNameSchema = exports_external.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => kebabCase(value)).describe("Define event topic name.");
162111
162148
  var TopicsDefaultSchema = exports_external.array(TopicNameSchema).refine((topics) => {
@@ -162251,7 +162288,7 @@ var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
162251
162288
  // src/feature/cron/schema/index.ts
162252
162289
  var CronsSchema = exports_external.record(ResourceIdSchema, exports_external.object({
162253
162290
  enabled: exports_external.boolean().default(true).describe("If the cron is enabled."),
162254
- consumer: FunctionSchema.describe("The consuming lambda function properties."),
162291
+ consumer: BundledFunctionSchema.describe("The consuming lambda function properties."),
162255
162292
  schedule: ScheduleExpressionSchema.describe(`The scheduling expression.
162256
162293
 
162257
162294
  example: "0 20 * * ? *"
@@ -162427,7 +162464,7 @@ var StoresSchema = exports_external.union([
162427
162464
 
162428
162465
  // src/feature/icon/schema.ts
162429
162466
  var staticOriginSchema = LocalDirectorySchema.describe("Specifies the path to a local image directory that will be uploaded in S3.");
162430
- var functionOriginSchema = FunctionSchema.describe("Specifies the file that will be called when an image isn't found in the (cache) bucket.");
162467
+ var functionOriginSchema = BundledFunctionSchema.describe("Specifies the file that will be called when an image isn't found in the (cache) bucket.");
162431
162468
  var IconsSchema = exports_external.record(ResourceIdSchema, exports_external.object({
162432
162469
  router: ResourceIdSchema.describe("The router id to link your icon proxy."),
162433
162470
  path: RouteSchema.describe("The path inside the router to link your icon proxy to."),
@@ -162455,7 +162492,7 @@ var transformationOptionsSchema = exports_external.object({
162455
162492
  quality: exports_external.number().int().min(1).max(100).optional()
162456
162493
  });
162457
162494
  var staticOriginSchema2 = LocalDirectorySchema.describe("Specifies the path to a local image directory that will be uploaded in S3.");
162458
- var functionOriginSchema2 = FunctionSchema.describe("Specifies the file that will be called when an image isn't found in the (cache) bucket.");
162495
+ var functionOriginSchema2 = BundledFunctionSchema.describe("Specifies the file that will be called when an image isn't found in the (cache) bucket.");
162459
162496
  var ImagesSchema = exports_external.record(ResourceIdSchema, exports_external.object({
162460
162497
  router: ResourceIdSchema.describe("The router id to link your image proxy."),
162461
162498
  path: RouteSchema.describe("The path inside the router to link your image proxy to."),
@@ -162525,7 +162562,7 @@ var AlarmSchema = exports_external.object({
162525
162562
  where: WhereSchema,
162526
162563
  period: DurationSchema,
162527
162564
  minDataPoints: exports_external.number().int().default(1),
162528
- trigger: exports_external.union([EmailSchema.transform((v7) => [v7]), EmailSchema.array(), FunctionSchema])
162565
+ trigger: exports_external.union([EmailSchema.transform((v7) => [v7]), EmailSchema.array(), BundledFunctionSchema])
162529
162566
  });
162530
162567
  var MetricsSchema = exports_external.record(ResourceIdSchema, exports_external.object({
162531
162568
  type: exports_external.enum(["number", "size", "duration"]),
@@ -162580,7 +162617,7 @@ var TablesSchema = exports_external.record(ResourceIdSchema, exports_external.ob
162580
162617
  "You can specify a number from 1 to 10."
162581
162618
  ].join(`
162582
162619
  `)),
162583
- consumer: FunctionSchema.describe("The consuming lambda function for the stream")
162620
+ consumer: BundledFunctionSchema.describe("The consuming lambda function for the stream")
162584
162621
  }).optional().describe("The settings for the DynamoDB table stream, which capture changes to items stored in the table."),
162585
162622
  indexes: exports_external.record(exports_external.string(), exports_external.object({
162586
162623
  hash: exports_external.union([KeySchema.transform((v7) => [v7]), KeySchema.array()]).describe("Specifies the name of the partition / hash key that makes up the primary key for the global secondary index."),
@@ -163782,8 +163819,21 @@ var shortId = (ns) => {
163782
163819
  return createHash10("md5").update(ns).digest("hex").substring(0, 10);
163783
163820
  };
163784
163821
 
163822
+ // src/feature/on-error-log/util.ts
163823
+ var filterPattern = `{${[
163824
+ `$.level = "WARN"`,
163825
+ `$.level = "ERROR"`,
163826
+ `$.level = "FATAL"`,
163827
+ `($.type = "platform.report" && $.record.status = "timeout")`,
163828
+ `($.type = "platform.report" && $.record.status = "error")`,
163829
+ `($.type = "platform.report" && $.record.status = "failure")`
163830
+ ].join(" || ")}}`;
163831
+
163785
163832
  // src/feature/on-failure/util.ts
163786
163833
  var getGlobalOnFailure = (ctx) => {
163834
+ if (!ctx.shared.has("on-failure", "bucket-arn")) {
163835
+ return;
163836
+ }
163787
163837
  return ctx.shared.get("on-failure", "bucket-arn");
163788
163838
  };
163789
163839
 
@@ -164241,14 +164291,6 @@ var bundleTypeScriptWithRolldown = async (props) => {
164241
164291
  }
164242
164292
  const routeKey = decodeURIComponent(encodedRouteKey);
164243
164293
  return `${routeKey.replaceAll(":", "--")}.${extension}`;
164244
- },
164245
- codeSplitting: {
164246
- groups: [
164247
- {
164248
- name: "shared",
164249
- minShareCount: 2
164250
- }
164251
- ]
164252
164294
  }
164253
164295
  });
164254
164296
  const hash2 = createHash11("sha1");
@@ -164533,12 +164575,7 @@ var bundleFeature = defineFeature({
164533
164575
  },
164534
164576
  s3Bucket: code.bucket,
164535
164577
  s3ObjectVersion: code.versionId,
164536
- s3Key: code.key.pipe((name2) => {
164537
- if (name2.startsWith("/")) {
164538
- return name2.substring(1);
164539
- }
164540
- return name2;
164541
- }),
164578
+ s3Key: code.key,
164542
164579
  sourceCodeHash: sourceHash,
164543
164580
  environment: {
164544
164581
  variables: {
@@ -164584,27 +164621,29 @@ var bundleFeature = defineFeature({
164584
164621
  }, {
164585
164622
  dependsOn: [policy]
164586
164623
  });
164587
- new aws3.lambda.FunctionEventInvokeConfig(group4, "async", {
164588
- functionName: lambda.functionName,
164589
- qualifier: alias.name,
164590
- maximumRetryAttempts: 2,
164591
- destinationConfig: {
164592
- onFailure: {
164593
- destination: onFailure
164624
+ if (onFailure) {
164625
+ new aws3.lambda.FunctionEventInvokeConfig(group4, "async", {
164626
+ functionName: lambda.functionName,
164627
+ qualifier: alias.name,
164628
+ maximumRetryAttempts: 2,
164629
+ destinationConfig: {
164630
+ onFailure: {
164631
+ destination: onFailure
164632
+ }
164594
164633
  }
164595
- }
164596
- }, {
164597
- dependsOn: [policy]
164598
- });
164599
- addPermission({
164600
- actions: ["s3:PutObject", "s3:ListBucket"],
164601
- resources: [onFailure, $interpolate`${onFailure}/*`],
164602
- conditions: {
164603
- StringEquals: {
164604
- "s3:ResourceAccount": ctx.accountId
164634
+ }, {
164635
+ dependsOn: [policy]
164636
+ });
164637
+ addPermission({
164638
+ actions: ["s3:PutObject", "s3:ListBucket"],
164639
+ resources: [onFailure, $interpolate`${onFailure}/*`],
164640
+ conditions: {
164641
+ StringEquals: {
164642
+ "s3:ResourceAccount": ctx.accountId
164643
+ }
164605
164644
  }
164606
- }
164607
- });
164645
+ });
164646
+ }
164608
164647
  let logGroup;
164609
164648
  if (defaults2.log.retention.value > 0n) {
164610
164649
  logGroup = new aws3.cloudwatch.LogGroup(group4, "log", {
@@ -164615,6 +164654,17 @@ var bundleFeature = defineFeature({
164615
164654
  actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
164616
164655
  resources: [logGroup.arn.pipe((arn) => `${arn}:*`)]
164617
164656
  });
164657
+ if (ctx.shared.has("on-error-log", "subscriber-arn")) {
164658
+ new aws3.cloudwatch.LogSubscriptionFilter(group4, "on-error-log", {
164659
+ name: "error-log-subscription",
164660
+ destinationArn: ctx.shared.get("on-error-log", "subscriber-arn"),
164661
+ logGroupName: logGroup.name,
164662
+ filterPattern
164663
+ }, {
164664
+ replaceOnChanges: ["destinationArn"],
164665
+ dependsOn: [ctx.shared.get("on-error-log", "permission")]
164666
+ });
164667
+ }
164618
164668
  }
164619
164669
  for (const [name2, value] of Object.entries(defaults2.environment ?? {})) {
164620
164670
  addEnv(name2, value);
@@ -172728,9 +172778,12 @@ var configFeature = defineFeature({
172728
172778
  `arn:aws:ssm:${ctx.appConfig.region}:${ctx.accountId}:parameter${configParameterPrefix(ctx.app.name)}/*`
172729
172779
  ]
172730
172780
  });
172731
- for (const name of ctx.appConfig.configs ?? []) {
172781
+ const names = ctx.appConfig.configs ?? [];
172782
+ for (const name of names) {
172732
172783
  ctx.registerConfig(name);
172733
- ctx.addEnv(`CONFIG_${constantCase(name)}`, name);
172784
+ }
172785
+ if (names.length > 0) {
172786
+ ctx.addEnv("CONFIGS", names.join(","));
172734
172787
  }
172735
172788
  }
172736
172789
  });
@@ -173050,20 +173103,9 @@ import { days as days8, seconds as seconds4, toDays as toDays6, toSeconds as toS
173050
173103
  import { generateFileHash as generateFileHash2 } from "@awsless/ts-file-cache";
173051
173104
  var import_deepmerge = __toESM(require_cjs2(), 1);
173052
173105
  import { createHash as createHash16 } from "crypto";
173106
+ import { readdir as readdir4, readFile as readFile16, rm as rm7, writeFile as writeFile10 } from "fs/promises";
173053
173107
  import { dirname as dirname8, join as join23 } from "path";
173054
173108
  import { fileURLToPath as fileURLToPath4 } from "url";
173055
-
173056
- // src/feature/on-error-log/util.ts
173057
- var filterPattern = `{${[
173058
- `$.level = "WARN"`,
173059
- `$.level = "ERROR"`,
173060
- `$.level = "FATAL"`,
173061
- `($.type = "platform.report" && $.record.status = "timeout")`,
173062
- `($.type = "platform.report" && $.record.status = "error")`,
173063
- `($.type = "platform.report" && $.record.status = "failure")`
173064
- ].join(" || ")}}`;
173065
-
173066
- // src/feature/function/util.ts
173067
173109
  var standaloneFields = [
173068
173110
  "runtime",
173069
173111
  "description",
@@ -173081,6 +173123,88 @@ var standaloneFields = [
173081
173123
  var isStandaloneFunction = (props) => {
173082
173124
  return standaloneFields.some((field) => typeof props[field] !== "undefined");
173083
173125
  };
173126
+ var registerFunctionBuild = (ctx, name, props) => {
173127
+ const exportName = parseExportName(props.handler ?? ctx.appConfig.defaults.function.handler);
173128
+ ctx.registerBuild("function", name, async (build2, { workspace }) => {
173129
+ const fingerprint = createHash16("sha1").update(await generateFileHash2(workspace, props.code.file)).update(props.wrapper ? await readFile16(props.wrapper) : "").update(JSON.stringify([
173130
+ exportName,
173131
+ props.code.minify,
173132
+ props.code.external,
173133
+ props.code.importAsString,
173134
+ props.code.moduleSideEffects,
173135
+ props.external
173136
+ ])).digest("hex");
173137
+ return build2(fingerprint, async (write) => {
173138
+ const handlerImport = `const { ${exportName === "default" ? "default: handler" : `${exportName}: handler`} } = await import(${JSON.stringify(props.code.file)})`;
173139
+ const entry = `import env from './awsless-env.mjs'
173140
+
173141
+ for (const name in env) {
173142
+ process.env[name] ??= env[name]
173143
+ }
173144
+
173145
+ ${props.wrapper ? `const { createHandler } = await import(${JSON.stringify(props.wrapper)})
173146
+ ${handlerImport}
173147
+
173148
+ export default createHandler(handler)` : `${handlerImport}
173149
+
173150
+ export default handler`}
173151
+ `;
173152
+ const temp = await createTempFolder(name);
173153
+ const entryFile = join23(temp.path, "entry.ts");
173154
+ await writeFile10(entryFile, entry);
173155
+ const result = await bundleTypeScriptWithRolldown({
173156
+ file: entryFile,
173157
+ minify: props.code.minify,
173158
+ external: [
173159
+ "./awsless-env.mjs",
173160
+ ...props.code.external ?? [],
173161
+ ...props.external ?? []
173162
+ ],
173163
+ moduleSideEffects: props.code.moduleSideEffects,
173164
+ importAsString: props.code.importAsString
173165
+ });
173166
+ await temp.delete();
173167
+ await rm7(getBuildPath("function", name, "files"), { recursive: true, force: true });
173168
+ await Promise.all([
173169
+ write("HASH", result.hash),
173170
+ ...result.files.map((file2) => write(`files/${file2.name}`, file2.code)),
173171
+ ...result.files.map((file2) => file2.map && write(`files/${file2.name}.map`, file2.map))
173172
+ ]);
173173
+ return {
173174
+ size: formatByteSize(result.files.reduce((total, file2) => total + file2.code.byteLength, 0))
173175
+ };
173176
+ });
173177
+ });
173178
+ const env5 = {};
173179
+ const envDeps = new Set;
173180
+ const addEnv = (name2, value) => {
173181
+ env5[name2] = value;
173182
+ for (const dep of findInputDeps(value)) {
173183
+ envDeps.add(dep);
173184
+ }
173185
+ };
173186
+ const zipFile = getBuildPath("function", name, "bundle.zip");
173187
+ const sourceHash = new Output(envDeps, async (resolve3) => {
173188
+ const buildHash = await readFile16(getBuildPath("function", name, "HASH"), "utf8");
173189
+ const vars = await resolveInputs(env5);
173190
+ const sorted = Object.fromEntries(Object.entries(vars).sort(([a15], [b17]) => a15.localeCompare(b17)));
173191
+ const envFile = `export default ${JSON.stringify(sorted, undefined, "\t")}
173192
+ `;
173193
+ const dir = getBuildPath("function", name, "files");
173194
+ const files = await readdir4(dir);
173195
+ const archive = await zipFiles([
173196
+ ...files.filter((file2) => !file2.endsWith(".map")).map((file2) => ({ name: file2, path: join23(dir, file2) })),
173197
+ { name: "awsless-env.mjs", code: Buffer.from(envFile, "utf8") }
173198
+ ]);
173199
+ await writeFile10(zipFile, archive);
173200
+ resolve3(createHash16("sha1").update(buildHash).update(envFile).digest("hex"));
173201
+ });
173202
+ return {
173203
+ zipFile,
173204
+ sourceHash,
173205
+ addEnv
173206
+ };
173207
+ };
173084
173208
  var createLambdaFunction = (ctx, id, local) => {
173085
173209
  const group4 = new Group(ctx.stack, "function", id);
173086
173210
  const props = import_deepmerge.default(ctx.appConfig.defaults.function, local);
@@ -173099,43 +173223,16 @@ var createLambdaFunction = (ctx, id, local) => {
173099
173223
  resourceName: id
173100
173224
  });
173101
173225
  const roleName = shortId(`${ctx.app.name}:${ctx.stack.name}:function:${id}:${ctx.appId}`);
173102
- const fileCode = local.code;
173103
- ctx.registerBuild("function", name, async (build2, { workspace }) => {
173104
- const fingerprint = createHash16("sha1").update(await generateFileHash2(workspace, fileCode.file)).update(JSON.stringify([
173105
- fileCode.minify,
173106
- fileCode.external,
173107
- fileCode.importAsString,
173108
- fileCode.moduleSideEffects
173109
- ])).digest("hex");
173110
- return build2(fingerprint, async (write) => {
173111
- const bundle = await bundleTypeScriptWithRolldown({
173112
- file: fileCode.file,
173113
- minify: fileCode.minify,
173114
- external: [
173115
- ...fileCode.external ?? [],
173116
- ...(props.layers ?? []).flatMap((layerId) => ctx.shared.entry("layer", "packages", layerId))
173117
- ],
173118
- moduleSideEffects: fileCode.moduleSideEffects,
173119
- importAsString: fileCode.importAsString
173120
- });
173121
- const archive = await zipFiles(bundle.files);
173122
- await Promise.all([
173123
- write("HASH", bundle.hash),
173124
- write("bundle.zip", archive),
173125
- ...bundle.files.map((file2) => write(`files/${file2.name}`, file2.code)),
173126
- ...bundle.files.map((file2) => file2.map && write(`files/${file2.name}.map`, file2.map))
173127
- ]);
173128
- return {
173129
- size: formatByteSize(archive.byteLength)
173130
- };
173131
- });
173226
+ const build2 = registerFunctionBuild(ctx, name, {
173227
+ code: local.code,
173228
+ handler: props.handler,
173229
+ external: (props.layers ?? []).flatMap((layerId) => ctx.shared.entry("layer", "packages", layerId))
173132
173230
  });
173133
- const sourceHash = $file(getBuildPath("function", name, "HASH"));
173134
173231
  const code = new aws3.s3.BucketObject(group4, "code", {
173135
173232
  bucket: ctx.shared.get("asset", "bucket").name,
173136
173233
  key: `lambda/${name}.zip`,
173137
- source: relativePath(getBuildPath("function", name, "bundle.zip")),
173138
- sourceHash
173234
+ source: relativePath(build2.zipFile),
173235
+ sourceHash: build2.sourceHash
173139
173236
  }, {
173140
173237
  replaceOnChanges: ["bucket", "key"]
173141
173238
  });
@@ -173164,11 +173261,11 @@ var createLambdaFunction = (ctx, id, local) => {
173164
173261
  }
173165
173262
  };
173166
173263
  const sandboxed = typeof local.sandbox !== "undefined" && local.sandbox !== false;
173167
- addPermission(...(sandboxed ? local.permissions : props.permissions) ?? []);
173168
- if (!sandboxed) {
173169
- ctx.onPermission((statement) => {
173170
- addPermission(statement);
173171
- });
173264
+ if (sandboxed) {
173265
+ addPermission(...local.permissions ?? []);
173266
+ } else {
173267
+ addPermission(...props.permissions ?? []);
173268
+ ctx.onPermission(addPermission);
173172
173269
  }
173173
173270
  const policy = new aws3.iam.RolePolicy(group4, "policy", {
173174
173271
  role: role.name,
@@ -173220,7 +173317,7 @@ var createLambdaFunction = (ctx, id, local) => {
173220
173317
  description: props.description ?? name,
173221
173318
  role: role.arn,
173222
173319
  runtime: props.runtime,
173223
- handler: props.handler,
173320
+ handler: "index.default",
173224
173321
  timeout: toSeconds4(props.timeout),
173225
173322
  memorySize: toMebibytes(props.memorySize),
173226
173323
  architectures: [props.architecture],
@@ -173236,13 +173333,8 @@ var createLambdaFunction = (ctx, id, local) => {
173236
173333
  },
173237
173334
  s3Bucket: code.bucket,
173238
173335
  s3ObjectVersion: code.versionId,
173239
- s3Key: code.key.pipe((name2) => {
173240
- if (name2.startsWith("/")) {
173241
- return name2.substring(1);
173242
- }
173243
- return name2;
173244
- }),
173245
- sourceCodeHash: sourceHash,
173336
+ s3Key: code.key,
173337
+ sourceCodeHash: build2.sourceHash,
173246
173338
  environment: {
173247
173339
  variables
173248
173340
  },
@@ -173260,7 +173352,30 @@ var createLambdaFunction = (ctx, id, local) => {
173260
173352
  }, {
173261
173353
  dependsOn
173262
173354
  });
173263
- ctx.addFunction(lambda);
173355
+ ctx.restartOnConfigChange(lambda);
173356
+ const onFailure = getGlobalOnFailure(ctx);
173357
+ if (onFailure) {
173358
+ new aws3.lambda.FunctionEventInvokeConfig(group4, "async", {
173359
+ functionName: lambda.functionName,
173360
+ maximumRetryAttempts: 2,
173361
+ destinationConfig: {
173362
+ onFailure: {
173363
+ destination: onFailure
173364
+ }
173365
+ }
173366
+ }, {
173367
+ dependsOn: [policy]
173368
+ });
173369
+ addPermission({
173370
+ actions: ["s3:PutObject", "s3:ListBucket"],
173371
+ resources: [onFailure, $interpolate`${onFailure}/*`],
173372
+ conditions: {
173373
+ StringEquals: {
173374
+ "s3:ResourceAccount": ctx.accountId
173375
+ }
173376
+ }
173377
+ });
173378
+ }
173264
173379
  variables.APP = ctx.appConfig.name;
173265
173380
  variables.APP_ID = ctx.appId;
173266
173381
  variables.AWS_ACCOUNT_ID = ctx.accountId;
@@ -173279,12 +173394,8 @@ var createLambdaFunction = (ctx, id, local) => {
173279
173394
  variables[key] = value;
173280
173395
  }
173281
173396
  if (!sandboxed) {
173282
- ctx.onEnv((name2, value) => {
173283
- variables[name2] = value;
173284
- });
173285
- ctx.onBind((name2, value) => {
173286
- variables[name2] = value;
173287
- });
173397
+ ctx.onEnv(build2.addEnv);
173398
+ ctx.onBind(build2.addEnv);
173288
173399
  }
173289
173400
  if (typeof local.sandbox === "object") {
173290
173401
  const routes = [
@@ -173300,9 +173411,9 @@ var createLambdaFunction = (ctx, id, local) => {
173300
173411
  if (routes.length > 0) {
173301
173412
  const bundle = ctx.shared.get("bundle", "main");
173302
173413
  const distDir = dirname8(fileURLToPath4(import.meta.url));
173303
- const proxy = createPrebuildLambdaFunction(group4, ctx, "function", `${id}-proxy`, {
173304
- bundleFile: join23(distDir, "/prebuild/sandbox-proxy/bundle.zip"),
173305
- bundleHash: join23(distDir, "/prebuild/sandbox-proxy/HASH"),
173414
+ const proxy = createLambdaFunctionFromZip(group4, ctx, "function", `${id}-proxy`, {
173415
+ zipFile: join23(distDir, "/prebuild/sandbox-proxy/bundle.zip"),
173416
+ sourceHash: $file(join23(distDir, "/prebuild/sandbox-proxy/HASH")),
173306
173417
  runtime: "nodejs24.x",
173307
173418
  handler: "index.default",
173308
173419
  timeout: ctx.appConfig.defaults.function.timeout,
@@ -173326,9 +173437,7 @@ var createLambdaFunction = (ctx, id, local) => {
173326
173437
  }
173327
173438
  const configs = local.sandbox.configs ?? [];
173328
173439
  if (configs.length > 0) {
173329
- for (const configName of configs) {
173330
- variables[`CONFIG_${constantCase(configName)}`] = configName;
173331
- }
173440
+ variables.CONFIGS = configs.join(",");
173332
173441
  addPermission({
173333
173442
  actions: [
173334
173443
  "ssm:GetParameter",
@@ -173358,6 +173467,7 @@ var createLambdaFunction = (ctx, id, local) => {
173358
173467
  logGroupName: logGroup.name,
173359
173468
  filterPattern
173360
173469
  }, {
173470
+ replaceOnChanges: ["destinationArn"],
173361
173471
  dependsOn: [ctx.shared.get("on-error-log", "permission")]
173362
173472
  });
173363
173473
  }
@@ -173376,7 +173486,7 @@ var createLambdaFunction = (ctx, id, local) => {
173376
173486
  }
173377
173487
  };
173378
173488
  };
173379
- var createPrebuildLambdaFunction = (parentGroup, ctx, ns, id, props) => {
173489
+ var createLambdaFunctionFromZip = (parentGroup, ctx, ns, id, props) => {
173380
173490
  let name;
173381
173491
  let roleName;
173382
173492
  const group4 = new Group(parentGroup, "function", id);
@@ -173407,12 +173517,11 @@ var createPrebuildLambdaFunction = (parentGroup, ctx, ns, id, props) => {
173407
173517
  postfix: ctx.appId
173408
173518
  });
173409
173519
  }
173410
- const sourceHash = $file(props.bundleHash);
173411
173520
  const code = new aws3.s3.BucketObject(group4, "code", {
173412
173521
  bucket: ctx.shared.get("asset", "bucket").name,
173413
173522
  key: `lambda/${name}.zip`,
173414
- source: relativePath(props.bundleFile),
173415
- sourceHash
173523
+ source: relativePath(props.zipFile),
173524
+ sourceHash: props.sourceHash
173416
173525
  }, {
173417
173526
  replaceOnChanges: ["bucket", "key"]
173418
173527
  });
@@ -173501,13 +173610,8 @@ var createPrebuildLambdaFunction = (parentGroup, ctx, ns, id, props) => {
173501
173610
  },
173502
173611
  s3Bucket: code.bucket,
173503
173612
  s3ObjectVersion: code.versionId,
173504
- s3Key: code.key.pipe((name2) => {
173505
- if (name2.startsWith("/")) {
173506
- return name2.substring(1);
173507
- }
173508
- return name2;
173509
- }),
173510
- sourceCodeHash: sourceHash,
173613
+ s3Key: code.key,
173614
+ sourceCodeHash: props.sourceHash,
173511
173615
  environment: {
173512
173616
  variables
173513
173617
  },
@@ -173525,11 +173629,35 @@ var createPrebuildLambdaFunction = (parentGroup, ctx, ns, id, props) => {
173525
173629
  }, {
173526
173630
  dependsOn
173527
173631
  });
173632
+ const onFailure = getGlobalOnFailure(ctx);
173633
+ if (onFailure) {
173634
+ new aws3.lambda.FunctionEventInvokeConfig(group4, "async", {
173635
+ functionName: lambda.functionName,
173636
+ maximumRetryAttempts: 2,
173637
+ destinationConfig: {
173638
+ onFailure: {
173639
+ destination: onFailure
173640
+ }
173641
+ }
173642
+ }, {
173643
+ dependsOn: [policy]
173644
+ });
173645
+ addPermission({
173646
+ actions: ["s3:PutObject", "s3:ListBucket"],
173647
+ resources: [onFailure, $interpolate`${onFailure}/*`],
173648
+ conditions: {
173649
+ StringEquals: {
173650
+ "s3:ResourceAccount": ctx.accountId
173651
+ }
173652
+ }
173653
+ });
173654
+ }
173528
173655
  variables.APP = ctx.appConfig.name;
173529
173656
  variables.APP_ID = ctx.appId;
173530
173657
  variables.AWS_ACCOUNT_ID = ctx.accountId;
173531
173658
  variables.REGION = ctx.appConfig.region;
173532
173659
  variables.STAGE = ctx.appConfig.stage ?? "default";
173660
+ variables.STANDALONE = "true";
173533
173661
  if ("stackConfig" in ctx) {
173534
173662
  variables.STACK = ctx.stackConfig.name;
173535
173663
  }
@@ -173553,6 +173681,7 @@ var createPrebuildLambdaFunction = (parentGroup, ctx, ns, id, props) => {
173553
173681
  logGroupName: logGroup.name,
173554
173682
  filterPattern
173555
173683
  }, {
173684
+ replaceOnChanges: ["destinationArn"],
173556
173685
  dependsOn: [ctx.shared.get("on-error-log", "permission")]
173557
173686
  });
173558
173687
  }
@@ -173670,7 +173799,7 @@ var functionFeature = defineFeature({
173670
173799
  });
173671
173800
 
173672
173801
  // src/feature/on-error-log/index.ts
173673
- import { formatRouteEnvName as formatRouteEnvName2 } from "awsless";
173802
+ import { days as days9 } from "@awsless/duration";
173674
173803
  import { dirname as dirname9, join as join24 } from "path";
173675
173804
  import { fileURLToPath as fileURLToPath5 } from "url";
173676
173805
  var onErrorLogFeature = defineFeature({
@@ -173681,73 +173810,61 @@ var onErrorLogFeature = defineFeature({
173681
173810
  return;
173682
173811
  }
173683
173812
  const group4 = new Group(ctx.base, "on-error-log", "main");
173684
- const bundle = ctx.shared.get("bundle", "main");
173685
173813
  const consumer = props.consumer;
173686
- const handlerRoute = formatRouteKey("base", "on-error-log", "handler");
173687
- const consumerRoute = formatRouteKey("base", "on-error-log", "consumer");
173688
- bundle.addHandler({
173689
- routeKey: handlerRoute,
173690
- file: join24(dirname9(fileURLToPath5(import.meta.url)), "/handlers/on-error-log.js"),
173691
- exportName: "default"
173692
- });
173693
- bundle.addEnv(formatRouteEnvName2(handlerRoute, "CONSUMER"), consumerRoute);
173694
- const requestTable = new aws3.dynamodb.Table(group4, "requests", {
173695
- name: formatGlobalResourceName({
173696
- appName: ctx.app.name,
173697
- resourceType: "on-error-log",
173698
- resourceName: "requests"
173699
- }),
173700
- hashKey: "id",
173701
- billingMode: "PAY_PER_REQUEST",
173702
- ttl: {
173703
- enabled: true,
173704
- attributeName: "ttl"
173705
- },
173706
- attribute: [
173707
- {
173708
- name: "id",
173709
- type: "S"
173710
- }
173711
- ]
173814
+ const name = formatGlobalResourceName({
173815
+ appName: ctx.app.name,
173816
+ resourceType: "on-error-log",
173817
+ resourceName: "handler"
173818
+ });
173819
+ const build2 = registerFunctionBuild(ctx, name, {
173820
+ code: consumer.code,
173821
+ handler: consumer.handler,
173822
+ wrapper: join24(dirname9(fileURLToPath5(import.meta.url)), "/handlers/on-error-log.js")
173712
173823
  });
173713
- bundle.addEnv(formatRouteEnvName2(handlerRoute, "TABLE"), requestTable.name);
173714
- bundle.addPermission({
173715
- effect: "allow",
173716
- actions: ["dynamodb:PutItem", "dynamodb:GetItem"],
173717
- resources: [requestTable.arn]
173824
+ const handler = createLambdaFunctionFromZip(group4, ctx, "on-error-log", "handler", {
173825
+ zipFile: build2.zipFile,
173826
+ sourceHash: build2.sourceHash,
173827
+ runtime: "nodejs24.x",
173828
+ handler: "index.default",
173829
+ memorySize: consumer.memorySize ?? ctx.appConfig.defaults.function.memorySize,
173830
+ timeout: consumer.timeout ?? ctx.appConfig.defaults.function.timeout,
173831
+ architecture: consumer.architecture ?? ctx.appConfig.defaults.function.architecture,
173832
+ vpc: consumer.vpc,
173833
+ log: {
173834
+ format: consumer.log?.format ?? "json",
173835
+ level: consumer.log?.level ?? "warn",
173836
+ system: consumer.log?.system ?? "warn",
173837
+ retention: consumer.log?.retention ?? days9(3)
173838
+ }
173718
173839
  });
173719
- registerBundleFunction(ctx, consumerRoute, consumer);
173840
+ ctx.onEnv(build2.addEnv);
173841
+ ctx.onBind(build2.addEnv);
173842
+ ctx.onPermission((statement) => handler.addPermission(statement));
173843
+ ctx.restartOnConfigChange(handler.lambda);
173720
173844
  const permission = new aws3.lambda.Permission(group4, "permission", {
173721
173845
  action: "lambda:InvokeFunction",
173722
173846
  principal: "logs.amazonaws.com",
173723
- functionName: bundle.lambda.functionName,
173724
- qualifier: bundle.alias.name,
173847
+ functionName: handler.lambda.functionName,
173725
173848
  sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/*/${ctx.app.name}--*`
173726
173849
  }, {
173727
- replaceOnChanges: ["functionName", "qualifier"]
173850
+ replaceOnChanges: ["functionName"]
173728
173851
  });
173729
- if (bundle.logGroup) {
173730
- new aws3.cloudwatch.LogSubscriptionFilter(group4, "bundle", {
173731
- name: "error-log-subscription",
173732
- destinationArn: bundle.alias.arn,
173733
- logGroupName: bundle.logGroup.name,
173734
- filterPattern
173735
- }, {
173736
- dependsOn: [permission]
173737
- });
173738
- }
173739
- ctx.shared.set("on-error-log", "subscriber-arn", bundle.alias.arn);
173852
+ ctx.shared.set("on-error-log", "subscriber-arn", handler.lambda.arn);
173740
173853
  ctx.shared.set("on-error-log", "permission", permission);
173741
173854
  }
173742
173855
  });
173743
173856
 
173744
173857
  // src/feature/on-failure/index.ts
173745
- import { days as days9, toSeconds as toSeconds5 } from "@awsless/duration";
173858
+ import { days as days10, toSeconds as toSeconds5 } from "@awsless/duration";
173746
173859
  import { dirname as dirname10, join as join25 } from "path";
173747
173860
  import { fileURLToPath as fileURLToPath6 } from "url";
173748
173861
  var onFailureFeature = defineFeature({
173749
173862
  name: "on-failure",
173750
173863
  onBefore(ctx) {
173864
+ const props = ctx.appConfig.defaults.onFailure;
173865
+ if (!props) {
173866
+ return;
173867
+ }
173751
173868
  const group4 = new Group(ctx.base, "on-failure", "main");
173752
173869
  const deadletter = new aws3.sqs.Queue(group4, "deadletter", {
173753
173870
  name: formatGlobalResourceName({
@@ -173755,16 +173872,16 @@ var onFailureFeature = defineFeature({
173755
173872
  resourceType: "on-failure",
173756
173873
  resourceName: "deadletter"
173757
173874
  }),
173758
- messageRetentionSeconds: toSeconds5(days9(14))
173875
+ messageRetentionSeconds: toSeconds5(days10(14))
173759
173876
  });
173760
- const bundleTimeout = toSeconds5(ctx.appConfig.defaults.function.timeout);
173877
+ const handlerTimeout = toSeconds5(props.consumer.timeout ?? ctx.appConfig.defaults.function.timeout);
173761
173878
  const queue2 = new aws3.sqs.Queue(group4, "on-failure", {
173762
173879
  name: formatGlobalResourceName({
173763
173880
  appName: ctx.app.name,
173764
173881
  resourceType: "on-failure",
173765
173882
  resourceName: "failure"
173766
173883
  }),
173767
- visibilityTimeoutSeconds: bundleTimeout * 6,
173884
+ visibilityTimeoutSeconds: handlerTimeout * 2,
173768
173885
  redrivePolicy: deadletter.arn.pipe((deadLetterTargetArn) => {
173769
173886
  return JSON.stringify({
173770
173887
  deadLetterTargetArn,
@@ -173789,13 +173906,12 @@ var onFailureFeature = defineFeature({
173789
173906
  }
173790
173907
  ]
173791
173908
  });
173792
- ctx.shared.set("on-failure", "bucket-arn", bucket.arn);
173793
173909
  ctx.shared.set("on-failure", "resources", {
173794
173910
  group: group4,
173795
173911
  bucket,
173796
173912
  queue: queue2
173797
173913
  });
173798
- const notify = ctx.appConfig.defaults.onFailure?.notify;
173914
+ const notify = props.notify;
173799
173915
  if (notify) {
173800
173916
  const topic = new aws3.sns.Topic(group4, "deadletter-topic", {
173801
173917
  name: formatGlobalResourceName({
@@ -173889,28 +174005,39 @@ var onFailureFeature = defineFeature({
173889
174005
  if (!props) {
173890
174006
  return;
173891
174007
  }
173892
- const bundle = ctx.shared.get("bundle", "main");
173893
174008
  const { group: group4, bucket, queue: queue2 } = ctx.shared.get("on-failure", "resources");
173894
- registerBundleFunction(ctx, formatRouteKey("base", "on-failure", "consumer"), props.consumer);
173895
- const distDir = dirname10(fileURLToPath6(import.meta.url));
173896
- const handler = createPrebuildLambdaFunction(group4, ctx, "on-failure", "handler", {
173897
- bundleFile: join25(distDir, "/prebuild/on-failure/bundle.zip"),
173898
- bundleHash: join25(distDir, "/prebuild/on-failure/HASH"),
174009
+ const name = formatGlobalResourceName({
174010
+ appName: ctx.app.name,
174011
+ resourceType: "on-failure",
174012
+ resourceName: "handler"
174013
+ });
174014
+ const consumer = props.consumer;
174015
+ const build2 = registerFunctionBuild(ctx, name, {
174016
+ code: consumer.code,
174017
+ handler: consumer.handler,
174018
+ wrapper: join25(dirname10(fileURLToPath6(import.meta.url)), "/handlers/on-failure.js")
174019
+ });
174020
+ const handler = createLambdaFunctionFromZip(group4, ctx, "on-failure", "handler", {
174021
+ zipFile: build2.zipFile,
174022
+ sourceHash: build2.sourceHash,
173899
174023
  runtime: "nodejs24.x",
173900
174024
  handler: "index.default",
173901
- memorySize: mebibytes(256),
173902
- timeout: ctx.appConfig.defaults.function.timeout,
174025
+ memorySize: consumer.memorySize ?? ctx.appConfig.defaults.function.memorySize,
174026
+ timeout: consumer.timeout ?? ctx.appConfig.defaults.function.timeout,
174027
+ architecture: consumer.architecture ?? ctx.appConfig.defaults.function.architecture,
174028
+ vpc: consumer.vpc,
173903
174029
  log: {
173904
- format: "json",
173905
- level: "warn",
173906
- system: "warn",
173907
- retention: days9(3)
174030
+ format: consumer.log?.format ?? "json",
174031
+ level: consumer.log?.level ?? "warn",
174032
+ system: consumer.log?.system ?? "warn",
174033
+ retention: consumer.log?.retention ?? days10(3)
173908
174034
  }
173909
174035
  });
174036
+ ctx.onEnv(build2.addEnv);
174037
+ ctx.onBind(build2.addEnv);
174038
+ ctx.onPermission((statement) => handler.addPermission(statement));
174039
+ ctx.restartOnConfigChange(handler.lambda);
173910
174040
  handler.addPermission({
173911
- actions: ["lambda:InvokeFunction"],
173912
- resources: [bundle.alias.arn]
173913
- }, {
173914
174041
  actions: ["s3:GetObject", "s3:DeleteObject"],
173915
174042
  resources: [$interpolate`${bucket.arn}/*`]
173916
174043
  }, {
@@ -173964,6 +174091,7 @@ var onFailureFeature = defineFeature({
173964
174091
  }
173965
174092
  ]
173966
174093
  }, { dependsOn: [queuePolicy] });
174094
+ ctx.shared.set("on-failure", "bucket-arn", bucket.arn);
173967
174095
  }
173968
174096
  });
173969
174097
 
@@ -173971,19 +174099,19 @@ var onFailureFeature = defineFeature({
173971
174099
  import { createHmac as createHmac5 } from "crypto";
173972
174100
  import { fileURLToPath as fileURLToPath8 } from "url";
173973
174101
  import { dirname as dirname12, join as join28 } from "path";
173974
- import { formatRouteEnvName as formatRouteEnvName3 } from "awsless";
174102
+ import { formatRouteEnvName as formatRouteEnvName2 } from "awsless";
173975
174103
 
173976
174104
  // src/feature/pubsub/util.ts
173977
174105
  import { toDays as toDays7 } from "@awsless/duration";
173978
174106
  import { stringify as stringify2 } from "@awsless/json";
173979
174107
  import { createHash as createHash18 } from "crypto";
173980
- import { readFile as readFile17 } from "fs/promises";
174108
+ import { readFile as readFile18 } from "fs/promises";
173981
174109
  import { fileURLToPath as fileURLToPath7 } from "url";
173982
174110
  import { dirname as dirname11, join as join27 } from "path";
173983
174111
 
173984
174112
  // src/feature/instance/build/executable.ts
173985
174113
  import { createHash as createHash17 } from "crypto";
173986
- import { readFile as readFile16 } from "fs/promises";
174114
+ import { readFile as readFile17 } from "fs/promises";
173987
174115
  import { join as join26 } from "path";
173988
174116
  var buildExecutable = async (input, outputPath, architecture) => {
173989
174117
  const filePath = join26(outputPath, "program");
@@ -174023,7 +174151,7 @@ var buildExecutable = async (input, outputPath, architecture) => {
174023
174151
  ${result.logs?.map((log) => log.message).join(`
174024
174152
  `)}`);
174025
174153
  }
174026
- const file2 = await readFile16(filePath);
174154
+ const file2 = await readFile17(filePath);
174027
174155
  return {
174028
174156
  hash: createHash17("sha1").update(file2).update("x86_64").digest("hex"),
174029
174157
  file: file2
@@ -174049,7 +174177,7 @@ var createPubSubService = (parentGroup, ctx, id, props, inputs) => {
174049
174177
  const image = "public.ecr.aws/aws-cli/aws-cli:arm64";
174050
174178
  const bundleFile = join27(__dirname2, "handlers/pubsub-server.js");
174051
174179
  ctx.registerBuild("pubsub", name, async (build2) => {
174052
- const hash2 = createHash18("sha1").update(await readFile17(bundleFile)).digest("hex");
174180
+ const hash2 = createHash18("sha1").update(await readFile18(bundleFile)).digest("hex");
174053
174181
  const fingerprint = `${hash2}-${ARCHITECTURE}`;
174054
174182
  return build2(fingerprint, async (write) => {
174055
174183
  const temp = await createTempFolder(`pubsub--${name}`);
@@ -174581,9 +174709,9 @@ var pubsubFeature = defineFeature({
174581
174709
  file: join28(__dirname3, "/handlers/pubsub-publisher.js"),
174582
174710
  exportName: "default"
174583
174711
  });
174584
- bundle.addEnv(formatRouteEnvName3(publisherRouteKey, "REDIS_HOST"), redisHost);
174585
- bundle.addEnv(formatRouteEnvName3(publisherRouteKey, "REDIS_PORT"), redisPort.pipe((port) => port.toString()));
174586
- bundle.addEnv(formatRouteEnvName3(publisherRouteKey, "CHANNEL"), channel);
174712
+ bundle.addEnv(formatRouteEnvName2(publisherRouteKey, "REDIS_HOST"), redisHost);
174713
+ bundle.addEnv(formatRouteEnvName2(publisherRouteKey, "REDIS_PORT"), redisPort.pipe((port) => port.toString()));
174714
+ bundle.addEnv(formatRouteEnvName2(publisherRouteKey, "CHANNEL"), channel);
174587
174715
  const routerProps = ctx.appConfig.defaults.router?.[props.router];
174588
174716
  if (!routerProps?.domain) {
174589
174717
  throw new FileError("app.json", `The pubsub "${id}" requires the "${props.router}" router to have a domain configured.`);
@@ -174838,7 +174966,7 @@ var restFeature = defineFeature({
174838
174966
  });
174839
174967
 
174840
174968
  // src/feature/rpc/index.ts
174841
- import { formatRouteEnvName as formatRouteEnvName4 } from "awsless";
174969
+ import { formatRouteEnvName as formatRouteEnvName3 } from "awsless";
174842
174970
  import { dirname as dirname13, join as join29, relative as relative5 } from "path";
174843
174971
  import { fileURLToPath as fileURLToPath9 } from "url";
174844
174972
  import { toSeconds as toSeconds7 } from "@awsless/duration";
@@ -174895,7 +175023,7 @@ var rpcFeature = defineFeature({
174895
175023
  file: join29(dirname13(fileURLToPath9(import.meta.url)), "/handlers/rpc.js"),
174896
175024
  exportName: "default"
174897
175025
  });
174898
- bundle.addEnv(formatRouteEnvName4(serverRouteKey, "TIMEOUT"), toSeconds7(ctx.appConfig.defaults.function.timeout).toString());
175026
+ bundle.addEnv(formatRouteEnvName3(serverRouteKey, "TIMEOUT"), toSeconds7(ctx.appConfig.defaults.function.timeout).toString());
174899
175027
  const lockTable = new aws3.dynamodb.Table(group4, "lock", {
174900
175028
  name: formatGlobalResourceName({
174901
175029
  appName: ctx.app.name,
@@ -174915,7 +175043,7 @@ var rpcFeature = defineFeature({
174915
175043
  }
174916
175044
  ]
174917
175045
  });
174918
- bundle.addEnv(formatRouteEnvName4(serverRouteKey, "LOCK_TABLE"), lockTable.name);
175046
+ bundle.addEnv(formatRouteEnvName3(serverRouteKey, "LOCK_TABLE"), lockTable.name);
174919
175047
  bundle.addPermission({
174920
175048
  effect: "allow",
174921
175049
  actions: ["dynamodb:UpdateItem", "dynamodb:DeleteItem"],
@@ -174924,7 +175052,7 @@ var rpcFeature = defineFeature({
174924
175052
  if (props.auth) {
174925
175053
  const authRouteKey = formatRouteKey("base", "rpc", `${id}-auth`);
174926
175054
  registerBundleFunction(ctx, authRouteKey, props.auth);
174927
- bundle.addEnv(formatRouteEnvName4(serverRouteKey, "AUTH"), authRouteKey);
175055
+ bundle.addEnv(formatRouteEnvName3(serverRouteKey, "AUTH"), authRouteKey);
174928
175056
  }
174929
175057
  const addRoutes = ctx.shared.entry("router", "addRoutes", props.router);
174930
175058
  addRoutes({
@@ -174949,7 +175077,7 @@ var rpcFeature = defineFeature({
174949
175077
  const entryId = kebabCase(`${id}-${shortId(name)}`);
174950
175078
  const routeKey = formatRouteKey(ctx.stack.name, "rpc", entryId);
174951
175079
  registerBundleFunction(ctx, routeKey, props.function);
174952
- bundle.addEnv(formatRouteEnvName4(serverRouteKey, `QUERY:${name}`), JSON.stringify({ function: routeKey, lock: props.lock }));
175080
+ bundle.addEnv(formatRouteEnvName3(serverRouteKey, `QUERY:${name}`), JSON.stringify({ function: routeKey, lock: props.lock }));
174953
175081
  }
174954
175082
  }
174955
175083
  }
@@ -175045,7 +175173,7 @@ import { createHash as createHash19 } from "crypto";
175045
175173
  import { dirname as dirname15, join as join32 } from "path";
175046
175174
 
175047
175175
  // src/util/cache.ts
175048
- import { lstat as lstat3, readdir as readdir4 } from "fs/promises";
175176
+ import { lstat as lstat3, readdir as readdir5 } from "fs/promises";
175049
175177
  import { join as join30 } from "path";
175050
175178
  var generateCacheKey = async (directories2) => {
175051
175179
  const files = await listAllFiles(directories2);
@@ -175069,7 +175197,7 @@ var listAllFiles = async (list2) => {
175069
175197
  for (const entry of list2) {
175070
175198
  const stat5 = await lstat3(entry);
175071
175199
  if (stat5.isDirectory()) {
175072
- const dirents = await readdir4(entry, {
175200
+ const dirents = await readdir5(entry, {
175073
175201
  recursive: true,
175074
175202
  withFileTypes: true
175075
175203
  });
@@ -175151,11 +175279,9 @@ var siteFeature = defineFeature({
175151
175279
  AWS_SECRET_ACCESS_KEY: credentials4.secretAccessKey,
175152
175280
  AWS_SESSION_TOKEN: credentials4.sessionToken
175153
175281
  };
175154
- for (const name2 of props.build?.configs ?? []) {
175155
- env5[`CONFIG_${constantCase(name2)}`] = name2;
175156
- }
175157
- for (const name2 of ctx.stackConfig.configs ?? []) {
175158
- env5[`CONFIG_${constantCase(name2)}`] = name2;
175282
+ const configs = props.build?.configs ?? [];
175283
+ if (configs.length > 0) {
175284
+ env5.CONFIGS = configs.join(",");
175159
175285
  }
175160
175286
  const instance = Bun.spawn(buildProps.command.split(" "), {
175161
175287
  cwd,
@@ -175561,11 +175687,11 @@ var tableFeature = defineFeature({
175561
175687
  parallelizationFactor: props.stream.concurrencyPerShard,
175562
175688
  functionResponseTypes: ["ReportBatchItemFailures"],
175563
175689
  startingPosition: "LATEST",
175564
- destinationConfig: {
175690
+ destinationConfig: onFailure ? {
175565
175691
  onFailure: {
175566
175692
  destinationArn: onFailure
175567
175693
  }
175568
- }
175694
+ } : undefined
175569
175695
  }, {
175570
175696
  dependsOn: [bundle.policy]
175571
175697
  });
@@ -176077,9 +176203,9 @@ var layerFeature = defineFeature({
176077
176203
 
176078
176204
  // src/feature/image/index.ts
176079
176205
  import { toDays as toDays9 } from "@awsless/duration";
176080
- import { formatRouteEnvName as formatRouteEnvName5 } from "awsless";
176206
+ import { formatRouteEnvName as formatRouteEnvName4 } from "awsless";
176081
176207
  import { createHash as createHash20 } from "crypto";
176082
- import { readFile as readFile18 } from "fs/promises";
176208
+ import { readFile as readFile19 } from "fs/promises";
176083
176209
  import { dirname as dirname16, join as join34 } from "path";
176084
176210
  import { fileURLToPath as fileURLToPath10 } from "url";
176085
176211
  var imageFeature = defineFeature({
@@ -176102,7 +176228,7 @@ var imageFeature = defineFeature({
176102
176228
  resourceName: "sharp"
176103
176229
  });
176104
176230
  ctx.registerBuild("image", layerId, async (build2) => {
176105
- const file2 = await readFile18(path2);
176231
+ const file2 = await readFile19(path2);
176106
176232
  const fingerprint = createHash20("sha1").update(file2).digest("hex");
176107
176233
  return build2(fingerprint, async (write) => {
176108
176234
  await Promise.all([
@@ -176191,17 +176317,17 @@ var imageFeature = defineFeature({
176191
176317
  }
176192
176318
  }
176193
176319
  });
176194
- bundle.addEnv(formatRouteEnvName5(serverRouteKey, "IMAGE_CONFIG"), JSON.stringify({
176320
+ bundle.addEnv(formatRouteEnvName4(serverRouteKey, "IMAGE_CONFIG"), JSON.stringify({
176195
176321
  presets: props.presets,
176196
176322
  extensions: props.extensions
176197
176323
  }));
176198
- bundle.addEnv(formatRouteEnvName5(serverRouteKey, "IMAGE_BUCKET"), bucket.name);
176199
- bundle.addEnv(formatRouteEnvName5(serverRouteKey, "IMAGE_FOLDER"), folder);
176324
+ bundle.addEnv(formatRouteEnvName4(serverRouteKey, "IMAGE_BUCKET"), bucket.name);
176325
+ bundle.addEnv(formatRouteEnvName4(serverRouteKey, "IMAGE_FOLDER"), folder);
176200
176326
  if (originRouteKey) {
176201
- bundle.addEnv(formatRouteEnvName5(serverRouteKey, "IMAGE_ORIGIN"), originRouteKey);
176327
+ bundle.addEnv(formatRouteEnvName4(serverRouteKey, "IMAGE_ORIGIN"), originRouteKey);
176202
176328
  }
176203
176329
  if (props.origin.static) {
176204
- bundle.addEnv(formatRouteEnvName5(serverRouteKey, "IMAGE_ORIGIN_S3"), "true");
176330
+ bundle.addEnv(formatRouteEnvName4(serverRouteKey, "IMAGE_ORIGIN_S3"), "true");
176205
176331
  }
176206
176332
  ctx.onReady(() => {
176207
176333
  if (props.origin.static) {
@@ -176229,7 +176355,7 @@ var imageFeature = defineFeature({
176229
176355
 
176230
176356
  // src/feature/icon/index.ts
176231
176357
  import { toDays as toDays10 } from "@awsless/duration";
176232
- import { formatRouteEnvName as formatRouteEnvName6 } from "awsless";
176358
+ import { formatRouteEnvName as formatRouteEnvName5 } from "awsless";
176233
176359
  import { dirname as dirname17, join as join35 } from "path";
176234
176360
  import { fileURLToPath as fileURLToPath11 } from "url";
176235
176361
  var iconFeature = defineFeature({
@@ -176277,17 +176403,17 @@ var iconFeature = defineFeature({
176277
176403
  }
176278
176404
  }
176279
176405
  });
176280
- bundle.addEnv(formatRouteEnvName6(serverRouteKey, "ICON_CONFIG"), JSON.stringify({
176406
+ bundle.addEnv(formatRouteEnvName5(serverRouteKey, "ICON_CONFIG"), JSON.stringify({
176281
176407
  preserveIds: props.preserveIds,
176282
176408
  symbols: props.symbols
176283
176409
  }));
176284
- bundle.addEnv(formatRouteEnvName6(serverRouteKey, "ICON_BUCKET"), bucket.name);
176285
- bundle.addEnv(formatRouteEnvName6(serverRouteKey, "ICON_FOLDER"), folder);
176410
+ bundle.addEnv(formatRouteEnvName5(serverRouteKey, "ICON_BUCKET"), bucket.name);
176411
+ bundle.addEnv(formatRouteEnvName5(serverRouteKey, "ICON_FOLDER"), folder);
176286
176412
  if (originRouteKey) {
176287
- bundle.addEnv(formatRouteEnvName6(serverRouteKey, "ICON_ORIGIN"), originRouteKey);
176413
+ bundle.addEnv(formatRouteEnvName5(serverRouteKey, "ICON_ORIGIN"), originRouteKey);
176288
176414
  }
176289
176415
  if (props.origin.static) {
176290
- bundle.addEnv(formatRouteEnvName6(serverRouteKey, "ICON_ORIGIN_S3"), "true");
176416
+ bundle.addEnv(formatRouteEnvName5(serverRouteKey, "ICON_ORIGIN_S3"), "true");
176291
176417
  }
176292
176418
  ctx.onReady(() => {
176293
176419
  if (props.origin.static) {
@@ -176329,13 +176455,13 @@ var import_deepmerge4 = __toESM(require_cjs2(), 1);
176329
176455
 
176330
176456
  // src/feature/job/build/executable.ts
176331
176457
  import { createHash as createHash21 } from "crypto";
176332
- import { readFile as readFile19, writeFile as writeFile10 } from "fs/promises";
176458
+ import { readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
176333
176459
  import { join as join36, resolve as resolve3 } from "path";
176334
176460
  var buildJobExecutable = async (input, outputPath, architecture) => {
176335
176461
  const filePath = join36(outputPath, "program");
176336
176462
  const wrapperPath = join36(outputPath, "wrapper.ts");
176337
176463
  const handlerPath = resolve3(input);
176338
- await writeFile10(wrapperPath, `import { parse } from '@awsless/json'
176464
+ await writeFile11(wrapperPath, `import { parse } from '@awsless/json'
176339
176465
  import { getObject } from '@awsless/s3'
176340
176466
  import handler from '${handlerPath}'
176341
176467
 
@@ -176384,7 +176510,7 @@ await handler(payload)
176384
176510
  ${result.logs?.map((log) => log.message).join(`
176385
176511
  `)}`);
176386
176512
  }
176387
- const file2 = await readFile19(filePath);
176513
+ const file2 = await readFile20(filePath);
176388
176514
  return {
176389
176515
  hash: createHash21("sha1").update(file2).update(target2).digest("hex"),
176390
176516
  file: file2
@@ -176837,7 +176963,7 @@ var jobFeature = defineFeature({
176837
176963
  });
176838
176964
 
176839
176965
  // src/feature/instance/index.ts
176840
- import { days as days10, seconds as seconds6, toSeconds as toSeconds11 } from "@awsless/duration";
176966
+ import { days as days11, seconds as seconds6, toSeconds as toSeconds11 } from "@awsless/duration";
176841
176967
 
176842
176968
  // src/feature/instance/util.ts
176843
176969
  import { toDays as toDays12, toSeconds as toSeconds10 } from "@awsless/duration";
@@ -177221,7 +177347,7 @@ var instanceFeature = defineFeature({
177221
177347
  const queue2 = new aws3.sqs.Queue(group4, "queue", {
177222
177348
  name: task2.name,
177223
177349
  visibilityTimeoutSeconds: toSeconds11(seconds6(30)),
177224
- messageRetentionSeconds: toSeconds11(days10(4)),
177350
+ messageRetentionSeconds: toSeconds11(days11(4)),
177225
177351
  maxMessageSize: toBytes(kibibytes(256)),
177226
177352
  receiveWaitTimeSeconds: toSeconds11(seconds6(20))
177227
177353
  });
@@ -177379,7 +177505,7 @@ var metricFeature = defineFeature({
177379
177505
  });
177380
177506
 
177381
177507
  // src/feature/router/index.ts
177382
- import { days as days11, seconds as seconds8, toSeconds as toSeconds14, years } from "@awsless/duration";
177508
+ import { days as days12, seconds as seconds8, toSeconds as toSeconds14, years } from "@awsless/duration";
177383
177509
 
177384
177510
  // src/feature/router/router-code.ts
177385
177511
  import { minutes as minutes8, seconds as seconds7, toSeconds as toSeconds13 } from "@awsless/duration";
@@ -177935,8 +178061,8 @@ var routerFeature = defineFeature({
177935
178061
  const cache7 = new aws3.cloudfront.CachePolicy(group4, "cache", {
177936
178062
  name,
177937
178063
  minTtl: toSeconds14(seconds8(0)),
177938
- maxTtl: toSeconds14(days11(365)),
177939
- defaultTtl: toSeconds14(days11(0)),
178064
+ maxTtl: toSeconds14(days12(365)),
178065
+ defaultTtl: toSeconds14(days12(0)),
177940
178066
  parametersInCacheKeyAndForwardedToOrigin: {
177941
178067
  enableAcceptEncodingBrotli: true,
177942
178068
  enableAcceptEncodingGzip: true,
@@ -178413,11 +178539,11 @@ var features = [
178413
178539
  routerFeature,
178414
178540
  commandFeature,
178415
178541
  layerFeature,
178542
+ onFailureFeature,
178543
+ onErrorLogFeature,
178544
+ bundleFeature,
178416
178545
  authFeature,
178417
178546
  functionFeature,
178418
- bundleFeature,
178419
- onErrorLogFeature,
178420
- onFailureFeature,
178421
178547
  instanceFeature,
178422
178548
  jobFeature,
178423
178549
  configFeature,
@@ -179222,6 +179348,12 @@ var createApp = (props) => {
179222
179348
  registerDomainZone(zone) {
179223
179349
  domainZones.push(zone);
179224
179350
  },
179351
+ restartOnConfigChange(lambda) {
179352
+ for (const configName of props.appConfig.configs ?? []) {
179353
+ functionsByConfig[configName] ??= [];
179354
+ functionsByConfig[configName].push(lambda);
179355
+ }
179356
+ },
179225
179357
  bind(name, value) {
179226
179358
  binds.push({ name, value });
179227
179359
  },
@@ -179268,7 +179400,7 @@ var createApp = (props) => {
179268
179400
  addWarning(props2) {
179269
179401
  warnings.push(props2);
179270
179402
  },
179271
- addFunction(lambda) {
179403
+ restartOnConfigChange(lambda) {
179272
179404
  for (const configName of props.appConfig.configs ?? []) {
179273
179405
  functionsByConfig[configName] ??= [];
179274
179406
  functionsByConfig[configName].push(lambda);
@@ -179783,7 +179915,7 @@ import { DynamoDBClient as DynamoDBClient4 } from "@awsless/dynamodb";
179783
179915
 
179784
179916
  // src/cli/ui/complex/run-tests.ts
179785
179917
  var import_wildstring3 = __toESM(require_wildstring(), 1);
179786
- import { mkdir as mkdir6, readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
179918
+ import { mkdir as mkdir6, readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
179787
179919
  import { join as join39 } from "path";
179788
179920
  import { parse as parse8, stringify as stringify5 } from "@awsless/json";
179789
179921
  import { generateFolderHash, loadWorkspace as loadWorkspace2 } from "@awsless/ts-file-cache";
@@ -179970,7 +180102,7 @@ var runTest = async (stack, dir, filters, workspace, opts) => {
179970
180102
  if (!process.env.NO_CACHE) {
179971
180103
  const exists2 = await fileExist(file2);
179972
180104
  if (exists2) {
179973
- const raw = await readFile20(file2, { encoding: "utf8" });
180105
+ const raw = await readFile21(file2, { encoding: "utf8" });
179974
180106
  const data = parse8(raw);
179975
180107
  if (data.fingerprint === fingerprint) {
179976
180108
  logs_exports.step(formatResult({
@@ -180010,7 +180142,7 @@ var runTest = async (stack, dir, filters, workspace, opts) => {
180010
180142
  logTestLogs(result);
180011
180143
  }
180012
180144
  logTestErrors(result);
180013
- await writeFile11(file2, stringify5({
180145
+ await writeFile12(file2, stringify5({
180014
180146
  ...result,
180015
180147
  fingerprint
180016
180148
  }));
@@ -185706,8 +185838,8 @@ var bind = (program3) => {
185706
185838
  }
185707
185839
  const configList = opts.config ?? [];
185708
185840
  const configs = {};
185709
- for (const name of configList) {
185710
- configs[`CONFIG_${constantCase(name)}`] = name;
185841
+ if (configList.length > 0) {
185842
+ configs.CONFIGS = configList.join(",");
185711
185843
  }
185712
185844
  if (configList.length ?? 0 > 0) {
185713
185845
  logs_exports.note("Bind Config", configList.map((v7) => color2.label(constantCase(v7))).join(`
@@ -185789,7 +185921,7 @@ var {
185789
185921
  isIBMi
185790
185922
  } = require_constants7();
185791
185923
  var stat5 = promisify4(fs3.stat);
185792
- var readdir5 = promisify4(fs3.readdir);
185924
+ var readdir6 = promisify4(fs3.readdir);
185793
185925
  var arrify = (value = []) => Array.isArray(value) ? value : [value];
185794
185926
  var flatten = (list3, result = []) => {
185795
185927
  list3.forEach((item) => {
@@ -185861,7 +185993,7 @@ class DirEntry {
185861
185993
  return;
185862
185994
  const dir = this.path;
185863
185995
  try {
185864
- await readdir5(dir);
185996
+ await readdir6(dir);
185865
185997
  } catch (err) {
185866
185998
  if (this._removeWatcher) {
185867
185999
  this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
@@ -186447,7 +186579,7 @@ var watchConfig = async (options, resolve4, reject) => {
186447
186579
  };
186448
186580
 
186449
186581
  // src/type-gen/generate.ts
186450
- import { mkdir as mkdir7, writeFile as writeFile12 } from "fs/promises";
186582
+ import { mkdir as mkdir7, writeFile as writeFile13 } from "fs/promises";
186451
186583
  import { dirname as dirname19, join as join40, relative as relative8 } from "path";
186452
186584
  var generateTypes = async (props) => {
186453
186585
  const files = [];
@@ -186462,7 +186594,7 @@ var generateTypes = async (props) => {
186462
186594
  files.push(relative8(directories.root, path2));
186463
186595
  }
186464
186596
  await mkdir7(dirname19(path2), { recursive: true });
186465
- await writeFile12(path2, code);
186597
+ await writeFile13(path2, code);
186466
186598
  }
186467
186599
  }
186468
186600
  });
@@ -186470,7 +186602,7 @@ var generateTypes = async (props) => {
186470
186602
  if (files.length) {
186471
186603
  const code = files.map((file2) => `/// <reference path='${file2}' />`).join(`
186472
186604
  `);
186473
- await writeFile12(join40(directories.root, `awsless.d.ts`), code);
186605
+ await writeFile13(join40(directories.root, `awsless.d.ts`), code);
186474
186606
  }
186475
186607
  };
186476
186608