@awsless/awsless 0.0.267 → 0.0.270

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,73 @@ 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 EnvironmentSchema2 = z12.record(z12.string(), z12.string()).optional().describe("Environment variable key-value pairs.");
497
+ var InstanceDefaultSchema = z12.object({
498
+ connect: ConnectSchema.default(false)
499
+ }).default({}).describe("Define the default settings for all instances in your stacks.");
500
+ var InstancesSchema = z12.record(
501
+ ResourceIdSchema,
502
+ z12.object({
503
+ image: ImageSchema,
504
+ type: TypeSchema,
505
+ code: CodeSchema,
506
+ command: CommandSchema.optional(),
507
+ environment: EnvironmentSchema2.optional()
508
+ })
509
+ ).optional().describe("Define the instances in your stack.");
510
+
406
511
  // src/feature/queue/schema.ts
407
- import { z as z9 } from "zod";
512
+ import { z as z13 } from "zod";
408
513
  import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
409
514
  import { kibibytes } from "@awsless/size";
410
515
  var RetentionPeriodSchema = DurationSchema.refine(
@@ -434,10 +539,10 @@ var ReceiveMessageWaitTimeSchema = DurationSchema.refine(
434
539
  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
540
  "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
541
  );
437
- var BatchSizeSchema = z9.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
542
+ var BatchSizeSchema = z13.number().int().min(1, "Minimum batch size is 1").max(1e4, "Maximum batch size is 10000").describe(
438
543
  "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
544
  );
440
- var MaxConcurrencySchema = z9.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
545
+ var MaxConcurrencySchema = z13.number().int().min(2, "Minimum max concurrency is 2").max(1e3, "Maximum max concurrency is 1000").describe(
441
546
  "Limits the number of concurrent instances that the queue worker can invoke. You can specify an integer from 2 to 1000."
442
547
  );
443
548
  var MaxBatchingWindow = DurationSchema.refine(
@@ -446,7 +551,7 @@ var MaxBatchingWindow = DurationSchema.refine(
446
551
  ).describe(
447
552
  "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
553
  );
449
- var QueueDefaultSchema = z9.object({
554
+ var QueueDefaultSchema = z13.object({
450
555
  retentionPeriod: RetentionPeriodSchema.default("7 days"),
451
556
  visibilityTimeout: VisibilityTimeoutSchema.default("30 seconds"),
452
557
  deliveryDelay: DeliveryDelaySchema.default("0 seconds"),
@@ -456,15 +561,15 @@ var QueueDefaultSchema = z9.object({
456
561
  maxConcurrency: MaxConcurrencySchema.optional(),
457
562
  maxBatchingWindow: MaxBatchingWindow.optional()
458
563
  }).default({});
459
- var QueuesSchema = z9.record(
564
+ var QueuesSchema = z13.record(
460
565
  ResourceIdSchema,
461
- z9.union([
566
+ z13.union([
462
567
  LocalFileSchema.transform((file) => ({
463
568
  consumer: {
464
569
  file
465
570
  }
466
571
  })),
467
- z9.object({
572
+ z13.object({
468
573
  consumer: FunctionSchema.describe("he consuming lambda function properties."),
469
574
  retentionPeriod: RetentionPeriodSchema.optional(),
470
575
  visibilityTimeout: VisibilityTimeoutSchema.optional(),
@@ -478,291 +583,134 @@ var QueuesSchema = z9.record(
478
583
  ])
479
584
  ).optional().describe("Define the queues in your stack.");
480
585
 
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
586
  // src/feature/rest/schema.ts
569
- import { z as z14 } from "zod";
587
+ import { z as z15 } from "zod";
570
588
 
571
589
  // 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")
590
+ import { z as z14 } from "zod";
591
+ var RouteSchema2 = z14.union([
592
+ z14.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/\{\}]*)$/gi, "Invalid route"),
593
+ z14.literal("$default")
576
594
  ]);
577
595
 
578
596
  // src/feature/rest/schema.ts
579
- var RestDefaultSchema = z14.record(
597
+ var RestDefaultSchema = z15.record(
580
598
  ResourceIdSchema,
581
- z14.object({
599
+ z15.object({
582
600
  domain: ResourceIdSchema.describe("The domain id to link your API with.").optional(),
583
- subDomain: z14.string().optional()
601
+ subDomain: z15.string().optional()
584
602
  })
585
603
  ).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.");
604
+ var RestSchema = z15.record(ResourceIdSchema, z15.record(RouteSchema2, FunctionSchema)).optional().describe("Define routes in your stack for your global REST API.");
587
605
 
588
- // src/config/app.ts
589
- var AppSchema = z15.object({
590
- $schema: z15.string().optional(),
591
- name: ResourceIdSchema.describe("App name."),
592
- region: RegionSchema.describe("The AWS region to deploy to."),
593
- profile: z15.string().describe("The AWS profile to deploy to."),
594
- // stage: z
595
- // .string()
596
- // .regex(/^[a-z]+$/)
597
- // .default('prod')
598
- // .describe('The deployment stage.'),
599
- defaults: z15.object({
600
- auth: AuthDefaultSchema,
601
- domains: DomainsDefaultSchema,
602
- function: FunctionDefaultSchema,
603
- queue: QueueDefaultSchema,
604
- graphql: GraphQLDefaultSchema,
605
- http: HttpDefaultSchema,
606
- rest: RestDefaultSchema
607
- }).default({}).describe("Default properties")
608
- });
606
+ // src/config/schema/region.ts
607
+ import { z as z16 } from "zod";
608
+ var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
609
+ var AF = ["af-south-1"];
610
+ var AP = [
611
+ "ap-east-1",
612
+ "ap-south-2",
613
+ "ap-southeast-3",
614
+ "ap-southeast-4",
615
+ "ap-south-1",
616
+ "ap-northeast-3",
617
+ "ap-northeast-2",
618
+ "ap-southeast-1",
619
+ "ap-southeast-2",
620
+ "ap-northeast-1"
621
+ ];
622
+ var CA = ["ca-central-1"];
623
+ var EU = [
624
+ "eu-central-1",
625
+ "eu-west-1",
626
+ "eu-west-2",
627
+ "eu-south-1",
628
+ "eu-west-3",
629
+ "eu-south-2",
630
+ "eu-north-1",
631
+ "eu-central-2"
632
+ ];
633
+ var ME = ["me-south-1", "me-central-1"];
634
+ var SA = ["sa-east-1"];
635
+ var regions = [...US, ...AF, ...AP, ...CA, ...EU, ...ME, ...SA];
636
+ var RegionSchema = z16.enum(regions);
637
+
638
+ // src/config/app.ts
639
+ var AppSchema = z17.object({
640
+ $schema: z17.string().optional(),
641
+ name: ResourceIdSchema.describe("App name."),
642
+ region: RegionSchema.describe("The AWS region to deploy to."),
643
+ profile: z17.string().describe("The AWS profile to deploy to."),
644
+ // stage: z
645
+ // .string()
646
+ // .regex(/^[a-z]+$/)
647
+ // .default('prod')
648
+ // .describe('The deployment stage.'),
649
+ defaults: z17.object({
650
+ auth: AuthDefaultSchema,
651
+ domains: DomainsDefaultSchema,
652
+ function: FunctionDefaultSchema,
653
+ instance: InstanceDefaultSchema,
654
+ queue: QueueDefaultSchema,
655
+ graphql: GraphQLDefaultSchema,
656
+ http: HttpDefaultSchema,
657
+ rest: RestDefaultSchema
658
+ }).default({}).describe("Default properties")
659
+ });
609
660
 
610
661
  // src/config/load/load.ts
611
662
  import { glob } from "glob";
612
663
 
613
664
  // 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.");
625
-
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.");
665
+ import { z as z31 } from "zod";
671
666
 
672
- // src/feature/store/schema.ts
667
+ // src/feature/cache/schema.ts
673
668
  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(
669
+ var TypeSchema2 = z18.enum([
670
+ "t4g.small",
671
+ "t4g.medium",
672
+ "r6g.large",
673
+ "r6g.xlarge",
674
+ "r6g.2xlarge",
675
+ "r6g.4xlarge",
676
+ "r6g.8xlarge",
677
+ "r6g.12xlarge",
678
+ "r6g.16xlarge",
679
+ "r6gd.xlarge",
680
+ "r6gd.2xlarge",
681
+ "r6gd.4xlarge",
682
+ "r6gd.8xlarge"
683
+ ]);
684
+ var PortSchema = z18.number().int().min(1).max(5e4);
685
+ var ShardsSchema = z18.number().int().min(0).max(100);
686
+ var ReplicasPerShardSchema = z18.number().int().min(0).max(5);
687
+ var EngineSchema = z18.enum(["7.0", "6.2"]);
688
+ var CachesSchema = z18.record(
722
689
  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.")
690
+ z18.object({
691
+ type: TypeSchema2.default("t4g.small"),
692
+ port: PortSchema.default(6379),
693
+ shards: ShardsSchema.default(1),
694
+ replicasPerShard: ReplicasPerShardSchema.default(1),
695
+ engine: EngineSchema.default("7.0"),
696
+ dataTiering: z18.boolean().default(false)
727
697
  })
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();
698
+ ).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
747
699
 
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.");
700
+ // src/feature/config/schema.ts
701
+ import { z as z19 } from "zod";
702
+ var ConfigNameSchema = z19.string().regex(/[a-z0-9\-]/g, "Invalid config name");
703
+ var ConfigsSchema = z19.array(ConfigNameSchema).optional().describe("Define the config values for your stack.");
756
704
 
757
705
  // src/feature/cron/schema/index.ts
758
- import { z as z24 } from "zod";
706
+ import { z as z21 } from "zod";
759
707
 
760
708
  // src/feature/cron/schema/schedule.ts
761
- import { z as z23 } from "zod";
709
+ import { z as z20 } from "zod";
762
710
  import { awsCronExpressionValidator } from "aws-cron-expression-validator";
763
- var RateExpressionSchema = z23.custom(
711
+ var RateExpressionSchema = z20.custom(
764
712
  (value) => {
765
- return z23.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
713
+ return z20.string().regex(/^[0-9]+ (seconds?|minutes?|hours?|days?)$/).refine((rate) => {
766
714
  const [str] = rate.split(" ");
767
715
  const number = parseInt(str);
768
716
  return number > 0;
@@ -778,9 +726,9 @@ var RateExpressionSchema = z23.custom(
778
726
  }
779
727
  return `rate(${rate})`;
780
728
  });
781
- var CronExpressionSchema = z23.custom(
729
+ var CronExpressionSchema = z20.custom(
782
730
  (value) => {
783
- return z23.string().safeParse(value).success;
731
+ return z20.string().safeParse(value).success;
784
732
  },
785
733
  { message: "Invalid cron expression" }
786
734
  ).superRefine((value, ctx) => {
@@ -789,12 +737,12 @@ var CronExpressionSchema = z23.custom(
789
737
  } catch (error) {
790
738
  if (error instanceof Error) {
791
739
  ctx.addIssue({
792
- code: z23.ZodIssueCode.custom,
740
+ code: z20.ZodIssueCode.custom,
793
741
  message: `Invalid cron expression: ${error.message}`
794
742
  });
795
743
  } else {
796
744
  ctx.addIssue({
797
- code: z23.ZodIssueCode.custom,
745
+ code: z20.ZodIssueCode.custom,
798
746
  message: "Invalid cron expression"
799
747
  });
800
748
  }
@@ -805,56 +753,39 @@ var CronExpressionSchema = z23.custom(
805
753
  var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
806
754
 
807
755
  // src/feature/cron/schema/index.ts
808
- var CronsSchema = z24.record(
756
+ var CronsSchema = z21.record(
809
757
  ResourceIdSchema,
810
- z24.object({
811
- enabled: z24.boolean().default(true).describe("If the cron is enabled."),
758
+ z21.object({
759
+ enabled: z21.boolean().default(true).describe("If the cron is enabled."),
812
760
  consumer: FunctionSchema.describe("The consuming lambda function properties."),
813
761
  schedule: ScheduleExpressionSchema.describe(
814
762
  'The scheduling expression.\n\nexample: "0 20 * * ? *"\nexample: "5 minutes"'
815
763
  ),
816
- payload: z24.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
764
+ payload: z21.unknown().optional().describe("The JSON payload that will be passed to the consumer.")
817
765
  })
818
766
  ).optional();
819
767
 
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(
768
+ // src/feature/on-failure/schema.ts
769
+ var OnFailureSchema = FunctionSchema.optional().describe(
770
+ "Defining a onFailure handler will add a global onFailure handler for the following resources:\n- Async lambda functions\n- SQS queues\n- DynamoDB streams"
771
+ );
772
+
773
+ // src/feature/pubsub/schema.ts
774
+ import { z as z22 } from "zod";
775
+ var PubSubSchema = z22.record(
842
776
  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)
777
+ z22.object({
778
+ sql: z22.string().describe("The SQL statement used to query the IOT topic."),
779
+ 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."),
780
+ consumer: FunctionSchema.describe("The consuming lambda function properties.")
850
781
  })
851
- ).optional().describe("Define the caches in your stack. For access to the cache put your functions inside the global VPC.");
782
+ ).optional().describe("Define the pubsub subscriber in your stack.");
852
783
 
853
784
  // src/feature/search/schema.ts
854
- import { z as z26 } from "zod";
785
+ import { z as z23 } from "zod";
855
786
  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([
787
+ var VersionSchema = z23.enum(["2.13", "2.11", "2.9", "2.7", "2.5", "2.3", "1.3"]);
788
+ var TypeSchema3 = z23.enum([
858
789
  "t3.small",
859
790
  "t3.medium",
860
791
  "t3.large",
@@ -955,41 +886,41 @@ var TypeSchema2 = z26.enum([
955
886
  "r6gd.16xlarge"
956
887
  ]);
957
888
  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(
889
+ var SearchsSchema = z23.record(
959
890
  ResourceIdSchema,
960
- z26.object({
961
- type: TypeSchema2.default("t3.small"),
962
- count: z26.number().int().min(1).default(1),
891
+ z23.object({
892
+ type: TypeSchema3.default("t3.small"),
893
+ count: z23.number().int().min(1).default(1),
963
894
  version: VersionSchema.default("2.13"),
964
895
  storage: StorageSizeSchema.default("10 GB"),
965
- vpc: z26.boolean().default(false)
896
+ vpc: z23.boolean().default(false)
966
897
  })
967
898
  ).optional().describe("Define the search instances in your stack. Backed by OpenSearch.");
968
899
 
969
900
  // src/feature/site/schema.ts
970
- import { z as z27 } from "zod";
971
- var ErrorResponsePathSchema = z27.string().describe(
901
+ import { z as z24 } from "zod";
902
+ var ErrorResponsePathSchema = z24.string().describe(
972
903
  "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
904
  );
974
- var StatusCodeSchema = z27.number().int().positive().optional().describe(
905
+ var StatusCodeSchema = z24.number().int().positive().optional().describe(
975
906
  "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
907
  );
977
908
  var MinTTLSchema = DurationSchema.describe(
978
909
  "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
910
  );
980
- var ErrorResponseSchema = z27.union([
911
+ var ErrorResponseSchema = z24.union([
981
912
  ErrorResponsePathSchema,
982
- z27.object({
913
+ z24.object({
983
914
  path: ErrorResponsePathSchema,
984
915
  statusCode: StatusCodeSchema.optional(),
985
916
  minTTL: MinTTLSchema.optional()
986
917
  })
987
918
  ]).optional();
988
- var SitesSchema = z27.record(
919
+ var SitesSchema = z24.record(
989
920
  ResourceIdSchema,
990
- z27.object({
921
+ z24.object({
991
922
  domain: ResourceIdSchema.describe("The domain id to link your site with."),
992
- subDomain: z27.string().optional(),
923
+ subDomain: z24.string().optional(),
993
924
  // bind: z
994
925
  // .object({
995
926
  // auth: z.array(ResourceIdSchema),
@@ -1012,7 +943,7 @@ var SitesSchema = z27.record(
1012
943
  // build: z.string().optional(),
1013
944
  // }),
1014
945
  // ]),
1015
- errors: z27.object({
946
+ errors: z24.object({
1016
947
  400: ErrorResponseSchema.describe("Customize a `400 Bad Request` response."),
1017
948
  403: ErrorResponseSchema.describe("Customize a `403 Forbidden` response."),
1018
949
  404: ErrorResponseSchema.describe("Customize a `404 Not Found` response."),
@@ -1025,16 +956,16 @@ var SitesSchema = z27.record(
1025
956
  503: ErrorResponseSchema.describe("Customize a `503 Service Unavailable` response."),
1026
957
  504: ErrorResponseSchema.describe("Customize a `504 Gateway Timeout` response.")
1027
958
  }).optional().describe("Customize the error responses for specific HTTP status codes."),
1028
- cors: z27.object({
1029
- override: z27.boolean().default(false),
959
+ cors: z24.object({
960
+ override: z24.boolean().default(false),
1030
961
  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"])
962
+ exposeHeaders: z24.string().array().optional(),
963
+ credentials: z24.boolean().default(false),
964
+ headers: z24.string().array().default(["*"]),
965
+ origins: z24.string().array().default(["*"]),
966
+ methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
1036
967
  }).optional().describe("Define the cors headers."),
1037
- security: z27.object({
968
+ security: z24.object({
1038
969
  // contentSecurityPolicy: z.object({
1039
970
  // override: z.boolean().default(false),
1040
971
  // policy: z.string(),
@@ -1076,56 +1007,187 @@ var SitesSchema = z27.record(
1076
1007
  // reportUri?: string
1077
1008
  // }
1078
1009
  }).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.")
1010
+ cache: z24.object({
1011
+ cookies: z24.string().array().optional().describe("Specifies the cookies that CloudFront includes in the cache key."),
1012
+ headers: z24.string().array().optional().describe("Specifies the headers that CloudFront includes in the cache key."),
1013
+ queries: z24.string().array().optional().describe("Specifies the query values that CloudFront includes in the cache key.")
1083
1014
  }).optional().describe(
1084
1015
  "Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
1085
1016
  )
1086
1017
  })
1087
1018
  ).optional().describe("Define the sites in your stack.");
1088
1019
 
1089
- // src/feature/task/schema.ts
1090
- import { z as z28 } from "zod";
1091
- var RetryAttemptsSchema2 = z28.number().int().min(0).max(2).describe(
1092
- "The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
1093
- );
1094
- var TaskSchema = z28.union([
1095
- LocalFileSchema.transform((file) => ({
1096
- consumer: { file },
1097
- retryAttempts: void 0
1098
- })),
1099
- z28.object({
1100
- consumer: FunctionSchema,
1101
- retryAttempts: RetryAttemptsSchema2.optional()
1102
- })
1103
- ]);
1104
- var TasksSchema = z28.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
1105
-
1106
- // src/config/stack.ts
1107
- var DependsSchema = ResourceIdSchema.array().optional().describe("Define the stacks that this stack is depended on.");
1108
- var NameSchema = ResourceIdSchema.refine((name) => !["base"].includes(name), {
1109
- message: `Stack name can't be a reserved name.`
1110
- }).describe("Stack name.");
1111
- var StackSchema = z29.object({
1112
- $schema: z29.string().optional(),
1113
- name: NameSchema,
1114
- depends: DependsSchema,
1115
- onFailure: OnFailureSchema,
1116
- auth: AuthSchema,
1117
- graphql: GraphQLSchema,
1118
- http: HttpSchema,
1119
- rest: RestSchema,
1120
- configs: ConfigsSchema,
1121
- crons: CronsSchema,
1122
- caches: CachesSchema,
1123
- topics: TopicsSchema,
1124
- subscribers: SubscribersSchema,
1020
+ // src/feature/store/schema.ts
1021
+ import { z as z25 } from "zod";
1022
+ var StoresSchema = z25.union([
1023
+ z25.array(ResourceIdSchema).transform((list4) => {
1024
+ const stores = {};
1025
+ for (const key of list4) {
1026
+ stores[key] = {};
1027
+ }
1028
+ return stores;
1029
+ }),
1030
+ z25.record(
1031
+ ResourceIdSchema,
1032
+ z25.object({
1033
+ // cors: CorsSchema,
1034
+ versioning: z25.boolean().default(false).describe("Enable versioning of your store."),
1035
+ events: z25.object({
1036
+ // create
1037
+ "created:*": FunctionSchema.optional().describe(
1038
+ "Subscribe to notifications regardless of the API that was used to create an object."
1039
+ ),
1040
+ "created:put": FunctionSchema.optional().describe(
1041
+ "Subscribe to notifications when an object is created using the PUT API operation."
1042
+ ),
1043
+ "created:post": FunctionSchema.optional().describe(
1044
+ "Subscribe to notifications when an object is created using the POST API operation."
1045
+ ),
1046
+ "created:copy": FunctionSchema.optional().describe(
1047
+ "Subscribe to notifications when an object is created using the COPY API operation."
1048
+ ),
1049
+ "created:upload": FunctionSchema.optional().describe(
1050
+ "Subscribe to notifications when an object multipart upload has been completed."
1051
+ ),
1052
+ // remove
1053
+ "removed:*": FunctionSchema.optional().describe(
1054
+ "Subscribe to notifications when an object is deleted or a delete marker for a versioned object is created."
1055
+ ),
1056
+ "removed:delete": FunctionSchema.optional().describe(
1057
+ "Subscribe to notifications when an object is deleted"
1058
+ ),
1059
+ "removed:marker": FunctionSchema.optional().describe(
1060
+ "Subscribe to notifications when a delete marker for a versioned object is created."
1061
+ )
1062
+ }).optional().describe("Describes the store events you want to subscribe too.")
1063
+ })
1064
+ )
1065
+ ]).optional().describe("Define the stores in your stack.");
1066
+
1067
+ // src/feature/stream/schema.ts
1068
+ import { z as z26 } from "zod";
1069
+ var LatencyModeSchema = z26.enum(["low", "normal"]).describe(
1070
+ `Channel latency mode. Valid values:
1071
+ - normal: Use "normal" to broadcast and deliver live video up to Full HD.
1072
+ - low: Use "low" for near real-time interactions with viewers.`
1073
+ );
1074
+ var TypeSchema4 = z26.enum(["standard", "basic", "advanced-sd", "advanced-hd"]).describe(`The channel type, which determines the allowable resolution and bitrate.
1075
+ If you exceed the allowable resolution or bitrate, the stream probably will disconnect immediately. Valid values:
1076
+ - 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.
1077
+ - 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.
1078
+ - 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.
1079
+ - 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.
1080
+ `);
1081
+ var StreamsSchema = z26.record(
1082
+ ResourceIdSchema,
1083
+ z26.object({
1084
+ type: TypeSchema4.default("standard"),
1085
+ // preset: PresetSchema.optional(),
1086
+ latencyMode: LatencyModeSchema.default("low")
1087
+ })
1088
+ ).optional().describe("Define the streams in your stack.");
1089
+
1090
+ // src/feature/table/schema.ts
1091
+ import { z as z27 } from "zod";
1092
+ var KeySchema = z27.string().min(1).max(255);
1093
+ var TablesSchema = z27.record(
1094
+ ResourceIdSchema,
1095
+ z27.object({
1096
+ hash: KeySchema.describe(
1097
+ "Specifies the name of the partition / hash key that makes up the primary key for the table."
1098
+ ),
1099
+ sort: KeySchema.optional().describe(
1100
+ "Specifies the name of the range / sort key that makes up the primary key for the table."
1101
+ ),
1102
+ fields: z27.record(z27.string(), z27.enum(["string", "number", "binary"])).optional().describe(
1103
+ 'A list of attributes that describe the key schema for the table and indexes. If no attribute field is defined we default to "string".'
1104
+ ),
1105
+ class: z27.enum(["standard", "standard-infrequent-access"]).default("standard").describe("The table class of the table."),
1106
+ pointInTimeRecovery: z27.boolean().default(false).describe("Indicates whether point in time recovery is enabled on the table."),
1107
+ timeToLiveAttribute: KeySchema.optional().describe(
1108
+ "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."
1109
+ ),
1110
+ stream: z27.object({
1111
+ type: z27.enum(["keys-only", "new-image", "old-image", "new-and-old-images"]).describe(
1112
+ "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."
1113
+ ),
1114
+ consumer: FunctionSchema.describe("The consuming lambda function for the stream")
1115
+ }).optional().describe(
1116
+ "The settings for the DynamoDB table stream, which capture changes to items stored in the table."
1117
+ ),
1118
+ indexes: z27.record(
1119
+ z27.string(),
1120
+ z27.object({
1121
+ /** Specifies the name of the partition / hash key that makes up the primary key for the global secondary index. */
1122
+ hash: KeySchema,
1123
+ /** Specifies the name of the range / sort key that makes up the primary key for the global secondary index. */
1124
+ sort: KeySchema.optional(),
1125
+ /** The set of attributes that are projected into the index:
1126
+ * - all - All of the table attributes are projected into the index.
1127
+ * - keys-only - Only the index and primary keys are projected into the index.
1128
+ * @default 'all'
1129
+ */
1130
+ projection: z27.enum(["all", "keys-only"]).default("all")
1131
+ })
1132
+ ).optional().describe("Specifies the global secondary indexes to be created on the table.")
1133
+ })
1134
+ ).optional().describe("Define the tables in your stack.");
1135
+
1136
+ // src/feature/task/schema.ts
1137
+ import { z as z28 } from "zod";
1138
+ var RetryAttemptsSchema2 = z28.number().int().min(0).max(2).describe(
1139
+ "The maximum number of times to retry when the function returns an error. You can specify a number from 0 to 2."
1140
+ );
1141
+ var TaskSchema = z28.union([
1142
+ LocalFileSchema.transform((file) => ({
1143
+ consumer: { file },
1144
+ retryAttempts: void 0
1145
+ })),
1146
+ z28.object({
1147
+ consumer: FunctionSchema,
1148
+ retryAttempts: RetryAttemptsSchema2.optional()
1149
+ })
1150
+ ]);
1151
+ var TasksSchema = z28.record(ResourceIdSchema, TaskSchema).optional().describe("Define the tasks in your stack.");
1152
+
1153
+ // src/feature/test/schema.ts
1154
+ import { z as z29 } from "zod";
1155
+ var TestsSchema = z29.union([LocalDirectorySchema.transform((v) => [v]), LocalDirectorySchema.array()]).describe("Define the location of your tests for your stack.").optional();
1156
+
1157
+ // src/feature/topic/schema.ts
1158
+ import { paramCase as paramCase2 } from "change-case";
1159
+ import { z as z30 } from "zod";
1160
+ 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.");
1161
+ var TopicsSchema = z30.array(TopicNameSchema).refine((topics) => {
1162
+ return topics.length === new Set(topics).size;
1163
+ }, "Must be a list of unique topic names").optional().describe("Define the event topics to publish too in your stack.");
1164
+ var SubscribersSchema = z30.record(TopicNameSchema, z30.union([EmailSchema, FunctionSchema])).optional().describe("Define the event topics to subscribe too in your stack.");
1165
+
1166
+ // src/config/stack.ts
1167
+ var DependsSchema = ResourceIdSchema.array().optional().describe("Define the stacks that this stack is depended on.");
1168
+ var NameSchema = ResourceIdSchema.refine((name) => !["base"].includes(name), {
1169
+ message: `Stack name can't be a reserved name.`
1170
+ }).describe("Stack name.");
1171
+ var StackSchema = z31.object({
1172
+ $schema: z31.string().optional(),
1173
+ name: NameSchema,
1174
+ depends: DependsSchema,
1175
+ onFailure: OnFailureSchema,
1176
+ auth: AuthSchema,
1177
+ graphql: GraphQLSchema,
1178
+ http: HttpSchema,
1179
+ rest: RestSchema,
1180
+ configs: ConfigsSchema,
1181
+ crons: CronsSchema,
1182
+ caches: CachesSchema,
1183
+ topics: TopicsSchema,
1184
+ subscribers: SubscribersSchema,
1125
1185
  functions: FunctionsSchema,
1186
+ instances: InstancesSchema,
1126
1187
  tasks: TasksSchema,
1127
1188
  tables: TablesSchema,
1128
1189
  stores: StoresSchema,
1190
+ streams: StreamsSchema,
1129
1191
  queues: QueuesSchema,
1130
1192
  pubsub: PubSubSchema,
1131
1193
  searchs: SearchsSchema,
@@ -1188,13 +1250,13 @@ var readConfigWithStage = async (file, stage) => {
1188
1250
  };
1189
1251
 
1190
1252
  // src/config/load/validate.ts
1191
- import { z as z30 } from "zod";
1253
+ import { z as z32 } from "zod";
1192
1254
  var validateConfig = async (schema, file, data) => {
1193
1255
  try {
1194
1256
  const result = await schema.parseAsync(data);
1195
1257
  return result;
1196
1258
  } catch (error) {
1197
- if (error instanceof z30.ZodError) {
1259
+ if (error instanceof z32.ZodError) {
1198
1260
  throw new ConfigError(file, error, data);
1199
1261
  }
1200
1262
  throw error;
@@ -1658,8 +1720,8 @@ var bootstrapAwsless = async (props) => {
1658
1720
  };
1659
1721
 
1660
1722
  // src/util/aws.ts
1723
+ import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
1661
1724
  import { fromIni } from "@aws-sdk/credential-providers";
1662
- import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
1663
1725
  var getCredentials = (profile) => {
1664
1726
  return fromIni({ profile });
1665
1727
  };
@@ -2056,11 +2118,11 @@ var findDependencies = async (file, code) => {
2056
2118
  // src/feature/function/build/zip.ts
2057
2119
  import JSZip from "jszip";
2058
2120
  var zipFiles = (files) => {
2059
- const zip = new JSZip();
2121
+ const zip2 = new JSZip();
2060
2122
  for (const file of files) {
2061
- zip.file(file.name, file.code);
2123
+ zip2.file(file.name, file.code);
2062
2124
  }
2063
- return zip.generateAsync({
2125
+ return zip2.generateAsync({
2064
2126
  type: "nodebuffer",
2065
2127
  compression: "DEFLATE",
2066
2128
  compressionOptions: {
@@ -2147,14 +2209,14 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
2147
2209
  const policy = new aws.iam.RolePolicy(group, "policy", {
2148
2210
  role: role.name,
2149
2211
  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
- ]
2212
+ version: "2012-10-17"
2213
+ // statements: [
2214
+ // {
2215
+ // // Give lambda access to all lambda's inside your app.
2216
+ // actions: ['lambda:InvokeFunction', 'lambda:InvokeAsync'],
2217
+ // resources: [`arn:aws:lambda:*:*:function:${ctx.appConfig.name}--*`],
2218
+ // },
2219
+ // ],
2158
2220
  });
2159
2221
  const lambda = new aws.lambda.Function(group, `function`, {
2160
2222
  ...props,
@@ -2166,7 +2228,10 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
2166
2228
  vpc: void 0,
2167
2229
  log: props.log
2168
2230
  });
2169
- ctx.registerFunction(lambda, policy);
2231
+ ctx.onEnv((name2, value) => {
2232
+ lambda.addEnvironment(name2, value);
2233
+ });
2234
+ ctx.registerPolicy(policy);
2170
2235
  lambda.addEnvironment("APP", ctx.appConfig.name);
2171
2236
  if ("stackConfig" in ctx) {
2172
2237
  lambda.addEnvironment("STACK", ctx.stackConfig.name);
@@ -2275,7 +2340,6 @@ var authFeature = defineFeature({
2275
2340
  const gen = new TypeFile("@awsless/awsless/client");
2276
2341
  const resources = new TypeObject(1);
2277
2342
  for (const name of Object.keys(ctx.appConfig.defaults.auth)) {
2278
- const authName = formatGlobalResourceName(ctx.appConfig.name, "auth", name);
2279
2343
  resources.addType(name, `{ readonly userPoolId: string, readonly clientId: string }`);
2280
2344
  }
2281
2345
  gen.addInterface("AuthResources", resources);
@@ -2367,8 +2431,8 @@ var authFeature = defineFeature({
2367
2431
  userSrp: true
2368
2432
  }
2369
2433
  });
2370
- ctx.bindEnv(`AUTH_${constantCase2(id)}_USER_POOL_ID`, userPool.id);
2371
- ctx.bindEnv(`AUTH_${constantCase2(id)}_CLIENT_ID`, client.id);
2434
+ ctx.bind(`AUTH_${constantCase2(id)}_USER_POOL_ID`, userPool.id);
2435
+ ctx.bind(`AUTH_${constantCase2(id)}_CLIENT_ID`, client.id);
2372
2436
  ctx.shared.set(`auth-${id}-user-pool-arn`, userPool.arn);
2373
2437
  ctx.shared.set(`auth-${id}-user-pool-id`, userPool.id);
2374
2438
  ctx.shared.set(`auth-${id}-client-id`, client.id);
@@ -2377,8 +2441,8 @@ var authFeature = defineFeature({
2377
2441
  });
2378
2442
 
2379
2443
  // src/feature/cache/index.ts
2444
+ import { aws as aws3, Node as Node3 } from "@awsless/formation";
2380
2445
  import { constantCase as constantCase3 } from "change-case";
2381
- import { Node as Node3, aws as aws3 } from "@awsless/formation";
2382
2446
  var typeGenCode = `
2383
2447
  import { Cluster, CommandOptions } from '@awsless/redis'
2384
2448
 
@@ -2433,11 +2497,9 @@ var cacheFeature = defineFeature({
2433
2497
  subnetGroupName: subnetGroup.name,
2434
2498
  ...props
2435
2499
  });
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
- });
2500
+ const prefix = `CACHE_${constantCase3(ctx.stack.name)}_${constantCase3(id)}`;
2501
+ ctx.addEnv(`${prefix}_HOST`, cluster.address);
2502
+ ctx.addEnv(`${prefix}_PORT`, props.port.toString());
2441
2503
  }
2442
2504
  }
2443
2505
  });
@@ -2563,9 +2625,9 @@ var configFeature = defineFeature({
2563
2625
  for (const name of configs) {
2564
2626
  ctx.registerConfig(name);
2565
2627
  }
2566
- ctx.onFunction(({ lambda, policy }) => {
2567
- if (configs.length) {
2568
- lambda.addEnvironment("CONFIG", configs.join(","));
2628
+ if (configs.length) {
2629
+ ctx.addEnv("CONFIG", configs.join(","));
2630
+ ctx.onPolicy((policy) => {
2569
2631
  policy.addStatement({
2570
2632
  actions: [
2571
2633
  "ssm:GetParameter",
@@ -2579,8 +2641,8 @@ var configFeature = defineFeature({
2579
2641
  )}/${paramCase4(name)}`
2580
2642
  )
2581
2643
  });
2582
- }
2583
- });
2644
+ });
2645
+ }
2584
2646
  }
2585
2647
  });
2586
2648
 
@@ -2615,8 +2677,8 @@ var cronFeature = defineFeature({
2615
2677
  });
2616
2678
 
2617
2679
  // src/feature/domain/index.ts
2618
- import { Node as Node5, aws as aws5 } from "@awsless/formation";
2619
2680
  import { minutes as minutes3 } from "@awsless/duration";
2681
+ import { aws as aws5, Node as Node5 } from "@awsless/formation";
2620
2682
  var domainFeature = defineFeature({
2621
2683
  name: "domain",
2622
2684
  onApp(ctx) {
@@ -2712,8 +2774,8 @@ var domainFeature = defineFeature({
2712
2774
  });
2713
2775
  }
2714
2776
  }
2715
- ctx.onFunction(
2716
- ({ policy }) => policy.addStatement({
2777
+ ctx.onPolicy(
2778
+ (policy) => policy.addStatement({
2717
2779
  actions: ["ses:*"],
2718
2780
  resources: [`arn:aws:ses:${ctx.appConfig.region}:${ctx.accountId}:identity/*`]
2719
2781
  })
@@ -2788,6 +2850,12 @@ var functionFeature = defineFeature({
2788
2850
  });
2789
2851
  ctx.shared.set("function-repository-name", repository.name);
2790
2852
  ctx.shared.set("function-repository-uri", repository.uri);
2853
+ ctx.onPolicy((policy) => {
2854
+ policy.addStatement({
2855
+ actions: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
2856
+ resources: [`arn:aws:lambda:*:*:function:${ctx.appConfig.name}--*`]
2857
+ });
2858
+ });
2791
2859
  },
2792
2860
  onStack(ctx) {
2793
2861
  for (const [id, props] of Object.entries(ctx.stackConfig.functions || {})) {
@@ -3137,9 +3205,9 @@ var graphqlFeature = defineFeature({
3137
3205
  evaluateTargetHealth: false
3138
3206
  }
3139
3207
  });
3140
- ctx.bindEnv(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, domainName);
3208
+ ctx.bind(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, domainName);
3141
3209
  } else {
3142
- ctx.bindEnv(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, api.graphql.uri);
3210
+ ctx.bind(`GRAPHQL_${constantCase4(id)}_ENDPOINT`, api.graphql.uri);
3143
3211
  }
3144
3212
  }
3145
3213
  },
@@ -3330,7 +3398,7 @@ var httpFeature = defineFeature({
3330
3398
  dnsName: loadBalancer.dnsName
3331
3399
  }
3332
3400
  });
3333
- ctx.bindEnv(`HTTP_${constantCase5(id)}_ENDPOINT`, domainName);
3401
+ ctx.bind(`HTTP_${constantCase5(id)}_ENDPOINT`, domainName);
3334
3402
  }
3335
3403
  },
3336
3404
  onStack(ctx) {
@@ -3374,8 +3442,140 @@ var httpFeature = defineFeature({
3374
3442
  }
3375
3443
  });
3376
3444
 
3445
+ // src/feature/instance/index.ts
3446
+ import { days as days3 } from "@awsless/duration";
3447
+ import { Asset as Asset3, aws as aws9, combine, Node as Node9, Output as Output2, unwrap } from "@awsless/formation";
3448
+ import { hashElement as hashElement2 } from "folder-hash";
3449
+ import { mkdir as mkdir2 } from "fs/promises";
3450
+ import { dirname as dirname9 } from "path";
3451
+ import { zip } from "zip-a-folder";
3452
+ var instanceFeature = defineFeature({
3453
+ name: "instance",
3454
+ onApp(ctx) {
3455
+ const group = new Node9(ctx.base, "instance", "asset");
3456
+ const bucket = new aws9.s3.Bucket(group, "bucket", {
3457
+ name: formatGlobalResourceName(ctx.appConfig.name, "instance", "assets"),
3458
+ forceDelete: true
3459
+ });
3460
+ ctx.shared.set("instance-bucket-name", bucket.name);
3461
+ if (ctx.appConfig.defaults.instance.connect) {
3462
+ new aws9.ec2.InstanceConnectEndpoint(group, "connect", {
3463
+ name: ctx.appConfig.name,
3464
+ subnetId: ctx.shared.get(`vpc-public-subnet-id-1`),
3465
+ securityGroupIds: [ctx.shared.get("vpc-security-group-id")]
3466
+ });
3467
+ }
3468
+ },
3469
+ onStack(ctx) {
3470
+ for (const [id, props] of Object.entries(ctx.stackConfig.instances ?? {})) {
3471
+ const group = new Node9(ctx.stack, "instance", id);
3472
+ const name = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "instance", id);
3473
+ const env = {
3474
+ APP: ctx.appConfig.name,
3475
+ STACK: ctx.stackConfig.name
3476
+ };
3477
+ ctx.onEnv((name2, value) => {
3478
+ env[name2] = value;
3479
+ if (value instanceof Output2) {
3480
+ template.dependsOn(...value.resources);
3481
+ }
3482
+ });
3483
+ const bucketName = ctx.shared.get("instance-bucket-name");
3484
+ const userData = new Output2([], (resolve) => {
3485
+ ctx.onReady(() => {
3486
+ combine([bucketName, ...Object.values(env)]).apply(([bucketName2]) => {
3487
+ const u = "ec2-user";
3488
+ const code2 = [
3489
+ `#!/bin/bash`,
3490
+ `cd /home/${u}`,
3491
+ `sudo -u ${u} aws configure set default.s3.use_dualstack_endpoint true`,
3492
+ `sudo -u ${u} aws s3 cp s3://${bucketName2}/${name} .`,
3493
+ `sudo -u ${u} unzip -o ${name} -d ./code`,
3494
+ `sudo -u ${u} rm ./${name}`,
3495
+ `cd ./code`,
3496
+ // system environment vars
3497
+ ...Object.entries(env).map(([key, value]) => {
3498
+ return `echo export ${key}="${unwrap(value)}" >> /etc/profile`;
3499
+ }),
3500
+ // user environment vars
3501
+ ...Object.entries(props.environment ?? {}).map(([key, value]) => {
3502
+ return `echo export ${key}="${value}" >> /etc/profile`;
3503
+ }),
3504
+ props.command ? `sudo -u ${u} ${props.command}` : ""
3505
+ ].join("\n");
3506
+ resolve(Asset3.fromString(Buffer.from(code2, "utf8").toString("base64")));
3507
+ });
3508
+ });
3509
+ });
3510
+ const bundleFile = getBuildPath("instance", name, "bundle.zip");
3511
+ ctx.registerBuild("instance", name, async (build3) => {
3512
+ const version = await hashElement2(props.code, {
3513
+ files: {
3514
+ exclude: ["stack.json"]
3515
+ }
3516
+ });
3517
+ await build3(version.hash, async () => {
3518
+ await mkdir2(dirname9(bundleFile), { recursive: true });
3519
+ await zip(props.code, bundleFile);
3520
+ });
3521
+ });
3522
+ const code = new aws9.s3.BucketObject(group, "code", {
3523
+ key: name,
3524
+ bucket: bucketName,
3525
+ body: Asset3.fromFile(bundleFile)
3526
+ });
3527
+ const template = new aws9.ec2.LaunchTemplate(group, "template", {
3528
+ name,
3529
+ imageId: props.image,
3530
+ instanceType: props.type,
3531
+ securityGroupIds: [ctx.shared.get("vpc-security-group-id")],
3532
+ monitoring: true,
3533
+ userData
3534
+ });
3535
+ const role = new aws9.iam.Role(group, "role", {
3536
+ name,
3537
+ assumedBy: "ec2.amazonaws.com"
3538
+ });
3539
+ const policy = new aws9.iam.RolePolicy(group, "policy", {
3540
+ name,
3541
+ role: role.name
3542
+ });
3543
+ policy.addStatement({
3544
+ actions: ["s3:GetObject"],
3545
+ resources: [bucketName.apply((bucket) => `arn:aws:s3:::${bucket}/${name}`)]
3546
+ });
3547
+ ctx.registerPolicy(policy);
3548
+ const profile = new aws9.iam.InstanceProfile(group, "profile", {
3549
+ name,
3550
+ roles: [role.name]
3551
+ });
3552
+ const instance = new aws9.ec2.Instance(group, "instance", {
3553
+ name,
3554
+ iamInstanceProfile: profile.arn,
3555
+ launchTemplate: template,
3556
+ subnetId: ctx.shared.get(`vpc-public-subnet-id-1`)
3557
+ });
3558
+ instance.dependsOn(code);
3559
+ const logGroup = new aws9.cloudWatch.LogGroup(group, "log", {
3560
+ name: `/awsless/instance/${name}`,
3561
+ retention: days3(3)
3562
+ });
3563
+ policy.addStatement(
3564
+ {
3565
+ actions: ["logs:CreateLogStream"],
3566
+ resources: [logGroup.arn]
3567
+ },
3568
+ {
3569
+ actions: ["logs:PutLogEvents"],
3570
+ resources: [logGroup.arn.apply((arn) => `${arn}:*`)]
3571
+ }
3572
+ );
3573
+ }
3574
+ }
3575
+ });
3576
+
3377
3577
  // src/feature/on-failure/index.ts
3378
- import { Node as Node9, aws as aws9 } from "@awsless/formation";
3578
+ import { Node as Node10, aws as aws10 } from "@awsless/formation";
3379
3579
  var onFailureFeature = defineFeature({
3380
3580
  name: "on-failure",
3381
3581
  onApp(ctx) {
@@ -3386,7 +3586,7 @@ var onFailureFeature = defineFeature({
3386
3586
  if (count > 1) {
3387
3587
  throw new TypeError("Only 1 onFailure configuration is allowed in your app.");
3388
3588
  }
3389
- const queue2 = new aws9.sqs.Queue(ctx.base, "on-failure", {
3589
+ const queue2 = new aws10.sqs.Queue(ctx.base, "on-failure", {
3390
3590
  name: formatGlobalResourceName(ctx.appConfig.name, "on-failure", "failure")
3391
3591
  });
3392
3592
  ctx.shared.set("on-failure-queue-arn", queue2.arn);
@@ -3397,9 +3597,9 @@ var onFailureFeature = defineFeature({
3397
3597
  return;
3398
3598
  }
3399
3599
  const queueArn = ctx.shared.get("on-failure-queue-arn");
3400
- const group = new Node9(ctx.stack, "on-failure", "failure");
3600
+ const group = new Node10(ctx.stack, "on-failure", "failure");
3401
3601
  const { lambda, policy } = createLambdaFunction(group, ctx, "on-failure", "failure", onFailure);
3402
- const source = new aws9.lambda.EventSourceMapping(group, "on-failure", {
3602
+ const source = new aws10.lambda.EventSourceMapping(group, "on-failure", {
3403
3603
  functionArn: lambda.arn,
3404
3604
  sourceArn: queueArn,
3405
3605
  batchSize: 10
@@ -3419,29 +3619,29 @@ var onFailureFeature = defineFeature({
3419
3619
  });
3420
3620
 
3421
3621
  // src/feature/pubsub/index.ts
3422
- import { Node as Node10, aws as aws10 } from "@awsless/formation";
3622
+ import { aws as aws11, Node as Node11 } from "@awsless/formation";
3423
3623
  var pubsubFeature = defineFeature({
3424
3624
  name: "pubsub",
3425
3625
  onApp(ctx) {
3426
- ctx.onFunction(({ policy }) => {
3626
+ ctx.onPolicy((policy) => {
3427
3627
  policy.addStatement({
3428
- actions: ["iot-data:publish"],
3628
+ actions: [`iot:Publish`],
3429
3629
  resources: [`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:rule/*`]
3430
3630
  });
3431
3631
  });
3432
3632
  },
3433
3633
  onStack(ctx) {
3434
3634
  for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
3435
- const group = new Node10(ctx.stack, "pubsub", id);
3635
+ const group = new Node11(ctx.stack, "pubsub", id);
3436
3636
  const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
3437
3637
  const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "pubsub", id);
3438
- const topic = new aws10.iot.TopicRule(group, "rule", {
3638
+ const topic = new aws11.iot.TopicRule(group, "rule", {
3439
3639
  name: name.replaceAll("-", "_"),
3440
3640
  sql: props.sql,
3441
3641
  sqlVersion: props.sqlVersion,
3442
3642
  actions: [{ lambda: { functionArn: lambda.arn } }]
3443
3643
  });
3444
- new aws10.lambda.Permission(group, "permission", {
3644
+ new aws11.lambda.Permission(group, "permission", {
3445
3645
  action: "lambda:InvokeFunction",
3446
3646
  principal: "iot.amazonaws.com",
3447
3647
  functionArn: lambda.arn,
@@ -3452,10 +3652,10 @@ var pubsubFeature = defineFeature({
3452
3652
  });
3453
3653
 
3454
3654
  // src/feature/queue/index.ts
3655
+ import { aws as aws12, Node as Node12 } from "@awsless/formation";
3455
3656
  import { camelCase as camelCase5, constantCase as constantCase6 } from "change-case";
3456
- import { relative as relative3 } from "path";
3457
3657
  import deepmerge2 from "deepmerge";
3458
- import { Node as Node11, aws as aws11 } from "@awsless/formation";
3658
+ import { relative as relative3 } from "path";
3459
3659
  var typeGenCode3 = `
3460
3660
  import { SendMessageOptions, SendMessageBatchOptions, BatchItem } from '@awsless/sqs'
3461
3661
  import type { Mock } from 'vitest'
@@ -3507,15 +3707,15 @@ var queueFeature = defineFeature({
3507
3707
  onStack(ctx) {
3508
3708
  for (const [id, local2] of Object.entries(ctx.stackConfig.queues || {})) {
3509
3709
  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", {
3710
+ const group = new Node12(ctx.stack, "queue", id);
3711
+ const queue2 = new aws12.sqs.Queue(group, "queue", {
3512
3712
  name: formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "queue", id),
3513
3713
  deadLetterArn: getGlobalOnFailure(ctx),
3514
3714
  ...props
3515
3715
  });
3516
3716
  const { lambda, policy } = createLambdaFunction(group, ctx, `queue`, id, props.consumer);
3517
3717
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
3518
- new aws11.lambda.EventSourceMapping(group, "event", {
3718
+ new aws12.lambda.EventSourceMapping(group, "event", {
3519
3719
  functionArn: lambda.arn,
3520
3720
  sourceArn: queue2.arn,
3521
3721
  batchSize: props.batchSize,
@@ -3526,27 +3726,27 @@ var queueFeature = defineFeature({
3526
3726
  actions: ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"],
3527
3727
  resources: [queue2.arn]
3528
3728
  });
3529
- ctx.onFunction(({ lambda: lambda2, policy: policy2 }) => {
3729
+ ctx.addEnv(`QUEUE_${constantCase6(ctx.stack.name)}_${constantCase6(id)}_URL`, queue2.url);
3730
+ ctx.onPolicy((policy2) => {
3530
3731
  policy2.addStatement(queue2.permissions);
3531
- lambda2.addEnvironment(`QUEUE_${constantCase6(ctx.stack.name)}_${constantCase6(id)}_URL`, queue2.url);
3532
3732
  });
3533
3733
  }
3534
3734
  }
3535
3735
  });
3536
3736
 
3537
3737
  // src/feature/rest/index.ts
3538
- import { aws as aws12, Node as Node12 } from "@awsless/formation";
3738
+ import { aws as aws13, Node as Node13 } from "@awsless/formation";
3539
3739
  import { constantCase as constantCase7 } from "change-case";
3540
3740
  var restFeature = defineFeature({
3541
3741
  name: "rest",
3542
3742
  onApp(ctx) {
3543
3743
  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", {
3744
+ const group = new Node13(ctx.base, "rest", id);
3745
+ const api = new aws13.apiGatewayV2.Api(group, "api", {
3546
3746
  name: formatGlobalResourceName(ctx.app.name, "rest", id),
3547
3747
  protocolType: "HTTP"
3548
3748
  });
3549
- const stage = new aws12.apiGatewayV2.Stage(group, "stage", {
3749
+ const stage = new aws13.apiGatewayV2.Stage(group, "stage", {
3550
3750
  name: "v1",
3551
3751
  apiId: api.id
3552
3752
  });
@@ -3555,7 +3755,7 @@ var restFeature = defineFeature({
3555
3755
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
3556
3756
  const hostedZoneId = ctx.shared.get(`hosted-zone-${props.domain}-id`);
3557
3757
  const certificateArn = ctx.shared.get(`certificate-${props.domain}-arn`);
3558
- const domain = new aws12.apiGatewayV2.DomainName(group, "domain", {
3758
+ const domain = new aws13.apiGatewayV2.DomainName(group, "domain", {
3559
3759
  name: domainName,
3560
3760
  certificates: [
3561
3761
  {
@@ -3563,12 +3763,12 @@ var restFeature = defineFeature({
3563
3763
  }
3564
3764
  ]
3565
3765
  });
3566
- const mapping = new aws12.apiGatewayV2.ApiMapping(group, "mapping", {
3766
+ const mapping = new aws13.apiGatewayV2.ApiMapping(group, "mapping", {
3567
3767
  apiId: api.id,
3568
3768
  domainName: domain.name,
3569
3769
  stage: stage.name
3570
3770
  });
3571
- const record = new aws12.route53.RecordSet(group, "record", {
3771
+ const record = new aws13.route53.RecordSet(group, "record", {
3572
3772
  hostedZoneId,
3573
3773
  type: "A",
3574
3774
  name: domainName,
@@ -3579,28 +3779,28 @@ var restFeature = defineFeature({
3579
3779
  }
3580
3780
  });
3581
3781
  record.dependsOn(domain, mapping);
3582
- ctx.bindEnv(`REST_${constantCase7(id)}_ENDPOINT`, domainName);
3782
+ ctx.bind(`REST_${constantCase7(id)}_ENDPOINT`, domainName);
3583
3783
  } else {
3584
3784
  }
3585
3785
  }
3586
3786
  },
3587
3787
  onStack(ctx) {
3588
3788
  for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
3589
- const restGroup = new Node12(ctx.stack, "rest", id);
3789
+ const restGroup = new Node13(ctx.stack, "rest", id);
3590
3790
  for (const [routeKey, props] of Object.entries(routes)) {
3591
- const group = new Node12(restGroup, "route", routeKey);
3791
+ const group = new Node13(restGroup, "route", routeKey);
3592
3792
  const apiId = ctx.shared.get(`rest-${id}-id`);
3593
3793
  const routeId = shortId(routeKey);
3594
3794
  const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
3595
3795
  ...props,
3596
3796
  description: `${id} ${routeKey}`
3597
3797
  });
3598
- const permission = new aws12.lambda.Permission(group, "permission", {
3798
+ const permission = new aws13.lambda.Permission(group, "permission", {
3599
3799
  action: "lambda:InvokeFunction",
3600
3800
  principal: "apigateway.amazonaws.com",
3601
3801
  functionArn: lambda.arn
3602
3802
  });
3603
- const integration = new aws12.apiGatewayV2.Integration(group, "integration", {
3803
+ const integration = new aws13.apiGatewayV2.Integration(group, "integration", {
3604
3804
  apiId,
3605
3805
  description: `${id} ${routeKey}`,
3606
3806
  method: "POST",
@@ -3610,7 +3810,7 @@ var restFeature = defineFeature({
3610
3810
  return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
3611
3811
  })
3612
3812
  });
3613
- const route = new aws12.apiGatewayV2.Route(group, "route", {
3813
+ const route = new aws13.apiGatewayV2.Route(group, "route", {
3614
3814
  apiId,
3615
3815
  routeKey,
3616
3816
  target: integration.id.apply((id2) => `integrations/${id2}`)
@@ -3622,7 +3822,7 @@ var restFeature = defineFeature({
3622
3822
  });
3623
3823
 
3624
3824
  // src/feature/search/index.ts
3625
- import { Node as Node13, aws as aws13 } from "@awsless/formation";
3825
+ import { aws as aws14, Node as Node14 } from "@awsless/formation";
3626
3826
  import { constantCase as constantCase8 } from "change-case";
3627
3827
  var typeGenCode4 = `
3628
3828
  import { AnyStruct, Table } from '@awsless/open-search'
@@ -3650,8 +3850,8 @@ var searchFeature = defineFeature({
3650
3850
  },
3651
3851
  onStack(ctx) {
3652
3852
  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", {
3853
+ const group = new Node14(ctx.stack, "search", id);
3854
+ const openSearch = new aws14.openSearch.Domain(group, "domain", {
3655
3855
  // name: formatLocalResourceName(ctx.app.name, ctx.stack.name, this.name, id),
3656
3856
  version: props.version,
3657
3857
  storageSize: props.storage,
@@ -3677,11 +3877,8 @@ var searchFeature = defineFeature({
3677
3877
  ]
3678
3878
  });
3679
3879
  }
3680
- ctx.onFunction(({ lambda, policy }) => {
3681
- lambda.addEnvironment(
3682
- `SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`,
3683
- openSearch.domainEndpoint
3684
- );
3880
+ ctx.addEnv(`SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`, openSearch.domainEndpoint);
3881
+ ctx.onPolicy((policy) => {
3685
3882
  policy.addStatement({
3686
3883
  actions: ["es:*"],
3687
3884
  resources: [openSearch.arn]
@@ -3692,8 +3889,8 @@ var searchFeature = defineFeature({
3692
3889
  });
3693
3890
 
3694
3891
  // 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";
3892
+ import { days as days4, seconds as seconds3 } from "@awsless/duration";
3893
+ import { Asset as Asset4, aws as aws15, Node as Node15 } from "@awsless/formation";
3697
3894
  import { glob as glob2 } from "glob";
3698
3895
  import { join as join8 } from "path";
3699
3896
 
@@ -3722,7 +3919,7 @@ var siteFeature = defineFeature({
3722
3919
  name: "site",
3723
3920
  onStack(ctx) {
3724
3921
  for (const [id, props] of Object.entries(ctx.stackConfig.sites ?? {})) {
3725
- const group = new Node14(ctx.stack, "site", id);
3922
+ const group = new Node15(ctx.stack, "site", id);
3726
3923
  const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "site", id);
3727
3924
  const origins = [];
3728
3925
  const originGroups = [];
@@ -3731,8 +3928,10 @@ var siteFeature = defineFeature({
3731
3928
  if (props.ssr) {
3732
3929
  const { lambda, code } = createLambdaFunction(group, ctx, `site`, id, props.ssr);
3733
3930
  versions.push(code.version);
3734
- ctx.registerSiteFunction(lambda);
3735
- new aws14.lambda.Permission(group, "permission", {
3931
+ ctx.onBind((name2, value) => {
3932
+ lambda.addEnvironment(name2, value);
3933
+ });
3934
+ new aws15.lambda.Permission(group, "permission", {
3736
3935
  principal: "*",
3737
3936
  // principal: 'cloudfront.amazonaws.com',
3738
3937
  action: "lambda:InvokeFunctionUrl",
@@ -3741,7 +3940,7 @@ var siteFeature = defineFeature({
3741
3940
  // urlAuthType: 'aws-iam',
3742
3941
  // sourceArn: distribution.arn,
3743
3942
  });
3744
- const url = new aws14.lambda.Url(group, "url", {
3943
+ const url = new aws15.lambda.Url(group, "url", {
3745
3944
  targetArn: lambda.arn,
3746
3945
  authType: "none"
3747
3946
  // authType: 'aws-iam',
@@ -3753,7 +3952,7 @@ var siteFeature = defineFeature({
3753
3952
  });
3754
3953
  }
3755
3954
  if (props.static) {
3756
- bucket = new aws14.s3.Bucket(group, "bucket", {
3955
+ bucket = new aws15.s3.Bucket(group, "bucket", {
3757
3956
  name,
3758
3957
  forceDelete: true,
3759
3958
  website: {
@@ -3770,7 +3969,7 @@ var siteFeature = defineFeature({
3770
3969
  ]
3771
3970
  });
3772
3971
  bucket.deletionPolicy = "after-deployment";
3773
- const accessControl = new aws14.cloudFront.OriginAccessControl(group, `access`, {
3972
+ const accessControl = new aws15.cloudFront.OriginAccessControl(group, `access`, {
3774
3973
  name,
3775
3974
  type: "s3",
3776
3975
  behavior: "always",
@@ -3782,10 +3981,10 @@ var siteFeature = defineFeature({
3782
3981
  nodir: true
3783
3982
  });
3784
3983
  for (const file of files) {
3785
- const object = new aws14.s3.BucketObject(group, file, {
3984
+ const object = new aws15.s3.BucketObject(group, file, {
3786
3985
  bucket: bucket.name,
3787
3986
  key: file,
3788
- body: Asset3.fromFile(join8(props.static, file)),
3987
+ body: Asset4.fromFile(join8(props.static, file)),
3789
3988
  cacheControl: getCacheControl(file),
3790
3989
  contentType: getContentType(file)
3791
3990
  });
@@ -3805,14 +4004,14 @@ var siteFeature = defineFeature({
3805
4004
  statusCodes: [403, 404]
3806
4005
  });
3807
4006
  }
3808
- const cache = new aws14.cloudFront.CachePolicy(group, "cache", {
4007
+ const cache = new aws15.cloudFront.CachePolicy(group, "cache", {
3809
4008
  name,
3810
4009
  minTtl: seconds3(1),
3811
- maxTtl: days3(365),
3812
- defaultTtl: days3(1),
4010
+ maxTtl: days4(365),
4011
+ defaultTtl: days4(1),
3813
4012
  ...props.cache
3814
4013
  });
3815
- const originRequest = new aws14.cloudFront.OriginRequestPolicy(group, "request", {
4014
+ const originRequest = new aws15.cloudFront.OriginRequestPolicy(group, "request", {
3816
4015
  name,
3817
4016
  header: {
3818
4017
  behavior: "all-except",
@@ -3820,7 +4019,7 @@ var siteFeature = defineFeature({
3820
4019
  }
3821
4020
  });
3822
4021
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
3823
- const responseHeaders = new aws14.cloudFront.ResponseHeadersPolicy(group, "response", {
4022
+ const responseHeaders = new aws15.cloudFront.ResponseHeadersPolicy(group, "response", {
3824
4023
  name,
3825
4024
  cors: props.cors,
3826
4025
  remove: ["server"]
@@ -3828,7 +4027,7 @@ var siteFeature = defineFeature({
3828
4027
  // override: true,
3829
4028
  // },
3830
4029
  });
3831
- const distribution = new aws14.cloudFront.Distribution(group, "distribution", {
4030
+ const distribution = new aws15.cloudFront.Distribution(group, "distribution", {
3832
4031
  name,
3833
4032
  certificateArn: ctx.shared.get(`global-certificate-${props.domain}-arn`),
3834
4033
  compress: true,
@@ -3856,13 +4055,13 @@ var siteFeature = defineFeature({
3856
4055
  };
3857
4056
  })
3858
4057
  });
3859
- new aws14.cloudFront.InvalidateCache(group, "invalidate", {
4058
+ new aws15.cloudFront.InvalidateCache(group, "invalidate", {
3860
4059
  distributionId: distribution.id,
3861
4060
  paths: ["/*"],
3862
4061
  versions
3863
4062
  });
3864
4063
  if (props.static) {
3865
- new aws14.s3.BucketPolicy(group, `policy`, {
4064
+ new aws15.s3.BucketPolicy(group, `policy`, {
3866
4065
  bucketName: bucket.name,
3867
4066
  statements: [
3868
4067
  {
@@ -3888,7 +4087,7 @@ var siteFeature = defineFeature({
3888
4087
  ]
3889
4088
  });
3890
4089
  }
3891
- new aws14.route53.RecordSet(group, `record`, {
4090
+ new aws15.route53.RecordSet(group, `record`, {
3892
4091
  hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
3893
4092
  type: "A",
3894
4093
  name: domainName,
@@ -3903,7 +4102,7 @@ var siteFeature = defineFeature({
3903
4102
  });
3904
4103
 
3905
4104
  // src/feature/store/index.ts
3906
- import { aws as aws15, Node as Node15 } from "@awsless/formation";
4105
+ import { aws as aws16, Node as Node16 } from "@awsless/formation";
3907
4106
  import { paramCase as paramCase6 } from "change-case";
3908
4107
  var typeGenCode5 = `
3909
4108
  import { Body, PutObjectProps, BodyStream, createPresignedPost } from '@awsless/s3'
@@ -3940,7 +4139,7 @@ var storeFeature = defineFeature({
3940
4139
  },
3941
4140
  onStack(ctx) {
3942
4141
  for (const [id, props] of Object.entries(ctx.stackConfig.stores ?? {})) {
3943
- const group = new Node15(ctx.stack, "store", id);
4142
+ const group = new Node16(ctx.stack, "store", id);
3944
4143
  const bucketName = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "store", id);
3945
4144
  const lambdaConfigs = [];
3946
4145
  const eventMap = {
@@ -3954,10 +4153,10 @@ var storeFeature = defineFeature({
3954
4153
  "removed:marker": "s3:ObjectRemoved:DeleteMarkerCreated"
3955
4154
  };
3956
4155
  for (const [event, funcProps] of Object.entries(props.events ?? {})) {
3957
- const eventGroup = new Node15(group, "event", event);
4156
+ const eventGroup = new Node16(group, "event", event);
3958
4157
  const eventId = paramCase6(`${id}-${shortId(event)}`);
3959
4158
  const { lambda } = createAsyncLambdaFunction(eventGroup, ctx, `store`, eventId, funcProps);
3960
- new aws15.lambda.Permission(eventGroup, "permission", {
4159
+ new aws16.lambda.Permission(eventGroup, "permission", {
3961
4160
  action: "lambda:InvokeFunction",
3962
4161
  principal: "s3.amazonaws.com",
3963
4162
  functionArn: lambda.arn,
@@ -3968,7 +4167,7 @@ var storeFeature = defineFeature({
3968
4167
  function: lambda.arn
3969
4168
  });
3970
4169
  }
3971
- const bucket = new aws15.s3.Bucket(group, "store", {
4170
+ const bucket = new aws16.s3.Bucket(group, "store", {
3972
4171
  name: bucketName,
3973
4172
  versioning: props.versioning,
3974
4173
  lambdaConfigs,
@@ -3983,15 +4182,39 @@ var storeFeature = defineFeature({
3983
4182
  // ---------------------------------------------
3984
4183
  ]
3985
4184
  });
3986
- ctx.onFunction(({ policy }) => {
4185
+ ctx.onPolicy((policy) => {
3987
4186
  policy.addStatement(bucket.permissions);
3988
4187
  });
3989
4188
  }
3990
4189
  }
3991
4190
  });
3992
4191
 
4192
+ // src/feature/stream/index.ts
4193
+ import { aws as aws17, Node as Node17 } from "@awsless/formation";
4194
+ import { constantCase as constantCase9 } from "change-case";
4195
+ var streamFeature = defineFeature({
4196
+ name: "stream",
4197
+ onStack(ctx) {
4198
+ for (const [id, props] of Object.entries(ctx.stackConfig.streams ?? {})) {
4199
+ const group = new Node17(ctx.stack, "stream", id);
4200
+ const name = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "stream", id);
4201
+ const channel = new aws17.ivs.Channel(group, "channel", {
4202
+ name,
4203
+ ...props
4204
+ });
4205
+ const streamKey = new aws17.ivs.StreamKey(group, "key", {
4206
+ channel: channel.arn
4207
+ });
4208
+ const prefix = `STREAM_${constantCase9(ctx.stack.name)}_${constantCase9(id)}`;
4209
+ ctx.bind(`${prefix}_ENDPOINT`, channel.playbackUrl);
4210
+ ctx.addEnv(`${prefix}_INGEST_ENDPOINT`, channel.ingestEndpoint);
4211
+ ctx.addEnv(`${prefix}_STREAM_KEY`, streamKey.value);
4212
+ }
4213
+ }
4214
+ });
4215
+
3993
4216
  // src/feature/table/index.ts
3994
- import { Node as Node16, aws as aws16 } from "@awsless/formation";
4217
+ import { aws as aws18, Node as Node18 } from "@awsless/formation";
3995
4218
  var tableFeature = defineFeature({
3996
4219
  name: "table",
3997
4220
  async onTypeGen(ctx) {
@@ -4010,8 +4233,8 @@ var tableFeature = defineFeature({
4010
4233
  },
4011
4234
  onStack(ctx) {
4012
4235
  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", {
4236
+ const group = new Node18(ctx.stack, "table", id);
4237
+ const table2 = new aws18.dynamodb.Table(group, "table", {
4015
4238
  ...props,
4016
4239
  name: formatLocalResourceName(ctx.appConfig.name, ctx.stackConfig.name, "table", id),
4017
4240
  stream: props.stream?.type
@@ -4020,7 +4243,7 @@ var tableFeature = defineFeature({
4020
4243
  const { lambda, policy } = createLambdaFunction(group, ctx, "table", id, props.stream.consumer);
4021
4244
  lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
4022
4245
  const onFailure = getGlobalOnFailure(ctx);
4023
- const source = new aws16.lambda.EventSourceMapping(group, id, {
4246
+ const source = new aws18.lambda.EventSourceMapping(group, id, {
4024
4247
  functionArn: lambda.arn,
4025
4248
  sourceArn: table2.streamArn,
4026
4249
  batchSize: 100,
@@ -4039,7 +4262,7 @@ var tableFeature = defineFeature({
4039
4262
  });
4040
4263
  }
4041
4264
  }
4042
- ctx.onFunction(({ policy }) => {
4265
+ ctx.onPolicy((policy) => {
4043
4266
  policy.addStatement(...table2.permissions);
4044
4267
  });
4045
4268
  }
@@ -4047,9 +4270,9 @@ var tableFeature = defineFeature({
4047
4270
  });
4048
4271
 
4049
4272
  // src/feature/task/index.ts
4273
+ import { Node as Node19 } from "@awsless/formation";
4050
4274
  import { camelCase as camelCase6 } from "change-case";
4051
4275
  import { relative as relative4 } from "path";
4052
- import { Node as Node17 } from "@awsless/formation";
4053
4276
  var typeGenCode6 = `
4054
4277
  import { InvokeOptions } from '@awsless/lambda'
4055
4278
  import type { Mock } from 'vitest'
@@ -4097,7 +4320,7 @@ var taskFeature = defineFeature({
4097
4320
  },
4098
4321
  onStack(ctx) {
4099
4322
  for (const [id, props] of Object.entries(ctx.stackConfig.tasks ?? {})) {
4100
- const group = new Node17(ctx.stack, "task", id);
4323
+ const group = new Node19(ctx.stack, "task", id);
4101
4324
  createAsyncLambdaFunction(group, ctx, "task", id, props.consumer);
4102
4325
  }
4103
4326
  }
@@ -4114,7 +4337,7 @@ var testFeature = defineFeature({
4114
4337
  });
4115
4338
 
4116
4339
  // src/feature/topic/index.ts
4117
- import { Node as Node18, aws as aws17 } from "@awsless/formation";
4340
+ import { aws as aws19, Node as Node20 } from "@awsless/formation";
4118
4341
  var typeGenCode7 = `
4119
4342
  import type { PublishOptions } from '@awsless/sns'
4120
4343
  import type { Mock } from 'vitest'
@@ -4151,8 +4374,8 @@ var topicFeature = defineFeature({
4151
4374
  onApp(ctx) {
4152
4375
  for (const stack of ctx.stackConfigs) {
4153
4376
  for (const id of stack.topics ?? []) {
4154
- const group = new Node18(ctx.base, "topic", id);
4155
- const topic = new aws17.sns.Topic(group, "topic", {
4377
+ const group = new Node20(ctx.base, "topic", id);
4378
+ const topic = new aws19.sns.Topic(group, "topic", {
4156
4379
  name: formatGlobalResourceName(ctx.appConfig.name, "topic", id)
4157
4380
  });
4158
4381
  ctx.shared.set(`topic-${id}-arn`, topic.arn);
@@ -4161,7 +4384,7 @@ var topicFeature = defineFeature({
4161
4384
  },
4162
4385
  onStack(ctx) {
4163
4386
  for (const id of ctx.stackConfig.topics ?? []) {
4164
- ctx.onFunction(({ policy }) => {
4387
+ ctx.onPolicy((policy) => {
4165
4388
  policy.addStatement({
4166
4389
  actions: ["sns:Publish"],
4167
4390
  resources: [ctx.shared.get(`topic-${id}-arn`)]
@@ -4169,22 +4392,22 @@ var topicFeature = defineFeature({
4169
4392
  });
4170
4393
  }
4171
4394
  for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
4172
- const group = new Node18(ctx.stack, "topic", id);
4395
+ const group = new Node20(ctx.stack, "topic", id);
4173
4396
  const topicArn = ctx.shared.get(`topic-${id}-arn`);
4174
4397
  if (typeof props === "string" && isEmail(props)) {
4175
- new aws17.sns.Subscription(group, id, {
4398
+ new aws19.sns.Subscription(group, id, {
4176
4399
  topicArn,
4177
4400
  protocol: "email",
4178
4401
  endpoint: props
4179
4402
  });
4180
4403
  } else if (typeof props === "object") {
4181
4404
  const { lambda } = createAsyncLambdaFunction(group, ctx, `topic`, id, props);
4182
- new aws17.sns.Subscription(group, id, {
4405
+ new aws19.sns.Subscription(group, id, {
4183
4406
  topicArn,
4184
4407
  protocol: "lambda",
4185
4408
  endpoint: lambda.arn
4186
4409
  });
4187
- new aws17.lambda.Permission(group, id, {
4410
+ new aws19.lambda.Permission(group, id, {
4188
4411
  action: "lambda:InvokeFunction",
4189
4412
  principal: "sns.amazonaws.com",
4190
4413
  functionArn: lambda.arn,
@@ -4196,52 +4419,72 @@ var topicFeature = defineFeature({
4196
4419
  });
4197
4420
 
4198
4421
  // src/feature/vpc/index.ts
4199
- import { Node as Node19, all, aws as aws18 } from "@awsless/formation";
4422
+ import { ipv6CidrBlockFromString } from "@arcanyx/cidr-slicer";
4423
+ import { aws as aws20, combine as combine2, Node as Node21 } from "@awsless/formation";
4200
4424
  var vpcFeature = defineFeature({
4201
4425
  name: "vpc",
4202
4426
  onApp(ctx) {
4203
- const group = new Node19(ctx.base, "vpc", "main");
4204
- const vpc = new aws18.ec2.Vpc(group, "vpc", {
4427
+ const group = new Node21(ctx.base, "vpc", "main");
4428
+ const vpc = new aws20.ec2.Vpc(group, "vpc", {
4205
4429
  name: ctx.app.name,
4206
- cidrBlock: aws18.ec2.Peer.ipv4("10.0.0.0/16")
4430
+ cidrBlock: aws20.ec2.Peer.ipv4("10.0.0.0/16")
4431
+ // cidrBlock: aws.ec2.Peer.ipv6('fd00:10:20::/48'),
4432
+ // cidrBlock: aws.ec2.Peer.ipv6('2a05:d018:c69:6600::/56'),
4433
+ // enableDnsSupport: true,
4434
+ // enableDnsHostnames: true,
4435
+ });
4436
+ const ipv6CidrBlock = new aws20.ec2.VPCCidrBlock(group, "ipv6", {
4437
+ vpcId: vpc.id,
4438
+ amazonProvidedIpv6CidrBlock: true
4439
+ });
4440
+ const slices = ipv6CidrBlock.ipv6CidrBlock.apply((ip) => {
4441
+ return ipv6CidrBlockFromString(ip).slice(64);
4207
4442
  });
4208
- const privateRouteTable = new aws18.ec2.RouteTable(group, "private", {
4443
+ const privateRouteTable = new aws20.ec2.RouteTable(group, "private", {
4209
4444
  vpcId: vpc.id,
4210
4445
  name: "private"
4211
4446
  });
4212
- const publicRouteTable = new aws18.ec2.RouteTable(group, "public", {
4447
+ const publicRouteTable = new aws20.ec2.RouteTable(group, "public", {
4213
4448
  vpcId: vpc.id,
4214
4449
  name: "public"
4215
4450
  });
4216
- const gateway = new aws18.ec2.InternetGateway(group, "gateway");
4217
- const attachment = new aws18.ec2.VPCGatewayAttachment(group, "attachment", {
4451
+ const gateway = new aws20.ec2.InternetGateway(group, "gateway");
4452
+ const attachment = new aws20.ec2.VPCGatewayAttachment(group, "attachment", {
4218
4453
  vpcId: vpc.id,
4219
4454
  internetGatewayId: gateway.id
4220
4455
  });
4221
- new aws18.ec2.Route(group, "route", {
4456
+ new aws20.ec2.Route(group, "route", {
4222
4457
  gatewayId: gateway.id,
4223
4458
  routeTableId: publicRouteTable.id,
4224
- destination: aws18.ec2.Peer.anyIpv4()
4459
+ // destination: aws.ec2.Peer.anyIpv4(),
4460
+ destination: aws20.ec2.Peer.anyIpv6()
4225
4461
  });
4226
4462
  ctx.shared.set(
4227
4463
  "vpc-id",
4228
4464
  // Some resources require the internet gateway to be attached.
4229
- all([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
4465
+ combine2([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
4230
4466
  );
4231
4467
  ctx.shared.set("vpc-security-group-id", vpc.defaultSecurityGroup);
4232
4468
  const zones = ["a", "b"];
4233
4469
  const tables = [privateRouteTable, publicRouteTable];
4234
- let block = 0;
4470
+ let block = 0n;
4235
4471
  for (const table2 of tables) {
4236
4472
  for (const i in zones) {
4237
4473
  const index = Number(i) + 1;
4238
4474
  const id = `${table2.identifier}-${index}`;
4239
- const subnet = new aws18.ec2.Subnet(group, id, {
4475
+ const subnet = new aws20.ec2.Subnet(group, id, {
4476
+ name: `${ctx.app.name}--${table2.identifier}-${index}`,
4240
4477
  vpcId: vpc.id,
4241
- cidrBlock: aws18.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
4478
+ cidrBlock: aws20.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
4479
+ // ipv6CidrBlock: aws.ec2.Peer.ipv6(`fd00:10:20:${++block}::/64`),
4480
+ // ipv6CidrBlock: aws.ec2.Peer.ipv6(`2a05:d018:c69:660${++block}::/64`),
4481
+ // ipv6CidrBlock: ipv6CidrBlock.ipv6CidrBlock.apply(ip => ),
4482
+ ipv6CidrBlock: slices.apply((list4) => aws20.ec2.Peer.ipv6(list4.get(block++).toString())),
4483
+ assignIpv6AddressOnCreation: true,
4484
+ // ipv6Native: true,
4242
4485
  availabilityZone: ctx.appConfig.region + zones[i]
4243
4486
  });
4244
- new aws18.ec2.SubnetRouteTableAssociation(group, id, {
4487
+ new aws20.ec2.SubnetRouteTableAssociation(group, id, {
4245
4488
  routeTableId: table2.id,
4246
4489
  subnetId: subnet.id
4247
4490
  });
@@ -4261,10 +4504,12 @@ var features = [
4261
4504
  authFeature,
4262
4505
  // 3
4263
4506
  functionFeature,
4507
+ instanceFeature,
4264
4508
  graphqlFeature,
4265
4509
  configFeature,
4266
4510
  searchFeature,
4267
4511
  pubsubFeature,
4512
+ streamFeature,
4268
4513
  tableFeature,
4269
4514
  topicFeature,
4270
4515
  queueFeature,
@@ -4313,26 +4558,39 @@ var createApp = (props, filters = []) => {
4313
4558
  const app = new App(props.appConfig.name);
4314
4559
  const base = new Stack(app, "base");
4315
4560
  const shared = new SharedData();
4316
- const binds = [];
4317
4561
  const siteFunctions = [];
4318
4562
  const configs = /* @__PURE__ */ new Set();
4319
4563
  const tests = [];
4320
4564
  const builders = [];
4321
- const allFunctions = [];
4322
- const globalListeners = [];
4323
- const allLocalListeners = {};
4324
- const allLocalFunctions = {};
4565
+ const readyListeners = [];
4566
+ const binds = [];
4567
+ const bindListeners = [];
4568
+ const allEnv = [];
4569
+ const allEnvListeners = [];
4570
+ const allLocalEnv = {};
4571
+ const allLocalEnvListeners = {};
4572
+ const allPolicies = [];
4573
+ const allPoliciesListeners = [];
4574
+ const allLocalPolicies = {};
4575
+ const allLocalPolicyListeners = {};
4325
4576
  for (const feature of features) {
4326
4577
  feature.onApp?.({
4327
4578
  ...props,
4328
4579
  app,
4580
+ // env,
4329
4581
  base,
4330
4582
  shared,
4331
- onFunction(callback) {
4332
- globalListeners.push(callback);
4583
+ onPolicy(callback) {
4584
+ allPoliciesListeners.push(callback);
4333
4585
  },
4334
- registerFunction(lambda, policy) {
4335
- allFunctions.push({ lambda, policy });
4586
+ // onFunction(callback) {
4587
+ // allFunctionListeners.push(callback)
4588
+ // },
4589
+ // registerFunction(lambda) {
4590
+ // allFunctions.push(lambda)
4591
+ // },
4592
+ registerPolicy(policy) {
4593
+ allPolicies.push(policy);
4336
4594
  },
4337
4595
  registerTest(name, paths) {
4338
4596
  tests.push({ name, paths });
@@ -4340,11 +4598,23 @@ var createApp = (props, filters = []) => {
4340
4598
  registerBuild(type, name, builder) {
4341
4599
  builders.push({ type, name, builder });
4342
4600
  },
4343
- registerSiteFunction(lambda) {
4344
- siteFunctions.push(lambda);
4345
- },
4346
- bindEnv(name, value) {
4601
+ // registerSiteFunction(lambda) {
4602
+ // siteFunctions.push(lambda)
4603
+ // },
4604
+ bind(name, value) {
4347
4605
  binds.push({ name, value });
4606
+ },
4607
+ onBind(cb) {
4608
+ bindListeners.push(cb);
4609
+ },
4610
+ addEnv(name, value) {
4611
+ allEnv.push({ name, value });
4612
+ },
4613
+ onEnv(cb) {
4614
+ allEnvListeners.push(cb);
4615
+ },
4616
+ onReady(cb) {
4617
+ readyListeners.push(cb);
4348
4618
  }
4349
4619
  });
4350
4620
  }
@@ -4354,25 +4624,37 @@ var createApp = (props, filters = []) => {
4354
4624
  filterdStacks = filterdStacks.filter((stack) => filtersWithDeps.includes(stack.name));
4355
4625
  }
4356
4626
  for (const stackConfig of filterdStacks) {
4357
- const localListeners = [];
4358
- const localFunctions = [];
4627
+ const localPolicyListeners = [];
4628
+ const localPolicies = [];
4629
+ const localEnvListeners = [];
4630
+ const localEnv = [];
4359
4631
  const stack = new Stack(app, stackConfig.name);
4360
- allLocalListeners[stack.name] = localListeners;
4361
- allLocalFunctions[stack.name] = localFunctions;
4632
+ allLocalPolicyListeners[stack.name] = localPolicyListeners;
4633
+ allLocalPolicies[stack.name] = localPolicies;
4634
+ allLocalEnvListeners[stack.name] = localEnvListeners;
4635
+ allLocalEnv[stack.name] = localEnv;
4362
4636
  for (const feature of features) {
4363
4637
  feature.onStack?.({
4364
4638
  ...props,
4365
4639
  stackConfig,
4366
4640
  app,
4641
+ // env,
4367
4642
  base,
4368
4643
  stack,
4369
4644
  shared,
4370
- onFunction(callback) {
4371
- localListeners.push(callback);
4645
+ // onFunction(callback) {
4646
+ // localFunctionListeners.push(callback)
4647
+ // },
4648
+ // registerFunction(lambda) {
4649
+ // allFunctions.push(lambda)
4650
+ // localFunctions.push(lambda)
4651
+ // },
4652
+ onPolicy(callback) {
4653
+ localPolicyListeners.push(callback);
4372
4654
  },
4373
- registerFunction(lambda, policy) {
4374
- allFunctions.push({ lambda, policy });
4375
- localFunctions.push({ lambda, policy });
4655
+ registerPolicy(policy) {
4656
+ allPolicies.push(policy);
4657
+ localPolicies.push(policy);
4376
4658
  },
4377
4659
  registerTest(name, paths) {
4378
4660
  tests.push({ name, paths });
@@ -4383,41 +4665,71 @@ var createApp = (props, filters = []) => {
4383
4665
  registerConfig(name) {
4384
4666
  configs.add(name);
4385
4667
  },
4386
- registerSiteFunction(lambda) {
4387
- siteFunctions.push(lambda);
4388
- },
4389
- bindEnv(name, value) {
4668
+ // registerSiteFunction(lambda) {
4669
+ // siteFunctions.push(lambda)
4670
+ // },
4671
+ // bindEnv(name, value) {
4672
+ // binds.push({ name, value })
4673
+ // },
4674
+ bind(name, value) {
4390
4675
  binds.push({ name, value });
4676
+ },
4677
+ onBind(cb) {
4678
+ bindListeners.push(cb);
4679
+ },
4680
+ addEnv(name, value) {
4681
+ localEnv.push({ name, value });
4682
+ },
4683
+ onEnv(cb) {
4684
+ localEnvListeners.push(cb);
4685
+ },
4686
+ onReady(cb) {
4687
+ readyListeners.push(cb);
4391
4688
  }
4392
4689
  });
4393
4690
  }
4394
- for (const listener of localListeners) {
4395
- for (const fn of localFunctions) {
4396
- listener(fn);
4691
+ for (const listener of localPolicyListeners) {
4692
+ for (const policy of localPolicies) {
4693
+ listener(policy);
4694
+ }
4695
+ }
4696
+ for (const listener of localEnvListeners) {
4697
+ for (const env of localEnv) {
4698
+ listener(env.name, env.value);
4397
4699
  }
4398
4700
  }
4399
4701
  }
4400
- for (const listener of globalListeners) {
4401
- for (const fn of allFunctions) {
4702
+ for (const listener of allPoliciesListeners) {
4703
+ for (const fn of allPolicies) {
4402
4704
  listener(fn);
4403
4705
  }
4404
4706
  }
4405
- for (const lambda of siteFunctions) {
4406
- for (const { name, value } of binds) {
4407
- lambda.addEnvironment(name, value);
4707
+ for (const listener of allEnvListeners) {
4708
+ for (const env of allEnv) {
4709
+ listener(env.name, env.value);
4408
4710
  }
4409
4711
  }
4410
4712
  for (const stackConfig of filterdStacks) {
4411
- const functions = allLocalFunctions[stackConfig.name];
4713
+ const policies = allLocalPolicies[stackConfig.name];
4714
+ const env = allLocalEnv[stackConfig.name];
4412
4715
  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);
4716
+ const policyListeners = allLocalPolicyListeners[dependency];
4717
+ const envListeners = allLocalEnvListeners[dependency];
4718
+ for (const policy of policies) {
4719
+ for (const listener of policyListeners) {
4720
+ listener(policy);
4721
+ }
4722
+ }
4723
+ for (const entry of env) {
4724
+ for (const listener of envListeners) {
4725
+ listener(entry.name, entry.value);
4417
4726
  }
4418
4727
  }
4419
4728
  }
4420
4729
  }
4730
+ for (const listener of readyListeners) {
4731
+ listener();
4732
+ }
4421
4733
  return {
4422
4734
  app,
4423
4735
  base,
@@ -4611,19 +4923,19 @@ import { confirm as confirm3 } from "@clack/prompts";
4611
4923
 
4612
4924
  // src/util/workspace.ts
4613
4925
  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";
4926
+ import { aws as aws22, local, WorkSpace } from "@awsless/formation";
4927
+ import { mkdir as mkdir3, readFile as readFile6, rm, writeFile as writeFile2 } from "fs/promises";
4928
+ import { dirname as dirname10, join as join9 } from "path";
4617
4929
  var createWorkSpace = (props) => {
4618
- const lockProvider = new aws20.dynamodb.LockProvider({
4930
+ const lockProvider = new aws22.dynamodb.LockProvider({
4619
4931
  ...props,
4620
4932
  tableName: "awsless-locks"
4621
4933
  });
4622
- const stateProvider = new aws20.s3.StateProvider({
4934
+ const stateProvider = new aws22.s3.StateProvider({
4623
4935
  ...props,
4624
4936
  bucket: "awsless-state"
4625
4937
  });
4626
- const cloudProviders = aws20.createCloudProviders({
4938
+ const cloudProviders = aws22.createCloudProviders({
4627
4939
  ...props,
4628
4940
  timeout: minutes4(60)
4629
4941
  });
@@ -4642,7 +4954,7 @@ var createWorkSpace = (props) => {
4642
4954
  var pullRemoteState = async (app, stateProvider) => {
4643
4955
  const file = join9(directories.state, `${app.urn}.json`);
4644
4956
  const state2 = await stateProvider.get(app.urn);
4645
- await mkdir2(dirname9(file), { recursive: true });
4957
+ await mkdir3(dirname10(file), { recursive: true });
4646
4958
  if (typeof state2 === "undefined") {
4647
4959
  await rm(file);
4648
4960
  } else {
@@ -4699,7 +5011,7 @@ import { confirm as confirm4 } from "@clack/prompts";
4699
5011
 
4700
5012
  // src/cli/ui/complex/run-tests.ts
4701
5013
  import { join as join11 } from "path";
4702
- import { mkdir as mkdir3, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
5014
+ import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
4703
5015
 
4704
5016
  // src/test/reporter.ts
4705
5017
  import { getSuites, getTests } from "@vitest/runner/utils";
@@ -4781,10 +5093,10 @@ import { startVitest } from "vitest/node";
4781
5093
  import commonjs3 from "@rollup/plugin-commonjs";
4782
5094
  import nodeResolve3 from "@rollup/plugin-node-resolve";
4783
5095
  import json3 from "@rollup/plugin-json";
4784
- import { dirname as dirname10, join as join10 } from "path";
5096
+ import { dirname as dirname11, join as join10 } from "path";
4785
5097
  import { fileURLToPath } from "url";
4786
5098
  var startTest = async (props) => {
4787
- const __dirname = dirname10(fileURLToPath(import.meta.url));
5099
+ const __dirname = dirname11(fileURLToPath(import.meta.url));
4788
5100
  const result = await startVitest(
4789
5101
  "test",
4790
5102
  props.filters,
@@ -4892,7 +5204,7 @@ var logTestErrors = (event) => {
4892
5204
  });
4893
5205
  };
4894
5206
  var runTest = async (stack, dir, filters) => {
4895
- await mkdir3(directories.test, { recursive: true });
5207
+ await mkdir4(directories.test, { recursive: true });
4896
5208
  const fingerprint = await fingerprintFromDirectory(dir);
4897
5209
  const file = join11(directories.test, `${stack}.json`);
4898
5210
  const exists = await fileExist(file);
@@ -5001,81 +5313,152 @@ var deploy = (program2) => {
5001
5313
  });
5002
5314
  };
5003
5315
 
5004
- // src/cli/command/diff.ts
5005
- import { aws as aws21, WorkSpace as WorkSpace2 } from "@awsless/formation";
5006
- import chalk7 from "chalk";
5007
- var diff = (program2) => {
5008
- program2.command("diff").description("Diff your app with AWS").action(async (filters) => {
5009
- await layout("diff", async ({ appConfig, stackConfigs }) => {
5316
+ // src/cli/command/auth/user/create.ts
5317
+ import {
5318
+ AdminCreateUserCommand,
5319
+ AdminSetUserPasswordCommand,
5320
+ CognitoIdentityProviderClient
5321
+ } from "@aws-sdk/client-cognito-identity-provider";
5322
+ import { unwrap as unwrap2 } from "@awsless/formation";
5323
+ import { password, select, text as text2 } from "@clack/prompts";
5324
+ var create = (program2) => {
5325
+ program2.command("create").argument("[name]", "The name of the auth instance").description("Create an user for your userpool").action(async (name) => {
5326
+ await layout("auth user create", async ({ appConfig, stackConfigs }) => {
5010
5327
  const region = appConfig.region;
5011
5328
  const credentials = getCredentials(appConfig.profile);
5012
5329
  const accountId = await getAccountId(credentials, region);
5013
- await bootstrapAwsless({ credentials, region });
5014
- const { app, builders } = createApp({ appConfig, stackConfigs, accountId }, filters);
5015
- await buildAssets(builders);
5016
- const workspace = new WorkSpace2({
5017
- stateProvider: new aws21.dynamodb.DynamoDBStateProvider({
5018
- credentials,
5019
- region,
5020
- tableName: "awsless-state"
5021
- }),
5022
- cloudProviders: aws21.createCloudProviders({
5023
- credentials,
5024
- region: appConfig.region
5025
- })
5026
- });
5027
- let total = 0;
5028
- const changes = [];
5029
- const formatResource = (stack, urn) => {
5030
- return urn.replace(stack.urn + ":", "").replace(/\{([a-z0-9\-]+)\}/gi, (_, v) => {
5031
- return `${color.dim("{")}${color.warning(v)}${color.dim("}")}`;
5032
- }).replaceAll(":", color.dim(":"));
5033
- };
5034
- await task("Find app differences", async () => {
5035
- for (const stack of app.stacks) {
5036
- const diff2 = await workspace.diffStack(stack);
5037
- total += diff2.creates.length;
5038
- total += diff2.updates.length;
5039
- total += diff2.deletes.length;
5040
- changes.push(
5041
- ...diff2.creates.map((v) => [
5042
- chalk7.magenta(stack.name),
5043
- color.success`create`,
5044
- formatResource(stack, v)
5045
- ]),
5046
- ...diff2.updates.map((v) => [
5047
- chalk7.magenta(stack.name),
5048
- color.warning`update`,
5049
- formatResource(stack, v)
5050
- ]),
5051
- ...diff2.deletes.map((v) => [
5052
- chalk7.magenta(stack.name),
5053
- color.error`delete`,
5054
- formatResource(stack, v)
5055
- ])
5056
- );
5057
- }
5058
- return "Done finding app differences.";
5059
- });
5060
- if (total > 0) {
5061
- console.log(
5062
- table({
5063
- head: ["stack", "operation", "resource"],
5064
- body: changes
5065
- })
5066
- );
5067
- }
5068
- return `${color.warning(total)} resources have changed.`;
5069
- });
5070
- });
5330
+ if (!name) {
5331
+ name = await select({
5332
+ message: "Select the auth userpool:",
5333
+ options: Object.keys(appConfig.defaults.auth).map((name2) => ({
5334
+ label: name2,
5335
+ value: name2
5336
+ }))
5337
+ });
5338
+ }
5339
+ if (!(name in appConfig.defaults.auth)) {
5340
+ throw new Error(`Provided auth name doesn't exist inside your app config.`);
5341
+ }
5342
+ const { shared, app } = createApp({ appConfig, stackConfigs, accountId });
5343
+ const { workspace } = createWorkSpace({
5344
+ credentials,
5345
+ accountId,
5346
+ region
5347
+ });
5348
+ await workspace.hydrate(app);
5349
+ let userPoolId;
5350
+ try {
5351
+ userPoolId = unwrap2(shared.get(`auth-${name}-user-pool-id`));
5352
+ } catch (_) {
5353
+ throw new Error(`The auth userpool hasn't been deployed yet.`);
5354
+ }
5355
+ const user2 = await text2({
5356
+ message: "Username:",
5357
+ validate(value) {
5358
+ if (!value) {
5359
+ return "Required";
5360
+ }
5361
+ return;
5362
+ }
5363
+ });
5364
+ const pass = await password({
5365
+ message: "Password:",
5366
+ mask: "*",
5367
+ validate(value) {
5368
+ if (!value) {
5369
+ return "Required";
5370
+ }
5371
+ return;
5372
+ }
5373
+ });
5374
+ const client = new CognitoIdentityProviderClient({
5375
+ region,
5376
+ credentials
5377
+ });
5378
+ await client.send(
5379
+ new AdminCreateUserCommand({
5380
+ UserPoolId: userPoolId,
5381
+ Username: user2.toString(),
5382
+ TemporaryPassword: pass.toString()
5383
+ })
5384
+ );
5385
+ await client.send(
5386
+ new AdminSetUserPasswordCommand({
5387
+ UserPoolId: userPoolId,
5388
+ Username: user2.toString(),
5389
+ Password: pass.toString(),
5390
+ Permanent: true
5391
+ })
5392
+ );
5393
+ return "User created.";
5394
+ });
5395
+ });
5396
+ };
5397
+
5398
+ // src/cli/command/auth/user/index.ts
5399
+ var commands2 = [create];
5400
+ var user = (program2) => {
5401
+ const command = program2.command("user").description(`Manage auth users`);
5402
+ commands2.forEach((cb) => cb(command));
5403
+ };
5404
+
5405
+ // src/cli/command/auth/index.ts
5406
+ var commands3 = [user];
5407
+ var auth = (program2) => {
5408
+ const command = program2.command("auth").description(`Manage auth`);
5409
+ commands3.forEach((cb) => cb(command));
5410
+ };
5411
+
5412
+ // src/cli/command/bind.ts
5413
+ import { unwrap as unwrap3 } from "@awsless/formation";
5414
+ import { note as note3 } from "@clack/prompts";
5415
+ import { spawn } from "child_process";
5416
+ var bind = (program2) => {
5417
+ program2.command("bind").argument("<command...>", "The command to execute").description(`Bind your site environment variables to a command`).action(async (commands7) => {
5418
+ await layout("bind", async ({ appConfig, stackConfigs }) => {
5419
+ const region = appConfig.region;
5420
+ const credentials = getCredentials(appConfig.profile);
5421
+ const accountId = await getAccountId(credentials, region);
5422
+ const { app, binds } = createApp({ appConfig, stackConfigs, accountId });
5423
+ const { workspace } = createWorkSpace({
5424
+ credentials,
5425
+ accountId,
5426
+ region
5427
+ });
5428
+ await workspace.hydrate(app);
5429
+ const env = {};
5430
+ for (const { name, value } of binds) {
5431
+ env[name] = unwrap3(value);
5432
+ }
5433
+ note3(wrap(list(env)), "Bind Env");
5434
+ const command = commands7.join(" ");
5435
+ spawn(command, {
5436
+ env: {
5437
+ // Pass the process env vars
5438
+ ...process.env,
5439
+ // Pass the site bind env vars
5440
+ ...env,
5441
+ // Basic info
5442
+ AWS_REGION: appConfig.region,
5443
+ AWS_ACCOUNT_ID: accountId
5444
+ // Give AWS access
5445
+ // AWS_ACCESS_KEY_ID: credentials.accessKeyId,
5446
+ // AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
5447
+ // AWS_SESSION_TOKEN: credentials.sessionToken,
5448
+ },
5449
+ stdio: "inherit",
5450
+ shell: true
5451
+ });
5452
+ });
5453
+ });
5071
5454
  };
5072
5455
 
5073
5456
  // src/cli/ui/complex/build-types.ts
5074
5457
  import { log as log9 } from "@clack/prompts";
5075
5458
 
5076
5459
  // 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";
5460
+ import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
5461
+ import { dirname as dirname12, join as join12, relative as relative5 } from "path";
5079
5462
  var generateTypes = async (props) => {
5080
5463
  const files = [];
5081
5464
  await Promise.all(
@@ -5089,7 +5472,7 @@ var generateTypes = async (props) => {
5089
5472
  if (include) {
5090
5473
  files.push(relative5(directories.root, path));
5091
5474
  }
5092
- await mkdir4(dirname11(path), { recursive: true });
5475
+ await mkdir5(dirname12(path), { recursive: true });
5093
5476
  await writeFile4(path, code);
5094
5477
  }
5095
5478
  }
@@ -5108,75 +5491,6 @@ var buildTypes = async (props) => {
5108
5491
  log9.step("Done generating type definition files.");
5109
5492
  };
5110
5493
 
5111
- // src/cli/command/types.ts
5112
- var types = (program2) => {
5113
- program2.command("types").description("Generate type definition files").action(async () => {
5114
- await layout("types", async (props) => {
5115
- await buildTypes(props);
5116
- return `Ready to use the ${color.info("@awsless/awsless")} libary!`;
5117
- });
5118
- });
5119
- };
5120
-
5121
- // src/cli/command/test.ts
5122
- var test = (program2) => {
5123
- program2.command("test").argument("[stacks...]", "Optionally filter stacks to test").option("-f --filters <string...>", "Optionally filter test files").description("Test your app").action(async (stacks, options) => {
5124
- await layout("test", async (props) => {
5125
- const region = props.appConfig.region;
5126
- const credentials = getCredentials(props.appConfig.profile);
5127
- const accountId = await getAccountId(credentials, region);
5128
- const { tests } = createApp({ ...props, accountId }, stacks);
5129
- if (tests.length === 0) {
5130
- return "No tests found.";
5131
- }
5132
- await runTests(tests, options?.filters);
5133
- return "All tests finished.";
5134
- });
5135
- });
5136
- };
5137
-
5138
- // src/cli/command/resource/list.ts
5139
- import chalk8 from "chalk";
5140
- var list3 = (program2) => {
5141
- program2.command("list").description(`List all defined resources`).action(async () => {
5142
- await layout("resource list", async ({ appConfig, stackConfigs }) => {
5143
- const region = appConfig.region;
5144
- const credentials = getCredentials(appConfig.profile);
5145
- const accountId = await getAccountId(credentials, region);
5146
- const { app } = createApp({ appConfig, stackConfigs, accountId });
5147
- const resources = [];
5148
- const formatResource = (stack, urn) => {
5149
- return urn.replace(stack.urn + ":", "").replace(/\{([a-z0-9\-\s\/\._]+)\}/gi, (_, v) => {
5150
- return `${color.dim("{")}${color.warning(v)}${color.dim("}")}`;
5151
- }).replaceAll(":", color.dim(":"));
5152
- };
5153
- for (const stack of app.stacks) {
5154
- for (const resource2 of stack.resources) {
5155
- resources.push([
5156
- chalk8.magenta(stack.name),
5157
- // resource.type,
5158
- formatResource(stack, resource2.urn)
5159
- ]);
5160
- }
5161
- }
5162
- console.log(
5163
- table({
5164
- // colWidths,
5165
- head: ["stack", "urn"],
5166
- body: resources
5167
- })
5168
- );
5169
- });
5170
- });
5171
- };
5172
-
5173
- // src/cli/command/resource/index.ts
5174
- var commands2 = [list3];
5175
- var resource = (program2) => {
5176
- const command = program2.command("resource").description(`Manage app resources`);
5177
- commands2.forEach((cb) => cb(command));
5178
- };
5179
-
5180
5494
  // src/config/load/watch.ts
5181
5495
  import { watch } from "chokidar";
5182
5496
  var watchConfig = async (options, resolve, reject) => {
@@ -5224,6 +5538,48 @@ var dev = (program2) => {
5224
5538
  });
5225
5539
  };
5226
5540
 
5541
+ // src/cli/command/resource/list.ts
5542
+ import chalk7 from "chalk";
5543
+ var list3 = (program2) => {
5544
+ program2.command("list").description(`List all defined resources`).action(async () => {
5545
+ await layout("resource list", async ({ appConfig, stackConfigs }) => {
5546
+ const region = appConfig.region;
5547
+ const credentials = getCredentials(appConfig.profile);
5548
+ const accountId = await getAccountId(credentials, region);
5549
+ const { app } = createApp({ appConfig, stackConfigs, accountId });
5550
+ const resources = [];
5551
+ const formatResource = (stack, urn) => {
5552
+ return urn.replace(stack.urn + ":", "").replace(/\{([a-z0-9\-\s\/\._]+)\}/gi, (_, v) => {
5553
+ return `${color.dim("{")}${color.warning(v)}${color.dim("}")}`;
5554
+ }).replaceAll(":", color.dim(":"));
5555
+ };
5556
+ for (const stack of app.stacks) {
5557
+ for (const resource2 of stack.resources) {
5558
+ resources.push([
5559
+ chalk7.magenta(stack.name),
5560
+ // resource.type,
5561
+ formatResource(stack, resource2.urn)
5562
+ ]);
5563
+ }
5564
+ }
5565
+ console.log(
5566
+ table({
5567
+ // colWidths,
5568
+ head: ["stack", "urn"],
5569
+ body: resources
5570
+ })
5571
+ );
5572
+ });
5573
+ });
5574
+ };
5575
+
5576
+ // src/cli/command/resource/index.ts
5577
+ var commands4 = [list3];
5578
+ var resource = (program2) => {
5579
+ const command = program2.command("resource").description(`Manage app resources`);
5580
+ commands4.forEach((cb) => cb(command));
5581
+ };
5582
+
5227
5583
  // src/cli/command/state/pull.ts
5228
5584
  var pull = (program2) => {
5229
5585
  program2.command("pull").description("Pull the remote state and store it locally").action(async () => {
@@ -5262,149 +5618,63 @@ var push = (program2) => {
5262
5618
  });
5263
5619
  };
5264
5620
 
5265
- // src/cli/command/state/index.ts
5266
- var commands3 = [pull, push];
5267
- var state = (program2) => {
5268
- const command = program2.command("state").description(`Manage app state`);
5269
- commands3.forEach((cb) => cb(command));
5270
- };
5271
-
5272
- // src/cli/command/auth/user/create.ts
5273
- import {
5274
- AdminCreateUserCommand,
5275
- AdminSetUserPasswordCommand,
5276
- CognitoIdentityProviderClient
5277
- } from "@aws-sdk/client-cognito-identity-provider";
5278
- import { unwrap } from "@awsless/formation";
5279
- import { password, select, text as text2 } from "@clack/prompts";
5280
- var create = (program2) => {
5281
- program2.command("create").argument("[name]", "The name of the auth instance").description("Create an user for your userpool").action(async (name) => {
5282
- await layout("auth user create", async ({ appConfig, stackConfigs }) => {
5621
+ // src/cli/command/state/unlock.ts
5622
+ import { confirm as confirm6 } from "@clack/prompts";
5623
+ var unlock = (program2) => {
5624
+ program2.command("unlock").description("Release the lock that ensures sequential deployments").action(async () => {
5625
+ await layout("state unlock", async ({ appConfig, stackConfigs }) => {
5283
5626
  const region = appConfig.region;
5284
5627
  const credentials = getCredentials(appConfig.profile);
5285
5628
  const accountId = await getAccountId(credentials, region);
5286
- if (!name) {
5287
- name = await select({
5288
- message: "Select the auth userpool:",
5289
- options: Object.keys(appConfig.defaults.auth).map((name2) => ({
5290
- label: name2,
5291
- value: name2
5292
- }))
5293
- });
5294
- }
5295
- if (!(name in appConfig.defaults.auth)) {
5296
- throw new Error(`Provided auth name doesn't exist inside your app config.`);
5629
+ const { app } = createApp({ appConfig, stackConfigs, accountId });
5630
+ const { lockProvider } = createWorkSpace({ credentials, region, accountId });
5631
+ const isLocked = await lockProvider.locked(app.urn);
5632
+ if (!isLocked) {
5633
+ return "No lock is exists.";
5297
5634
  }
5298
- const { shared, app } = createApp({ appConfig, stackConfigs, accountId });
5299
- const { workspace } = createWorkSpace({
5300
- credentials,
5301
- accountId,
5302
- region
5635
+ const ok = await confirm6({
5636
+ message: "Releasing the lock that ensures sequential deployments might result in corrupt state if a deployment is still running. Are you sure?",
5637
+ initialValue: false
5303
5638
  });
5304
- await workspace.hydrate(app);
5305
- let userPoolId;
5306
- try {
5307
- userPoolId = unwrap(shared.get(`auth-${name}-user-pool-id`));
5308
- } catch (_) {
5309
- throw new Error(`The auth userpool hasn't been deployed yet.`);
5639
+ if (!ok) {
5640
+ throw new Cancelled();
5310
5641
  }
5311
- const user2 = await text2({
5312
- message: "Username:",
5313
- validate(value) {
5314
- if (!value) {
5315
- return "Required";
5316
- }
5317
- return;
5318
- }
5319
- });
5320
- const pass = await password({
5321
- message: "Password:",
5322
- mask: "*",
5323
- validate(value) {
5324
- if (!value) {
5325
- return "Required";
5326
- }
5327
- return;
5328
- }
5329
- });
5330
- const client = new CognitoIdentityProviderClient({
5331
- region,
5332
- credentials
5333
- });
5334
- await client.send(
5335
- new AdminCreateUserCommand({
5336
- UserPoolId: userPoolId,
5337
- Username: user2.toString(),
5338
- TemporaryPassword: pass.toString()
5339
- })
5340
- );
5341
- await client.send(
5342
- new AdminSetUserPasswordCommand({
5343
- UserPoolId: userPoolId,
5344
- Username: user2.toString(),
5345
- Password: pass.toString(),
5346
- Permanent: true
5347
- })
5348
- );
5349
- return "User created.";
5642
+ await lockProvider.insecureReleaseLock(app.urn);
5643
+ return "The state lock was been successfully released.";
5350
5644
  });
5351
5645
  });
5352
5646
  };
5353
5647
 
5354
- // src/cli/command/auth/user/index.ts
5355
- var commands4 = [create];
5356
- var user = (program2) => {
5357
- const command = program2.command("user").description(`Manage auth users`);
5358
- commands4.forEach((cb) => cb(command));
5359
- };
5360
-
5361
- // src/cli/command/auth/index.ts
5362
- var commands5 = [user];
5363
- var auth = (program2) => {
5364
- const command = program2.command("auth").description(`Manage auth`);
5648
+ // src/cli/command/state/index.ts
5649
+ var commands5 = [pull, push, unlock];
5650
+ var state = (program2) => {
5651
+ const command = program2.command("state").description(`Manage app state`);
5365
5652
  commands5.forEach((cb) => cb(command));
5366
5653
  };
5367
5654
 
5368
- // src/cli/command/bind.ts
5369
- import { unwrap as unwrap2 } from "@awsless/formation";
5370
- import { note as note3 } from "@clack/prompts";
5371
- import { spawn } from "child_process";
5372
- var bind = (program2) => {
5373
- program2.command("bind").argument("<command...>", "The command to execute").description(`Bind your site environment variables to a command`).action(async (commands7) => {
5374
- await layout("bind", async ({ appConfig, stackConfigs }) => {
5375
- const region = appConfig.region;
5376
- const credentials = getCredentials(appConfig.profile);
5655
+ // src/cli/command/test.ts
5656
+ var test = (program2) => {
5657
+ program2.command("test").argument("[stacks...]", "Optionally filter stacks to test").option("-f --filters <string...>", "Optionally filter test files").description("Test your app").action(async (stacks, options) => {
5658
+ await layout("test", async (props) => {
5659
+ const region = props.appConfig.region;
5660
+ const credentials = getCredentials(props.appConfig.profile);
5377
5661
  const accountId = await getAccountId(credentials, region);
5378
- const { app, binds } = createApp({ appConfig, stackConfigs, accountId });
5379
- const { workspace } = createWorkSpace({
5380
- credentials,
5381
- accountId,
5382
- region
5383
- });
5384
- await workspace.hydrate(app);
5385
- const env = {};
5386
- for (const { name, value } of binds) {
5387
- env[name] = unwrap2(value);
5662
+ const { tests } = createApp({ ...props, accountId }, stacks);
5663
+ if (tests.length === 0) {
5664
+ return "No tests found.";
5388
5665
  }
5389
- note3(wrap(list(env)), "Bind Env");
5390
- const command = commands7.join(" ");
5391
- spawn(command, {
5392
- env: {
5393
- // Pass the process env vars
5394
- ...process.env,
5395
- // Pass the site bind env vars
5396
- ...env,
5397
- // Basic info
5398
- AWS_REGION: appConfig.region,
5399
- AWS_ACCOUNT_ID: accountId
5400
- // Give AWS access
5401
- // AWS_ACCESS_KEY_ID: credentials.accessKeyId,
5402
- // AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
5403
- // AWS_SESSION_TOKEN: credentials.sessionToken,
5404
- },
5405
- stdio: "inherit",
5406
- shell: true
5407
- });
5666
+ await runTests(tests, options?.filters);
5667
+ return "All tests finished.";
5668
+ });
5669
+ });
5670
+ };
5671
+
5672
+ // src/cli/command/types.ts
5673
+ var types = (program2) => {
5674
+ program2.command("types").description("Generate type definition files").action(async () => {
5675
+ await layout("types", async (props) => {
5676
+ await buildTypes(props);
5677
+ return `Ready to use the ${color.info("@awsless/awsless")} libary!`;
5408
5678
  });
5409
5679
  });
5410
5680
  };
@@ -5415,7 +5685,7 @@ var commands6 = [
5415
5685
  types,
5416
5686
  build2,
5417
5687
  deploy,
5418
- diff,
5688
+ // diff,
5419
5689
  del2,
5420
5690
  dev,
5421
5691
  bind,