@intentius/chant-lexicon-aws 0.0.22 → 0.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-aws",
3
- "version": "0.0.22",
3
+ "version": "0.1.0",
4
4
  "description": "AWS CloudFormation lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -43,11 +43,14 @@
43
43
  "prepack": "bun run generate && bun run bundle && bun run validate"
44
44
  },
45
45
  "dependencies": {
46
- "@intentius/chant": "0.0.22",
47
46
  "fflate": "^0.8.2",
48
47
  "js-yaml": "^4.1.0"
49
48
  },
50
49
  "devDependencies": {
50
+ "@intentius/chant": "0.1.0",
51
51
  "typescript": "^5.9.3"
52
+ },
53
+ "peerDependencies": {
54
+ "@intentius/chant": "^0.1.0"
52
55
  }
53
56
  }
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import {
3
3
  EcsCluster,
4
4
  LoadBalancer,
@@ -21,14 +21,21 @@ export interface AlbSharedProps {
21
21
  listenerPort?: number;
22
22
  protocol?: "HTTP" | "HTTPS";
23
23
  certificateArn?: string;
24
+ defaults?: {
25
+ cluster?: Partial<ConstructorParameters<typeof EcsCluster>[0]>;
26
+ executionRole?: Partial<ConstructorParameters<typeof Role>[0]>;
27
+ alb?: Partial<ConstructorParameters<typeof LoadBalancer>[0]>;
28
+ listener?: Partial<ConstructorParameters<typeof Listener>[0]>;
29
+ };
24
30
  }
25
31
 
26
32
  export const AlbShared = Composite<AlbSharedProps>((props) => {
27
33
  const listenerPort = props.listenerPort ?? 80;
28
34
  const protocol = props.protocol ?? "HTTP";
35
+ const { defaults: defs } = props;
29
36
 
30
37
  // ECS Cluster
31
- const cluster = new EcsCluster({});
38
+ const cluster = new EcsCluster(mergeDefaults({}, defs?.cluster));
32
39
 
33
40
  // Execution role — ECR pull + CloudWatch Logs write
34
41
  const executionPolicyDocument = {
@@ -52,10 +59,10 @@ export const AlbShared = Composite<AlbSharedProps>((props) => {
52
59
  PolicyDocument: executionPolicyDocument,
53
60
  });
54
61
 
55
- const executionRole = new Role({
62
+ const executionRole = new Role(mergeDefaults({
56
63
  AssumeRolePolicyDocument: ecsTrustPolicy,
57
64
  Policies: [executionPolicy],
58
- });
65
+ }, defs?.executionRole));
59
66
 
60
67
  // ALB security group — ingress on listener port from anywhere
61
68
  const albIngress = new SecurityGroup_Ingress({
@@ -72,12 +79,12 @@ export const AlbShared = Composite<AlbSharedProps>((props) => {
72
79
  });
73
80
 
74
81
  // Application Load Balancer
75
- const alb = new LoadBalancer({
82
+ const alb = new LoadBalancer(mergeDefaults({
76
83
  Type: "application",
77
84
  Scheme: "internet-facing",
78
85
  Subnets: props.publicSubnetIds,
79
86
  SecurityGroups: [albSg.GroupId],
80
- });
87
+ }, defs?.alb));
81
88
 
82
89
  // Listener — default action is fixed-response 404
83
90
  const fixedResponse = new Listener_FixedResponseConfig({
@@ -105,7 +112,7 @@ export const AlbShared = Composite<AlbSharedProps>((props) => {
105
112
  listenerProps.Certificates = [cert];
106
113
  }
107
114
 
108
- const listener = new Listener(listenerProps);
115
+ const listener = new Listener(mergeDefaults(listenerProps, defs?.listener));
109
116
 
110
117
  return {
111
118
  cluster,
@@ -783,3 +783,85 @@ describe("RdsInstance", () => {
783
783
  expect(dbProps.VPCSecurityGroups[0]).toBeInstanceOf(AttrRef);
784
784
  });
785
785
  });
786
+
787
+ describe("per-member defaults", () => {
788
+ test("LambdaFunction: role defaults add extra ManagedPolicyArns", () => {
789
+ const instance = LambdaFunction({
790
+ ...baseProps,
791
+ defaults: {
792
+ role: { ManagedPolicyArns: ["arn:aws:iam::aws:policy/Extra"] },
793
+ },
794
+ });
795
+ const roleProps = (instance.role as any).props;
796
+ // Arrays concatenate: base [BasicExecution] + override [Extra]
797
+ expect(roleProps.ManagedPolicyArns).toContain(
798
+ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
799
+ );
800
+ expect(roleProps.ManagedPolicyArns).toContain("arn:aws:iam::aws:policy/Extra");
801
+ });
802
+
803
+ test("LambdaFunction: func defaults override Timeout", () => {
804
+ const instance = LambdaFunction({
805
+ ...baseProps,
806
+ defaults: { func: { Timeout: 120 } },
807
+ });
808
+ const funcProps = (instance.func as any).props;
809
+ expect(funcProps.Timeout).toBe(120);
810
+ });
811
+
812
+ test("LambdaApi: permission defaults are applied", () => {
813
+ const instance = LambdaApi({
814
+ ...baseProps,
815
+ defaults: {
816
+ permission: { Action: "lambda:InvokeFunction" },
817
+ },
818
+ });
819
+ const permProps = (instance.permission as any).props;
820
+ expect(permProps.Action).toBe("lambda:InvokeFunction");
821
+ });
822
+
823
+ test("LambdaSqs: queue defaults are applied", () => {
824
+ const instance = LambdaSqs({
825
+ ...baseProps,
826
+ defaults: {
827
+ queue: { VisibilityTimeout: 60 },
828
+ },
829
+ });
830
+ const queueProps = (instance.queue as any).props;
831
+ expect(queueProps.VisibilityTimeout).toBe(60);
832
+ });
833
+
834
+ test("VpcDefault: vpc defaults are applied", () => {
835
+ const instance = VpcDefault({
836
+ defaults: {
837
+ vpc: { EnableDnsHostnames: false },
838
+ },
839
+ });
840
+ const vpcProps = (instance.vpc as any).props;
841
+ // Scalar override wins
842
+ expect(vpcProps.EnableDnsHostnames).toBe(false);
843
+ expect(vpcProps.EnableDnsSupport).toBe(true);
844
+ });
845
+
846
+ test("RdsInstance: db defaults are applied", () => {
847
+ const instance = RdsInstance({
848
+ vpcId: "vpc-123",
849
+ subnetIds: ["subnet-1", "subnet-2"],
850
+ masterPassword: "secret",
851
+ defaults: {
852
+ db: { DeletionProtection: true },
853
+ },
854
+ });
855
+ const dbProps = (instance.db as any).props;
856
+ expect(dbProps.DeletionProtection).toBe(true);
857
+ });
858
+
859
+ test("defaults with no overrides leaves behavior unchanged", () => {
860
+ const withoutDefaults = LambdaFunction(baseProps);
861
+ const withDefaults = LambdaFunction({ ...baseProps, defaults: {} });
862
+ const funcPropsA = (withoutDefaults.func as any).props;
863
+ const funcPropsB = (withDefaults.func as any).props;
864
+ expect(funcPropsA.FunctionName).toBe(funcPropsB.FunctionName);
865
+ expect(funcPropsA.Timeout).toBe(funcPropsB.Timeout);
866
+ });
867
+ });
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import {
3
3
  EcsCluster,
4
4
  EcsService,
@@ -41,6 +41,15 @@ export interface FargateAlbProps {
41
41
  ManagedPolicyArns?: string[];
42
42
  Policies?: InstanceType<typeof Role_Policy>[];
43
43
  logRetentionDays?: number;
44
+ defaults?: {
45
+ cluster?: Partial<ConstructorParameters<typeof EcsCluster>[0]>;
46
+ executionRole?: Partial<ConstructorParameters<typeof Role>[0]>;
47
+ taskRole?: Partial<ConstructorParameters<typeof Role>[0]>;
48
+ taskDef?: Partial<ConstructorParameters<typeof TaskDefinition>[0]>;
49
+ alb?: Partial<ConstructorParameters<typeof LoadBalancer>[0]>;
50
+ targetGroup?: Partial<ConstructorParameters<typeof TargetGroup>[0]>;
51
+ service?: Partial<ConstructorParameters<typeof EcsService>[0]>;
52
+ };
44
53
  }
45
54
 
46
55
  export const FargateAlb = Composite<FargateAlbProps>((props) => {
@@ -51,9 +60,10 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
51
60
  const healthCheckPath = props.healthCheckPath ?? "/";
52
61
  const listenerPort = props.listenerPort ?? 80;
53
62
  const logRetentionDays = props.logRetentionDays ?? 30;
63
+ const { defaults: defs } = props;
54
64
 
55
65
  // ECS Cluster
56
- const cluster = new EcsCluster({});
66
+ const cluster = new EcsCluster(mergeDefaults({}, defs?.cluster));
57
67
 
58
68
  // Execution role — ECR pull + CloudWatch Logs write
59
69
  const executionPolicyDocument = {
@@ -77,17 +87,17 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
77
87
  PolicyDocument: executionPolicyDocument,
78
88
  });
79
89
 
80
- const executionRole = new Role({
90
+ const executionRole = new Role(mergeDefaults({
81
91
  AssumeRolePolicyDocument: ecsTrustPolicy,
82
92
  Policies: [executionPolicy],
83
- });
93
+ }, defs?.executionRole));
84
94
 
85
95
  // Task role — app permissions
86
- const taskRole = new Role({
96
+ const taskRole = new Role(mergeDefaults({
87
97
  AssumeRolePolicyDocument: ecsTrustPolicy,
88
98
  ManagedPolicyArns: props.ManagedPolicyArns,
89
99
  Policies: props.Policies,
90
- });
100
+ }, defs?.taskRole));
91
101
 
92
102
  // Log group
93
103
  const logGroup = new LogGroup({
@@ -129,7 +139,7 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
129
139
  });
130
140
 
131
141
  // Task definition
132
- const taskDef = new TaskDefinition({
142
+ const taskDef = new TaskDefinition(mergeDefaults({
133
143
  NetworkMode: "awsvpc",
134
144
  RequiresCompatibilities: ["FARGATE"],
135
145
  Cpu: cpu,
@@ -137,7 +147,7 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
137
147
  ExecutionRoleArn: executionRole.Arn,
138
148
  TaskRoleArn: taskRole.Arn,
139
149
  ContainerDefinitions: [container],
140
- });
150
+ }, defs?.taskDef));
141
151
 
142
152
  // ALB security group — ingress on listener port from anywhere
143
153
  const albIngress = new SecurityGroup_Ingress({
@@ -168,21 +178,21 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
168
178
  });
169
179
 
170
180
  // Application Load Balancer
171
- const alb = new LoadBalancer({
181
+ const alb = new LoadBalancer(mergeDefaults({
172
182
  Type: "application",
173
183
  Scheme: "internet-facing",
174
184
  Subnets: props.publicSubnetIds,
175
185
  SecurityGroups: [albSg.GroupId],
176
- });
186
+ }, defs?.alb));
177
187
 
178
188
  // Target group
179
- const targetGroup = new TargetGroup({
189
+ const targetGroup = new TargetGroup(mergeDefaults({
180
190
  TargetType: "ip",
181
191
  Protocol: "HTTP",
182
192
  Port: containerPort,
183
193
  VpcId: props.vpcId,
184
194
  HealthCheckPath: healthCheckPath,
185
- });
195
+ }, defs?.targetGroup));
186
196
 
187
197
  // Listener
188
198
  const defaultAction = new Listener_Action({
@@ -215,7 +225,7 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
215
225
  });
216
226
 
217
227
  const service = new EcsService(
218
- {
228
+ mergeDefaults({
219
229
  Cluster: cluster.Arn,
220
230
  TaskDefinition: taskDef.TaskDefinitionArn,
221
231
  LaunchType: "FARGATE",
@@ -223,7 +233,7 @@ export const FargateAlb = Composite<FargateAlbProps>((props) => {
223
233
  HealthCheckGracePeriodSeconds: 60,
224
234
  LoadBalancers: [serviceLoadBalancer],
225
235
  NetworkConfiguration: networkConfig,
226
- },
236
+ }, defs?.service),
227
237
  { DependsOn: [listener] },
228
238
  );
229
239
 
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import {
3
3
  EcsService,
4
4
  EcsService_LoadBalancer,
@@ -54,6 +54,12 @@ export interface FargateServiceProps {
54
54
  ManagedPolicyArns?: string[];
55
55
  Policies?: InstanceType<typeof Role_Policy>[];
56
56
  logRetentionDays?: number;
57
+ defaults?: {
58
+ taskRole?: Partial<ConstructorParameters<typeof Role>[0]>;
59
+ taskDef?: Partial<ConstructorParameters<typeof TaskDefinition>[0]>;
60
+ targetGroup?: Partial<ConstructorParameters<typeof TargetGroup>[0]>;
61
+ service?: Partial<ConstructorParameters<typeof EcsService>[0]>;
62
+ };
57
63
  }
58
64
 
59
65
  export const FargateService = Composite<FargateServiceProps>((props) => {
@@ -70,13 +76,14 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
70
76
  const desiredCount = props.desiredCount ?? 2;
71
77
  const healthCheckPath = props.healthCheckPath ?? "/";
72
78
  const logRetentionDays = props.logRetentionDays ?? 30;
79
+ const { defaults: defs } = props;
73
80
 
74
81
  // Task role — app permissions
75
- const taskRole = new Role({
82
+ const taskRole = new Role(mergeDefaults({
76
83
  AssumeRolePolicyDocument: ecsTrustPolicy,
77
84
  ManagedPolicyArns: props.ManagedPolicyArns,
78
85
  Policies: props.Policies,
79
- });
86
+ }, defs?.taskRole));
80
87
 
81
88
  // Log group
82
89
  const logGroup = new LogGroup({
@@ -118,7 +125,7 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
118
125
  });
119
126
 
120
127
  // Task definition
121
- const taskDef = new TaskDefinition({
128
+ const taskDef = new TaskDefinition(mergeDefaults({
122
129
  NetworkMode: "awsvpc",
123
130
  RequiresCompatibilities: ["FARGATE"],
124
131
  Cpu: cpu,
@@ -126,7 +133,7 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
126
133
  ExecutionRoleArn: props.executionRoleArn,
127
134
  TaskRoleArn: taskRole.Arn,
128
135
  ContainerDefinitions: [container],
129
- });
136
+ }, defs?.taskDef));
130
137
 
131
138
  // Task security group — ingress on container port from ALB SG
132
139
  const taskIngress = new SecurityGroup_Ingress({
@@ -143,13 +150,13 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
143
150
  });
144
151
 
145
152
  // Target group
146
- const targetGroup = new TargetGroup({
153
+ const targetGroup = new TargetGroup(mergeDefaults({
147
154
  TargetType: "ip",
148
155
  Protocol: "HTTP",
149
156
  Port: containerPort,
150
157
  VpcId: props.vpcId,
151
158
  HealthCheckPath: healthCheckPath,
152
- });
159
+ }, defs?.targetGroup));
153
160
 
154
161
  // Listener rule conditions
155
162
  const conditions: InstanceType<typeof ListenerRule_RuleCondition>[] = [];
@@ -209,7 +216,7 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
209
216
  });
210
217
 
211
218
  const service = new EcsService(
212
- {
219
+ mergeDefaults({
213
220
  Cluster: props.clusterArn,
214
221
  TaskDefinition: taskDef.TaskDefinitionArn,
215
222
  LaunchType: "FARGATE",
@@ -217,7 +224,7 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
217
224
  HealthCheckGracePeriodSeconds: 60,
218
225
  LoadBalancers: [serviceLoadBalancer],
219
226
  NetworkConfiguration: networkConfig,
220
- },
227
+ }, defs?.service),
221
228
  { DependsOn: [rule] },
222
229
  );
223
230
 
@@ -1,20 +1,24 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import { Permission } from "../generated";
3
3
  import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
4
4
 
5
5
  export interface LambdaApiProps extends LambdaFunctionProps {
6
6
  sourceArn?: string;
7
+ defaults?: LambdaFunctionProps["defaults"] & {
8
+ permission?: Partial<ConstructorParameters<typeof Permission>[0]>;
9
+ };
7
10
  }
8
11
 
9
12
  export const LambdaApi = Composite<LambdaApiProps>((props) => {
13
+ const { defaults } = props;
10
14
  const { role, func } = LambdaFunction(props);
11
15
 
12
- const permission = new Permission({
16
+ const permission = new Permission(mergeDefaults({
13
17
  FunctionName: func.Arn,
14
18
  Action: "lambda:InvokeFunction",
15
19
  Principal: "apigateway.amazonaws.com",
16
20
  SourceArn: props.sourceArn,
17
- });
21
+ }, defaults?.permission));
18
22
 
19
23
  return { role, func, permission };
20
24
  }, "LambdaApi");
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import { Table, Table_AttributeDefinition, Table_KeySchema, Role_Policy } from "../generated";
3
3
  import { DynamoDBActions } from "../actions/dynamodb";
4
4
  import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
@@ -8,6 +8,9 @@ export interface LambdaDynamoDBProps extends LambdaFunctionProps {
8
8
  partitionKey: string;
9
9
  sortKey?: string;
10
10
  access?: "ReadOnly" | "ReadWrite" | "Full";
11
+ defaults?: LambdaFunctionProps["defaults"] & {
12
+ table?: Partial<ConstructorParameters<typeof Table>[0]>;
13
+ };
11
14
  }
12
15
 
13
16
  export const LambdaDynamoDB = Composite<LambdaDynamoDBProps>((props) => {
@@ -27,12 +30,14 @@ export const LambdaDynamoDB = Composite<LambdaDynamoDBProps>((props) => {
27
30
  );
28
31
  }
29
32
 
30
- const table = new Table({
33
+ const { defaults } = props;
34
+
35
+ const table = new Table(mergeDefaults({
31
36
  TableName: props.tableName,
32
37
  BillingMode: "PAY_PER_REQUEST",
33
38
  AttributeDefinitions: attributeDefinitions,
34
39
  KeySchema: keySchema,
35
- });
40
+ }, defaults?.table));
36
41
 
37
42
  const access = props.access ?? "ReadWrite";
38
43
  const dynamoPolicyDocument = {
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import { EventRule, EventRule_Target, Permission } from "../generated";
3
3
  import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
4
4
 
@@ -7,12 +7,17 @@ export interface LambdaEventBridgeProps extends LambdaFunctionProps {
7
7
  schedule?: string;
8
8
  eventPattern?: Record<string, unknown>;
9
9
  enabled?: boolean;
10
+ defaults?: LambdaFunctionProps["defaults"] & {
11
+ rule?: Partial<ConstructorParameters<typeof EventRule>[0]>;
12
+ permission?: Partial<ConstructorParameters<typeof Permission>[0]>;
13
+ };
10
14
  }
11
15
 
12
16
  export const LambdaEventBridge = Composite<LambdaEventBridgeProps>((props) => {
17
+ const { defaults } = props;
13
18
  const { role, func } = LambdaFunction(props);
14
19
 
15
- const rule = new EventRule({
20
+ const rule = new EventRule(mergeDefaults({
16
21
  Name: props.ruleName,
17
22
  ScheduleExpression: props.schedule,
18
23
  EventPattern: props.eventPattern,
@@ -23,14 +28,14 @@ export const LambdaEventBridge = Composite<LambdaEventBridgeProps>((props) => {
23
28
  Id: "Target0",
24
29
  }),
25
30
  ],
26
- });
31
+ }, defaults?.rule));
27
32
 
28
- const permission = new Permission({
33
+ const permission = new Permission(mergeDefaults({
29
34
  FunctionName: func.Arn,
30
35
  Action: "lambda:InvokeFunction",
31
36
  Principal: "events.amazonaws.com",
32
37
  SourceArn: rule.Arn,
33
- });
38
+ }, defaults?.permission));
34
39
 
35
40
  return { rule, role, func, permission };
36
41
  }, "LambdaEventBridge");
@@ -1,4 +1,4 @@
1
- import { Composite, withDefaults } from "@intentius/chant";
1
+ import { Composite, withDefaults, mergeDefaults } from "@intentius/chant";
2
2
  import { Role, Function, Function_VpcConfig, Role_Policy } from "../generated";
3
3
 
4
4
  const lambdaTrustPolicy = {
@@ -28,9 +28,14 @@ export interface LambdaFunctionProps {
28
28
  ManagedPolicyArns?: string[];
29
29
  Policies?: InstanceType<typeof Role_Policy>[];
30
30
  VpcConfig?: ConstructorParameters<typeof Function_VpcConfig>[0];
31
+ defaults?: {
32
+ role?: Partial<ConstructorParameters<typeof Role>[0]>;
33
+ func?: Partial<ConstructorParameters<typeof Function>[0]>;
34
+ };
31
35
  }
32
36
 
33
37
  export const LambdaFunction = Composite<LambdaFunctionProps>((props) => {
38
+ const { defaults } = props;
34
39
  const managedPolicies = [BASIC_EXECUTION_ARN];
35
40
  if (props.VpcConfig) {
36
41
  managedPolicies.push(VPC_ACCESS_ARN);
@@ -39,13 +44,13 @@ export const LambdaFunction = Composite<LambdaFunctionProps>((props) => {
39
44
  managedPolicies.push(...props.ManagedPolicyArns);
40
45
  }
41
46
 
42
- const role = new Role({
47
+ const role = new Role(mergeDefaults({
43
48
  AssumeRolePolicyDocument: lambdaTrustPolicy,
44
49
  ManagedPolicyArns: managedPolicies,
45
50
  Policies: props.Policies,
46
- });
51
+ }, defaults?.role));
47
52
 
48
- const func = new Function({
53
+ const func = new Function(mergeDefaults({
49
54
  FunctionName: props.name,
50
55
  Runtime: props.Runtime as any,
51
56
  Handler: props.Handler,
@@ -55,7 +60,7 @@ export const LambdaFunction = Composite<LambdaFunctionProps>((props) => {
55
60
  MemorySize: props.MemorySize,
56
61
  Environment: props.Environment,
57
62
  VpcConfig: props.VpcConfig ? new Function_VpcConfig(props.VpcConfig) : undefined,
58
- });
63
+ }, defaults?.func));
59
64
 
60
65
  return { role, func };
61
66
  }, "LambdaFunction");
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import {
3
3
  Bucket,
4
4
  Bucket_BucketEncryption,
@@ -14,6 +14,9 @@ import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
14
14
  export interface LambdaS3Props extends LambdaFunctionProps {
15
15
  bucketName?: string;
16
16
  access?: "ReadOnly" | "ReadWrite" | "Full";
17
+ defaults?: LambdaFunctionProps["defaults"] & {
18
+ bucket?: Partial<ConstructorParameters<typeof Bucket>[0]>;
19
+ };
17
20
  }
18
21
 
19
22
  export const LambdaS3 = Composite<LambdaS3Props>((props) => {
@@ -36,11 +39,13 @@ export const LambdaS3 = Composite<LambdaS3Props>((props) => {
36
39
  RestrictPublicBuckets: true,
37
40
  });
38
41
 
39
- const bucket = new Bucket({
42
+ const { defaults } = props;
43
+
44
+ const bucket = new Bucket(mergeDefaults({
40
45
  BucketName: props.bucketName,
41
46
  BucketEncryption: bucketEncryption,
42
47
  PublicAccessBlockConfiguration: publicAccessBlock,
43
- });
48
+ }, defaults?.bucket));
44
49
 
45
50
  const access = props.access ?? "ReadWrite";
46
51
  const s3PolicyDocument = {
@@ -1,30 +1,36 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import { Topic, Subscription, Permission } from "../generated";
3
3
  import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
4
4
 
5
5
  export interface LambdaSnsProps extends LambdaFunctionProps {
6
6
  topicName?: string;
7
+ defaults?: LambdaFunctionProps["defaults"] & {
8
+ topic?: Partial<ConstructorParameters<typeof Topic>[0]>;
9
+ subscription?: Partial<ConstructorParameters<typeof Subscription>[0]>;
10
+ permission?: Partial<ConstructorParameters<typeof Permission>[0]>;
11
+ };
7
12
  }
8
13
 
9
14
  export const LambdaSns = Composite<LambdaSnsProps>((props) => {
15
+ const { defaults } = props;
10
16
  const { role, func } = LambdaFunction(props);
11
17
 
12
- const topic = new Topic({
18
+ const topic = new Topic(mergeDefaults({
13
19
  TopicName: props.topicName,
14
- });
20
+ }, defaults?.topic));
15
21
 
16
- const subscription = new Subscription({
22
+ const subscription = new Subscription(mergeDefaults({
17
23
  TopicArn: topic.TopicArn,
18
24
  Protocol: "lambda",
19
25
  Endpoint: func.Arn,
20
- });
26
+ }, defaults?.subscription));
21
27
 
22
- const permission = new Permission({
28
+ const permission = new Permission(mergeDefaults({
23
29
  FunctionName: func.Arn,
24
30
  Action: "lambda:InvokeFunction",
25
31
  Principal: "sns.amazonaws.com",
26
32
  SourceArn: topic.TopicArn,
27
- });
33
+ }, defaults?.permission));
28
34
 
29
35
  return { topic, role, func, subscription, permission };
30
36
  }, "LambdaSns");
@@ -1,4 +1,4 @@
1
- import { Composite } from "@intentius/chant";
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
2
  import { Queue, EventSourceMapping, Role_Policy } from "../generated";
3
3
  import { SQSActions } from "../actions/sqs";
4
4
  import { LambdaFunction, type LambdaFunctionProps } from "./lambda-function";
@@ -7,12 +7,18 @@ export interface LambdaSqsProps extends LambdaFunctionProps {
7
7
  queueName?: string;
8
8
  batchSize?: number;
9
9
  maxBatchingWindow?: number;
10
+ defaults?: LambdaFunctionProps["defaults"] & {
11
+ queue?: Partial<ConstructorParameters<typeof Queue>[0]>;
12
+ eventSourceMapping?: Partial<ConstructorParameters<typeof EventSourceMapping>[0]>;
13
+ };
10
14
  }
11
15
 
12
16
  export const LambdaSqs = Composite<LambdaSqsProps>((props) => {
13
- const queue = new Queue({
17
+ const { defaults } = props;
18
+
19
+ const queue = new Queue(mergeDefaults({
14
20
  QueueName: props.queueName,
15
- });
21
+ }, defaults?.queue));
16
22
 
17
23
  const sqsPolicyDocument = {
18
24
  Version: "2012-10-17",
@@ -33,12 +39,12 @@ export const LambdaSqs = Composite<LambdaSqsProps>((props) => {
33
39
  const policies = props.Policies ? [sqsPolicy, ...props.Policies] : [sqsPolicy];
34
40
  const { role, func } = LambdaFunction({ ...props, Policies: policies });
35
41
 
36
- const eventSourceMapping = new EventSourceMapping({
42
+ const eventSourceMapping = new EventSourceMapping(mergeDefaults({
37
43
  EventSourceArn: queue.Arn,
38
44
  FunctionName: func.Arn,
39
45
  BatchSize: props.batchSize ?? 10,
40
46
  MaximumBatchingWindowInSeconds: props.maxBatchingWindow,
41
- });
47
+ }, defaults?.eventSourceMapping));
42
48
 
43
49
  return { queue, role, func, eventSourceMapping };
44
50
  }, "LambdaSqs");