@composurecdk/core 0.5.0 → 0.6.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/dist/builder.d.ts +59 -2
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +43 -3
- package/dist/builder.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/builder.d.ts
CHANGED
|
@@ -9,6 +9,31 @@ type Constructor<T> = new () => T;
|
|
|
9
9
|
interface ObjectWithProps<Props extends object> {
|
|
10
10
|
props: Partial<Props>;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Optional hook a builder class can implement to clone non-`props` state
|
|
14
|
+
* during {@link IBuilder.copy}.
|
|
15
|
+
*
|
|
16
|
+
* The default `.copy()` shallow-clones `props` and wraps a fresh instance.
|
|
17
|
+
* State stored outside `props` (private fields, internal accumulators) is
|
|
18
|
+
* invisible to that default. A class with such state defines a method
|
|
19
|
+
* keyed by this symbol to copy it onto the new instance.
|
|
20
|
+
*
|
|
21
|
+
* See ADR-0005 for the full protocol, including how decorator layers
|
|
22
|
+
* participate.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* class StackBuilder {
|
|
27
|
+
* props: Partial<StackProps> = {};
|
|
28
|
+
* readonly #tags: [string, string][] = [];
|
|
29
|
+
*
|
|
30
|
+
* [COPY_STATE](target: StackBuilder): void {
|
|
31
|
+
* target.#tags.push(...this.#tags);
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const COPY_STATE: unique symbol;
|
|
12
37
|
/**
|
|
13
38
|
* A fluent builder interface generated from a props type and a target class.
|
|
14
39
|
*
|
|
@@ -20,6 +45,9 @@ interface ObjectWithProps<Props extends object> {
|
|
|
20
45
|
* replaced to return the builder. All other members of `T` pass through as-is,
|
|
21
46
|
* allowing methods like `build()` to be called directly on the builder.
|
|
22
47
|
*
|
|
48
|
+
* Every builder also exposes {@link IBuilder.copy | `.copy()`}, which returns
|
|
49
|
+
* an independent builder with the same configured state.
|
|
50
|
+
*
|
|
23
51
|
* @typeParam Props - The configurable properties.
|
|
24
52
|
* @typeParam T - The target class the builder wraps.
|
|
25
53
|
*/
|
|
@@ -27,11 +55,37 @@ export type IBuilder<Props extends object, T> = {
|
|
|
27
55
|
[K in keyof Props]-?: ((arg: Props[K]) => IBuilder<Props, T>) & (() => Props[K]);
|
|
28
56
|
} & {
|
|
29
57
|
[K in keyof T]: T[K] extends (...args: infer A) => T ? (...args: A) => IBuilder<Props, T> : T[K];
|
|
58
|
+
} & {
|
|
59
|
+
/**
|
|
60
|
+
* Returns an independent builder with the same configured props and any
|
|
61
|
+
* state that the underlying class copies via {@link COPY_STATE}.
|
|
62
|
+
*
|
|
63
|
+
* Mutations to the returned builder do not affect the original, and
|
|
64
|
+
* vice versa.
|
|
65
|
+
*
|
|
66
|
+
* `props` is shallow-cloned (`{ ...this.props }`). Top-level keys are
|
|
67
|
+
* independent; nested object references (CDK constructs, IRoles, IVpcs,
|
|
68
|
+
* etc.) are shared by design — they are construct identities, not
|
|
69
|
+
* configuration data. Builders with internal lists/maps/sets that should
|
|
70
|
+
* be deep-cloned implement {@link COPY_STATE}.
|
|
71
|
+
*
|
|
72
|
+
* Use cases:
|
|
73
|
+
* - **Variant authoring** — derive multiple builders from a shared base
|
|
74
|
+
* (`const us = base.copy().region("us-east-1")`).
|
|
75
|
+
* - **Strategy hand-off snapshot** — pass an isolated builder to a stack
|
|
76
|
+
* strategy (`singleStack(base.copy())`) so later mutations to the
|
|
77
|
+
* original don't leak into the strategy's lazy `build()`.
|
|
78
|
+
*
|
|
79
|
+
* See ADR-0005 for the design rationale.
|
|
80
|
+
*/
|
|
81
|
+
copy(): IBuilder<Props, T>;
|
|
30
82
|
};
|
|
31
83
|
/**
|
|
32
84
|
* Creates a fluent builder wrapping an instance of `T`.
|
|
33
85
|
*
|
|
34
86
|
* The builder is backed by a {@link Proxy} that intercepts property access:
|
|
87
|
+
* - For `copy`: returns a function that produces an independent builder with
|
|
88
|
+
* the same configured state (see {@link IBuilder.copy}).
|
|
35
89
|
* - For keys in `Props`: returns a getter/setter function. When called with a
|
|
36
90
|
* value, it sets the prop and returns the builder. When called with no args,
|
|
37
91
|
* it returns the current value.
|
|
@@ -39,8 +93,11 @@ export type IBuilder<Props extends object, T> = {
|
|
|
39
93
|
* - For all other members: delegates directly to the underlying instance.
|
|
40
94
|
*
|
|
41
95
|
* @param constructor - The class to instantiate and wrap.
|
|
42
|
-
* @
|
|
96
|
+
* @param instance - Optional pre-existing instance to wrap. Defaults to
|
|
97
|
+
* `new constructor()`. Used internally by {@link IBuilder.copy} to wrap a
|
|
98
|
+
* freshly cloned instance without re-running the constructor for new state.
|
|
99
|
+
* @returns A fluent {@link IBuilder} wrapping `instance`.
|
|
43
100
|
*/
|
|
44
|
-
export declare function Builder<Props extends object, T extends ObjectWithProps<Props>>(constructor: Constructor<T
|
|
101
|
+
export declare function Builder<Props extends object, T extends ObjectWithProps<Props>>(constructor: Constructor<T>, instance?: T): IBuilder<Props, T>;
|
|
45
102
|
export {};
|
|
46
103
|
//# sourceMappingURL=builder.d.ts.map
|
package/dist/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC;AAElC;;;GAGG;AACH,UAAU,eAAe,CAAC,KAAK,SAAS,MAAM;IAC5C,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACvB;AAED
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC;AAElC;;;GAGG;AACH,UAAU,eAAe,CAAC,KAAK,SAAS,MAAM;IAC5C,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,eAA+C,CAAC;AAEvE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC,IAAI;KAC7C,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;CACjF,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACjG,GAAG;IACF;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC,SAAS,eAAe,CAAC,KAAK,CAAC,EAC5E,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,EAC3B,QAAQ,GAAE,CAAqB,GAC9B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CA+CpB"}
|
package/dist/builder.js
CHANGED
|
@@ -1,7 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional hook a builder class can implement to clone non-`props` state
|
|
3
|
+
* during {@link IBuilder.copy}.
|
|
4
|
+
*
|
|
5
|
+
* The default `.copy()` shallow-clones `props` and wraps a fresh instance.
|
|
6
|
+
* State stored outside `props` (private fields, internal accumulators) is
|
|
7
|
+
* invisible to that default. A class with such state defines a method
|
|
8
|
+
* keyed by this symbol to copy it onto the new instance.
|
|
9
|
+
*
|
|
10
|
+
* See ADR-0005 for the full protocol, including how decorator layers
|
|
11
|
+
* participate.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* class StackBuilder {
|
|
16
|
+
* props: Partial<StackProps> = {};
|
|
17
|
+
* readonly #tags: [string, string][] = [];
|
|
18
|
+
*
|
|
19
|
+
* [COPY_STATE](target: StackBuilder): void {
|
|
20
|
+
* target.#tags.push(...this.#tags);
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const COPY_STATE = Symbol.for("composurecdk.builder.copyState");
|
|
1
26
|
/**
|
|
2
27
|
* Creates a fluent builder wrapping an instance of `T`.
|
|
3
28
|
*
|
|
4
29
|
* The builder is backed by a {@link Proxy} that intercepts property access:
|
|
30
|
+
* - For `copy`: returns a function that produces an independent builder with
|
|
31
|
+
* the same configured state (see {@link IBuilder.copy}).
|
|
5
32
|
* - For keys in `Props`: returns a getter/setter function. When called with a
|
|
6
33
|
* value, it sets the prop and returns the builder. When called with no args,
|
|
7
34
|
* it returns the current value.
|
|
@@ -9,16 +36,29 @@
|
|
|
9
36
|
* - For all other members: delegates directly to the underlying instance.
|
|
10
37
|
*
|
|
11
38
|
* @param constructor - The class to instantiate and wrap.
|
|
12
|
-
* @
|
|
39
|
+
* @param instance - Optional pre-existing instance to wrap. Defaults to
|
|
40
|
+
* `new constructor()`. Used internally by {@link IBuilder.copy} to wrap a
|
|
41
|
+
* freshly cloned instance without re-running the constructor for new state.
|
|
42
|
+
* @returns A fluent {@link IBuilder} wrapping `instance`.
|
|
13
43
|
*/
|
|
14
|
-
export function Builder(constructor) {
|
|
15
|
-
const instance = new constructor();
|
|
44
|
+
export function Builder(constructor, instance = new constructor()) {
|
|
16
45
|
const methods = new Set(Object.getOwnPropertyNames(Object.getPrototypeOf(instance)).filter((key) => key !== "constructor" && typeof instance[key] === "function"));
|
|
17
46
|
const proxy = new Proxy(instance, {
|
|
18
47
|
get(target, prop) {
|
|
19
48
|
if (typeof prop === "symbol") {
|
|
20
49
|
return Reflect.get(target, prop);
|
|
21
50
|
}
|
|
51
|
+
if (prop === "copy") {
|
|
52
|
+
return () => {
|
|
53
|
+
const next = new constructor();
|
|
54
|
+
next.props = { ...target.props };
|
|
55
|
+
const hook = target[COPY_STATE];
|
|
56
|
+
if (typeof hook === "function") {
|
|
57
|
+
hook.call(target, next);
|
|
58
|
+
}
|
|
59
|
+
return Builder(constructor, next);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
22
62
|
// Props getter/setter
|
|
23
63
|
if (!methods.has(prop)) {
|
|
24
64
|
return (...args) => {
|
package/dist/builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAiDvE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,OAAO,CACrB,WAA2B,EAC3B,WAAc,IAAI,WAAW,EAAE;IAE/B,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,KAAK,aAAa,IAAI,OAAQ,QAAoC,CAAC,GAAG,CAAC,KAAK,UAAU,CAC5F,CACF,CAAC;IAEF,MAAM,KAAK,GAAuB,IAAI,KAAK,CAAC,QAAQ,EAAE;QACpD,GAAG,CAAC,MAAS,EAAE,IAAqB;YAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAY,CAAC;YAC9C,CAAC;YAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,GAAG,EAAE;oBACV,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;oBAC/B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAI,MAA6C,CAAC,UAAU,CAAC,CAAC;oBACxE,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;wBAC9B,IAA0B,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBACjD,CAAC;oBACD,OAAO,OAAO,CAAW,WAAW,EAAE,IAAI,CAAC,CAAC;gBAC9C,CAAC,CAAC;YACJ,CAAC;YAED,sBAAsB;YACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACtB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAmB,CAAC,CAAC;oBAC3C,CAAC;oBACD,MAAM,CAAC,KAAK,CAAC,IAAmB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAuB,CAAC;oBAClE,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC;YACJ,CAAC;YAED,gEAAgE;YAChE,MAAM,MAAM,GAAI,MAAkC,CAAC,IAAI,CAAiC,CAAC;YACzF,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAY,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACnD,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAC;QACJ,CAAC;KACF,CAAuB,CAAC;IAEzB,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Builder, type IBuilder } from "./builder.js";
|
|
1
|
+
export { Builder, COPY_STATE, type IBuilder } from "./builder.js";
|
|
2
2
|
export { constructId, sanitizeConstructId } from "./construct-id.js";
|
|
3
3
|
export { compose, type ComposedSystem, type ConfiguredSystem, type AfterBuildHook, } from "./compose.js";
|
|
4
4
|
export { CyclicDependencyError } from "./cyclic-dependency-error.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,WAAW,EACX,aAAa,GACd,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Builder } from "./builder.js";
|
|
1
|
+
export { Builder, COPY_STATE } from "./builder.js";
|
|
2
2
|
export { constructId, sanitizeConstructId } from "./construct-id.js";
|
|
3
3
|
export { compose, } from "./compose.js";
|
|
4
4
|
export { CyclicDependencyError } from "./cyclic-dependency-error.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAiB,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACL,OAAO,GAIR,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAmB,MAAM,UAAU,CAAC;AACrE,OAAO,EAGL,WAAW,EACX,aAAa,GACd,MAAM,qBAAqB,CAAC"}
|