@awsless/awsless 0.0.556 → 0.0.558

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
@@ -992,38 +992,36 @@ var OnLogDefaultSchema = z17.union([
992
992
  })
993
993
  ]).optional().describe("Define a subscription on all Lambda functions logs.");
994
994
 
995
- // src/feature/pubsub/schema.ts
995
+ // src/feature/pubsub/appsync/schema.ts
996
996
  import { z as z18 } from "zod";
997
997
  var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
998
998
  var PubSubDefaultSchema = z18.record(
999
999
  ResourceIdSchema,
1000
1000
  z18.object({
1001
- auth: FunctionSchema,
1001
+ auth: FunctionSchema.describe("The authentication function for the pubsub API."),
1002
1002
  domain: DomainSchema.optional(),
1003
- subDomain: z18.string().optional()
1004
- // auth: z.union([
1005
- // ResourceIdSchema,
1006
- // z.object({
1007
- // authorizer: FunctionSchema,
1008
- // // ttl: AuthorizerTtl.default('1 hour'),
1009
- // }),
1010
- // ]),
1011
- // policy: z
1012
- // .object({
1013
- // publish: z.array(z.string()).optional(),
1014
- // subscribe: z.array(z.string()).optional(),
1015
- // })
1016
- // .optional(),
1003
+ subDomain: z18.string().optional(),
1004
+ namespaces: z18.array(z18.string()).optional().describe('The namespaces for the PubSub API. If not set, a single "default" namespace is created.'),
1005
+ logLevel: z18.enum(["none", "info", "error", "debug", "all"]).optional().describe("The logging level for AppSync API. When set, logging is enabled.")
1017
1006
  })
1018
- ).optional().describe("Define the pubsub subscriber in your stack.");
1007
+ ).optional().describe("Define the pubsub API configuration in your stack.");
1019
1008
  var PubSubSchema = z18.record(
1020
1009
  ResourceIdSchema,
1021
1010
  z18.object({
1022
- sql: z18.string().describe("The SQL statement used to query the IOT topic."),
1023
- sqlVersion: z18.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."),
1024
- consumer: FunctionSchema.describe("The consuming lambda function properties.")
1011
+ channels: z18.array(z18.string()).describe("The event channels this subscriber listens to."),
1012
+ filter: z18.object({
1013
+ eventType: z18.string().optional().describe("Filter events by event type.")
1014
+ // Add more filter options as needed
1015
+ // userId: z.string().optional(),
1016
+ // custom: z.record(z.string(), z.any()).optional(),
1017
+ }).optional().describe("Event filtering options."),
1018
+ consumer: FunctionSchema.describe("The consuming lambda function properties."),
1019
+ batchSize: z18.number().int().min(1).max(100).default(1).describe("Number of events to batch before invoking the consumer function."),
1020
+ retryPolicy: z18.object({
1021
+ maxRetries: z18.number().int().min(0).max(3).default(2).describe("Maximum number of retry attempts.")
1022
+ }).optional().describe("Retry policy for failed event processing.")
1025
1023
  })
1026
- ).optional().describe("Define the pubsub subscriber in your stack.");
1024
+ ).optional().describe("Define the pubsub event subscribers in your stack.");
1027
1025
 
1028
1026
  // src/feature/queue/schema.ts
1029
1027
  import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
@@ -1665,7 +1663,7 @@ var SitesSchema = z34.record(
1665
1663
  cacheKey: z34.union([LocalEntrySchema.transform((v) => [v]), LocalEntrySchema.array()]).describe(
1666
1664
  `Specifies the files and directories to generate the cache key for your custom build command.`
1667
1665
  ),
1668
- configs: z34.string().array().describe("Define the config values for your build command.")
1666
+ configs: z34.string().array().optional().describe("Define the config values for your build command.")
1669
1667
  }).optional().describe(`Specifies the build process for sites that need a build step.`),
1670
1668
  static: z34.union([LocalDirectorySchema, z34.boolean()]).optional().describe(
1671
1669
  "Specifies the path to the static files directory. Additionally you can also pass `true` when you don't have local static files, but still want to make an S3 bucket."
@@ -1721,10 +1719,10 @@ var SitesSchema = z34.record(
1721
1719
  origins: z34.string().array().default(["*"]),
1722
1720
  methods: z34.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
1723
1721
  }).optional().describe("Specify the cors headers."),
