@composurecdk/cloudformation 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.
@@ -0,0 +1,3 @@
1
+ export { createStackBuilder, type IStackBuilder, type StackBuilderResult, } from "./stack-builder.js";
2
+ export { singleStack, groupedStacks } from "./strategies.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createStackBuilder, } from "./stack-builder.js";
2
+ export { singleStack, groupedStacks } from "./strategies.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { Stack, type StackProps } from "aws-cdk-lib";
2
+ import { type IConstruct } from "constructs";
3
+ import { type IBuilder, type Lifecycle, type ScopeFactory } from "@composurecdk/core";
4
+ /**
5
+ * The build output of a {@link IStackBuilder}. Contains the CDK Stack
6
+ * created during {@link Lifecycle.build}.
7
+ */
8
+ export interface StackBuilderResult {
9
+ /** The CDK Stack created by the builder. */
10
+ stack: Stack;
11
+ }
12
+ /**
13
+ * A fluent builder for configuring and creating a CloudFormation Stack.
14
+ *
15
+ * Each configuration property from the CDK {@link StackProps} is exposed
16
+ * as an overloaded method: call with a value to set it (returns the builder
17
+ * for chaining), or call with no arguments to read the current value.
18
+ *
19
+ * The builder implements {@link Lifecycle}, so it can be used directly as a
20
+ * component in a {@link compose | composed system}. When built, it creates
21
+ * a Stack with the configured properties and returns a
22
+ * {@link StackBuilderResult}.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const stack = createStackBuilder()
27
+ * .description("Network infrastructure")
28
+ * .terminationProtection(true)
29
+ * .build(app, "NetworkStack");
30
+ * ```
31
+ */
32
+ export type IStackBuilder = IBuilder<StackProps, StackBuilder> & {
33
+ /**
34
+ * Adds a tag to the Stack. Tags are applied to the Stack and propagate
35
+ * to all resources within it.
36
+ *
37
+ * @param key - The tag key.
38
+ * @param value - The tag value.
39
+ * @returns The builder for chaining.
40
+ */
41
+ tag(key: string, value: string): IStackBuilder;
42
+ /**
43
+ * Returns a {@link ScopeFactory} that creates Stacks with the builder's
44
+ * configured properties. Use this to integrate with
45
+ * {@link singleStack} or {@link groupedStacks} strategies.
46
+ *
47
+ * @returns A factory function compatible with stack strategies.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const factory = createStackBuilder()
52
+ * .terminationProtection(true)
53
+ * .toScopeFactory();
54
+ *
55
+ * compose({ ... }, { ... })
56
+ * .withStackStrategy(singleStack(factory))
57
+ * .build(app, "MySystem");
58
+ * ```
59
+ */
60
+ toScopeFactory(): ScopeFactory;
61
+ };
62
+ declare class StackBuilder implements Lifecycle<StackBuilderResult> {
63
+ props: Partial<StackProps>;
64
+ private readonly tags;
65
+ tag(key: string, value: string): this;
66
+ toScopeFactory(): ScopeFactory;
67
+ build(scope: IConstruct, id: string): StackBuilderResult;
68
+ }
69
+ /**
70
+ * Creates a new {@link IStackBuilder} for configuring a CloudFormation Stack.
71
+ *
72
+ * This is the entry point for declarative stack configuration. The returned
73
+ * builder exposes every {@link StackProps} property as a fluent setter/getter,
74
+ * plus {@link IStackBuilder.tag | .tag()} for adding tags and
75
+ * {@link IStackBuilder.toScopeFactory | .toScopeFactory()} for integration
76
+ * with stack strategies.
77
+ *
78
+ * @returns A fluent builder for a CloudFormation Stack.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * // Build a stack directly
83
+ * const { stack } = createStackBuilder()
84
+ * .description("Service layer")
85
+ * .terminationProtection(true)
86
+ * .build(app, "ServiceStack");
87
+ *
88
+ * // Use as a scope factory with strategies
89
+ * const factory = createStackBuilder()
90
+ * .terminationProtection(true)
91
+ * .tag("team", "platform")
92
+ * .toScopeFactory();
93
+ *
94
+ * compose({ ... }, { ... })
95
+ * .withStackStrategy(singleStack(factory))
96
+ * .build(app, "MySystem");
97
+ * ```
98
+ */
99
+ export declare function createStackBuilder(): IStackBuilder;
100
+ export {};
101
+ //# sourceMappingURL=stack-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-builder.d.ts","sourceRoot":"","sources":["../src/stack-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAQ,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE/F;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,KAAK,EAAE,KAAK,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,GAAG;IAC/D;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC;IAE/C;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,IAAI,YAAY,CAAC;CAChC,CAAC;AAEF,cAAM,YAAa,YAAW,SAAS,CAAC,kBAAkB,CAAC;IACzD,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAM;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAE/C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKrC,cAAc,IAAI,YAAY;IAY9B,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,kBAAkB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAElD"}
@@ -0,0 +1,62 @@
1
+ import { Stack, Tags } from "aws-cdk-lib";
2
+ import { Builder } from "@composurecdk/core";
3
+ class StackBuilder {
4
+ props = {};
5
+ tags = [];
6
+ tag(key, value) {
7
+ this.tags.push([key, value]);
8
+ return this;
9
+ }
10
+ toScopeFactory() {
11
+ const props = { ...this.props };
12
+ const tags = [...this.tags];
13
+ return (scope, id) => {
14
+ const stack = new Stack(scope, id, props);
15
+ tags.forEach(([key, value]) => {
16
+ Tags.of(stack).add(key, value);
17
+ });
18
+ return stack;
19
+ };
20
+ }
21
+ build(scope, id) {
22
+ const stack = new Stack(scope, id, this.props);
23
+ this.tags.forEach(([key, value]) => {
24
+ Tags.of(stack).add(key, value);
25
+ });
26
+ return { stack };
27
+ }
28
+ }
29
+ /**
30
+ * Creates a new {@link IStackBuilder} for configuring a CloudFormation Stack.
31
+ *
32
+ * This is the entry point for declarative stack configuration. The returned
33
+ * builder exposes every {@link StackProps} property as a fluent setter/getter,
34
+ * plus {@link IStackBuilder.tag | .tag()} for adding tags and
35
+ * {@link IStackBuilder.toScopeFactory | .toScopeFactory()} for integration
36
+ * with stack strategies.
37
+ *
38
+ * @returns A fluent builder for a CloudFormation Stack.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * // Build a stack directly
43
+ * const { stack } = createStackBuilder()
44
+ * .description("Service layer")
45
+ * .terminationProtection(true)
46
+ * .build(app, "ServiceStack");
47
+ *
48
+ * // Use as a scope factory with strategies
49
+ * const factory = createStackBuilder()
50
+ * .terminationProtection(true)
51
+ * .tag("team", "platform")
52
+ * .toScopeFactory();
53
+ *
54
+ * compose({ ... }, { ... })
55
+ * .withStackStrategy(singleStack(factory))
56
+ * .build(app, "MySystem");
57
+ * ```
58
+ */
59
+ export function createStackBuilder() {
60
+ return Builder(StackBuilder);
61
+ }
62
+ //# sourceMappingURL=stack-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-builder.js","sourceRoot":"","sources":["../src/stack-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAmB,IAAI,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAoD,MAAM,oBAAoB,CAAC;AA+D/F,MAAM,YAAY;IAChB,KAAK,GAAwB,EAAE,CAAC;IACf,IAAI,GAAuB,EAAE,CAAC;IAE/C,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,cAAc;QACZ,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,CAAC,KAAiB,EAAE,EAAU,EAAE,EAAE;YACvC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC5B,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAiB,EAAE,EAAU;QACjC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,KAAmB,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YACjC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAA2B,YAAY,CAAkB,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { type ScopeFactory, type StackStrategy } from "@composurecdk/core";
2
+ /**
3
+ * Creates a strategy that places all components in a single Stack.
4
+ *
5
+ * The Stack is created lazily on the first call to `resolve` and reused for
6
+ * all subsequent components.
7
+ *
8
+ * @param factory - Optional factory for creating the Stack. Defaults to
9
+ * a plain CDK `Stack` via {@link createStackBuilder}.
10
+ * @returns A {@link StackStrategy} that groups all components into one Stack.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * compose({ handler, api }, { handler: [], api: ["handler"] })
15
+ * .withStackStrategy(singleStack())
16
+ * .build(app, "MySystem");
17
+ * ```
18
+ */
19
+ export declare function singleStack(factory?: ScopeFactory): StackStrategy;
20
+ /**
21
+ * Creates a strategy that groups components into named Stacks determined by
22
+ * a classifier function.
23
+ *
24
+ * Components that return the same group key share a Stack. Stacks are created
25
+ * lazily as new group keys are encountered.
26
+ *
27
+ * @param classify - A function that maps a component key to a group name.
28
+ * @param factory - Optional factory for creating Stacks. Defaults to
29
+ * a plain CDK `Stack` via {@link createStackBuilder}. The factory receives
30
+ * `${systemId}-${group}` as the id.
31
+ * @returns A {@link StackStrategy} that groups components by classifier output.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * compose({ handler, api, table }, { ... })
36
+ * .withStackStrategy(groupedStacks(key => key === "table" ? "persistence" : "service"))
37
+ * .build(app, "MySystem");
38
+ * ```
39
+ */
40
+ export declare function groupedStacks(classify: (componentKey: string) => string, factory?: ScopeFactory): StackStrategy;
41
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../src/strategies.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,aAAa,EAGnB,MAAM,oBAAoB,CAAC;AAO5B;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,aAAa,CAEjE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,EAC1C,OAAO,CAAC,EAAE,YAAY,GACrB,aAAa,CAEf"}
@@ -0,0 +1,49 @@
1
+ import { singleStack as coreSingleStack, groupedStacks as coreGroupedStacks, } from "@composurecdk/core";
2
+ import { createStackBuilder } from "./stack-builder.js";
3
+ function defaultFactory() {
4
+ return createStackBuilder().toScopeFactory();
5
+ }
6
+ /**
7
+ * Creates a strategy that places all components in a single Stack.
8
+ *
9
+ * The Stack is created lazily on the first call to `resolve` and reused for
10
+ * all subsequent components.
11
+ *
12
+ * @param factory - Optional factory for creating the Stack. Defaults to
13
+ * a plain CDK `Stack` via {@link createStackBuilder}.
14
+ * @returns A {@link StackStrategy} that groups all components into one Stack.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * compose({ handler, api }, { handler: [], api: ["handler"] })
19
+ * .withStackStrategy(singleStack())
20
+ * .build(app, "MySystem");
21
+ * ```
22
+ */
23
+ export function singleStack(factory) {
24
+ return coreSingleStack(factory ?? defaultFactory());
25
+ }
26
+ /**
27
+ * Creates a strategy that groups components into named Stacks determined by
28
+ * a classifier function.
29
+ *
30
+ * Components that return the same group key share a Stack. Stacks are created
31
+ * lazily as new group keys are encountered.
32
+ *
33
+ * @param classify - A function that maps a component key to a group name.
34
+ * @param factory - Optional factory for creating Stacks. Defaults to
35
+ * a plain CDK `Stack` via {@link createStackBuilder}. The factory receives
36
+ * `${systemId}-${group}` as the id.
37
+ * @returns A {@link StackStrategy} that groups components by classifier output.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * compose({ handler, api, table }, { ... })
42
+ * .withStackStrategy(groupedStacks(key => key === "table" ? "persistence" : "service"))
43
+ * .build(app, "MySystem");
44
+ * ```
45
+ */
46
+ export function groupedStacks(classify, factory) {
47
+ return coreGroupedStacks(classify, factory ?? defaultFactory());
48
+ }
49
+ //# sourceMappingURL=strategies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../src/strategies.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,IAAI,eAAe,EAC9B,aAAa,IAAI,iBAAiB,GACnC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,SAAS,cAAc;IACrB,OAAO,kBAAkB,EAAE,CAAC,cAAc,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,OAAO,eAAe,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA0C,EAC1C,OAAsB;IAEtB,OAAO,iBAAiB,CAAC,QAAQ,EAAE,OAAO,IAAI,cAAc,EAAE,CAAC,CAAC;AAClE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@composurecdk/cloudformation",
3
+ "version": "0.1.0",
4
+ "description": "Composable CloudFormation stack builder and stack assignment strategies",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "scripts": {
19
+ "clean": "rm -rf dist",
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "typecheck": "tsc --noEmit",
22
+ "test": "vitest run --passWithNoTests",
23
+ "test:watch": "vitest"
24
+ },
25
+ "keywords": [],
26
+ "author": "Jason Duffett (https://github.com/laazyj)",
27
+ "license": "MIT",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "type": "module",
32
+ "peerDependencies": {
33
+ "@composurecdk/core": "^0.1.0",
34
+ "aws-cdk-lib": "^2.0.0",
35
+ "constructs": "^10.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^25.5.0",
39
+ "aws-cdk-lib": "^2.245.0",
40
+ "constructs": "^10.6.0",
41
+ "typescript": "^6.0.2",
42
+ "vitest": "^4.1.2"
43
+ }
44
+ }