@awsless/awsless 0.0.267 → 0.0.268

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
@@ -69,52 +69,23 @@ var debug = (...parts) => {
69
69
  };
70
70
 
71
71
  // src/config/app.ts
72
- import { z as z15 } from "zod";
72
+ import { z as z17 } from "zod";
73
+
74
+ // src/feature/auth/schema.ts
75
+ import { z as z7 } from "zod";
73
76
 
74
77
  // src/config/schema/resource-id.ts
75
78
  import { paramCase } from "change-case";
76
79
  import { z } from "zod";
77
80
  var ResourceIdSchema = z.string().min(3).max(24).regex(/^[a-z0-9\-]+$/i, "Invalid resource ID").transform((value) => paramCase(value));
78
81
 
79
- // src/config/schema/region.ts
80
- import { z as z2 } from "zod";
81
- var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
82
- var AF = ["af-south-1"];
83
- var AP = [
84
- "ap-east-1",
85
- "ap-south-2",
86
- "ap-southeast-3",
87
- "ap-southeast-4",
88
- "ap-south-1",
89
- "ap-northeast-3",
90
- "ap-northeast-2",
91
- "ap-southeast-1",
92
- "ap-southeast-2",
93
- "ap-northeast-1"
94
- ];
95
- var CA = ["ca-central-1"];
96
- var EU = [
97
- "eu-central-1",
98
- "eu-west-1",
99
- "eu-west-2",
100
- "eu-south-1",
101
- "eu-west-3",
102
- "eu-south-2",
103
- "eu-north-1",
104
- "eu-central-2"
105
- ];
106
- var ME = ["me-south-1", "me-central-1"];
107
- var SA = ["sa-east-1"];
108
- var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
109
- var RegionSchema = z2.enum(regions);
110
-
111
- // src/feature/domain/schema.ts
112
- import { z as z4 } from "zod";
82
+ // src/feature/function/schema.ts
83
+ import { z as z5 } from "zod";
113
84
 
114
85
  // src/config/schema/duration.ts
115
- import { z as z3 } from "zod";
86
+ import { z as z2 } from "zod";
116
87
  import { parse } from "@awsless/duration";
