@intentius/chant-lexicon-aws 0.0.6 → 0.0.9
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/integrity.json +25 -10
- package/dist/manifest.json +1 -1
- package/dist/meta.json +9444 -4597
- package/dist/rules/cf-refs.ts +99 -0
- package/dist/rules/ext001.ts +32 -25
- package/dist/rules/hardcoded-region.ts +1 -0
- package/dist/rules/iam-wildcard.ts +1 -0
- package/dist/rules/s3-encryption.ts +3 -3
- package/dist/rules/waw016.ts +86 -0
- package/dist/rules/waw017.ts +53 -0
- package/dist/rules/waw018.ts +71 -0
- package/dist/rules/waw019.ts +82 -0
- package/dist/rules/waw020.ts +64 -0
- package/dist/rules/waw021.ts +53 -0
- package/dist/rules/waw022.ts +43 -0
- package/dist/rules/waw023.ts +47 -0
- package/dist/rules/waw024.ts +54 -0
- package/dist/rules/waw025.ts +43 -0
- package/dist/rules/waw026.ts +46 -0
- package/dist/rules/waw027.ts +50 -0
- package/dist/rules/waw028.ts +47 -0
- package/dist/rules/waw029.ts +62 -0
- package/dist/rules/waw030.ts +246 -0
- package/dist/skills/chant-aws.md +430 -0
- package/dist/types/index.d.ts +58525 -58501
- package/package.json +2 -2
- package/src/actions/actions.test.ts +75 -0
- package/src/actions/dynamodb.ts +36 -0
- package/src/actions/ecr.ts +9 -0
- package/src/actions/ecs.ts +5 -0
- package/src/actions/iam.ts +3 -0
- package/src/actions/index.ts +9 -0
- package/src/actions/lambda.ts +11 -0
- package/src/actions/logs.ts +4 -0
- package/src/actions/s3.ts +34 -0
- package/src/actions/sns.ts +5 -0
- package/src/actions/sqs.ts +15 -0
- package/src/codegen/__snapshots__/snapshot.test.ts.snap +20 -20
- package/src/codegen/docs-links.test.ts +143 -0
- package/src/codegen/docs.ts +294 -124
- package/src/codegen/generate-lexicon.ts +8 -0
- package/src/codegen/generate-typescript.ts +25 -1
- package/src/codegen/generate.ts +1 -13
- package/src/codegen/package.ts +2 -0
- package/src/codegen/typecheck.test.ts +1 -1
- package/src/composites/composites.test.ts +442 -0
- package/src/composites/fargate-alb.ts +253 -0
- package/src/composites/index.ts +20 -0
- package/src/composites/lambda-api.ts +20 -0
- package/src/composites/lambda-dynamodb.ts +64 -0
- package/src/composites/lambda-eventbridge.ts +36 -0
- package/src/composites/lambda-function.ts +76 -0
- package/src/composites/lambda-s3.ts +72 -0
- package/src/composites/lambda-sns.ts +30 -0
- package/src/composites/lambda-sqs.ts +44 -0
- package/src/composites/scheduled-lambda.ts +37 -0
- package/src/composites/vpc-default.ts +148 -0
- package/src/default-tags.test.ts +38 -0
- package/src/default-tags.ts +77 -0
- package/src/generated/index.d.ts +58525 -58501
- package/src/generated/index.ts +1351 -1351
- package/src/generated/lexicon-aws.json +9444 -4597
- package/src/import/generator.test.ts +5 -5
- package/src/import/generator.ts +4 -4
- package/src/import/roundtrip-fixtures.test.ts +2 -1
- package/src/import/roundtrip.test.ts +5 -5
- package/src/index.ts +21 -0
- package/src/integration.test.ts +92 -21
- package/src/intrinsics.ts +24 -13
- package/src/lint/post-synth/cf-refs.ts +99 -0
- package/src/lint/post-synth/ext001.test.ts +214 -31
- package/src/lint/post-synth/ext001.ts +32 -25
- package/src/lint/post-synth/waw013.test.ts +120 -0
- package/src/lint/post-synth/waw014.test.ts +121 -0
- package/src/lint/post-synth/waw015.test.ts +147 -0
- package/src/lint/post-synth/waw016.test.ts +141 -0
- package/src/lint/post-synth/waw016.ts +86 -0
- package/src/lint/post-synth/waw017.test.ts +130 -0
- package/src/lint/post-synth/waw017.ts +53 -0
- package/src/lint/post-synth/waw018.test.ts +109 -0
- package/src/lint/post-synth/waw018.ts +71 -0
- package/src/lint/post-synth/waw019.test.ts +138 -0
- package/src/lint/post-synth/waw019.ts +82 -0
- package/src/lint/post-synth/waw020.test.ts +125 -0
- package/src/lint/post-synth/waw020.ts +64 -0
- package/src/lint/post-synth/waw021.test.ts +81 -0
- package/src/lint/post-synth/waw021.ts +53 -0
- package/src/lint/post-synth/waw022.test.ts +54 -0
- package/src/lint/post-synth/waw022.ts +43 -0
- package/src/lint/post-synth/waw023.test.ts +53 -0
- package/src/lint/post-synth/waw023.ts +47 -0
- package/src/lint/post-synth/waw024.test.ts +64 -0
- package/src/lint/post-synth/waw024.ts +54 -0
- package/src/lint/post-synth/waw025.test.ts +42 -0
- package/src/lint/post-synth/waw025.ts +43 -0
- package/src/lint/post-synth/waw026.test.ts +54 -0
- package/src/lint/post-synth/waw026.ts +46 -0
- package/src/lint/post-synth/waw027.test.ts +63 -0
- package/src/lint/post-synth/waw027.ts +50 -0
- package/src/lint/post-synth/waw028.test.ts +68 -0
- package/src/lint/post-synth/waw028.ts +47 -0
- package/src/lint/post-synth/waw029.test.ts +179 -0
- package/src/lint/post-synth/waw029.ts +62 -0
- package/src/lint/post-synth/waw030.test.ts +800 -0
- package/src/lint/post-synth/waw030.ts +246 -0
- package/src/lint/rules/hardcoded-region.ts +1 -0
- package/src/lint/rules/iam-wildcard.ts +1 -0
- package/src/lint/rules/rules.test.ts +8 -8
- package/src/lint/rules/s3-encryption.ts +3 -3
- package/src/lsp/completions.ts +2 -0
- package/src/lsp/hover.ts +17 -0
- package/src/nested-stack-integration.test.ts +100 -0
- package/src/nested-stack.ts +2 -2
- package/src/plugin.test.ts +13 -15
- package/src/plugin.ts +552 -114
- package/src/serializer.test.ts +370 -43
- package/src/serializer.ts +69 -17
- package/src/spec/fetch.ts +10 -0
- package/src/spec/parse.test.ts +141 -0
- package/src/spec/parse.ts +40 -0
- package/src/taggable.ts +44 -0
- package/src/testdata/nested-stacks/app.ts +26 -0
- package/src/testdata/nested-stacks/network/outputs.ts +17 -0
- package/src/testdata/nested-stacks/network/security.ts +17 -0
- package/src/testdata/nested-stacks/network/vpc.ts +54 -0
- package/dist/skills/aws-cloudformation.md +0 -41
- package/src/codegen/rollback.test.ts +0 -80
- package/src/codegen/rollback.ts +0 -20
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Composite } from "@intentius/chant";
|
|
2
|
+
import {
|
|
3
|
+
Vpc,
|
|
4
|
+
Subnet,
|
|
5
|
+
InternetGateway,
|
|
6
|
+
VPCGatewayAttachment,
|
|
7
|
+
RouteTable,
|
|
8
|
+
EC2Route,
|
|
9
|
+
SubnetRouteTableAssociation,
|
|
10
|
+
EIP,
|
|
11
|
+
NatGateway,
|
|
12
|
+
} from "../generated";
|
|
13
|
+
import { Select, GetAZs } from "../intrinsics";
|
|
14
|
+
|
|
15
|
+
export interface VpcDefaultProps {
|
|
16
|
+
cidr?: string;
|
|
17
|
+
publicSubnet1Cidr?: string;
|
|
18
|
+
publicSubnet2Cidr?: string;
|
|
19
|
+
privateSubnet1Cidr?: string;
|
|
20
|
+
privateSubnet2Cidr?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const VpcDefault = Composite<VpcDefaultProps>((props) => {
|
|
24
|
+
const cidr = props.cidr ?? "10.0.0.0/16";
|
|
25
|
+
const publicSubnet1Cidr = props.publicSubnet1Cidr ?? "10.0.0.0/20";
|
|
26
|
+
const publicSubnet2Cidr = props.publicSubnet2Cidr ?? "10.0.16.0/20";
|
|
27
|
+
const privateSubnet1Cidr = props.privateSubnet1Cidr ?? "10.0.128.0/20";
|
|
28
|
+
const privateSubnet2Cidr = props.privateSubnet2Cidr ?? "10.0.144.0/20";
|
|
29
|
+
|
|
30
|
+
const az1 = Select(0, GetAZs(""));
|
|
31
|
+
const az2 = Select(1, GetAZs(""));
|
|
32
|
+
|
|
33
|
+
const vpc = new Vpc({
|
|
34
|
+
CidrBlock: cidr,
|
|
35
|
+
EnableDnsSupport: true,
|
|
36
|
+
EnableDnsHostnames: true,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const igw = new InternetGateway({});
|
|
40
|
+
|
|
41
|
+
const igwAttachment = new VPCGatewayAttachment({
|
|
42
|
+
VpcId: vpc.VpcId,
|
|
43
|
+
InternetGatewayId: igw.InternetGatewayId,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Public subnets
|
|
47
|
+
const publicSubnet1 = new Subnet({
|
|
48
|
+
VpcId: vpc.VpcId,
|
|
49
|
+
CidrBlock: publicSubnet1Cidr,
|
|
50
|
+
AvailabilityZone: az1,
|
|
51
|
+
MapPublicIpOnLaunch: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const publicSubnet2 = new Subnet({
|
|
55
|
+
VpcId: vpc.VpcId,
|
|
56
|
+
CidrBlock: publicSubnet2Cidr,
|
|
57
|
+
AvailabilityZone: az2,
|
|
58
|
+
MapPublicIpOnLaunch: true,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Private subnets
|
|
62
|
+
const privateSubnet1 = new Subnet({
|
|
63
|
+
VpcId: vpc.VpcId,
|
|
64
|
+
CidrBlock: privateSubnet1Cidr,
|
|
65
|
+
AvailabilityZone: az1,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const privateSubnet2 = new Subnet({
|
|
69
|
+
VpcId: vpc.VpcId,
|
|
70
|
+
CidrBlock: privateSubnet2Cidr,
|
|
71
|
+
AvailabilityZone: az2,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Public route table
|
|
75
|
+
const publicRouteTable = new RouteTable({
|
|
76
|
+
VpcId: vpc.VpcId,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const publicRoute = new EC2Route(
|
|
80
|
+
{
|
|
81
|
+
RouteTableId: publicRouteTable.RouteTableId,
|
|
82
|
+
DestinationCidrBlock: "0.0.0.0/0",
|
|
83
|
+
GatewayId: igw.InternetGatewayId,
|
|
84
|
+
},
|
|
85
|
+
{ DependsOn: [igwAttachment] },
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const publicRta1 = new SubnetRouteTableAssociation({
|
|
89
|
+
SubnetId: publicSubnet1.SubnetId,
|
|
90
|
+
RouteTableId: publicRouteTable.RouteTableId,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const publicRta2 = new SubnetRouteTableAssociation({
|
|
94
|
+
SubnetId: publicSubnet2.SubnetId,
|
|
95
|
+
RouteTableId: publicRouteTable.RouteTableId,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// NAT gateway
|
|
99
|
+
const natEip = new EIP({
|
|
100
|
+
Domain: "vpc",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const natGateway = new NatGateway({
|
|
104
|
+
AllocationId: natEip.AllocationId,
|
|
105
|
+
SubnetId: publicSubnet1.SubnetId,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Private route table
|
|
109
|
+
const privateRouteTable = new RouteTable({
|
|
110
|
+
VpcId: vpc.VpcId,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const privateRoute = new EC2Route({
|
|
114
|
+
RouteTableId: privateRouteTable.RouteTableId,
|
|
115
|
+
DestinationCidrBlock: "0.0.0.0/0",
|
|
116
|
+
NatGatewayId: natGateway.NatGatewayId,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const privateRta1 = new SubnetRouteTableAssociation({
|
|
120
|
+
SubnetId: privateSubnet1.SubnetId,
|
|
121
|
+
RouteTableId: privateRouteTable.RouteTableId,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const privateRta2 = new SubnetRouteTableAssociation({
|
|
125
|
+
SubnetId: privateSubnet2.SubnetId,
|
|
126
|
+
RouteTableId: privateRouteTable.RouteTableId,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
vpc,
|
|
131
|
+
igw,
|
|
132
|
+
igwAttachment,
|
|
133
|
+
publicSubnet1,
|
|
134
|
+
publicSubnet2,
|
|
135
|
+
privateSubnet1,
|
|
136
|
+
privateSubnet2,
|
|
137
|
+
publicRouteTable,
|
|
138
|
+
publicRoute,
|
|
139
|
+
publicRta1,
|
|
140
|
+
publicRta2,
|
|
141
|
+
privateRouteTable,
|
|
142
|
+
privateRta1,
|
|
143
|
+
privateRta2,
|
|
144
|
+
natEip,
|
|
145
|
+
natGateway,
|
|
146
|
+
privateRoute,
|
|
147
|
+
};
|
|
148
|
+
}, "VpcDefault");
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, test, expect } from "bun:test";
|
|
2
|
+
import { DECLARABLE_MARKER } from "@intentius/chant/declarable";
|
|
3
|
+
import { defaultTags, isDefaultTags, DEFAULT_TAGS_MARKER } from "./default-tags";
|
|
4
|
+
|
|
5
|
+
describe("defaultTags", () => {
|
|
6
|
+
test("factory returns correct markers and tags", () => {
|
|
7
|
+
const tags = defaultTags([
|
|
8
|
+
{ Key: "Env", Value: "prod" },
|
|
9
|
+
{ Key: "Team", Value: "platform" },
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
expect(tags[DEFAULT_TAGS_MARKER]).toBe(true);
|
|
13
|
+
expect(tags[DECLARABLE_MARKER]).toBe(true);
|
|
14
|
+
expect(tags.lexicon).toBe("aws");
|
|
15
|
+
expect(tags.entityType).toBe("chant:aws:defaultTags");
|
|
16
|
+
expect(tags.tags).toHaveLength(2);
|
|
17
|
+
expect(tags.tags[0]).toEqual({ Key: "Env", Value: "prod" });
|
|
18
|
+
expect(tags.tags[1]).toEqual({ Key: "Team", Value: "platform" });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("factory accepts empty tags array", () => {
|
|
22
|
+
const tags = defaultTags([]);
|
|
23
|
+
expect(tags.tags).toHaveLength(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("isDefaultTags returns true for DefaultTags", () => {
|
|
27
|
+
const tags = defaultTags([{ Key: "k", Value: "v" }]);
|
|
28
|
+
expect(isDefaultTags(tags)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("isDefaultTags returns false for non-DefaultTags", () => {
|
|
32
|
+
expect(isDefaultTags(null)).toBe(false);
|
|
33
|
+
expect(isDefaultTags(undefined)).toBe(false);
|
|
34
|
+
expect(isDefaultTags({})).toBe(false);
|
|
35
|
+
expect(isDefaultTags("string")).toBe(false);
|
|
36
|
+
expect(isDefaultTags({ lexicon: "aws" })).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Tags — declares project-wide tags for all taggable resources.
|
|
3
|
+
*
|
|
4
|
+
* When a project exports a `defaultTags(...)` declaration, the serializer
|
|
5
|
+
* automatically injects those tags into every taggable resource at synthesis
|
|
6
|
+
* time. Explicit tags on individual resources take precedence.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { DECLARABLE_MARKER, type Declarable } from "@intentius/chant/declarable";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Marker symbol for default tags identification.
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_TAGS_MARKER = Symbol.for("chant.aws.defaultTags");
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A single tag entry — Key is always a string, Value supports strings,
|
|
18
|
+
* Parameters, intrinsics, or any value the serializer can resolve.
|
|
19
|
+
*/
|
|
20
|
+
export interface TagEntry {
|
|
21
|
+
readonly Key: string;
|
|
22
|
+
readonly Value: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A default tags declaration — wraps a tag array into a Declarable
|
|
27
|
+
* that the serializer uses to inject tags into all taggable resources.
|
|
28
|
+
*/
|
|
29
|
+
export interface DefaultTags extends Declarable {
|
|
30
|
+
readonly [DEFAULT_TAGS_MARKER]: true;
|
|
31
|
+
readonly [DECLARABLE_MARKER]: true;
|
|
32
|
+
readonly lexicon: "aws";
|
|
33
|
+
readonly entityType: "chant:aws:defaultTags";
|
|
34
|
+
readonly tags: readonly TagEntry[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Type guard for DefaultTags.
|
|
39
|
+
*/
|
|
40
|
+
export function isDefaultTags(value: unknown): value is DefaultTags {
|
|
41
|
+
return (
|
|
42
|
+
typeof value === "object" &&
|
|
43
|
+
value !== null &&
|
|
44
|
+
DEFAULT_TAGS_MARKER in value &&
|
|
45
|
+
(value as Record<symbol, unknown>)[DEFAULT_TAGS_MARKER] === true
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Declare project-wide default tags for all taggable resources.
|
|
51
|
+
*
|
|
52
|
+
* Tags are injected at synthesis time into every resource that supports
|
|
53
|
+
* tagging (per the CloudFormation Registry metadata). If a resource has
|
|
54
|
+
* an explicit Tag with the same Key, the explicit value wins.
|
|
55
|
+
*
|
|
56
|
+
* @param tags - Array of { Key, Value } tag entries
|
|
57
|
+
* @returns A DefaultTags Declarable
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { defaultTags, Sub, AWS } from "@intentius/chant-lexicon-aws";
|
|
62
|
+
*
|
|
63
|
+
* export const tags = defaultTags([
|
|
64
|
+
* { Key: "Project", Value: "my-app" },
|
|
65
|
+
* { Key: "Environment", Value: Sub`${AWS.StackName}` },
|
|
66
|
+
* ]);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function defaultTags(tags: TagEntry[]): DefaultTags {
|
|
70
|
+
return {
|
|
71
|
+
[DEFAULT_TAGS_MARKER]: true,
|
|
72
|
+
[DECLARABLE_MARKER]: true,
|
|
73
|
+
lexicon: "aws",
|
|
74
|
+
entityType: "chant:aws:defaultTags",
|
|
75
|
+
tags,
|
|
76
|
+
};
|
|
77
|
+
}
|