1724
- auth: z34.object({
1725
- username: z34.string().describe("Basic auth username"),
1726
- password: z34.string().describe("Basic auth password")
1727
- }).optional().describe("Enable basic authentication for the site"),
1722
+ basicAuth: z34.object({
1723
+ username: z34.string().describe("Basic auth username."),
1724
+ password: z34.string().describe("Basic auth password.")
1725
+ }).optional().describe("Enable basic authentication for the site."),
1728
1726
  security: z34.object({
1729
1727
  // contentSecurityPolicy: z.object({
1730
1728
  // override: z.boolean().default(false),
@@ -3899,7 +3897,8 @@ var onLogFeature = defineFeature({
3899
3897
  action: "lambda:InvokeFunction",
3900
3898
  principal: "logs.amazonaws.com",
3901
3899
  functionName: lambda.functionName,
3902
- sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/lambda/${ctx.app.name}--*`
3900
+ sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/*/${ctx.app.name}--*`
3901
+ // sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/lambda/${ctx.app.name}--*`,
3903
3902
  });
3904
3903
  ctx.shared.set("on-log", "consumer-arn", lambda.arn);
3905
3904
  }
@@ -3956,7 +3955,7 @@ var onFailureFeature = defineFeature({
3956
3955
  }
3957
3956
  });
3958
3957
 
3959
- // src/feature/pubsub/index.ts
3958
+ // src/feature/pubsub/appsync/index.ts
3960
3959
  import { $ as $9, Group as Group9 } from "@awsless/formation";
3961
3960
  import { constantCase as constantCase5 } from "change-case";
3962
3961
 
@@ -3978,91 +3977,141 @@ var formatFullDomainName = (config2, id, subDomain) => {
3978
3977
  return domain2;
3979
3978
  };
3980
3979
 