117
- var DurationSchema = z3.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/, "Invalid duration").transform((v) => parse(v));
88
+ var DurationSchema = z2.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/, "Invalid duration").transform((v) => parse(v));
118
89
  var durationMin = (min) => {
119
90
  return (duration) => {
120
91
  return duration.value >= min.value;
@@ -126,32 +97,9 @@ var durationMax = (max) => {
126
97
  };
127
98
  };
128
99
 
129
- // src/feature/domain/schema.ts
130
- var DomainNameSchema = z4.string().regex(/[a-z\-\_\.]/g, "Invalid domain name").describe(
131
- "Enter a fully qualified domain name, for example, www.example.com. You can optionally include a trailing dot. If you omit the trailing dot, Amazon Route 53 assumes that the domain name that you specify is fully qualified. This means that Route 53 treats www.example.com (without a trailing dot) and www.example.com. (with a trailing dot) as identical."
132
- );
133
- var DNSTypeSchema = z4.enum(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"]).describe("The DNS record type.");
134
- var TTLSchema = DurationSchema.describe("The resource record cache time to live (TTL).");
135
- var RecordsSchema = z4.string().array().describe("One or more values that correspond with the value that you specified for the Type property.");
136
- var DomainsDefaultSchema = z4.record(
137
- ResourceIdSchema,
138
- z4.object({
139
- domain: DomainNameSchema.describe("Define the domain name"),
140
- dns: z4.object({
141
- name: DomainNameSchema.optional(),
142
- type: DNSTypeSchema,
143
- ttl: TTLSchema,
144
- records: RecordsSchema
145
- }).array().optional().describe("Define the domain dns records")
146
- })
147
- ).optional().describe("Define the domains for your application.");
148
-
149
- // src/feature/function/schema.ts
150
- import { z as z7 } from "zod";
151
-
152
100
  // src/config/schema/local-file.ts
153
101
  import { stat } from "fs/promises";
154
- import { z as z5 } from "zod";
102
+ import { z as z3 } from "zod";
155
103
 
156
104
  // src/util/path.ts
157
105
  import { lstat } from "fs/promises";
@@ -220,7 +168,7 @@ var resolvePath = (path) => {
220
168
  }
221
169
  return join2(directories.root, path);
222
170
  };
223
- var LocalFileSchema = z5.string().transform((path) => resolvePath(path)).refine(async (path) => {
171
+ var LocalFileSchema = z3.string().transform((path) => resolvePath(path)).refine(async (path) => {
224
172
  try {
225
173
  const s = await stat(path);
226
174
  return s.isFile();
@@ -230,9 +178,9 @@ var LocalFileSchema = z5.string().transform((path) => resolvePath(path)).refine(
230
178
  }, `File doesn't exist`);
231
179
 
232
180
  // src/config/schema/size.ts
233
- import { z as z6 } from "zod";
181
+ import { z as z4 } from "zod";
234
182
  import { parse as parse2 } from "@awsless/size";
235
- var SizeSchema = z6.string().regex(/^[0-9]+ (B|KB|MB|GB|TB|PB)$/, "Invalid size").transform((v) => parse2(v));
183
+ var SizeSchema = z4.string().regex(/^[0-9]+ (B|KB|MB|GB|TB|PB)$/, "Invalid size").transform((v) => parse2(v));
236
184
  var sizeMin = (min) => {
237
185
  return (size) => {
238
186
  return size.value >= min.value;
@@ -257,62 +205,62 @@ var EphemeralStorageSizeSchema = SizeSchema.refine(
257
205
  sizeMin(mebibytes(512)),
258
206
  "Minimum ephemeral storage size is 512 MB"
259
207
  ).refine(sizeMax(gibibytes(10)), "Minimum ephemeral storage size is 10 GB").describe("The size of the function's /tmp directory. You can specify a size value from 512 MB to 10 GB.");
260
- var ReservedConcurrentExecutionsSchema = z7.number().int().min(0).describe(
208
+ var ReservedConcurrentExecutionsSchema = z5.number().int().min(0).describe(
261
209
  "The number of simultaneous executions to reserve for the function. You can specify a number from 0."
262
210
  );
263
- var EnvironmentSchema = z7.record(z7.string(), z7.string()).optional().describe("Environment variable key-value pairs.");
264
- var ArchitectureSchema = z7.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the function supports.");
265
- var RetryAttemptsSchema = z7.number().int().min(0).max(2).describe(
211
+ var EnvironmentSchema = z5.record(z5.string(), z5.string()).optional().describe("Environment variable key-value pairs.");
212
+ var ArchitectureSchema = z5.enum(["x86_64", "arm64"]).describe("The instruction set architecture that the function supports.");
213
+ var RetryAttemptsSchema = z5.number().int().min(0).max(2).describe(
266
214
  "The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
267
215
  );
268
- var RuntimeSchema = z7.enum(["nodejs18.x", "nodejs20.x"]).describe("The identifier of the function's runtime.");
269
- var ActionSchema = z7.string();
270
- var ActionsSchema = z7.union([ActionSchema.transform((v) => [v]), ActionSchema.array()]);
271
- var ArnSchema = z7.string().startsWith("arn:");
272
- var WildcardSchema = z7.literal("*");
273
- var ResourceSchema = z7.union([ArnSchema, WildcardSchema]).transform((v) => v);
274
- var ResourcesSchema = z7.union([ResourceSchema.transform((v) => [v]), ResourceSchema.array()]);
275
- var PermissionSchema = z7.object({
276
- effect: z7.enum(["allow", "deny"]).default("allow"),
216
+ var RuntimeSchema = z5.enum(["nodejs18.x", "nodejs20.x"]).describe("The identifier of the function's runtime.");
217
+ var ActionSchema = z5.string();
218
+ var ActionsSchema = z5.union([ActionSchema.transform((v) => [v]), ActionSchema.array()]);
219
+ var ArnSchema = z5.string().startsWith("arn:");
220
+ var WildcardSchema = z5.literal("*");
221
+ var ResourceSchema = z5.union([ArnSchema, WildcardSchema]).transform((v) => v);
222
+ var ResourcesSchema = z5.union([ResourceSchema.transform((v) => [v]), ResourceSchema.array()]);
223
+ var PermissionSchema = z5.object({
224
+ effect: z5.enum(["allow", "deny"]).default("allow"),
277
225
  actions: ActionsSchema,
278
226
  resources: ResourcesSchema
279
227
  });
280
- var PermissionsSchema = z7.union([PermissionSchema.transform((v) => [v]), PermissionSchema.array()]).describe("Add IAM permissions to your function.");
281
- var WarmSchema = z7.number().int().min(0).max(10).describe(
228
+ var PermissionsSchema = z5.union([PermissionSchema.transform((v) => [v]), PermissionSchema.array()]).describe("Add IAM permissions to your function.");
229
+ var WarmSchema = z5.number().int().min(0).max(10).describe(
282
230
  "Specify how many functions you want to warm up each 5 minutes. You can specify a number from 0 to 10."
283
231
  );
284
- var VPCSchema = z7.boolean().describe("Put the function inside your global VPC.");
285
- var MinifySchema = z7.boolean().describe("Minify the function code.");
286
- var HandlerSchema = z7.string().describe("The name of the exported method within your code that Lambda calls to run your function.");
232
+ var VPCSchema = z5.boolean().describe("Put the function inside your global VPC.");
233
+ var MinifySchema = z5.boolean().describe("Minify the function code.");
234
+ var HandlerSchema = z5.string().describe("The name of the exported method within your code that Lambda calls to run your function.");
287
235
  var FileSchema = LocalFileSchema.describe("The file path of the function code.");
288
- var DescriptionSchema = z7.string().describe("A description of the function.");
236
+ var DescriptionSchema = z5.string().describe("A description of the function.");
289
237
  var LogRetentionSchema = DurationSchema.refine(
290
238
  durationMin(days(0)),
291
239
  "Minimum log retention is 0 day, which will disable logging."
292
240
  );
293
- var LogSchema = z7.union([
294
- z7.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
241
+ var LogSchema = z5.union([
242
+ z5.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
295
243
  LogRetentionSchema.transform((retention) => ({ retention })),
296
- z7.object({
244
+ z5.object({
297
245
  retention: LogRetentionSchema.describe("The log retention duration."),
298
- format: z7.enum(["text", "json"]).describe(
246
+ format: z5.enum(["text", "json"]).describe(
299
247
  `The format in which Lambda sends your function's application and system logs to CloudWatch. Select between plain text and structured JSON.`
300
248
  ).optional(),
301
- system: z7.enum(["debug", "info", "warn"]).describe(
249
+ system: z5.enum(["debug", "info", "warn"]).describe(
302
250
  "Set this property to filter the system logs for your function that Lambda sends to CloudWatch. Lambda only sends system logs at the selected level of detail and lower, where DEBUG is the highest level and WARN is the lowest."
303
251
  ).optional(),
304
- level: z7.enum(["trace", "debug", "info", "warn", "error", "fatal"]).describe(
252
+ level: z5.enum(["trace", "debug", "info", "warn", "error", "fatal"]).describe(
305
253
  "Set this property to filter the application logs for your function that Lambda sends to CloudWatch. Lambda only sends application logs at the selected level of detail and lower, where TRACE is the highest level and FATAL is the lowest."
306
254
  ).optional()
307
255
  })
308
256
  ]).describe(
309
257
  "Enable logging to a CloudWatch log group. Providing a duration value will set the log retention time."
310
258
  );
311
- var FunctionSchema = z7.union([
259
+ var FunctionSchema = z5.union([
312
260
  LocalFileSchema.transform((file) => ({
313
261
  file
314
262
  })),
315
- z7.object({
263
+ z5.object({
316
264
  file: FileSchema,
317
265
  description: DescriptionSchema.optional(),
318
266
  handler: HandlerSchema.optional(),
@@ -331,8 +279,8 @@ var FunctionSchema = z7.union([
331
279
  permissions: PermissionsSchema.optional()
332
280
  })
333
281
  ]);
334
- var FunctionsSchema = z7.record(ResourceIdSchema, FunctionSchema).optional().describe("Define the functions in your stack.");
335
- var FunctionDefaultSchema = z7.object({
282
+ var FunctionsSchema = z5.record(ResourceIdSchema, FunctionSchema).optional().describe("Define the functions in your stack.");
283
+ var FunctionDefaultSchema = z5.object({
336
284
  handler: HandlerSchema.default("index.default"),
337
285
  minify: MinifySchema.default(true),
338
286
  warm: WarmSchema.default(0),
@@ -354,19 +302,111 @@ var FunctionDefaultSchema = z7.object({
354
302
  permissions: PermissionsSchema.optional()
355
303
  }).default({});
356
304
 
357
- // src/feature/graphql/schema.ts
305
+ // src/config/schema/email.ts
306
+ import { z as z6 } from "zod";
307
+ var EmailSchema = z6.string().email();
308
+ var isEmail = (value) => {
309
+ return EmailSchema.safeParse(value).success;
310
+ };
311
+
312
+ // src/feature/auth/schema.ts
313
+ var TriggersSchema = z7.object({
314
+ beforeToken: FunctionSchema.optional().describe("A pre jwt token generation AWS Lambda trigger."),
315
+ beforeLogin: FunctionSchema.optional().describe("A pre user login AWS Lambda trigger."),
316
+ afterLogin: FunctionSchema.optional().describe("A post user login AWS Lambda trigger."),
317
+ beforeRegister: FunctionSchema.optional().describe("A pre user register AWS Lambda trigger."),
318
+ afterRegister: FunctionSchema.optional().describe("A post user register AWS Lambda trigger."),
319
+ customMessage: FunctionSchema.optional().describe("A custom message AWS Lambda trigger."),
320
+ // /** A custom email sender AWS Lambda trigger */
321
+ // emailSender: FunctionSchema.optional(),
322
+ defineChallenge: FunctionSchema.optional().describe("Defines the authentication challenge."),
323
+ createChallenge: FunctionSchema.optional().describe("Creates an authentication challenge."),
324
+ verifyChallenge: FunctionSchema.optional().describe("Verifies the authentication challenge response.")
325
+ }).describe("Specifies the configuration for AWS Lambda triggers.");
326
+ var AuthSchema = z7.record(
327
+ ResourceIdSchema,
328
+ z7.object({
329
+ access: z7.boolean().default(false).describe("Give access to every function in this stack to your cognito instance."),
330
+ triggers: TriggersSchema.optional()
331
+ })
332
+ ).optional().describe("Define the auth triggers in your stack.");
333
+ var AuthDefaultSchema = z7.record(
334
+ ResourceIdSchema,
335
+ z7.object({
336
+ allowUserRegistration: z7.boolean().default(true).describe("Specifies whether users can create an user account or if only the administrator can."),
337
+ messaging: z7.object({
338
+ fromEmail: EmailSchema.describe("Specifies the sender's email address."),
339
+ fromName: z7.string().optional().describe("Specifies the sender's name."),
340
+ replyTo: EmailSchema.optional().describe(
341
+ "The destination to which the receiver of the email should reply."
342
+ )
343
+ }).optional().describe("The email configuration for sending messages."),
344
+ // secret: z.boolean().default(false).describe('Specifies whether you want to generate a client secret.'),
345
+ username: z7.object({
346
+ emailAlias: z7.boolean().default(true).describe("Allow the user email to be used as username."),
347
+ caseSensitive: z7.boolean().default(false).describe(
348
+ "Specifies whether username case sensitivity will be enabled. When usernames and email addresses are case insensitive, users can sign in as the same user when they enter a different capitalization of their user name."
349
+ )
350
+ }).default({}).describe("The username policy."),
351
+ password: z7.object({
352
+ minLength: z7.number().int().min(6).max(99).default(12).describe("Required users to have at least the minimum password length."),
353
+ uppercase: z7.boolean().default(true).describe("Required users to use at least one uppercase letter in their password."),
354
+ lowercase: z7.boolean().default(true).describe("Required users to use at least one lowercase letter in their password."),
355
+ numbers: z7.boolean().default(true).describe("Required users to use at least one number in their password."),
356
+ symbols: z7.boolean().default(true).describe("Required users to use at least one symbol in their password."),
357
+ temporaryPasswordValidity: DurationSchema.default("7 days").describe(
358
+ "The duration a temporary password is valid. If the user doesn't sign in during this time, an administrator must reset their password."
359
+ )
360
+ }).default({}).describe("The password policy."),
361
+ validity: z7.object({
362
+ idToken: DurationSchema.default("1 hour").describe(
363
+ "The ID token time limit. After this limit expires, your user can't use their ID token."
364
+ ),
365
+ accessToken: DurationSchema.default("1 hour").describe(
366
+ "The access token time limit. After this limit expires, your user can't use their access token."
367
+ ),
368
+ refreshToken: DurationSchema.default("365 days").describe(
369
+ "The refresh token time limit. After this limit expires, your user can't use their refresh token."
370
+ )
371
+ }).default({}).describe("Specifies the validity duration for every JWT token."),
372
+ triggers: TriggersSchema.optional()
373
+ })
374
+ ).default({}).describe("Define the authenticatable users in your app.");
375
+
376
+ // src/feature/domain/schema.ts
358
377
  import { z as z8 } from "zod";
378
+ var DomainNameSchema = z8.string().regex(/[a-z\-\_\.]/g, "Invalid domain name").describe(
379
+ "Enter a fully qualified domain name, for example, www.example.com. You can optionally include a trailing dot. If you omit the trailing dot, Amazon Route 53 assumes that the domain name that you specify is fully qualified. This means that Route 53 treats www.example.com (without a trailing dot) and www.example.com. (with a trailing dot) as identical."
380
+ );
381
+ var DNSTypeSchema = z8.enum(["A", "AAAA", "CAA", "CNAME", "DS", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"]).describe("The DNS record type.");
382
+ var TTLSchema = DurationSchema.describe("The resource record cache time to live (TTL).");
383
+ var RecordsSchema = z8.string().array().describe("One or more values that correspond with the value that you specified for the Type property.");
384
+ var DomainsDefaultSchema = z8.record(
385
+ ResourceIdSchema,
386
+ z8.object({
387
+ domain: DomainNameSchema.describe("Define the domain name"),
388
+ dns: z8.object({
389
+ name: DomainNameSchema.optional(),
390
+ type: DNSTypeSchema,
391
+ ttl: TTLSchema,
392
+ records: RecordsSchema
393
+ }).array().optional().describe("Define the domain dns records")
394
+ })
395
+ ).optional().describe("Define the domains for your application.");
396
+
397
+ // src/feature/graphql/schema.ts
398
+ import { z as z9 } from "zod";
359
399
  var AuthorizerTtl = DurationSchema.describe(
360
400
  `The number of seconds a response should be cached for. The maximum value is one hour (3600 seconds). The Lambda function can override this by returning a ttlOverride key in its response.`
361
401
  );
362
- var GraphQLDefaultSchema = z8.record(
402
+ var GraphQLDefaultSchema = z9.record(
363
403
  ResourceIdSchema,
364
- z8.object({
404
+ z9.object({
365
405
  domain: ResourceIdSchema.describe("The domain id to link your API with.").optional(),
366
- subDomain: z8.string().optional(),
367
- auth: z8.union([
406
+ subDomain: z9.string().optional(),
407
+ auth: z9.union([
368
408
  ResourceIdSchema,
369
- z8.object({
409
+ z9.object({
370
410
  authorizer: FunctionSchema,
371
411
  ttl: AuthorizerTtl.default("1 hour")
372
412
  })
@@ -378,22 +418,22 @@ var GraphQLDefaultSchema = z8.record(
378
418
  resolver: LocalFileSchema.optional()
379
419
  })
380
420
  ).describe(`Define the global GraphQL API's.`).optional();
381
- var GraphQLSchema = z8.record(
421
+ var GraphQLSchema = z9.record(
382
422
  ResourceIdSchema,
383
- z8.object({
423
+ z9.object({
384
424
  // schema: z.union([LocalFileSchema.transform(v => [v]), z.array(LocalFileSchema).min(1)]).optional(),
385
425
  schema: LocalFileSchema.describe("The graphql schema file."),
386
- resolvers: z8.record(
426
+ resolvers: z9.record(
387
427
  // TypeName
388
- z8.string(),
389
- z8.record(
428
+ z9.string(),
429
+ z9.record(
390
430
  // FieldName
391
- z8.string(),
392
- z8.union([
431
+ z9.string(),
432
+ z9.union([
393
433
  FunctionSchema.transform((consumer) => ({
394
434
  consumer
395
435
  })),
396
- z8.object({
436
+ z9.object({
397
437
  consumer: FunctionSchema,
398
438
  resolver: LocalFileSchema.optional()
399
439
  })
@@ -403,8 +443,71 @@ var GraphQLSchema = z8.record(
403
443
  })
404
444
  ).describe("Define the schema & resolvers in your stack for your global GraphQL API.").optional();
405
445
 
446
+ // src/feature/http/schema.ts
447
+ import { z as z10 } from "zod";
448
+ var RouteSchema = z10.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route").transform((v) => v);
449
+ var HttpDefaultSchema = z10.record(
450
+ ResourceIdSchema,
451
+ z10.object({
452
+ domain: ResourceIdSchema.describe("The domain id to link your API with."),
453
+ subDomain: z10.string().optional()
454
+ // auth: ResourceIdSchema.optional(),
455
+ })
456
+ ).optional().describe("Define your global HTTP API's.");
457
+ var HttpSchema = z10.record(ResourceIdSchema, z10.record(RouteSchema, FunctionSchema)).optional().describe("Define routes in your stack for your global HTTP API.");
458
+
459
+ // src/feature/instance/schema.ts
460
+ import { z as z12 } from "zod";
461
+
462
+ // src/config/schema/local-directory.ts
463
+ import { stat as stat2 } from "fs/promises";
464
+ import { z as z11 } from "zod";
465
+ var LocalDirectorySchema = z11.string().transform((path) => resolvePath(path)).refine(async (path) => {
466
+ try {
467
+ const s = await stat2(path);
468
+ return s.isDirectory();
469
+ } catch (error) {
470
+ return false;
471
+ }
472
+ }, `Directory doesn't exist`);
473
+
474
+ // src/feature/instance/schema.ts
475
+ var ImageSchema = z12.string().regex(/^ami\-[0-9a-f]+/).describe("The ID of the AMI.");
476
+ var TypeSchema = z12.enum([
477
+ "t3.nano",
478
+ "t3.micro",
479
+ "t3.small",
480
+ "t3.medium",
481
+ "t3.large",
482
+ "t3.xlarge",
483
+ "t3.2xlarge",
484
+ "t4g.nano",
485
+ "t4g.micro",
486
+ "t4g.small",
487
+ "t4g.medium",
488
+ "t4g.large",
489
+ "t4g.xlarge",
490
+ "t4g.2xlarge",
491
+ "g4ad.xlarge"
492
+ ]).describe(`The instance type.`);
493
+ var CommandSchema = z12.string().describe(`The script you want to execute when the instance starts up.`);
494
+ var CodeSchema = LocalDirectorySchema.describe(`The code directory that will be deployed to your instance.`);
495
+ var ConnectSchema = z12.boolean().describe("Allows you to connect to all instances with an Instance Connect Endpoint.");
496
+ var InstanceDefaultSchema = z12.object({
497
+ connect: ConnectSchema.default(false)
498
+ }).default({}).describe("Define the default settings for all instances in your stacks.");
499
+ var InstancesSchema = z12.record(
500
+ ResourceIdSchema,
501
+ z12.object({
502
+ image: ImageSchema,
503
+ type: TypeSchema,
504
+ code: CodeSchema,
505
+ command: CommandSchema.optional()
506
+ })
507
+ ).optional().describe("Define the instances in your stack.");
508
+
406
509
  // src/feature/queue/schema.ts
407
- import { z as z9 } from "zod";
510
+ import { z as z13 } from "zod";
408
511
  import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
409
512
  import { kibibytes } from "@awsless/size";
410
513
  var RetentionPeriodSchema = DurationSchema.refine(
@@ -434,10 +537,10 @@ var ReceiveMessageWaitTimeSchema = DurationSchema.refine(
434
537
  var MaxMessageSizeSchema = SizeSchema.refine(sizeMin(kibibytes(1)), "Minimum max message size is 1 KB").refine(sizeMax(kibibytes(256)), "Maximum max message size is 256 KB").describe(
435
538
  "The limit of how many bytes that a message can contain before Amazon SQS rejects it. You can specify an size from 1 KB to 256 KB."
436
539
  );
437
- var BatchSizeSchema = z9.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
540
+ var BatchSizeSchema = z13.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
438
541
  "The maximum number of records in each batch that Lambda pulls from your queue and sends to your function. Lambda passes all of the records in the batch to the function in a single call, up to the payload limit for synchronous invocation (6 MB). You can specify an integer from 1 to 10000."
439
542
  );
440
- var MaxConcurrencySchema = z9.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
543
+ var MaxConcurrencySchema = z13.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
441
544
  "Limits the number of concurrent instances that the queue worker can invoke. You can specify an integer from 2 to 1000."
442
545
  );
443
546
  var MaxBatchingWindow = DurationSchema.refine(
@@ -446,7 +549,7 @@ var MaxBatchingWindow = DurationSchema.refine(
446
549
  ).describe(
447
550
  "The maximum amount of time, that Lambda spends gathering records before invoking the function. You can specify an duration from 0 seconds to 5 minutes."
448
551
  );
449
- var QueueDefaultSchema = z9.object({
552
+ var QueueDefaultSchema = z13.object({
450
553
  retentionPeriod: RetentionPeriodSchema.default("7 days"),
451
554
  visibilityTimeout: VisibilityTimeoutSchema.default("30 seconds"),
452
555
  deliveryDelay: DeliveryDelaySchema.default("0 seconds"),
@@ -456,15 +559,15 @@ var QueueDefaultSchema = z9.object({
456
559
  maxConcurrency: MaxConcurrencySchema.optional(),
457
560
  maxBatchingWindow: MaxBatchingWindow.optional()
458
561
  }).default({});
459
- var QueuesSchema = z9.record(
562
+ var QueuesSchema = z13.record(
460
563
  ResourceIdSchema,
461
- z9.union([
564
+ z13.union([
462
565
  LocalFileSchema.transform((file) => ({
463
566
  consumer: {
464
567
  file
465
568
  }
466
569
  })),
467
- z9.object({
570
+ z13.object({
468
571
  consumer: FunctionSchema.describe("he consuming lambda function properties."),
469
572
  retentionPeriod: RetentionPeriodSchema.optional(),
470
573
  visibilityTimeout: VisibilityTimeoutSchema.optional(),
@@ -478,128 +581,74 @@ var QueuesSchema = z9.record(
478
581
  ])
479
582
  ).optional().describe("Define the queues in your stack.");
480
583
 
481
- // src/feature/auth/schema.ts
482
- import { z as z11 } from "zod";
483
-
484
- // src/config/schema/email.ts
485
- import { z as z10 } from "zod";
486
- var EmailSchema = z10.string().email();
487
- var isEmail = (value) => {
488
- return EmailSchema.safeParse(value).success;
489
- };
490
-
491
- // src/feature/auth/schema.ts
492
- var TriggersSchema = z11.object({
493
- beforeToken: FunctionSchema.optional().describe("A pre jwt token generation AWS Lambda trigger."),
494
- beforeLogin: FunctionSchema.optional().describe("A pre user login AWS Lambda trigger."),
495
- afterLogin: FunctionSchema.optional().describe("A post user login AWS Lambda trigger."),
496
- beforeRegister: FunctionSchema.optional().describe("A pre user register AWS Lambda trigger."),
497
- afterRegister: FunctionSchema.optional().describe("A post user register AWS Lambda trigger."),
498
- customMessage: FunctionSchema.optional().describe("A custom message AWS Lambda trigger."),
499
- // /** A custom email sender AWS Lambda trigger */
500
- // emailSender: FunctionSchema.optional(),
501
- defineChallenge: FunctionSchema.optional().describe("Defines the authentication challenge."),
502
- createChallenge: FunctionSchema.optional().describe("Creates an authentication challenge."),
503
- verifyChallenge: FunctionSchema.optional().describe("Verifies the authentication challenge response.")
504
- }).describe("Specifies the configuration for AWS Lambda triggers.");
505
- var AuthSchema = z11.record(
506
- ResourceIdSchema,
507
- z11.object({
508
- access: z11.boolean().default(false).describe("Give access to every function in this stack to your cognito instance."),
509
- triggers: TriggersSchema.optional()
510
- })
511
- ).optional().describe("Define the auth triggers in your stack.");
512
- var AuthDefaultSchema = z11.record(
513
- ResourceIdSchema,
514
- z11.object({
515
- allowUserRegistration: z11.boolean().default(true).describe("Specifies whether users can create an user account or if only the administrator can."),
516
- messaging: z11.object({
517
- fromEmail: EmailSchema.describe("Specifies the sender's email address."),
518
- fromName: z11.string().optional().describe("Specifies the sender's name."),
519
- replyTo: EmailSchema.optional().describe(
520
- "The destination to which the receiver of the email should reply."
521
- )
522
- }).optional().describe("The email configuration for sending messages."),
523
- // secret: z.boolean().default(false).describe('Specifies whether you want to generate a client secret.'),
524
- username: z11.object({
525
- emailAlias: z11.boolean().default(true).describe("Allow the user email to be used as username."),
526
- caseSensitive: z11.boolean().default(false).describe(
527
- "Specifies whether username case sensitivity will be enabled. When usernames and email addresses are case insensitive, users can sign in as the same user when they enter a different capitalization of their user name."
528
- )
529
- }).default({}).describe("The username policy."),
530
- password: z11.object({
531
- minLength: z11.number().int().min(6).max(99).default(12).describe("Required users to have at least the minimum password length."),
532
- uppercase: z11.boolean().default(true).describe("Required users to use at least one uppercase letter in their password."),
533
- lowercase: z11.boolean().default(true).describe("Required users to use at least one lowercase letter in their password."),
534
- numbers: z11.boolean().default(true).describe("Required users to use at least one number in their password."),
535
- symbols: z11.boolean().default(true).describe("Required users to use at least one symbol in their password."),
536
- temporaryPasswordValidity: DurationSchema.default("7 days").describe(
537
- "The duration a temporary password is valid. If the user doesn't sign in during this time, an administrator must reset their password."
538
- )
539
- }).default({}).describe("The password policy."),
540
- validity: z11.object({
541
- idToken: DurationSchema.default("1 hour").describe(
542
- "The ID token time limit. After this limit expires, your user can't use their ID token."
543
- ),
544
- accessToken: DurationSchema.default("1 hour").describe(
545
- "The access token time limit. After this limit expires, your user can't use their access token."
546
- ),
547
- refreshToken: DurationSchema.default("365 days").describe(
548
- "The refresh token time limit. After this limit expires, your user can't use their refresh token."
549
- )
550
- }).default({}).describe("Specifies the validity duration for every JWT token."),
551
- triggers: TriggersSchema.optional()
552
- })
553
- ).default({}).describe("Define the authenticatable users in your app.");
554
-
555
- // src/feature/http/schema.ts
556
- import { z as z12 } from "zod";
557
- var RouteSchema = z12.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route").transform((v) => v);
558
- var HttpDefaultSchema = z12.record(
559
- ResourceIdSchema,
560
- z12.object({
561
- domain: ResourceIdSchema.describe("The domain id to link your API with."),
562
- subDomain: z12.string().optional()
563
- // auth: ResourceIdSchema.optional(),
564
- })
565
- ).optional().describe("Define your global HTTP API's.");
566
- var HttpSchema = z12.record(ResourceIdSchema, z12.record(RouteSchema, FunctionSchema)).optional().describe("Define routes in your stack for your global HTTP API.");
567
-
568
584
  // src/feature/rest/schema.ts
569
- import { z as z14 } from "zod";
585
+ import { z as z15 } from "zod";
570
586
 
571
587
  // src/config/schema/route.ts
572
- import { z as z13 } from "zod";
573
- var RouteSchema2 = z13.union([
574
- z13.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route"),
575
- z13.literal("$default")
588
+ import { z as z14 } from "zod";
589
+ var RouteSchema2 = z14.union([
590
+ z14.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route"),
591
+ z14.literal("$default")
576
592
  ]);
577
593
 
578
594
  // src/feature/rest/schema.ts
579
- var RestDefaultSchema = z14.record(
595
+ var RestDefaultSchema = z15.record(
580
596
  ResourceIdSchema,
581
- z14.object({
597
+ z15.object({
582
598
  domain: ResourceIdSchema.describe("The domain id to link your API with.").optional(),
583
- subDomain: z14.string().optional()
599
+ subDomain: z15.string().optional()
584
600
  })
585
601
  ).optional().describe("Define your global REST API's.");
586
- var RestSchema = z14.record(ResourceIdSchema, z14.record(RouteSchema2, FunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
602
+ var RestSchema = z15.record(ResourceIdSchema, z15.record(RouteSchema2, FunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
603
+
604
+ // src/config/schema/region.ts
605
+ import { z as z16 } from "zod";
606
+ var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
607
+ var AF = ["af-south-1"];
608
+ var AP = [
609
+ "ap-east-1",
610
+ "ap-south-2",
611
+ "ap-southeast-3",
612
+ "ap-southeast-4",
613
+ "ap-south-1",
614
+ "ap-northeast-3",
615
+ "ap-northeast-2",
616
+ "ap-southeast-1",
617
+ "ap-southeast-2",
618
+ "ap-northeast-1"
619
+ ];
620
+ var CA = ["ca-central-1"];
621
+ var EU = [
622
+ "eu-central-1",
623
+ "eu-west-1",
624
+ "eu-west-2",
625
+ "eu-south-1",
626
+ "eu-west-3",
627
+ "eu-south-2",
628
+ "eu-north-1",
629
+ "eu-central-2"
630
+ ];
631
+ var ME = ["me-south-1", "me-central-1"];
632
+ var SA = ["sa-east-1"];
633
+ var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
634
+ var RegionSchema = z16.enum(regions);
587
635
 
588
636
  // src/config/app.ts
589
- var AppSchema = z15.object({
590
- $schema: z15.string().optional(),
637
+ var AppSchema = z17.object({
638
+ $schema: z17.string().optional(),
591
639
  name: ResourceIdSchema.describe("App name."),
592
640
  region: RegionSchema.describe("The AWS region to deploy to."),
593
- profile: z15.string().describe("The AWS profile to deploy to."),
641
+ profile: z17.string().describe("The AWS profile to deploy to."),
594
642
  // stage: z
595
643
  // .string()
596
644
  // .regex(/^[a-z]+$/)
597
645
  // .default('prod')
598
646
  // .describe('The deployment stage.'),
599
- defaults: z15.object({
647
+ defaults: z17.object({
600
648
  auth: AuthDefaultSchema,
601
649
  domains: DomainsDefaultSchema,
602
650
  function: FunctionDefaultSchema,
651
+ instance: InstanceDefaultSchema,
603
652
  queue: QueueDefaultSchema,
604
653
  graphql: GraphQLDefaultSchema,
605
654
  http: HttpDefaultSchema,
@@ -611,158 +660,55 @@ var AppSchema = z15.object({
611
660
  import { glob } from "glob";
612
661
 
613
662
  // src/config/stack.ts
614
- import { z as z29 } from "zod";
615
-
616
- // src/feature/on-failure/schema.ts
617
- var OnFailureSchema = FunctionSchema.optional().describe(
618
- "Defining a onFailure handler will add a global onFailure handler for the following resources:\n- Async lambda functions\n- SQS queues\n- DynamoDB streams"
619
- );
620
-
621
- // src/feature/config/schema.ts
622
- import { z as z16 } from "zod";
623
- var ConfigNameSchema = z16.string().regex(/[a-z0-9\-]/g, "Invalid config name");
624
- var ConfigsSchema = z16.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
663
+ import { z as z31 } from "zod";
625
664
 
626
- // src/feature/table/schema.ts
627
- import { z as z17 } from "zod";
628
- var KeySchema = z17.string().min(1).max(255);
629
- var TablesSchema = z17.record(
630
- ResourceIdSchema,
631
- z17.object({
632
- hash: KeySchema.describe(
633
- "Specifies the name of the partition / hash key that makes up the primary key for the table."
634
- ),
635
- sort: KeySchema.optional().describe(
636
- "Specifies the name of the range / sort key that makes up the primary key for the table."
637
- ),
638
- fields: z17.record(z17.string(), z17.enum(["string", "number", "binary"])).optional().describe(
639
- 'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
640
- ),
641
- class: z17.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
642
- pointInTimeRecovery: z17.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
643
- timeToLiveAttribute: KeySchema.optional().describe(
644
- "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."
645
- ),
646
- stream: z17.object({
647
- type: z17.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
648
- "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."
649
- ),
650
- consumer: FunctionSchema.describe("The consuming lambda function for the stream")
651
- }).optional().describe(
652
- "The settings for the DynamoDB table stream, which capture changes to items stored in the table."
653
- ),
654
- indexes: z17.record(
655
- z17.string(),
656
- z17.object({
657
- /** Specifies the name of the partition / hash key that makes up the primary key for the global secondary index. */
658
- hash: KeySchema,
659
- /** Specifies the name of the range / sort key that makes up the primary key for the global secondary index. */
660
- sort: KeySchema.optional(),
661
- /** The set of attributes that are projected into the index:
662
- * - all - All of the table attributes are projected into the index.
663
- * - keys-only - Only the index and primary keys are projected into the index.
664
- * @default 'all'
665
- */
666
- projection: z17.enum(["all", "keys-only"]).default("all")
667
- })
668
- ).optional().describe("Specifies the global secondary indexes to be created on the table.")
669
- })
670
- ).optional().describe("Define the tables in your stack.");
671
-
672
- // src/feature/store/schema.ts
665
+ // src/feature/cache/schema.ts
673
666
  import { z as z18 } from "zod";
674
- var StoresSchema = z18.union([
675
- z18.array(ResourceIdSchema).transform((list4) => {
676
- const stores = {};
677
- for (const key of list4) {
678
- stores[key] = {};
679
- }
680
- return stores;
681
- }),
682
- z18.record(
683
- ResourceIdSchema,
684
- z18.object({
685
- // cors: CorsSchema,
686
- versioning: z18.boolean().default(false).describe("Enable versioning of your store."),
687
- events: z18.object({
688
- // create
689
- "created:*": FunctionSchema.optional().describe(
690
- "Subscribe to notifications regardless of the API that was used to create an object."
691
- ),
692
- "created:put": FunctionSchema.optional().describe(
693
- "Subscribe to notifications when an object is created using the PUT API operation."
694
- ),
695
- "created:post": FunctionSchema.optional().describe(
696
- "Subscribe to notifications when an object is created using the POST API operation."
697
- ),
698
- "created:copy": FunctionSchema.optional().describe(
699
- "Subscribe to notifications when an object is created using the COPY API operation."
700
- ),
701
- "created:upload": FunctionSchema.optional().describe(
702
- "Subscribe to notifications when an object multipart upload has been completed."
703
- ),
704
- // remove
705
- "removed:*": FunctionSchema.optional().describe(
706
- "Subscribe to notifications when an object is deleted or a delete marker for a versioned object is created."
707
- ),
708
- "removed:delete": FunctionSchema.optional().describe(
709
- "Subscribe to notifications when an object is deleted"
710
- ),
711
- "removed:marker": FunctionSchema.optional().describe(
712
- "Subscribe to notifications when a delete marker for a versioned object is created."
713
- )
714
- }).optional().describe("Describes the store events you want to subscribe too.")
715
- })
716
- )
717
- ]).optional().describe("Define the stores in your stack.");
718
-
719
- // src/feature/pubsub/schema.ts
720
- import { z as z19 } from "zod";
721
- var PubSubSchema = z19.record(
722
- ResourceIdSchema,
723
- z19.object({
724
- sql: z19.string().describe("The SQL statement used to query the IOT topic."),
725
- sqlVersion: z19.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23").describe("The version of the SQL rules engine to use when evaluating the rule."),
726
- consumer: FunctionSchema.describe("The consuming lambda function properties.")
727
- })
728
- ).optional().describe("Define the pubsub subscriber in your stack.");
729
-
730
- // src/feature/test/schema.ts
731
- import { z as z21 } from "zod";
732
-
733
- // src/config/schema/local-directory.ts
734
- import { stat as stat2 } from "fs/promises";
735
- import { z as z20 } from "zod";
736
- var LocalDirectorySchema = z20.string().transform((path) => resolvePath(path)).refine(async (path) => {
737
- try {
738
- const s = await stat2(path);
739
- return s.isDirectory();
740
- } catch (error) {
741
- return false;
742
- }
743
- }, `Directory doesn't exist`);
744
-
745
- // src/feature/test/schema.ts
746
- var TestsSchema = z21.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
667
+ var TypeSchema2 = z18.enum([
668
+ "t4g.small",
669
+ "t4g.medium",
670
+ "r6g.large",
671
+ "r6g.xlarge",
672
+ "r6g.2xlarge",
673
+ "r6g.4xlarge",
674
+ "r6g.8xlarge",
675
+ "r6g.12xlarge",
676
+ "r6g.16xlarge",
677
+ "r6gd.xlarge",
678
+ "r6gd.2xlarge",
679
+ "r6gd.4xlarge",
680
+ "r6gd.8xlarge"
681
+ ]);
682
+ var PortSchema = z18.number().int().min(1).max(5e4);
683
+ var ShardsSchema = z18.number().int().min(0).max(100);
684
+ var ReplicasPerShardSchema = z18.number().int().min(0).max(5);
685
+ var EngineSchema = z18.enum(["7.0", "6.2"]);
686
+ var CachesSchema = z18.record(
687
+ ResourceIdSchema,
688
+ z18.object({
689
+ type: TypeSchema2.default("t4g.small"),
690
+ port: PortSchema.default(6379),
691
+ shards: ShardsSchema.default(1),
692
+ replicasPerShard: ReplicasPerShardSchema.default(1),
693
+ engine: EngineSchema.default("7.0"),
694
+ dataTiering: z18.boolean().default(false)
695
+ })
696
+ ).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
747
697
 
748
- // src/feature/topic/schema.ts
749
- import { paramCase as paramCase2 } from "change-case";
750
- import { z as z22 } from "zod";
751
- var TopicNameSchema = z22.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => paramCase2(value)).describe("Define event topic name.");
752
- var TopicsSchema = z22.array(TopicNameSchema).refine((topics) => {
753
- return topics.length === new Set(topics).size;
754
- }, "Must be a list of unique topic names").optional().describe("Define the event topics to publish too in your stack.");
755
- var SubscribersSchema = z22.record(TopicNameSchema, z22.union([EmailSchema, FunctionSchema])).optional().describe("Define the event topics to subscribe too in your stack.");
698
+ // src/feature/config/schema.ts
699
+ import { z as z19 } from "zod";
700
+ var ConfigNameSchema = z19.string().regex(/[a-z0-9\-]/g, "Invalid config name");
701
+ var ConfigsSchema = z19.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
756
702
 
757
703
  // src/feature/cron/schema/index.ts
758
- import { z as z24 } from "zod";
704
+ import { z as z21 } from "zod";
759
705
 
760
706
  // src/feature/cron/schema/schedule.ts
761
- import { z as z23 } from "zod";
707
+ import { z as z20 } from "zod";
762
708
  import { awsCronExpressionValidator } from "aws-cron-expression-validator";
763
- var RateExpressionSchema = z23.custom(
709
+ var RateExpressionSchema = z20.custom(
764
710
  (value) => {
765
- return z23.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
711
+ return z20.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
766
712
  const [str] = rate.split(" ");
767
713
  const number = parseInt(str);
768
714
  return number > 0;
@@ -778,9 +724,9 @@ var RateExpressionSchema = z23.custom(
778
724
  }
779
725
  return `rate(${rate})`;
780
726
  });
781
- var CronExpressionSchema = z23.custom(
727
+ var CronExpressionSchema = z20.custom(
782
728
  (value) => {
783
- return z23.string().safeParse(value).success;
729
+ return z20.string().safeParse(value).success;
784
730
  },
785
731
  { message: "Invalid cron expression" }
786
732
  ).superRefine((value, ctx) => {
@@ -789,12 +735,12 @@ var CronExpressionSchema = z23.custom(
789
735
  } catch (error) {
790
736
  if (error instanceof Error) {
791
737
  ctx.addIssue({
792
- code: z23.ZodIssueCode.custom,
738
+ code: z20.ZodIssueCode.custom,
793
739
  message: `Invalid cron expression: ${error.message}`
794
740
  });
795
741
  } else {
796
742
  ctx.addIssue({
797
- code: z23.ZodIssueCode.custom,
743
+ code: z20.ZodIssueCode.custom,
798
744
  message: "Invalid cron expression"
799
745
  });
800
746
  }
@@ -805,56 +751,39 @@ var CronExpressionSchema = z23.custom(
805
751
  var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
806
752
 
807
753
  // src/feature/cron/schema/index.ts
808
- var CronsSchema = z24.record(
754
+ var CronsSchema = z21.record(
809
755
  ResourceIdSchema,
810
- z24.object({
811
- enabled: z24.boolean().default(true).describe("If the cron is enabled."),
756
+ z21.object({
757
+ enabled: z21.boolean().default(true).describe("If the cron is enabled."),
812
758
  consumer: FunctionSchema.describe("The consuming lambda function properties."),
813
759
  schedule: ScheduleExpressionSchema.describe(
814
760
  'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
815
761
  ),
816
- payload: z24.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
762
+ payload: z21.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
817
763
  })
818
764
  ).optional();
819
765
 
820
- // src/feature/cache/schema.ts
821
- import { z as z25 } from "zod";
822
- var TypeSchema = z25.enum([
823
- "t4g.small",
824
- "t4g.medium",
825
- "r6g.large",
826
- "r6g.xlarge",
827
- "r6g.2xlarge",
828
- "r6g.4xlarge",
829
- "r6g.8xlarge",
830
- "r6g.12xlarge",
831
- "r6g.16xlarge",
832
- "r6gd.xlarge",
833
- "r6gd.2xlarge",
834
- "r6gd.4xlarge",
835
- "r6gd.8xlarge"
836
- ]);
837
- var PortSchema = z25.number().int().min(1).max(5e4);
838
- var ShardsSchema = z25.number().int().min(0).max(100);
839
- var ReplicasPerShardSchema = z25.number().int().min(0).max(5);
840
- var EngineSchema = z25.enum(["7.0", "6.2"]);
841
- var CachesSchema = z25.record(
766
+ // src/feature/on-failure/schema.ts
767
+ var OnFailureSchema = FunctionSchema.optional().describe(
768
+ "Defining a onFailure handler will add a global onFailure handler for the following resources:\n- Async lambda functions\n- SQS queues\n- DynamoDB streams"
769
+ );
770
+
771
+ // src/feature/pubsub/schema.ts
772
+ import { z as z22 } from "zod";
773
+ var PubSubSchema = z22.record(
842
774
  ResourceIdSchema,
843
- z25.object({
844
- type: TypeSchema.default("t4g.small"),
845
- port: PortSchema.default(6379),
846
- shards: ShardsSchema.default(1),
847
- replicasPerShard: ReplicasPerShardSchema.default(1),
848
- engine: EngineSchema.default("7.0"),
849
- dataTiering: z25.boolean().default(false)
775
+ z22.object({
776
+ sql: z22.string().describe("The SQL statement used to query the IOT topic."),
777
+ sqlVersion: z22.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23").describe("The version of the SQL rules engine to use when evaluating the rule."),
778
+ consumer: FunctionSchema.describe("The consuming lambda function properties.")
850
779
  })
851
- ).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
780
+ ).optional().describe("Define the pubsub subscriber in your stack.");
852
781
 
853
782
  // src/feature/search/schema.ts
854
- import { z as z26 } from "zod";
783
+ import { z as z23 } from "zod";
855
784
  import { gibibytes as gibibytes2 } from "@awsless/size";
856
- var VersionSchema = z26.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]);
857
- var TypeSchema2 = z26.enum([
785
+ var VersionSchema = z23.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]);
786
+ var TypeSchema3 = z23.enum([
858
787
  "t3.small",
859
788
  "t3.medium",
860
789
  "t3.large",
@@ -955,41 +884,41 @@ var TypeSchema2 = z26.enum([
955
884
  "r6gd.16xlarge"
956
885
  ]);
957
886
  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.");
958
- var SearchsSchema = z26.record(
887
+ var SearchsSchema = z23.record(
959
888
  ResourceIdSchema,
960
- z26.object({
961
- type: TypeSchema2.default("t3.small"),
962
- count: z26.number().int().min(1).default(1),
889
+ z23.object({
890
+ type: TypeSchema3.default("t3.small"),
891
+ count: z23.number().int().min(1).default(1),
963
892
  version: VersionSchema.default("2.13"),
964
893
  storage: StorageSizeSchema.default("10 GB"),
965
- vpc: z26.boolean().default(false)
894
+ vpc: z23.boolean().default(false)
966
895
  })
967
896
  ).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
968
897
 
969
898
  // src/feature/site/schema.ts
970
- import { z as z27 } from "zod";
971
- var ErrorResponsePathSchema = z27.string().describe(
899
+ import { z as z24 } from "zod";
900
+ var ErrorResponsePathSchema = z24.string().describe(
972
901
  "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."
973
902
  );
974
- var StatusCodeSchema = z27.number().int().positive().optional().describe(
903
+ var StatusCodeSchema = z24.number().int().positive().optional().describe(
975
904
  "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."
976
905
  );
977
906
  var MinTTLSchema = DurationSchema.describe(
978
907
  "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."
979
908
  );
980
- var ErrorResponseSchema = z27.union([
909
+ var ErrorResponseSchema = z24.union([
981
910
  ErrorResponsePathSchema,
982
- z27.object({
911
+ z24.object({
983
912
  path: ErrorResponsePathSchema,
984
913
  statusCode: StatusCodeSchema.optional(),
985
914
  minTTL: MinTTLSchema.optional()
986
915
  })
987
916
  ]).optional();
988
- var SitesSchema = z27.record(
917
+ var SitesSchema = z24.record(
989
918
  ResourceIdSchema,
990
- z27.object({
919
+ z24.object({
991
920
  domain: ResourceIdSchema.describe("The domain id to link your site with."),
992
- subDomain: z27.string().optional(),
921
+ subDomain: z24.string().optional(),
993
922
  // bind: z
994
923
  // .object({
995
924
  // auth: z.array(ResourceIdSchema),
@@ -1012,7 +941,7 @@ var SitesSchema = z27.record(
1012
941
  // build: z.string().optional(),
1013
942
  // }),
1014
943
  // ]),
1015
- errors: z27.object({
944
+ errors: z24.object({
1016
945
  400: ErrorResponseSchema.describe("Customize a `400 Bad Request` response."),
1017
946
  403: ErrorResponseSchema.describe("Customize a `403 Forbidden` response."),
1018
947
  404: ErrorResponseSchema.describe("Customize a `404 Not Found` response."),
@@ -1025,16 +954,16 @@ var SitesSchema = z27.record(
1025
954
  503: ErrorResponseSchema.describe("Customize a `503 Service Unavailable` response."),
1026
955
  504: ErrorResponseSchema.describe("Customize a `504 Gateway Timeout` response.")
1027
956
  }).optional().describe("Customize the error responses for specific HTTP status codes."),
1028
- cors: z27.object({
1029
- override: z27.boolean().default(false),
957
+ cors: z24.object({
958
+ override: z24.boolean().default(false),
1030
959
  maxAge: DurationSchema.default("365 days"),
1031
- exposeHeaders: z27.string().array().optional(),
1032
- credentials: z27.boolean().default(false),
1033
- headers: z27.string().array().default(["*"]),
1034
- origins: z27.string().array().default(["*"]),
1035
- methods: z27.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
960
+ exposeHeaders: z24.string().array().optional(),
961
+ credentials: z24.boolean().default(false),
962
+ headers: z24.string().array().default(["*"]),
963
+ origins: z24.string().array().default(["*"]),
964
+ methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
1036
965
  }).optional().describe("Define the cors headers."),
1037
- security: z27.object({
966
+ security: z24.object({
1038
967
  // contentSecurityPolicy: z.object({
1039
968
  // override: z.boolean().default(false),
1040
969
  // policy: z.string(),
@@ -1076,16 +1005,132 @@ var SitesSchema = z27.record(
1076
1005
  // reportUri?: string
1077
1006
  // }
1078
1007
  }).optional().describe("Define the security policy."),
1079
- cache: z27.object({
1080
- cookies: z27.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
1081
- headers: z27.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
1082
- queries: z27.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
1008
+ cache: z24.object({
1009
+ cookies: z24.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
1010
+ headers: z24.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
1011
+ queries: z24.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
1083
1012
  }).optional().describe(
1084
1013
  "Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
1085
1014
  )
1086
1015
  })
1087
1016
  ).optional().describe("Define the sites in your stack.");
1088
1017
 
1018
+ // src/feature/store/schema.ts
1019
+ import { z as z25 } from "zod";
1020
+ var StoresSchema = z25.union([
1021
+ z25.array(ResourceIdSchema).transform((list4) => {
1022
+ const stores = {};
1023
+ for (const key of list4) {
1024
+ stores[key] = {};
1025
+ }
1026
+ return stores;
1027
+ }),
1028
+ z25.record(
1029
+ ResourceIdSchema,
1030
+ z25.object({
1031
+ // cors: CorsSchema,
1032
+ versioning: z25.boolean().default(false).describe("Enable versioning of your store."),
1033
+ events: z25.object({
1034
+ // create
1035
+ "created:*": FunctionSchema.optional().describe(
1036
+ "Subscribe to notifications regardless of the API that was used to create an object."
1037
+ ),
1038
+ "created:put": FunctionSchema.optional().describe(
1039
+ "Subscribe to notifications when an object is created using the PUT API operation."
1040
+ ),
1041
+ "created:post": FunctionSchema.optional().describe(
1042
+ "Subscribe to notifications when an object is created using the POST API operation."
1043
+ ),
1044
+ "created:copy": FunctionSchema.optional().describe(
1045
+ "Subscribe to notifications when an object is created using the COPY API operation."
1046
+ ),
1047
+ "created:upload": FunctionSchema.optional().describe(
1048
+ "Subscribe to notifications when an object multipart upload has been completed."
1049
+ ),
1050
+ // remove
1051
+ "removed:*": FunctionSchema.optional().describe(
1052
+ "Subscribe to notifications when an object is deleted or a delete marker for a versioned object is created."
1053
+ ),
1054
+ "removed:delete": FunctionSchema.optional().describe(
1055
+ "Subscribe to notifications when an object is deleted"
1056
+ ),
1057
+ "removed:marker": FunctionSchema.optional().describe(
1058
+ "Subscribe to notifications when a delete marker for a versioned object is created."
1059
+ )
1060
+ }).optional().describe("Describes the store events you want to subscribe too.")
1061
+ })
1062
+ )
1063
+ ]).optional().describe("Define the stores in your stack.");
1064
+
1065
+ // src/feature/stream/schema.ts
1066
+ import { z as z26 } from "zod";
1067
+ var LatencyModeSchema = z26.enum(["low", "normal"]).describe(
1068
+ `Channel latency mode. Valid values:
1069
+ - normal: Use "normal" to broadcast and deliver live video up to Full HD.
1070
+ - low: Use "low" for near real-time interactions with viewers.`
1071
+ );
1072
+ var TypeSchema4 = z26.enum(["standard", "basic", "advanced-sd", "advanced-hd"]).describe(`The channel type, which determines the allowable resolution and bitrate.
1073
+ If you exceed the allowable resolution or bitrate, the stream probably will disconnect immediately. Valid values:
1074
+ - 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.
1075
+ - 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.
1076
+ - 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.
1077
+ - 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.
1078
+ `);
1079
+ var StreamsSchema = z26.record(
1080
+ ResourceIdSchema,
1081
+ z26.object({
1082
+ type: TypeSchema4.default("standard"),
1083
+ // preset: PresetSchema.optional(),
1084
+ latencyMode: LatencyModeSchema.default("low")
1085
+ })
1086
+ ).optional().describe("Define the streams in your stack.");
1087
+
1088
+ // src/feature/table/schema.ts
1089
+ import { z as z27 } from "zod";
1090
+ var KeySchema = z27.string().min(1).max(255);
1091
+ var TablesSchema = z27.record(
1092
+ ResourceIdSchema,
1093
+ z27.object({
1094
+ hash: KeySchema.describe(
1095
+ "Specifies the name of the partition / hash key that makes up the primary key for the table."
1096
+ ),
1097
+ sort: KeySchema.optional().describe(
1098
+ "Specifies the name of the range / sort key that makes up the primary key for the table."
1099
+ ),
1100
+ fields: z27.record(z27.string(), z27.enum(["string", "number", "binary"])).optional().describe(
1101
+ 'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
1102
+ ),
1103
+ class: z27.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
1104
+ pointInTimeRecovery: z27.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
1105
+ timeToLiveAttribute: KeySchema.optional().describe(
1106
+ "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."
1107
+ ),
1108
+ stream: z27.object({
1109
+ type: z27.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
1110
+ "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."
1111
+ ),
1112
+ consumer: FunctionSchema.describe("The consuming lambda function for the stream")
1113
+ }).optional().describe(
1114
+ "The settings for the DynamoDB table stream, which capture changes to items stored in the table."
1115
+ ),
1116
+ indexes: z27.record(
1117
+ z27.string(),
1118
+ z27.object({
1119
+ /** Specifies the name of the partition / hash key that makes up the primary key for the global secondary index. */
1120
+ hash: KeySchema,
1121
+ /** Specifies the name of the range / sort key that makes up the primary key for the global secondary index. */
1122
+ sort: KeySchema.optional(),
1123
+ /** The set of attributes that are projected into the index:
1124
+ * - all - All of the table attributes are projected into the index.
1125
+ * - keys-only - Only the index and primary keys are projected into the index.
1126
+ * @default 'all'
1127
+ */
1128
+ projection: z27.enum(["all", "keys-only"]).default("all")
1129
+ })
1130
+ ).optional().describe("Specifies the global secondary indexes to be created on the table.")
1131
+ })
1132
+ ).optional().describe("Define the tables in your stack.");
1133
+
1089
1134
  // src/feature/task/schema.ts
1090
1135
  import { z as z28 } from "zod";
1091
1136
  var RetryAttemptsSchema2 = z28.number().int().min(0).max(2).describe(
@@ -1103,13 +1148,26 @@ var TaskSchema = z28.union([
1103
1148
  ]);
1104
1149
  var TasksSchema = z28.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
1105
1150
 
1151
+ // src/feature/test/schema.ts
1152
+ import { z as z29 } from "zod";
1153
+ var TestsSchema = z29.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
1154
+
1155
+ // src/feature/topic/schema.ts
1156
+ import { paramCase as paramCase2 } from "change-case";
1157
+ import { z as z30 } from "zod";
1158
+ var TopicNameSchema = z30.string().min(3).max(256).regex(/^[a-z0-9\-]+$/i, "Invalid topic name").transform((value) => paramCase2(value)).describe("Define event topic name.");
1159
+ var TopicsSchema = z30.array(TopicNameSchema).refine((topics) => {
1160
+ return topics.length === new Set(topics).size;
1161
+ }, "Must be a list of unique topic names").optional().describe("Define the event topics to publish too in your stack.");
1162
+ var SubscribersSchema = z30.record(TopicNameSchema, z30.union([EmailSchema, FunctionSchema])).optional().describe("Define the event topics to subscribe too in your stack.");
1163
+
1106
1164
  // src/config/stack.ts
1107
1165
  var DependsSchema = ResourceIdSchema.array().optional().describe("Define the stacks that this stack is depended on.");
1108
1166
  var NameSchema = ResourceIdSchema.refine((name) => !["base"].includes(name), {
1109
1167
  message: `Stack name can't be a reserved name.`
1110
1168
  }).describe("Stack name.");
1111
- var StackSchema = z29.object({
1112
- $schema: z29.string().optional(),
1169
+ var StackSchema = z31.object({
1170
+ $schema: z31.string().optional(),
1113
1171
  name: NameSchema,
1114
1172
  depends: DependsSchema,
1115
1173
  onFailure: OnFailureSchema,
@@ -1123,9 +1181,11 @@ var StackSchema = z29.object({
1123
1181
  topics: TopicsSchema,
1124
1182
  subscribers: SubscribersSchema,
1125
1183
  functions: FunctionsSchema,
1184
+ instances: InstancesSchema,
1126
1185
  tasks: TasksSchema,
1127
1186
  tables: TablesSchema,
1128
1187
  stores: StoresSchema,
1188
+ streams: StreamsSchema,
1129
1189
  queues: QueuesSchema,
1130
1190
  pubsub: PubSubSchema,
1131
1191
  searchs: SearchsSchema,
@@ -1188,13 +1248,13 @@ var readConfigWithStage = async (file, stage) => {
1188
1248
  };
1189
1249
 
1190
1250
  // src/config/load/validate.ts
1191
- import { z as z30 } from "zod";
1251
+ import { z as z32 } from "zod";
1192
1252
  var validateConfig = async (schema, file, data) => {
1193
1253
  try {
1194
1254
  const result = await schema.parseAsync(data);
1195
1255
  return result;
1196
1256
  } catch (error) {
1197
- if (error instanceof z30.ZodError) {
1257
+ if (error instanceof z32.ZodError) {
1198
1258
  throw new ConfigError(file, error, data);
1199
1259
  }
1200
1260
  throw error;
@@ -2056,11 +2116,11 @@ var findDependencies = async (file, code) => {
2056
2116
  // src/feature/function/build/zip.ts
2057
2117
  import JSZip from "jszip";
2058
2118
  var zipFiles = (files) => {
2059
- const zip = new JSZip();
2119
+ const zip2 = new JSZip();
2060
2120
  for (const file of files) {
2061
- zip.file(file.name, file.code);
2121
+ zip2.file(file.name, file.code);
2062
2122
  }
2063
- return zip.generateAsync({
2123
+ return zip2.generateAsync({
2064
2124
  type: "nodebuffer",
2065
2125
  compression: "DEFLATE",
2066
2126
  compressionOptions: {
@@ -2147,14 +2207,14 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
2147
2207
  const policy = new aws.iam.RolePolicy(group, "policy", {
2148
2208
  role: role.name,
2149
2209
  name: "lambda-policy",
2150
- version: "2012-10-17",
2151
- statements: [
2152
- {
2153
- // Give lambda access to all lambda's inside your app.
2154
- actions: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
2155
- resources: [`arn:aws:lambda:*:*:function:${ctx.appConfig.name}--*`]
2156
- }
2157
- ]
2210
+ version: "2012-10-17"
2211
+ // statements: [
2212
+ // {
2213
+ // // Give lambda access to all lambda's inside your app.
2214
+ // actions: ['lambda:InvokeFunction', 'lambda:InvokeAsync'],
2215
+ // resources: [`arn:aws:lambda:*:*:function:${ctx.appConfig.name}--*`],
2216
+ // },
2217
+ // ],
2158
2218
  });
2159
2219
  const lambda = new aws.lambda.Function(group, `function`, {
2160
2220
  ...props,
@@ -2166,7 +2226,10 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
2166
2226
  vpc: void 0,
2167
2227
  log: props.log
2168
2228
  });
2169
- ctx.registerFunction(lambda, policy);
2229
+ ctx.onEnv((name2, value) => {
2230
+ lambda.addEnvironment(name2, value);
2231
+ });
2232
+ ctx.registerPolicy(policy);
2170
2233
  lambda.addEnvironment("APP", ctx.appConfig.name);
2171
2234
  if ("stackConfig" in ctx) {
2172
2235
  lambda.addEnvironment("STACK", ctx.stackConfig.name);
@@ -2275,7 +2338,6 @@ var authFeature = defineFeature({
2275
2338
  const gen = new TypeFile("@awsless/awsless/client");
2276
2339
  const resources = new TypeObject(1);
2277
2340
  for (const name of Object.keys(ctx.appConfig.defaults.auth)) {
2278
- const authName = formatGlobalResourceName(ctx.appConfig.name, "auth", name);
2279
2341
  resources.addType(name, `{ readonly userPoolId: string, readonly clientId: string }`);
2280
2342
  }
2281
2343
  gen.addInterface("AuthResources", resources);
@@ -2367,8 +2429,8 @@ var authFeature = defineFeature({
2367
2429
  userSrp: true
2368
2430
  }
2369
2431
  });
2370
- ctx.bindEnv(`AUTH_${constantCase2(id)}_USER_POOL_ID`, userPool.id);
2371
- ctx.bindEnv(`AUTH_${constantCase2(id)}_CLIENT_ID`, client.id);
2432
+ ctx.bind(`AUTH_${constantCase2(id)}_USER_POOL_ID`, userPool.id);
2433
+ ctx.bind(`AUTH_${constantCase2(id)}_CLIENT_ID`, client.id);
2372
2434
  ctx.shared.set(`auth-${id}-user-pool-arn`, userPool.arn);
2373
2435
  ctx.shared.set(`auth-${id}-user-pool-id`, userPool.id);
2374
2436
  ctx.shared.set(`auth-${id}-client-id`, client.id);
@@ -2377,8 +2439,8 @@ var authFeature = defineFeature({
2377
2439
  });
2378
2440
 
2379
2441
  // src/feature/cache/index.ts
2442
+ import { aws as aws3, Node as Node3 } from "@awsless/formation";
2380
2443
  import { constantCase as constantCase3 } from "change-case";
2381
- import { Node as Node3, aws as aws3 } from "@awsless/formation";
2382
2444
  var typeGenCode = `
2383
2445
  import { Cluster, CommandOptions } from '@awsless/redis'
2384
2446
 
@@ -2433,11 +2495,9 @@ var cacheFeature = defineFeature({
2433
2495
  subnetGroupName: subnetGroup.name,
2434
2496
  ...props
2435
2497
  });
2436
- ctx.onFunction(({ lambda }) => {
2437
- const prefix = `CACHE_${constantCase3(ctx.stack.name)}_${constantCase3(id)}`;
2438
- lambda.addEnvironment(`${prefix}_HOST`, cluster.address);
2439
- lambda.addEnvironment(`${prefix}_PORT`, props.port.toString());
2440
- });
2498
+ const prefix = `CACHE_${constantCase3(ctx.stack.name)}_${constantCase3(id)}`;
2499
+ ctx.addEnv(`${prefix}_HOST`, cluster.address);
2500
+ ctx.addEnv(`${prefix}_PORT`, props.port.toString());
2441
2501
  }
2442
2502
  }
2443
2503
  });
@@ -2563,9 +2623,9 @@ var configFeature = defineFeature({
2563
2623
  for (const name of configs) {
2564
2624
  ctx.registerConfig(name);
2565
2625
  }
2566
- ctx.onFunction(({ lambda, policy }) => {
2567
- if (configs.length) {
2568
- lambda.addEnvironment("CONFIG", configs.join(","));
2626
+ if (configs.length) {
2627
+ ctx.addEnv("CONFIG", configs.join(","));
2628
+ ctx.onPolicy((policy) => {
2569
2629
  policy.addStatement({
2570
2630
  actions: [
2571
2631
  "ssm:GetParameter",
@@ -2579,8 +2639,8 @@ var configFeature = defineFeature({
2579
2639
  )}/${paramCase4(name)}`
2580
2640
  )
2581
2641
  });
2582
- }
2583
- });
2642
+ });
2643
+ }
2584
2644
  }
2585
2645
  });
2586
2646
 
@@ -2615,8 +2675,8 @@ var cronFeature = defineFeature({
2615
2675
  });
2616
2676
 
2617
2677
  // src/feature/domain/index.ts
2618
- import { Node as Node5, aws as aws5 } from "@awsless/formation";
2619
2678
  import { minutes as minutes3 } from "@awsless/duration";
2679
+ import { aws as aws5, Node as Node5 } from "@awsless/formation";
2620
2680
  var domainFeature = defineFeature({
2621
2681
  name: "domain",
2622
2682
  onApp(ctx) {
@@ -2712,8 +2772,8 @@ var domainFeature = defineFeature({
2712
2772
  });
2713
2773
  }
2714
2774
  }
2715
- ctx.onFunction(
2716
- ({ policy }) => policy.addStatement({
2775
+ ctx.onPolicy(
2776
+ (policy) => policy.addStatement({
2717
2777
  actions: ["ses:*"],
2718
2778
  resources: [`arn:aws:ses:${ctx.appConfig.region}:${ctx.accountId}:identity/*`]
2719
2779
  })
@@ -2788,6 +2848,12 @@ var functionFeature = defineFeature({
2788
2848
  });
2789
2849
  ctx.shared.set("function-repository-name", repository.name);
2790
2850
  ctx.shared.set("function-repository-uri", repository.uri);
2851
+ ctx.onPolicy((policy) => {
2852
+ policy.addStatement({
2853
+ actions: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
2854
+ resources: [`arn:aws:lambda:*:*:function:${ctx.appConfig.name}--*`]
2855
+ });
2856
+ });
2791
2857
  },
2792
2858
  onStack(ctx) {
2793
2859
  for (const [id, props] of Object.entries(ctx.stackConfig.functions || {})) {
@@ -3137,9 +3203,9 @@ var graphqlFeature = defineFeature({
3137
3203
  evaluateTargetHealth: false
3138
3204
  }
3139
3205
  });
3140
- ctx.bindEnv(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, domainName);
3206
+ ctx.bind(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, domainName);
3141
3207
  } else {
3142
- ctx.bindEnv(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, api.graphql.uri);
3208
+ ctx.bind(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, api.graphql.uri);
3143
3209
  }
3144
3210
  }
3145
3211
  },
@@ -3330,7 +3396,7 @@ var httpFeature = defineFeature({
3330
3396
  dnsName: loadBalancer.dnsName
3331
3397
  }
3332
3398
  });
3333
- ctx.bindEnv(`HTTP_${constantCase5(id)}_ENDPOINT`, domainName);
3399
+ ctx.bind(`HTTP_${constantCase5(id)}_ENDPOINT`, domainName);
3334
3400
  }
3335
3401
  },
3336
3402
  onStack(ctx) {
@@ -3374,8 +3440,147 @@ var httpFeature = defineFeature({
3374
3440
  }
3375
3441
  });
3376
3442
 
3443
+ // src/feature/instance/index.ts
3444
+ import { days as days3 } from "@awsless/duration";
3445
+ import { Asset as Asset3, aws as aws9, combine, Node as Node9, Output as Output2, unwrap } from "@awsless/formation";
3446
+ import { hashElement as hashElement2 } from "folder-hash";
3447
+ import { mkdir as mkdir2 } from "fs/promises";
3448
+ import { dirname as dirname9 } from "path";
3449
+ import { zip } from "zip-a-folder";
3450
+ var instanceFeature = defineFeature({
3451
+ name: "instance",
3452
+ onApp(ctx) {
3453
+ const group = new Node9(ctx.base, "instance", "asset");
3454
+ const bucket = new aws9.s3.Bucket(group, "bucket", {
3455
+ name: formatGlobalResourceName(ctx.appConfig.name, "instance", "assets"),
3456
+ versioning: true,
3457
+ forceDelete: true
3458
+ });
3459
+ ctx.shared.set("instance-bucket-name", bucket.name);
3460
+ if (ctx.appConfig.defaults.instance.connect) {
3461
+ new aws9.ec2.InstanceConnectEndpoint(group, "connect", {
3462
+ name: ctx.appConfig.name,
3463
+ subnetId: ctx.shared.get(`vpc-public-subnet-id-1`),
3464
+ securityGroupIds: [ctx.shared.get("vpc-security-group-id")]
3465
+ });
3466
+ }
3467
+ },
3468
+ onStack(ctx) {
3469
+ for (const [id, props] of Object.entries(ctx.stackConfig.instances ?? {})) {
3470
+ const group = new Node9(ctx.stack, "instance", id);
3471
+ const name = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "instance", id);
3472
+ const env = {
3473
+ APP: ctx.appConfig.name,
3474
+ STACK: ctx.stackConfig.name
3475
+ };
3476
+ ctx.onEnv((name2, value) => {
3477
+ env[name2] = value;
3478
+ if (value instanceof Output2) {
3479
+ template.dependsOn(...value.resources);
3480
+ }
3481
+ });
3482
+ const bucketName = ctx.shared.get("instance-bucket-name");
3483
+ const userData = new Output2([], (resolve) => {
3484
+ ctx.onReady(() => {
3485
+ combine([bucketName, ...Object.values(env)]).apply(async ([bucketName2]) => {
3486
+ const u = "ec2-user";
3487
+ const code2 = [
3488
+ `#!/bin/bash`,
3489
+ `cd /home/${u}`,
3490
+ `sudo -u ${u} aws configure set default.s3.use_dualstack_endpoint true`,
3491
+ `sudo -u ${u} aws s3 cp s3://${bucketName2}/${name} .`,
3492
+ `sudo -u ${u} unzip -o ${name} -d ./code`,
3493
+ `sudo -u ${u} rm ./${name}`,
3494
+ `cd ./code`,
3495
+ ...Object.entries(env).map(([key, value]) => {
3496
+ return `export ${key}="${unwrap(value)}"`;
3497
+ }),
3498
+ props.command ? `sudo -u ${u} ${props.command}` : ""
3499
+ ].join("\n");
3500
+ resolve(Asset3.fromString(Buffer.from(code2, "utf8").toString("base64")));
3501
+ });
3502
+ });
3503
+ });
3504
+ const bundleFile = getBuildPath("instance", name, "bundle.zip");
3505
+ ctx.registerBuild("instance", name, async (build3) => {
3506
+ const version = await hashElement2(props.code, {
3507
+ files: {
3508
+ exclude: ["stack.json"]
3509
+ }
3510
+ });
3511
+ await build3(version.hash, async () => {
3512
+ await mkdir2(dirname9(bundleFile), { recursive: true });
3513
+ await zip(props.code, bundleFile);
3514
+ });
3515
+ });
3516
+ const code = new aws9.s3.BucketObject(group, "code", {
3517
+ key: name,
3518
+ bucket: bucketName,
3519
+ body: Asset3.fromFile(bundleFile)
3520
+ });
3521
+ const template = new aws9.ec2.LaunchTemplate(group, "template", {
3522
+ name,
3523
+ imageId: props.image,
3524
+ instanceType: props.type,
3525
+ securityGroupIds: [ctx.shared.get("vpc-security-group-id")],
3526
+ monitoring: true,
3527
+ userData
3528
+ // userData: userData.value.apply(Asset.fromString),
3529
+ // userData: Asset.fromString('echo 1'),
3530
+ });
3531
+ const role = new aws9.iam.Role(group, "role", {
3532
+ name,
3533
+ assumedBy: "ec2.amazonaws.com"
3534
+ });
3535
+ const policy = new aws9.iam.RolePolicy(group, "policy", {
3536
+ name,
3537
+ role: role.name
3538
+ });
3539
+ policy.addStatement({
3540
+ actions: [
3541
+ "s3:GetObject"
3542
+ //
3543
+ // 's3:*',
3544
+ ],
3545
+ resources: [
3546
+ bucketName.apply((bucket) => `arn:aws:s3:::${bucket}/${name}`)
3547
+ //
3548
+ // '*',
3549
+ ]
3550
+ });
3551
+ ctx.registerPolicy(policy);
3552
+ const profile = new aws9.iam.InstanceProfile(group, "profile", {
3553
+ name,
3554
+ roles: [role.name]
3555
+ });
3556
+ const instance = new aws9.ec2.Instance(group, "instance", {
3557
+ name,
3558
+ iamInstanceProfile: profile.arn,
3559
+ launchTemplate: template,
3560
+ subnetId: ctx.shared.get(`vpc-public-subnet-id-1`)
3561
+ // keyName: props.ssh ? ctx.shared.get('instance-key-name') : undefined,
3562
+ });
3563
+ instance.dependsOn(code);
3564
+ const logGroup = new aws9.cloudWatch.LogGroup(group, "log", {
3565
+ name: `/awsless/instance/${name}`,
3566
+ retention: days3(3)
3567
+ });
3568
+ policy.addStatement(
3569
+ {
3570
+ actions: ["logs:CreateLogStream"],
3571
+ resources: [logGroup.arn]
3572
+ },
3573
+ {
3574
+ actions: ["logs:PutLogEvents"],
3575
+ resources: [logGroup.arn.apply((arn) => `${arn}:*`)]
3576
+ }
3577
+ );
3578
+ }
3579
+ }
3580
+ });
3581
+
3377
3582
  // src/feature/on-failure/index.ts
3378
- import { Node as Node9, aws as aws9 } from "@awsless/formation";
3583
+ import { Node as Node10, aws as aws10 } from "@awsless/formation";
3379
3584
  var onFailureFeature = defineFeature({
3380
3585
  name: "on-failure",
3381
3586
  onApp(ctx) {
@@ -3386,7 +3591,7 @@ var onFailureFeature = defineFeature({
3386
3591
  if (count > 1) {
3387
3592
  throw new TypeError("Only 1 onFailure configuration is allowed in your app.");
3388
3593
  }
3389
- const queue2 = new aws9.sqs.Queue(ctx.base, "on-failure", {
3594
+ const queue2 = new aws10.sqs.Queue(ctx.base, "on-failure", {
3390
3595
  name: formatGlobalResourceName(ctx.appConfig.name, "on-failure", "failure")
3391
3596
  });
3392
3597
  ctx.shared.set("on-failure-queue-arn", queue2.arn);
@@ -3397,9 +3602,9 @@ var onFailureFeature = defineFeature({
3397
3602
  return;
3398
3603
  }
3399
3604
  const queueArn = ctx.shared.get("on-failure-queue-arn");
3400
- const group = new Node9(ctx.stack, "on-failure", "failure");
3605
+ const group = new Node10(ctx.stack, "on-failure", "failure");
3401
3606
  const { lambda, policy } = createLambdaFunction(group, ctx, "on-failure", "failure", onFailure);
3402
- const source = new aws9.lambda.EventSourceMapping(group, "on-failure", {
3607
+ const source = new aws10.lambda.EventSourceMapping(group, "on-failure", {
3403
3608
  functionArn: lambda.arn,
3404
3609
  sourceArn: queueArn,
3405
3610
  batchSize: 10
@@ -3419,29 +3624,29 @@ var onFailureFeature = defineFeature({
3419
3624
  });
3420
3625
 
3421
3626
  // src/feature/pubsub/index.ts
3422
- import { Node as Node10, aws as aws10 } from "@awsless/formation";
3627
+ import { aws as aws11, Node as Node11 } from "@awsless/formation";
3423
3628
  var pubsubFeature = defineFeature({
3424
3629
  name: "pubsub",
3425
3630
  onApp(ctx) {
3426
- ctx.onFunction(({ policy }) => {
3631
+ ctx.onPolicy((policy) => {
3427
3632
  policy.addStatement({
3428
- actions: ["iot-data:publish"],
3633
+ actions: [`iot:Publish`],
3429
3634
  resources: [`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:rule/*`]
3430
3635
  });
3431
3636
  });
3432
3637
  },
3433
3638
  onStack(ctx) {
3434
3639
  for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
3435
- const group = new Node10(ctx.stack, "pubsub", id);
3640
+ const group = new Node11(ctx.stack, "pubsub", id);
3436
3641
  const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
3437
3642
  const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "pubsub", id);
3438
- const topic = new aws10.iot.TopicRule(group, "rule", {
3643
+ const topic = new aws11.iot.TopicRule(group, "rule", {
3439
3644
  name: name.replaceAll("-", "_"),
3440
3645
  sql: props.sql,
3441
3646
  sqlVersion: props.sqlVersion,
3442
3647
  actions: [{ lambda: { functionArn: lambda.arn } }]
3443
3648
  });
3444
- new aws10.lambda.Permission(group, "permission", {
3649
+ new aws11.lambda.Permission(group, "permission", {
3445
3650
  action: "lambda:InvokeFunction",
3446
3651
  principal: "iot.amazonaws.com",
3447
3652
  functionArn: lambda.arn,
@@ -3452,10 +3657,10 @@ var pubsubFeature = defineFeature({
3452
3657
  });
3453
3658
 
3454
3659
  // src/feature/queue/index.ts
3660
+ import { aws as aws12, Node as Node12 } from "@awsless/formation";
3455
3661
  import { camelCase as camelCase5, constantCase as constantCase6 } from "change-case";
3456
- import { relative as relative3 } from "path";
3457
3662
  import deepmerge2 from "deepmerge";
3458
- import { Node as Node11, aws as aws11 } from "@awsless/formation";
3663
+ import { relative as relative3 } from "path";
3459
3664
  var typeGenCode3 = `
3460
3665
  import { SendMessageOptions, SendMessageBatchOptions, BatchItem } from '@awsless/sqs'
3461
3666
  import type { Mock } from 'vitest'
@@ -3507,15 +3712,15 @@ var queueFeature = defineFeature({
3507
3712
  onStack(ctx) {
3508
3713
  for (const [id, local2] of Object.entries(ctx.stackConfig.queues || {})) {
3509
3714
  const props = deepmerge2(ctx.appConfig.defaults.queue, local2);
3510
- const group = new Node11(ctx.stack, "queue", id);
3511
- const queue2 = new aws11.sqs.Queue(group, "queue", {
3715
+ const group = new Node12(ctx.stack, "queue", id);
3716
+ const queue2 = new aws12.sqs.Queue(group, "queue", {
3512
3717
  name: formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "queue", id),
3513
3718
  deadLetterArn: getGlobalOnFailure(ctx),
3514
3719
  ...props
3515
3720
  });
3516
3721
  const { lambda, policy } = createLambdaFunction(group, ctx, `queue`, id, props.consumer);
3517
3722
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
3518
- new aws11.lambda.EventSourceMapping(group, "event", {
3723
+ new aws12.lambda.EventSourceMapping(group, "event", {
3519
3724
  functionArn: lambda.arn,
3520
3725
  sourceArn: queue2.arn,
3521
3726
  batchSize: props.batchSize,
@@ -3526,27 +3731,27 @@ var queueFeature = defineFeature({
3526
3731
  actions: ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"],
3527
3732
  resources: [queue2.arn]
3528
3733
  });
3529
- ctx.onFunction(({ lambda: lambda2, policy: policy2 }) => {
3734
+ ctx.addEnv(`QUEUE_${constantCase6(ctx.stack.name)}_${constantCase6(id)}_URL`, queue2.url);
3735
+ ctx.onPolicy((policy2) => {
3530
3736
  policy2.addStatement(queue2.permissions);
3531
- lambda2.addEnvironment(`QUEUE_${constantCase6(ctx.stack.name)}_${constantCase6(id)}_URL`, queue2.url);
3532
3737
  });
3533
3738
  }
3534
3739
  }
3535
3740
  });
3536
3741
 
3537
3742
  // src/feature/rest/index.ts
3538
- import { aws as aws12, Node as Node12 } from "@awsless/formation";
3743
+ import { aws as aws13, Node as Node13 } from "@awsless/formation";
3539
3744
  import { constantCase as constantCase7 } from "change-case";
3540
3745
  var restFeature = defineFeature({
3541
3746
  name: "rest",
3542
3747
  onApp(ctx) {
3543
3748
  for (const [id, props] of Object.entries(ctx.appConfig.defaults?.rest ?? {})) {
3544
- const group = new Node12(ctx.base, "rest", id);
3545
- const api = new aws12.apiGatewayV2.Api(group, "api", {
3749
+ const group = new Node13(ctx.base, "rest", id);
3750
+ const api = new aws13.apiGatewayV2.Api(group, "api", {
3546
3751
  name: formatGlobalResourceName(ctx.app.name, "rest", id),
3547
3752
  protocolType: "HTTP"
3548
3753
  });
3549
- const stage = new aws12.apiGatewayV2.Stage(group, "stage", {
3754
+ const stage = new aws13.apiGatewayV2.Stage(group, "stage", {
3550
3755
  name: "v1",
3551
3756
  apiId: api.id
3552
3757
  });
@@ -3555,7 +3760,7 @@ var restFeature = defineFeature({
3555
3760
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
3556
3761
  const hostedZoneId = ctx.shared.get(`hosted-zone-${props.domain}-id`);
3557
3762
  const certificateArn = ctx.shared.get(`certificate-${props.domain}-arn`);
3558
- const domain = new aws12.apiGatewayV2.DomainName(group, "domain", {
3763
+ const domain = new aws13.apiGatewayV2.DomainName(group, "domain", {
3559
3764
  name: domainName,
3560
3765
  certificates: [
3561
3766
  {
@@ -3563,12 +3768,12 @@ var restFeature = defineFeature({
3563
3768
  }
3564
3769
  ]
3565
3770
  });
3566
- const mapping = new aws12.apiGatewayV2.ApiMapping(group, "mapping", {
3771
+ const mapping = new aws13.apiGatewayV2.ApiMapping(group, "mapping", {
3567
3772
  apiId: api.id,
3568
3773
  domainName: domain.name,
3569
3774
  stage: stage.name
3570
3775
  });
3571
- const record = new aws12.route53.RecordSet(group, "record", {
3776
+ const record = new aws13.route53.RecordSet(group, "record", {
3572
3777
  hostedZoneId,
3573
3778
  type: "A",
3574
3779
  name: domainName,
@@ -3579,28 +3784,28 @@ var restFeature = defineFeature({
3579
3784
  }
3580
3785
  });
3581
3786
  record.dependsOn(domain, mapping);
3582
- ctx.bindEnv(`REST_${constantCase7(id)}_ENDPOINT`, domainName);
3787
+ ctx.bind(`REST_${constantCase7(id)}_ENDPOINT`, domainName);
3583
3788
  } else {
3584
3789
  }
3585
3790
  }
3586
3791
  },
3587
3792
  onStack(ctx) {
3588
3793
  for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
3589
- const restGroup = new Node12(ctx.stack, "rest", id);
3794
+ const restGroup = new Node13(ctx.stack, "rest", id);
3590
3795
  for (const [routeKey, props] of Object.entries(routes)) {
3591
- const group = new Node12(restGroup, "route", routeKey);
3796
+ const group = new Node13(restGroup, "route", routeKey);
3592
3797
  const apiId = ctx.shared.get(`rest-${id}-id`);
3593
3798
  const routeId = shortId(routeKey);
3594
3799
  const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
3595
3800
  ...props,
3596
3801
  description: `${id} ${routeKey}`
3597
3802
  });
3598
- const permission = new aws12.lambda.Permission(group, "permission", {
3803
+ const permission = new aws13.lambda.Permission(group, "permission", {
3599
3804
  action: "lambda:InvokeFunction",
3600
3805
  principal: "apigateway.amazonaws.com",
3601
3806
  functionArn: lambda.arn
3602
3807
  });
3603
- const integration = new aws12.apiGatewayV2.Integration(group, "integration", {
3808
+ const integration = new aws13.apiGatewayV2.Integration(group, "integration", {
3604
3809
  apiId,
3605
3810
  description: `${id} ${routeKey}`,
3606
3811
  method: "POST",
@@ -3610,7 +3815,7 @@ var restFeature = defineFeature({
3610
3815
  return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
3611
3816
  })
3612
3817
  });
3613
- const route = new aws12.apiGatewayV2.Route(group, "route", {
3818
+ const route = new aws13.apiGatewayV2.Route(group, "route", {
3614
3819
  apiId,
3615
3820
  routeKey,
3616
3821
  target: integration.id.apply((id2) => `integrations/${id2}`)
@@ -3622,7 +3827,7 @@ var restFeature = defineFeature({
3622
3827
  });
3623
3828
 
3624
3829
  // src/feature/search/index.ts
3625
- import { Node as Node13, aws as aws13 } from "@awsless/formation";
3830
+ import { aws as aws14, Node as Node14 } from "@awsless/formation";
3626
3831
  import { constantCase as constantCase8 } from "change-case";
3627
3832
  var typeGenCode4 = `
3628
3833
  import { AnyStruct, Table } from '@awsless/open-search'
@@ -3650,8 +3855,8 @@ var searchFeature = defineFeature({
3650
3855
  },
3651
3856
  onStack(ctx) {
3652
3857
  for (const [id, props] of Object.entries(ctx.stackConfig.searchs ?? {})) {
3653
- const group = new Node13(ctx.stack, "search", id);
3654
- const openSearch = new aws13.openSearch.Domain(group, "domain", {
3858
+ const group = new Node14(ctx.stack, "search", id);
3859
+ const openSearch = new aws14.openSearch.Domain(group, "domain", {
3655
3860
  // name: formatLocalResourceName(ctx.app.name, ctx.stack.name, this.name, id),
3656
3861
  version: props.version,
3657
3862
  storageSize: props.storage,
@@ -3677,11 +3882,8 @@ var searchFeature = defineFeature({
3677
3882
  ]
3678
3883
  });
3679
3884
  }
3680
- ctx.onFunction(({ lambda, policy }) => {
3681
- lambda.addEnvironment(
3682
- `SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`,
3683
- openSearch.domainEndpoint
3684
- );
3885
+ ctx.addEnv(`SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`, openSearch.domainEndpoint);
3886
+ ctx.onPolicy((policy) => {
3685
3887
  policy.addStatement({
3686
3888
  actions: ["es:*"],
3687
3889
  resources: [openSearch.arn]
@@ -3692,8 +3894,8 @@ var searchFeature = defineFeature({
3692
3894
  });
3693
3895
 
3694
3896
  // src/feature/site/index.ts
3695
- import { Asset as Asset3, Node as Node14, aws as aws14 } from "@awsless/formation";
3696
- import { days as days3, seconds as seconds3 } from "@awsless/duration";
3897
+ import { days as days4, seconds as seconds3 } from "@awsless/duration";
3898
+ import { Asset as Asset4, aws as aws15, Node as Node15 } from "@awsless/formation";
3697
3899
  import { glob as glob2 } from "glob";
3698
3900
  import { join as join8 } from "path";
3699
3901
 
@@ -3722,7 +3924,7 @@ var siteFeature = defineFeature({
3722
3924
  name: "site",
3723
3925
  onStack(ctx) {
3724
3926
  for (const [id, props] of Object.entries(ctx.stackConfig.sites ?? {})) {
3725
- const group = new Node14(ctx.stack, "site", id);
3927
+ const group = new Node15(ctx.stack, "site", id);
3726
3928
  const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "site", id);
3727
3929
  const origins = [];
3728
3930
  const originGroups = [];
@@ -3731,8 +3933,10 @@ var siteFeature = defineFeature({
3731
3933
  if (props.ssr) {
3732
3934
  const { lambda, code } = createLambdaFunction(group, ctx, `site`, id, props.ssr);
3733
3935
  versions.push(code.version);
3734
- ctx.registerSiteFunction(lambda);
3735
- new aws14.lambda.Permission(group, "permission", {
3936
+ ctx.onBind((name2, value) => {
3937
+ lambda.addEnvironment(name2, value);
3938
+ });
3939
+ new aws15.lambda.Permission(group, "permission", {
3736
3940
  principal: "*",
3737
3941
  // principal: 'cloudfront.amazonaws.com',
3738
3942
  action: "lambda:InvokeFunctionUrl",
@@ -3741,7 +3945,7 @@ var siteFeature = defineFeature({
3741
3945
  // urlAuthType: 'aws-iam',
3742
3946
  // sourceArn: distribution.arn,
3743
3947
  });
3744
- const url = new aws14.lambda.Url(group, "url", {
3948
+ const url = new aws15.lambda.Url(group, "url", {
3745
3949
  targetArn: lambda.arn,
3746
3950
  authType: "none"
3747
3951
  // authType: 'aws-iam',
@@ -3753,7 +3957,7 @@ var siteFeature = defineFeature({
3753
3957
  });
3754
3958
  }
3755
3959
  if (props.static) {
3756
- bucket = new aws14.s3.Bucket(group, "bucket", {
3960
+ bucket = new aws15.s3.Bucket(group, "bucket", {
3757
3961
  name,
3758
3962
  forceDelete: true,
3759
3963
  website: {
@@ -3770,7 +3974,7 @@ var siteFeature = defineFeature({
3770
3974
  ]
3771
3975
  });
3772
3976
  bucket.deletionPolicy = "after-deployment";
3773
- const accessControl = new aws14.cloudFront.OriginAccessControl(group, `access`, {
3977
+ const accessControl = new aws15.cloudFront.OriginAccessControl(group, `access`, {
3774
3978
  name,
3775
3979
  type: "s3",
3776
3980
  behavior: "always",
@@ -3782,10 +3986,10 @@ var siteFeature = defineFeature({
3782
3986
  nodir: true
3783
3987
  });
3784
3988
  for (const file of files) {
3785
- const object = new aws14.s3.BucketObject(group, file, {
3989
+ const object = new aws15.s3.BucketObject(group, file, {
3786
3990
  bucket: bucket.name,
3787
3991
  key: file,
3788
- body: Asset3.fromFile(join8(props.static, file)),
3992
+ body: Asset4.fromFile(join8(props.static, file)),
3789
3993
  cacheControl: getCacheControl(file),
3790
3994
  contentType: getContentType(file)
3791
3995
  });
@@ -3805,14 +4009,14 @@ var siteFeature = defineFeature({
3805
4009
  statusCodes: [403, 404]
3806
4010
  });
3807
4011
  }
3808
- const cache = new aws14.cloudFront.CachePolicy(group, "cache", {
4012
+ const cache = new aws15.cloudFront.CachePolicy(group, "cache", {
3809
4013
  name,
3810
4014
  minTtl: seconds3(1),
3811
- maxTtl: days3(365),
3812
- defaultTtl: days3(1),
4015
+ maxTtl: days4(365),
4016
+ defaultTtl: days4(1),
3813
4017
  ...props.cache
3814
4018
  });
3815
- const originRequest = new aws14.cloudFront.OriginRequestPolicy(group, "request", {
4019
+ const originRequest = new aws15.cloudFront.OriginRequestPolicy(group, "request", {
3816
4020
  name,
3817
4021
  header: {
3818
4022
  behavior: "all-except",
@@ -3820,7 +4024,7 @@ var siteFeature = defineFeature({
3820
4024
  }
3821
4025
  });
3822
4026
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
3823
- const responseHeaders = new aws14.cloudFront.ResponseHeadersPolicy(group, "response", {
4027
+ const responseHeaders = new aws15.cloudFront.ResponseHeadersPolicy(group, "response", {
3824
4028
  name,
3825
4029
  cors: props.cors,
3826
4030
  remove: ["server"]
@@ -3828,7 +4032,7 @@ var siteFeature = defineFeature({
3828
4032
  // override: true,
3829
4033
  // },
3830
4034
  });
3831
- const distribution = new aws14.cloudFront.Distribution(group, "distribution", {
4035
+ const distribution = new aws15.cloudFront.Distribution(group, "distribution", {
3832
4036
  name,
3833
4037
  certificateArn: ctx.shared.get(`global-certificate-${props.domain}-arn`),
3834
4038
  compress: true,
@@ -3856,13 +4060,13 @@ var siteFeature = defineFeature({
3856
4060
  };
3857
4061
  })
3858
4062
  });
3859
- new aws14.cloudFront.InvalidateCache(group, "invalidate", {
4063
+ new aws15.cloudFront.InvalidateCache(group, "invalidate", {
3860
4064
  distributionId: distribution.id,
3861
4065
  paths: ["/*"],
3862
4066
  versions
3863
4067
  });
3864
4068
  if (props.static) {
3865
- new aws14.s3.BucketPolicy(group, `policy`, {
4069
+ new aws15.s3.BucketPolicy(group, `policy`, {
3866
4070
  bucketName: bucket.name,
3867
4071
  statements: [
3868
4072
  {
@@ -3888,7 +4092,7 @@ var siteFeature = defineFeature({
3888
4092
  ]
3889
4093
  });
3890
4094
  }
3891
- new aws14.route53.RecordSet(group, `record`, {
4095
+ new aws15.route53.RecordSet(group, `record`, {
3892
4096
  hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
3893
4097
  type: "A",
3894
4098
  name: domainName,
@@ -3903,7 +4107,7 @@ var siteFeature = defineFeature({
3903
4107
  });
3904
4108
 
3905
4109
  // src/feature/store/index.ts
3906
- import { aws as aws15, Node as Node15 } from "@awsless/formation";
4110
+ import { aws as aws16, Node as Node16 } from "@awsless/formation";
3907
4111
  import { paramCase as paramCase6 } from "change-case";
3908
4112
  var typeGenCode5 = `
3909
4113
  import { Body, PutObjectProps, BodyStream, createPresignedPost } from '@awsless/s3'
@@ -3940,7 +4144,7 @@ var storeFeature = defineFeature({
3940
4144
  },
3941
4145
  onStack(ctx) {
3942
4146
  for (const [id, props] of Object.entries(ctx.stackConfig.stores ?? {})) {
3943
- const group = new Node15(ctx.stack, "store", id);
4147
+ const group = new Node16(ctx.stack, "store", id);
3944
4148
  const bucketName = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "store", id);
3945
4149
  const lambdaConfigs = [];
3946
4150
  const eventMap = {
@@ -3954,10 +4158,10 @@ var storeFeature = defineFeature({
3954
4158
  "removed:marker": "s3:ObjectRemoved:DeleteMarkerCreated"
3955
4159
  };
3956
4160
  for (const [event, funcProps] of Object.entries(props.events ?? {})) {
3957
- const eventGroup = new Node15(group, "event", event);
4161
+ const eventGroup = new Node16(group, "event", event);
3958
4162
  const eventId = paramCase6(`${id}-${shortId(event)}`);
3959
4163
  const { lambda } = createAsyncLambdaFunction(eventGroup, ctx, `store`, eventId, funcProps);
3960
- new aws15.lambda.Permission(eventGroup, "permission", {
4164
+ new aws16.lambda.Permission(eventGroup, "permission", {
3961
4165
  action: "lambda:InvokeFunction",
3962
4166
  principal: "s3.amazonaws.com",
3963
4167
  functionArn: lambda.arn,
@@ -3968,7 +4172,7 @@ var storeFeature = defineFeature({
3968
4172
  function: lambda.arn
3969
4173
  });
3970
4174
  }
3971
- const bucket = new aws15.s3.Bucket(group, "store", {
4175
+ const bucket = new aws16.s3.Bucket(group, "store", {
3972
4176
  name: bucketName,
3973
4177
  versioning: props.versioning,
3974
4178
  lambdaConfigs,
@@ -3983,15 +4187,39 @@ var storeFeature = defineFeature({
3983
4187
  // ---------------------------------------------
3984
4188
  ]
3985
4189
  });
3986
- ctx.onFunction(({ policy }) => {
4190
+ ctx.onPolicy((policy) => {
3987
4191
  policy.addStatement(bucket.permissions);
3988
4192
  });
3989
4193
  }
3990
4194
  }
3991
4195
  });
3992
4196
 
4197
+ // src/feature/stream/index.ts
4198
+ import { aws as aws17, Node as Node17 } from "@awsless/formation";
4199
+ import { constantCase as constantCase9 } from "change-case";
4200
+ var streamFeature = defineFeature({
4201
+ name: "stream",
4202
+ onStack(ctx) {
4203
+ for (const [id, props] of Object.entries(ctx.stackConfig.streams ?? {})) {
4204
+ const group = new Node17(ctx.stack, "stream", id);
4205
+ const name = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "stream", id);
4206
+ const channel = new aws17.ivs.Channel(group, "channel", {
4207
+ name,
4208
+ ...props
4209
+ });
4210
+ const streamKey = new aws17.ivs.StreamKey(group, "key", {
4211
+ channel: channel.arn
4212
+ });
4213
+ const prefix = `STREAM_${constantCase9(ctx.stack.name)}_${constantCase9(id)}`;
4214
+ ctx.bind(`${prefix}_ENDPOINT`, channel.playbackUrl);
4215
+ ctx.addEnv(`${prefix}_INGEST_ENDPOINT`, channel.ingestEndpoint);
4216
+ ctx.addEnv(`${prefix}_STREAM_KEY`, streamKey.value);
4217
+ }
4218
+ }
4219
+ });
4220
+
3993
4221
  // src/feature/table/index.ts
3994
- import { Node as Node16, aws as aws16 } from "@awsless/formation";
4222
+ import { aws as aws18, Node as Node18 } from "@awsless/formation";
3995
4223
  var tableFeature = defineFeature({
3996
4224
  name: "table",
3997
4225
  async onTypeGen(ctx) {
@@ -4010,8 +4238,8 @@ var tableFeature = defineFeature({
4010
4238
  },
4011
4239
  onStack(ctx) {
4012
4240
  for (const [id, props] of Object.entries(ctx.stackConfig.tables ?? {})) {
4013
- const group = new Node16(ctx.stack, "table", id);
4014
- const table2 = new aws16.dynamodb.Table(group, "table", {
4241
+ const group = new Node18(ctx.stack, "table", id);
4242
+ const table2 = new aws18.dynamodb.Table(group, "table", {
4015
4243
  ...props,
4016
4244
  name: formatLocalResourceName(ctx.appConfig.name, ctx.stackConfig.name, "table", id),
4017
4245
  stream: props.stream?.type
@@ -4020,7 +4248,7 @@ var tableFeature = defineFeature({
4020
4248
  const { lambda, policy } = createLambdaFunction(group, ctx, "table", id, props.stream.consumer);
4021
4249
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
4022
4250
  const onFailure = getGlobalOnFailure(ctx);
4023
- const source = new aws16.lambda.EventSourceMapping(group, id, {
4251
+ const source = new aws18.lambda.EventSourceMapping(group, id, {
4024
4252
  functionArn: lambda.arn,
4025
4253
  sourceArn: table2.streamArn,
4026
4254
  batchSize: 100,
@@ -4039,7 +4267,7 @@ var tableFeature = defineFeature({
4039
4267
  });
4040
4268
  }
4041
4269
  }
4042
- ctx.onFunction(({ policy }) => {
4270
+ ctx.onPolicy((policy) => {
4043
4271
  policy.addStatement(...table2.permissions);
4044
4272
  });
4045
4273
  }
@@ -4047,9 +4275,9 @@ var tableFeature = defineFeature({
4047
4275
  });
4048
4276
 
4049
4277
  // src/feature/task/index.ts
4278
+ import { Node as Node19 } from "@awsless/formation";
4050
4279
  import { camelCase as camelCase6 } from "change-case";
4051
4280
  import { relative as relative4 } from "path";
4052
- import { Node as Node17 } from "@awsless/formation";
4053
4281
  var typeGenCode6 = `
4054
4282
  import { InvokeOptions } from '@awsless/lambda'
4055
4283
  import type { Mock } from 'vitest'
@@ -4097,7 +4325,7 @@ var taskFeature = defineFeature({
4097
4325
  },
4098
4326
  onStack(ctx) {
4099
4327
  for (const [id, props] of Object.entries(ctx.stackConfig.tasks ?? {})) {
4100
- const group = new Node17(ctx.stack, "task", id);
4328
+ const group = new Node19(ctx.stack, "task", id);
4101
4329
  createAsyncLambdaFunction(group, ctx, "task", id, props.consumer);
4102
4330
  }
4103
4331
  }
@@ -4114,7 +4342,7 @@ var testFeature = defineFeature({
4114
4342
  });
4115
4343
 
4116
4344
  // src/feature/topic/index.ts
4117
- import { Node as Node18, aws as aws17 } from "@awsless/formation";
4345
+ import { aws as aws19, Node as Node20 } from "@awsless/formation";
4118
4346
  var typeGenCode7 = `
4119
4347
  import type { PublishOptions } from '@awsless/sns'
4120
4348
  import type { Mock } from 'vitest'
@@ -4151,8 +4379,8 @@ var topicFeature = defineFeature({
4151
4379
  onApp(ctx) {
4152
4380
  for (const stack of ctx.stackConfigs) {
4153
4381
  for (const id of stack.topics ?? []) {
4154
- const group = new Node18(ctx.base, "topic", id);
4155
- const topic = new aws17.sns.Topic(group, "topic", {
4382
+ const group = new Node20(ctx.base, "topic", id);
4383
+ const topic = new aws19.sns.Topic(group, "topic", {
4156
4384
  name: formatGlobalResourceName(ctx.appConfig.name, "topic", id)
4157
4385
  });
4158
4386
  ctx.shared.set(`topic-${id}-arn`, topic.arn);
@@ -4161,7 +4389,7 @@ var topicFeature = defineFeature({
4161
4389
  },
4162
4390
  onStack(ctx) {
4163
4391
  for (const id of ctx.stackConfig.topics ?? []) {
4164
- ctx.onFunction(({ policy }) => {
4392
+ ctx.onPolicy((policy) => {
4165
4393
  policy.addStatement({
4166
4394
  actions: ["sns:Publish"],
4167
4395
  resources: [ctx.shared.get(`topic-${id}-arn`)]
@@ -4169,22 +4397,22 @@ var topicFeature = defineFeature({
4169
4397
  });
4170
4398
  }
4171
4399
  for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
4172
- const group = new Node18(ctx.stack, "topic", id);
4400
+ const group = new Node20(ctx.stack, "topic", id);
4173
4401
  const topicArn = ctx.shared.get(`topic-${id}-arn`);
4174
4402
  if (typeof props === "string" && isEmail(props)) {
4175
- new aws17.sns.Subscription(group, id, {
4403
+ new aws19.sns.Subscription(group, id, {
4176
4404
  topicArn,
4177
4405
  protocol: "email",
4178
4406
  endpoint: props
4179
4407
  });
4180
4408
  } else if (typeof props === "object") {
4181
4409
  const { lambda } = createAsyncLambdaFunction(group, ctx, `topic`, id, props);
4182
- new aws17.sns.Subscription(group, id, {
4410
+ new aws19.sns.Subscription(group, id, {
4183
4411
  topicArn,
4184
4412
  protocol: "lambda",
4185
4413
  endpoint: lambda.arn
4186
4414
  });
4187
- new aws17.lambda.Permission(group, id, {
4415
+ new aws19.lambda.Permission(group, id, {
4188
4416
  action: "lambda:InvokeFunction",
4189
4417
  principal: "sns.amazonaws.com",
4190
4418
  functionArn: lambda.arn,
@@ -4196,52 +4424,72 @@ var topicFeature = defineFeature({
4196
4424
  });
4197
4425
 
4198
4426
  // src/feature/vpc/index.ts
4199
- import { Node as Node19, all, aws as aws18 } from "@awsless/formation";
4427
+ import { ipv6CidrBlockFromString } from "@arcanyx/cidr-slicer";
4428
+ import { aws as aws20, combine as combine2, Node as Node21 } from "@awsless/formation";
4200
4429
  var vpcFeature = defineFeature({
4201
4430
  name: "vpc",
4202
4431
  onApp(ctx) {
4203
- const group = new Node19(ctx.base, "vpc", "main");
4204
- const vpc = new aws18.ec2.Vpc(group, "vpc", {
4432
+ const group = new Node21(ctx.base, "vpc", "main");
4433
+ const vpc = new aws20.ec2.Vpc(group, "vpc", {
4205
4434
  name: ctx.app.name,
4206
- cidrBlock: aws18.ec2.Peer.ipv4("10.0.0.0/16")
4435
+ cidrBlock: aws20.ec2.Peer.ipv4("10.0.0.0/16")
4436
+ // cidrBlock: aws.ec2.Peer.ipv6('fd00:10:20::/48'),
4437
+ // cidrBlock: aws.ec2.Peer.ipv6('2a05:d018:c69:6600::/56'),
4438
+ // enableDnsSupport: true,
4439
+ // enableDnsHostnames: true,
4440
+ });
4441
+ const ipv6CidrBlock = new aws20.ec2.VPCCidrBlock(group, "ipv6", {
4442
+ vpcId: vpc.id,
4443
+ amazonProvidedIpv6CidrBlock: true
4444
+ });
4445
+ const slices = ipv6CidrBlock.ipv6CidrBlock.apply((ip) => {
4446
+ return ipv6CidrBlockFromString(ip).slice(64);
4207
4447
  });
4208
- const privateRouteTable = new aws18.ec2.RouteTable(group, "private", {
4448
+ const privateRouteTable = new aws20.ec2.RouteTable(group, "private", {
4209
4449
  vpcId: vpc.id,
4210
4450
  name: "private"
4211
4451
  });
4212
- const publicRouteTable = new aws18.ec2.RouteTable(group, "public", {
4452
+ const publicRouteTable = new aws20.ec2.RouteTable(group, "public", {
4213
4453
  vpcId: vpc.id,
4214
4454
  name: "public"
4215
4455
  });
4216
- const gateway = new aws18.ec2.InternetGateway(group, "gateway");
4217
- const attachment = new aws18.ec2.VPCGatewayAttachment(group, "attachment", {
4456
+ const gateway = new aws20.ec2.InternetGateway(group, "gateway");
4457
+ const attachment = new aws20.ec2.VPCGatewayAttachment(group, "attachment", {
4218
4458
  vpcId: vpc.id,
4219
4459
  internetGatewayId: gateway.id
4220
4460
  });
4221
- new aws18.ec2.Route(group, "route", {
4461
+ new aws20.ec2.Route(group, "route", {
4222
4462
  gatewayId: gateway.id,
4223
4463
  routeTableId: publicRouteTable.id,
4224
- destination: aws18.ec2.Peer.anyIpv4()
4464
+ // destination: aws.ec2.Peer.anyIpv4(),
4465
+ destination: aws20.ec2.Peer.anyIpv6()
4225
4466
  });
4226
4467
  ctx.shared.set(
4227
4468
  "vpc-id",
4228
4469
  // Some resources require the internet gateway to be attached.
4229
- all([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
4470
+ combine2([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
4230
4471
  );
4231
4472
  ctx.shared.set("vpc-security-group-id", vpc.defaultSecurityGroup);
4232
4473
  const zones = ["a", "b"];
4233
4474
  const tables = [privateRouteTable, publicRouteTable];
4234
- let block = 0;
4475
+ let block = 0n;
4235
4476
  for (const table2 of tables) {
4236
4477
  for (const i in zones) {
4237
4478
  const index = Number(i) + 1;
4238
4479
  const id = `${table2.identifier}-${index}`;
4239
- const subnet = new aws18.ec2.Subnet(group, id, {
4480
+ const subnet = new aws20.ec2.Subnet(group, id, {
4481
+ name: `${ctx.app.name}--${table2.identifier}-${index}`,
4240
4482
  vpcId: vpc.id,
4241
- cidrBlock: aws18.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
4483
+ cidrBlock: aws20.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
4484
+ // ipv6CidrBlock: aws.ec2.Peer.ipv6(`fd00:10:20:${++block}::/64`),
4485
+ // ipv6CidrBlock: aws.ec2.Peer.ipv6(`2a05:d018:c69:660${++block}::/64`),
4486
+ // ipv6CidrBlock: ipv6CidrBlock.ipv6CidrBlock.apply(ip => ),
4487
+ ipv6CidrBlock: slices.apply((list4) => aws20.ec2.Peer.ipv6(list4.get(block++).toString())),
4488
+ assignIpv6AddressOnCreation: true,
4489
+ // ipv6Native: true,
4242
4490
  availabilityZone: ctx.appConfig.region + zones[i]
4243
4491
  });
4244
- new aws18.ec2.SubnetRouteTableAssociation(group, id, {
4492
+ new aws20.ec2.SubnetRouteTableAssociation(group, id, {
4245
4493
  routeTableId: table2.id,
4246
4494
  subnetId: subnet.id
4247
4495
  });
@@ -4261,10 +4509,12 @@ var features = [
4261
4509
  authFeature,
4262
4510
  // 3
4263
4511
  functionFeature,
4512
+ instanceFeature,
4264
4513
  graphqlFeature,
4265
4514
  configFeature,
4266
4515
  searchFeature,
4267
4516
  pubsubFeature,
4517
+ streamFeature,
4268
4518
  tableFeature,
4269
4519
  topicFeature,
4270
4520
  queueFeature,
@@ -4313,26 +4563,39 @@ var createApp = (props, filters = []) => {
4313
4563
  const app = new App(props.appConfig.name);
4314
4564
  const base = new Stack(app, "base");
4315
4565
  const shared = new SharedData();
4316
- const binds = [];
4317
4566
  const siteFunctions = [];
4318
4567
  const configs = /* @__PURE__ */ new Set();
4319
4568
  const tests = [];
4320
4569
  const builders = [];
4321
- const allFunctions = [];
4322
- const globalListeners = [];
4323
- const allLocalListeners = {};
4324
- const allLocalFunctions = {};
4570
+ const readyListeners = [];
4571
+ const binds = [];
4572
+ const bindListeners = [];
4573
+ const allEnv = [];
4574
+ const allEnvListeners = [];
4575
+ const allLocalEnv = {};
4576
+ const allLocalEnvListeners = {};
4577
+ const allPolicies = [];
4578
+ const allPoliciesListeners = [];
4579
+ const allLocalPolicies = {};
4580
+ const allLocalPolicyListeners = {};
4325
4581
  for (const feature of features) {
4326
4582
  feature.onApp?.({
4327
4583
  ...props,
4328
4584
  app,
4585
+ // env,
4329
4586
  base,
4330
4587
  shared,
4331
- onFunction(callback) {
4332
- globalListeners.push(callback);
4588
+ onPolicy(callback) {
4589
+ allPoliciesListeners.push(callback);
4333
4590
  },
4334
- registerFunction(lambda, policy) {
4335
- allFunctions.push({ lambda, policy });
4591
+ // onFunction(callback) {
4592
+ // allFunctionListeners.push(callback)
4593
+ // },
4594
+ // registerFunction(lambda) {
4595
+ // allFunctions.push(lambda)
4596
+ // },
4597
+ registerPolicy(policy) {
4598
+ allPolicies.push(policy);
4336
4599
  },
4337
4600
  registerTest(name, paths) {
4338
4601
  tests.push({ name, paths });
@@ -4340,11 +4603,23 @@ var createApp = (props, filters = []) => {
4340
4603
  registerBuild(type, name, builder) {
4341
4604
  builders.push({ type, name, builder });
4342
4605
  },
4343
- registerSiteFunction(lambda) {
4344
- siteFunctions.push(lambda);
4345
- },
4346
- bindEnv(name, value) {
4606
+ // registerSiteFunction(lambda) {
4607
+ // siteFunctions.push(lambda)
4608
+ // },
4609
+ bind(name, value) {
4347
4610
  binds.push({ name, value });
4611
+ },
4612
+ onBind(cb) {
4613
+ bindListeners.push(cb);
4614
+ },
4615
+ addEnv(name, value) {
4616
+ allEnv.push({ name, value });
4617
+ },
4618
+ onEnv(cb) {
4619
+ allEnvListeners.push(cb);
4620
+ },
4621
+ onReady(cb) {
4622
+ readyListeners.push(cb);
4348
4623
  }
4349
4624
  });
4350
4625
  }
@@ -4354,25 +4629,37 @@ var createApp = (props, filters = []) => {
4354
4629
  filterdStacks = filterdStacks.filter((stack) => filtersWithDeps.includes(stack.name));
4355
4630
  }
4356
4631
  for (const stackConfig of filterdStacks) {
4357
- const localListeners = [];
4358
- const localFunctions = [];
4632
+ const localPolicyListeners = [];
4633
+ const localPolicies = [];
4634
+ const localEnvListeners = [];
4635
+ const localEnv = [];
4359
4636
  const stack = new Stack(app, stackConfig.name);
4360
- allLocalListeners[stack.name] = localListeners;
4361
- allLocalFunctions[stack.name] = localFunctions;
4637
+ allLocalPolicyListeners[stack.name] = localPolicyListeners;
4638
+ allLocalPolicies[stack.name] = localPolicies;
4639
+ allLocalEnvListeners[stack.name] = localEnvListeners;
4640
+ allLocalEnv[stack.name] = localEnv;
4362
4641
  for (const feature of features) {
4363
4642
  feature.onStack?.({
4364
4643
  ...props,
4365
4644
  stackConfig,
4366
4645
  app,
4646
+ // env,
4367
4647
  base,
4368
4648
  stack,
4369
4649
  shared,
4370
- onFunction(callback) {
4371
- localListeners.push(callback);
4650
+ // onFunction(callback) {
4651
+ // localFunctionListeners.push(callback)
4652
+ // },
4653
+ // registerFunction(lambda) {
4654
+ // allFunctions.push(lambda)
4655
+ // localFunctions.push(lambda)
4656
+ // },
4657
+ onPolicy(callback) {
4658
+ localPolicyListeners.push(callback);
4372
4659
  },
4373
- registerFunction(lambda, policy) {
4374
- allFunctions.push({ lambda, policy });
4375
- localFunctions.push({ lambda, policy });
4660
+ registerPolicy(policy) {
4661
+ allPolicies.push(policy);
4662
+ localPolicies.push(policy);
4376
4663
  },
4377
4664
  registerTest(name, paths) {
4378
4665
  tests.push({ name, paths });
@@ -4383,41 +4670,71 @@ var createApp = (props, filters = []) => {
4383
4670
  registerConfig(name) {
4384
4671
  configs.add(name);
4385
4672
  },
4386
- registerSiteFunction(lambda) {
4387
- siteFunctions.push(lambda);
4388
- },
4389
- bindEnv(name, value) {
4673
+ // registerSiteFunction(lambda) {
4674
+ // siteFunctions.push(lambda)
4675
+ // },
4676
+ // bindEnv(name, value) {
4677
+ // binds.push({ name, value })
4678
+ // },
4679
+ bind(name, value) {
4390
4680
  binds.push({ name, value });
4681
+ },
4682
+ onBind(cb) {
4683
+ bindListeners.push(cb);
4684
+ },
4685
+ addEnv(name, value) {
4686
+ localEnv.push({ name, value });
4687
+ },
4688
+ onEnv(cb) {
4689
+ localEnvListeners.push(cb);
4690
+ },
4691
+ onReady(cb) {
4692
+ readyListeners.push(cb);
4391
4693
  }
4392
4694
  });
4393
4695
  }
4394
- for (const listener of localListeners) {
4395
- for (const fn of localFunctions) {
4396
- listener(fn);
4696
+ for (const listener of localPolicyListeners) {
4697
+ for (const policy of localPolicies) {
4698
+ listener(policy);
4699
+ }
4700
+ }
4701
+ for (const listener of localEnvListeners) {
4702
+ for (const env of localEnv) {
4703
+ listener(env.name, env.value);
4397
4704
  }
4398
4705
  }
4399
4706
  }
4400
- for (const listener of globalListeners) {
4401
- for (const fn of allFunctions) {
4707
+ for (const listener of allPoliciesListeners) {
4708
+ for (const fn of allPolicies) {
4402
4709
  listener(fn);
4403
4710
  }
4404
4711
  }
4405
- for (const lambda of siteFunctions) {
4406
- for (const { name, value } of binds) {
4407
- lambda.addEnvironment(name, value);
4712
+ for (const listener of allEnvListeners) {
4713
+ for (const env of allEnv) {
4714
+ listener(env.name, env.value);
4408
4715
  }
4409
4716
  }
4410
4717
  for (const stackConfig of filterdStacks) {
4411
- const functions = allLocalFunctions[stackConfig.name];
4718
+ const policies = allLocalPolicies[stackConfig.name];
4719
+ const env = allLocalEnv[stackConfig.name];
4412
4720
  for (const dependency of stackConfig.depends ?? []) {
4413
- const listeners = allLocalListeners[dependency];
4414
- for (const fn of functions) {
4415
- for (const listener of listeners) {
4416
- listener(fn);
4721
+ const policyListeners = allLocalPolicyListeners[dependency];
4722
+ const envListeners = allLocalEnvListeners[dependency];
4723
+ for (const policy of policies) {
4724
+ for (const listener of policyListeners) {
4725
+ listener(policy);
4726
+ }
4727
+ }
4728
+ for (const entry of env) {
4729
+ for (const listener of envListeners) {
4730
+ listener(entry.name, entry.value);
4417
4731
  }
4418
4732
  }
4419
4733
  }
4420
4734
  }
4735
+ for (const listener of readyListeners) {
4736
+ listener();
4737
+ }
4421
4738
  return {
4422
4739
  app,
4423
4740
  base,
@@ -4611,19 +4928,19 @@ import { confirm as confirm3 } from "@clack/prompts";
4611
4928
 
4612
4929
  // src/util/workspace.ts
4613
4930
  import { minutes as minutes4 } from "@awsless/duration";
4614
- import { aws as aws20, local, WorkSpace } from "@awsless/formation";
4615
- import { mkdir as mkdir2, readFile as readFile6, rm, writeFile as writeFile2 } from "fs/promises";
4616
- import { dirname as dirname9, join as join9 } from "path";
4931
+ import { aws as aws22, local, WorkSpace } from "@awsless/formation";
4932
+ import { mkdir as mkdir3, readFile as readFile6, rm, writeFile as writeFile2 } from "fs/promises";
4933
+ import { dirname as dirname10, join as join9 } from "path";
4617
4934
  var createWorkSpace = (props) => {
4618
- const lockProvider = new aws20.dynamodb.LockProvider({
4935
+ const lockProvider = new aws22.dynamodb.LockProvider({
4619
4936
  ...props,
4620
4937
  tableName: "awsless-locks"
4621
4938
  });
4622
- const stateProvider = new aws20.s3.StateProvider({
4939
+ const stateProvider = new aws22.s3.StateProvider({
4623
4940
  ...props,
4624
4941
  bucket: "awsless-state"
4625
4942
  });
4626
- const cloudProviders = aws20.createCloudProviders({
4943
+ const cloudProviders = aws22.createCloudProviders({
4627
4944
  ...props,
4628
4945
  timeout: minutes4(60)
4629
4946
  });
@@ -4642,7 +4959,7 @@ var createWorkSpace = (props) => {
4642
4959
  var pullRemoteState = async (app, stateProvider) => {
4643
4960
  const file = join9(directories.state, `${app.urn}.json`);
4644
4961
  const state2 = await stateProvider.get(app.urn);
4645
- await mkdir2(dirname9(file), { recursive: true });
4962
+ await mkdir3(dirname10(file), { recursive: true });
4646
4963
  if (typeof state2 === "undefined") {
4647
4964
  await rm(file);
4648
4965
  } else {
@@ -4699,7 +5016,7 @@ import { confirm as confirm4 } from "@clack/prompts";
4699
5016
 
4700
5017
  // src/cli/ui/complex/run-tests.ts
4701
5018
  import { join as join11 } from "path";
4702
- import { mkdir as mkdir3, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
5019
+ import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
4703
5020
 
4704
5021
  // src/test/reporter.ts
4705
5022
  import { getSuites, getTests } from "@vitest/runner/utils";
@@ -4781,10 +5098,10 @@ import { startVitest } from "vitest/node";
4781
5098
  import commonjs3 from "@rollup/plugin-commonjs";
4782
5099
  import nodeResolve3 from "@rollup/plugin-node-resolve";
4783
5100
  import json3 from "@rollup/plugin-json";
4784
- import { dirname as dirname10, join as join10 } from "path";
5101
+ import { dirname as dirname11, join as join10 } from "path";
4785
5102
  import { fileURLToPath } from "url";
4786
5103
  var startTest = async (props) => {
4787
- const __dirname = dirname10(fileURLToPath(import.meta.url));
5104
+ const __dirname = dirname11(fileURLToPath(import.meta.url));
4788
5105
  const result = await startVitest(
4789
5106
  "test",
4790
5107
  props.filters,
@@ -4892,7 +5209,7 @@ var logTestErrors = (event) => {
4892
5209
  });
4893
5210
  };
4894
5211
  var runTest = async (stack, dir, filters) => {
4895
- await mkdir3(directories.test, { recursive: true });
5212
+ await mkdir4(directories.test, { recursive: true });
4896
5213
  const fingerprint = await fingerprintFromDirectory(dir);
4897
5214
  const file = join11(directories.test, `${stack}.json`);
4898
5215
  const exists = await fileExist(file);
@@ -5002,7 +5319,7 @@ var deploy = (program2) => {
5002
5319
  };
5003
5320
 
5004
5321
  // src/cli/command/diff.ts
5005
- import { aws as aws21, WorkSpace as WorkSpace2 } from "@awsless/formation";
5322
+ import { aws as aws23, WorkSpace as WorkSpace2 } from "@awsless/formation";
5006
5323
  import chalk7 from "chalk";
5007
5324
  var diff = (program2) => {
5008
5325
  program2.command("diff").description("Diff your app with AWS").action(async (filters) => {
@@ -5011,15 +5328,15 @@ var diff = (program2) => {
5011
5328
  const credentials = getCredentials(appConfig.profile);
5012
5329
  const accountId = await getAccountId(credentials, region);
5013
5330
  await bootstrapAwsless({ credentials, region });
5014
- const { app, builders } = createApp({ appConfig, stackConfigs, accountId }, filters);
5331
+ const { app, builders } = await createApp({ appConfig, stackConfigs, accountId }, filters);
5015
5332
  await buildAssets(builders);
5016
5333
  const workspace = new WorkSpace2({
5017
- stateProvider: new aws21.dynamodb.DynamoDBStateProvider({
5334
+ stateProvider: new aws23.dynamodb.DynamoDBStateProvider({
5018
5335
  credentials,
5019
5336
  region,
5020
5337
  tableName: "awsless-state"
5021
5338
  }),
5022
- cloudProviders: aws21.createCloudProviders({
5339
+ cloudProviders: aws23.createCloudProviders({
5023
5340
  credentials,
5024
5341
  region: appConfig.region
5025
5342
  })
@@ -5074,8 +5391,8 @@ var diff = (program2) => {
5074
5391
  import { log as log9 } from "@clack/prompts";
5075
5392
 
5076
5393
  // src/type-gen/generate.ts
5077
- import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
5078
- import { dirname as dirname11, join as join12, relative as relative5 } from "path";
5394
+ import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
5395
+ import { dirname as dirname12, join as join12, relative as relative5 } from "path";
5079
5396
  var generateTypes = async (props) => {
5080
5397
  const files = [];
5081
5398
  await Promise.all(
@@ -5089,7 +5406,7 @@ var generateTypes = async (props) => {
5089
5406
  if (include) {
5090
5407
  files.push(relative5(directories.root, path));
5091
5408
  }
5092
- await mkdir4(dirname11(path), { recursive: true });
5409
+ await mkdir5(dirname12(path), { recursive: true });
5093
5410
  await writeFile4(path, code);
5094
5411
  }
5095
5412
  }
@@ -5275,7 +5592,7 @@ import {
5275
5592
  AdminSetUserPasswordCommand,
5276
5593
  CognitoIdentityProviderClient
5277
5594
  } from "@aws-sdk/client-cognito-identity-provider";
5278
- import { unwrap } from "@awsless/formation";
5595
+ import { unwrap as unwrap2 } from "@awsless/formation";
5279
5596
  import { password, select, text as text2 } from "@clack/prompts";
5280
5597
  var create = (program2) => {
5281
5598
  program2.command("create").argument("[name]", "The name of the auth instance").description("Create an user for your userpool").action(async (name) => {
@@ -5304,7 +5621,7 @@ var create = (program2) => {
5304
5621
  await workspace.hydrate(app);
5305
5622
  let userPoolId;
5306
5623
  try {
5307
- userPoolId = unwrap(shared.get(`auth-${name}-user-pool-id`));
5624
+ userPoolId = unwrap2(shared.get(`auth-${name}-user-pool-id`));
5308
5625
  } catch (_) {
5309
5626
  throw new Error(`The auth userpool hasn't been deployed yet.`);
5310
5627
  }
@@ -5366,7 +5683,7 @@ var auth = (program2) => {
5366
5683
  };
5367
5684
 
5368
5685
  // src/cli/command/bind.ts
5369
- import { unwrap as unwrap2 } from "@awsless/formation";
5686
+ import { unwrap as unwrap3 } from "@awsless/formation";
5370
5687
  import { note as note3 } from "@clack/prompts";
5371
5688
  import { spawn } from "child_process";
5372
5689
  var bind = (program2) => {
@@ -5384,7 +5701,7 @@ var bind = (program2) => {
5384
5701
  await workspace.hydrate(app);
5385
5702
  const env = {};
5386
5703
  for (const { name, value } of binds) {
5387
- env[name] = unwrap2(value);
5704
+ env[name] = unwrap3(value);
5388
5705
  }
5389
5706
  note3(wrap(list(env)), "Bind Env");
5390
5707
  const command = commands7.join(" ");