3981
- // src/feature/pubsub/index.ts
3980
+ // src/feature/pubsub/appsync/index.ts
3982
3981
  var pubsubFeature = defineFeature({
3983
3982
  name: "pubsub",
3984
3983
  onApp(ctx) {
3985
- for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
3984
+ for (const [id, props] of Object.entries(ctx.appConfig.defaults?.pubsub ?? {})) {
3986
3985
  const group = new Group9(ctx.base, "pubsub", id);
3987
- const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, props.auth);
3986
+ const shortName = `${ctx.app.name}--${id}`;
3988
3987
  const name = formatGlobalResourceName({
3989
3988
  appName: ctx.app.name,
3990
3989
  resourceType: "pubsub",
3991
3990
  resourceName: id
3992
3991
  });
3993
- const authorizer = new $9.aws.iot.Authorizer(group, "authorizer", {
3994
- name,
3995
- authorizerFunctionArn: lambda.arn,
3996
- status: "ACTIVE",
3997
- signingDisabled: true,
3998
- enableCachingForHttp: false
3992
+ const authGroup = new Group9(group, "auth", "lambda");
3993
+ const { lambda: authLambda } = createLambdaFunction(authGroup, ctx, "pubsub", `${id}-auth`, {
3994
+ ...props.auth,
3995
+ description: `PubSub ${id} authorizer`
3999
3996
  });
4000
- new $9.aws.lambda.Permission(group, "permission", {
4001
- functionName: lambda.functionName,
4002
- action: "lambda:InvokeFunction",
4003
- principal: "iot.amazonaws.com",
4004
- sourceArn: authorizer.arn
3997
+ let loggingRole;
3998
+ if (props.logLevel) {
3999
+ loggingRole = new $9.aws.iam.Role(group, "logging-role", {
4000
+ name: shortId(`${name}-logging-role`),
4001
+ assumeRolePolicy: JSON.stringify({
4002
+ Version: "2012-10-17",
4003
+ Statement: [
4004
+ {
4005
+ Effect: "Allow",
4006
+ Principal: {
4007
+ Service: "appsync.amazonaws.com"
4008
+ },
4009
+ Action: "sts:AssumeRole"
4010
+ }
4011
+ ]
4012
+ })
4013
+ });
4014
+ new $9.aws.iam.RolePolicyAttachment(group, "logs-policy", {
4015
+ role: loggingRole.name,
4016
+ policyArn: "arn:aws:iam::aws:policy/service-role/AWSAppSyncPushToCloudWatchLogs"
4017
+ });
4018
+ }
4019
+ const api = new $9.aws.appsync.Api(group, "api", {
4020
+ name: shortName,
4021
+ eventConfig: [
4022
+ {
4023
+ connectionAuthMode: [{ authType: "AWS_IAM" }, { authType: "AWS_LAMBDA" }],
4024
+ authProvider: [
4025
+ {
4026
+ authType: "AWS_LAMBDA",
4027
+ lambdaAuthorizerConfig: [
4028
+ {
4029
+ authorizerUri: authLambda.arn,
4030
+ authorizerResultTtlInSeconds: 300
4031
+ }
4032
+ ]
4033
+ },
4034
+ {
4035
+ authType: "AWS_IAM"
4036
+ }
4037
+ ],
4038
+ defaultPublishAuthMode: [
4039
+ {
4040
+ authType: "AWS_IAM"
4041
+ }
4042
+ ],
4043
+ defaultSubscribeAuthMode: [
4044
+ {
4045
+ authType: "AWS_LAMBDA"
4046
+ },
4047
+ {
4048
+ authType: "AWS_IAM"
4049
+ }
4050
+ ],
4051
+ logConfig: props.logLevel ? [
4052
+ {
4053
+ logLevel: props.logLevel.toUpperCase(),
4054
+ cloudwatchLogsRoleArn: loggingRole.arn
4055
+ }
4056
+ ] : void 0
4057
+ }
4058
+ ]
4005
4059
  });
4006
- ctx.bind(`PUBSUB_${constantCase5(id)}_AUTHORIZER`, name);
4007
- const endpoint = $9.aws.iot.getEndpoint(group, "endpoint", {
4008
- endpointType: "iot:Data-ATS"
4060
+ const namespaces = props.namespaces ?? ["default"];
4061
+ for (const namespace of namespaces) {
4062
+ new $9.aws.appsync.ChannelNamespace(group, `namespace-${namespace}`, {
4063
+ name: namespace,
4064
+ apiId: api.apiId
4065
+ });
4066
+ }
4067
+ new $9.aws.lambda.Permission(group, "auth-permission", {
4068
+ action: "lambda:InvokeFunction",
4069
+ principal: "appsync.amazonaws.com",
4070
+ functionName: authLambda.functionName,
4071
+ sourceArn: api.apiArn
4009
4072
  });
4010
4073
  if (props.domain) {
4011
4074
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
4012
- new $9.aws.iot.DomainConfiguration(group, "domain", {
4013
- name,
4075
+ const zoneId = ctx.shared.entry("domain", `zone-id`, props.domain);
4076
+ const certificateArn = ctx.shared.entry("domain", `certificate-arn`, props.domain);
4077
+ const apiDomain = new $9.aws.appsync.DomainName(group, "domain", {
4014
4078
  domainName,
4015
- serverCertificateArns: [ctx.shared.entry("domain", `certificate-arn`, props.domain)],
4016
- authorizerConfig: {
4017
- defaultAuthorizerName: authorizer.name
4018
- }
4019
- // validationCertificate: ctx.shared.get(`global-certificate-${props.domain}-arn`),
4079
+ certificateArn
4080
+ });
4081
+ new $9.aws.appsync.DomainNameApiAssociation(group, "domain-association", {
4082
+ apiId: api.apiArn,
4083
+ domainName: apiDomain.domainName
4020
4084
  });
4021
4085
  new $9.aws.route53.Record(group, "record", {
4022
- zoneId: ctx.shared.entry("domain", `zone-id`, props.domain),
4023
- name: domainName,
4086
+ zoneId,
4024
4087
  type: "CNAME",
4025
- records: [endpoint.endpointAddress]
4088
+ name: domainName,
4089
+ records: [apiDomain.appsyncDomainName],
4090
+ ttl: 300
4026
4091
  });
4027
- ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, domainName);
4092
+ ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, `${domainName}/event`);
4093
+ ctx.bind(`PUBSUB_${constantCase5(id)}_REALTIME_ENDPOINT`, `${domainName}/event/realtime`);
4028
4094
  } else {
4029
- ctx.bind(`PUBSUB_${constantCase5(id)}_ENDPOINT`, endpoint.endpointAddress);
4095
+ ctx.bind(
4096
+ `PUBSUB_${constantCase5(id)}_ENDPOINT`,
4097
+ api.dns.pipe((dns) => dns.HTTP)
4098
+ );
4099
+ ctx.bind(
4100
+ `PUBSUB_${constantCase5(id)}_REALTIME_ENDPOINT`,
4101
+ api.dns.pipe((dns) => dns.REALTIME)
4102
+ );
4030
4103
  }
4031
4104
  }
4032
- ctx.addGlobalPermission({
4033
- actions: [`iot:Publish`],
4034
- resources: [
4035
- //
4036
- `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`,
4037
- `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/pubsub/*`
4038
- ]
4039
- });
4040
- },
4041
- onStack(ctx) {
4042
- for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
4043
- const group = new Group9(ctx.stack, "pubsub", id);
4044
- const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
4045
- const name = formatLocalResourceName({
4046
- appName: ctx.app.name,
4047
- stackName: ctx.stack.name,
4048
- resourceType: "pubsub",
4049
- resourceName: id
4050
- });
4051
- const topic = new $9.aws.iot.TopicRule(group, "rule", {
4052
- name: name.replaceAll("-", "_"),
4053
- enabled: true,
4054
- sql: props.sql,
4055
- sqlVersion: props.sqlVersion,
4056
- lambda: [{ functionArn: lambda.arn }]
4057
- });
4058
- new $9.aws.lambda.Permission(group, "permission", {
4059
- action: "lambda:InvokeFunction",
4060
- principal: "iot.amazonaws.com",
4061
- functionName: lambda.functionName,
4062
- sourceArn: topic.arn
4063
- });
4064
- }
4065
4105
  }
4106
+ // Note: The onStack method would handle channel namespaces and subscriptions
4107
+ // but is commented out for now as it needs to be refactored for AppSync Event API
4108
+ // onStack(ctx) {
4109
+ // // Channel namespaces and event handlers would be configured here
4110
+ // // This would include:
4111
+ // // 1. Creating channel namespaces with their own auth modes (overriding defaults)
4112
+ // // 2. Setting up event handlers (Lambda functions) for specific channels
4113
+ // // 3. Configuring event filtering and routing rules
4114
+ // },
4066
4115
  });
4067
4116
 
4068
4117
  // src/feature/queue/index.ts
@@ -5305,7 +5354,7 @@ var siteFeature = defineFeature({
5305
5354
  runtime: `cloudfront-js-2.0`,
5306
5355
  comment: `Viewer Request - ${name}`,
5307
5356
  publish: true,
5308
- code: getViewerRequestFunctionCode(domainName, bucket, functionUrl, props.auth),
5357
+ code: getViewerRequestFunctionCode(domainName, bucket, functionUrl, props.basicAuth),
5309
5358
  keyValueStoreAssociations: kvs ? [kvs.arn] : void 0
5310
5359
  });
5311
5360
  const distribution = new $15.aws.cloudfront.Distribution(group, "distribution", {
@@ -5946,7 +5995,8 @@ var testFeature = defineFeature({
5946
5995
  ctx.addWarning({
5947
5996
  message: [
5948
5997
  `Stack ${color.info(ctx.stack.name)} has no tests defined.`,
5949
- `Consider adding test cases to ensure stability.`
5998
+ `Consider adding test cases to ensure stability.`,
5999
+ `If your stack doesn't need tests you can set the tests field to \`false\``
5950
6000
  ].join(" ")
5951
6001
  });
5952
6002
  }
@@ -7011,7 +7061,8 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
7011
7061
  let logGroup;
7012
7062
  if (props.log.retention && props.log.retention.value > 0n) {
7013
7063
  logGroup = new $25.aws.cloudwatch.LogGroup(group, "log", {
7014
- name: `/aws/ecs/${name}`,
7064
+ // name: `/aws/ecs/${name}`,
7065
+ name: `/aws/lambda/${name}`,
7015
7066
  retentionInDays: toDays8(props.log.retention)
7016
7067
  });
7017
7068
  const onLogArn = getGlobalOnLog(ctx);
@@ -7091,7 +7142,8 @@ var createFargateTask = (parentGroup, ctx, ns, id, local) => {
7091
7142
  logConfiguration: {
7092
7143
  logDriver: "awslogs",
7093
7144
  options: {
7094
- "awslogs-group": `/aws/ecs/${name}`,
7145
+ // 'awslogs-group': `/aws/ecs/${name}`,
7146
+ "awslogs-group": `/aws/lambda/${name}`,
7095
7147
  "awslogs-region": ctx.appConfig.region,
7096
7148
  "awslogs-stream-prefix": "ecs"
7097
7149
  // mode: 'non-blocking',
@@ -384,38 +384,36 @@ var OnLogDefaultSchema = z14.union([
384
384
  })
385
385
  ]).optional().describe("Define a subscription on all Lambda functions logs.");
386
386
 
387
- // src/feature/pubsub/schema.ts
387
+ // src/feature/pubsub/appsync/schema.ts
388
388
  import { z as z15 } from "zod";
389
389
  var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
390
390
  var PubSubDefaultSchema = z15.record(
391
391
  ResourceIdSchema,
392
392
  z15.object({
393
- auth: FunctionSchema,
393
+ auth: FunctionSchema.describe("The authentication function for the pubsub API."),
394
394
  domain: DomainSchema.optional(),
395
- subDomain: z15.string().optional()
396
- // auth: z.union([
397
- // ResourceIdSchema,
398
- // z.object({
399
- // authorizer: FunctionSchema,
400
- // // ttl: AuthorizerTtl.default('1 hour'),
401
- // }),
402
- // ]),
403
- // policy: z
404
- // .object({
405
- // publish: z.array(z.string()).optional(),
406
- // subscribe: z.array(z.string()).optional(),
407
- // })
408
- // .optional(),
395
+ subDomain: z15.string().optional(),
396
+ namespaces: z15.array(z15.string()).optional().describe('The namespaces for the PubSub API. If not set, a single "default" namespace is created.'),
397
+ logLevel: z15.enum(["none", "info", "error", "debug", "all"]).optional().describe("The logging level for AppSync API. When set, logging is enabled.")
409
398
  })
410
- ).optional().describe("Define the pubsub subscriber in your stack.");
399
+ ).optional().describe("Define the pubsub API configuration in your stack.");
411
400
  var PubSubSchema = z15.record(
412
401
  ResourceIdSchema,
413
402
  z15.object({
414
- sql: z15.string().describe("The SQL statement used to query the IOT topic."),
415
- sqlVersion: z15.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."),
416
- consumer: FunctionSchema.describe("The consuming lambda function properties.")
403
+ channels: z15.array(z15.string()).describe("The event channels this subscriber listens to."),
404
+ filter: z15.object({
405
+ eventType: z15.string().optional().describe("Filter events by event type.")
406
+ // Add more filter options as needed
407
+ // userId: z.string().optional(),
408
+ // custom: z.record(z.string(), z.any()).optional(),
409
+ }).optional().describe("Event filtering options."),
410
+ consumer: FunctionSchema.describe("The consuming lambda function properties."),
411
+ batchSize: z15.number().int().min(1).max(100).default(1).describe("Number of events to batch before invoking the consumer function."),
412
+ retryPolicy: z15.object({
413
+ maxRetries: z15.number().int().min(0).max(3).default(2).describe("Maximum number of retry attempts.")
414
+ }).optional().describe("Retry policy for failed event processing.")
417
415
  })
418
- ).optional().describe("Define the pubsub subscriber in your stack.");
416
+ ).optional().describe("Define the pubsub event subscribers in your stack.");
419
417
 
420
418
  // src/feature/queue/schema.ts
421
419
  import { days as days2, hours, minutes as minutes2, seconds as seconds2 } from "@awsless/duration";
@@ -1057,7 +1055,7 @@ var SitesSchema = z31.record(
1057
1055
  cacheKey: z31.union([LocalEntrySchema.transform((v) => [v]), LocalEntrySchema.array()]).describe(
1058
1056
  `Specifies the files and directories to generate the cache key for your custom build command.`
1059
1057
  ),
1060
- configs: z31.string().array().describe("Define the config values for your build command.")
1058
+ configs: z31.string().array().optional().describe("Define the config values for your build command.")
1061
1059
  }).optional().describe(`Specifies the build process for sites that need a build step.`),
1062
1060
  static: z31.union([LocalDirectorySchema, z31.boolean()]).optional().describe(
1063
1061
  "Specifies the path to the static files directory. Additionally you can also pass `true` when you don't have local static files, but still want to make an S3 bucket."
@@ -1113,10 +1111,10 @@ var SitesSchema = z31.record(
1113
1111
  origins: z31.string().array().default(["*"]),
1114
1112
  methods: z31.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
1115
1113
  }).optional().describe("Specify the cors headers."),
1116
- auth: z31.object({
1117
- username: z31.string().describe("Basic auth username"),
1118
- password: z31.string().describe("Basic auth password")
1119
- }).optional().describe("Enable basic authentication for the site"),
1114
+ basicAuth: z31.object({
1115
+ username: z31.string().describe("Basic auth username."),
1116
+ password: z31.string().describe("Basic auth password.")
1117
+ }).optional().describe("Enable basic authentication for the site."),
1120
1118
  security: z31.object({
1121
1119
  // contentSecurityPolicy: z.object({
1122
1120
  // override: z.boolean().default(false),
Binary file
Binary file
@@ -1 +1 @@
1
- 355b49989570d95758c09af3e91d59c93fcf2284
1
+ e4e6754c9211e7052132876e9d5853a8fca5bafe
Binary file