diff --git a/src/constructs/core/parameters.test.ts b/src/constructs/core/parameters.test.ts index ff7c53b60..55b0fa0d1 100644 --- a/src/constructs/core/parameters.test.ts +++ b/src/constructs/core/parameters.test.ts @@ -1,22 +1,17 @@ import "@aws-cdk/assert/jest"; import { SynthUtils } from "@aws-cdk/assert/lib/synth-utils"; -import { Stack } from "@aws-cdk/core"; import { simpleGuStackForTesting } from "../../../test/utils"; import type { SynthedStack } from "../../../test/utils"; -import { Stage, Stages } from "../../constants"; import { GuAmiParameter, GuArnParameter, GuInstanceTypeParameter, GuParameter, GuS3ObjectArnParameter, - GuStackParameter, - GuStageParameter, GuStringParameter, GuSubnetListParameter, GuVpcParameter, } from "./parameters"; -import type { GuStack } from "./stack"; describe("The GuParameter class", () => { it("sets the type as passed through by default", () => { @@ -84,39 +79,6 @@ describe("The GuStringParameter class", () => { }); }); -describe("The GuStageParameter class", () => { - it("should set the values as required", () => { - const stack = new Stack() as GuStack; - - new GuStageParameter(stack); - - const json = SynthUtils.toCloudFormation(stack) as SynthedStack; - - expect(json.Parameters.Stage).toEqual({ - Type: "String", - Description: "Stage name", - AllowedValues: Stages, - Default: Stage.CODE, - }); - }); -}); - -describe("The GuStackParameter class", () => { - it("should set the values as required", () => { - const stack = new Stack() as GuStack; - - new GuStackParameter(stack); - - const json = SynthUtils.toCloudFormation(stack) as SynthedStack; - - expect(json.Parameters.Stack).toEqual({ - Type: "String", - Description: "Name of this stack", - Default: "deploy", - }); - }); -}); - describe("The GuInstanceTypeParameter class", () => { it("should combine default, override and prop values", () => { const stack = simpleGuStackForTesting(); diff --git a/src/constructs/core/parameters.ts b/src/constructs/core/parameters.ts index 975efd2aa..63b0a7ba1 100644 --- a/src/constructs/core/parameters.ts +++ b/src/constructs/core/parameters.ts @@ -10,11 +10,16 @@ export interface GuParameterProps extends CfnParameterProps { export type GuNoTypeParameterProps = Omit; export class GuParameter extends CfnParameter { + public readonly id: string; + constructor(scope: GuStack, id: string, props: GuParameterProps) { super(scope, id, { ...props, type: props.fromSSM ? `AWS::SSM::Parameter::Value<${props.type ?? "String"}>` : props.type, }); + + this.id = id; + scope.setParam(this); } } @@ -25,7 +30,8 @@ export class GuStringParameter extends GuParameter { } export class GuStageParameter extends GuParameter { - constructor(scope: GuStack, id: string = "Stage") { + public static readonly defaultId = "Stage"; + constructor(scope: GuStack, id: string = GuStageParameter.defaultId) { super(scope, id, { type: "String", description: "Stage name", @@ -36,7 +42,8 @@ export class GuStageParameter extends GuParameter { } export class GuStackParameter extends GuParameter { - constructor(scope: GuStack, id: string = "Stack") { + public static readonly defaultId = "Stack"; + constructor(scope: GuStack, id: string = GuStackParameter.defaultId) { super(scope, id, { type: "String", description: "Name of this stack", diff --git a/src/constructs/core/stack.test.ts b/src/constructs/core/stack.test.ts index e4bf1cb66..59e21867d 100644 --- a/src/constructs/core/stack.test.ts +++ b/src/constructs/core/stack.test.ts @@ -7,6 +7,7 @@ import { alphabeticalTags, simpleGuStackForTesting } from "../../../test/utils"; import type { SynthedStack } from "../../../test/utils"; import { Stage, Stages } from "../../constants"; import { TrackingTag } from "../../constants/library-info"; +import { GuParameter } from "./parameters"; import { GuStack } from "./stack"; describe("The GuStack construct", () => { @@ -63,4 +64,21 @@ describe("The GuStack construct", () => { expect(stack.app).toBe("MyApp"); }); + + it("should return a parameter that exists", () => { + const stack = new GuStack(new App(), "Test", { app: "MyApp", stack: "test" }); + const testParam = new GuParameter(stack, "MyTestParam", {}); + stack.setParam(testParam); + + const actual = stack.getParam("MyTestParam"); + expect(actual).toBe(testParam); + }); + + it("should throw on attempt to get a parameter that doesn't exist", () => { + const stack = new GuStack(new App(), "Test", { app: "MyApp", stack: "test" }); + + expect(() => stack.getParam("i-do-not-exist")).toThrowError( + "Attempting to read parameter i-do-not-exist which does not exist" + ); + }); }); diff --git a/src/constructs/core/stack.ts b/src/constructs/core/stack.ts index 0780b4eb8..d3d011ac1 100644 --- a/src/constructs/core/stack.ts +++ b/src/constructs/core/stack.ts @@ -1,6 +1,7 @@ import type { App, StackProps } from "@aws-cdk/core"; import { Stack, Tags } from "@aws-cdk/core"; import { TrackingTag } from "../../constants/library-info"; +import type { GuParameter } from "./parameters"; import { GuStageParameter } from "./parameters"; export interface GuStackProps extends StackProps { @@ -39,14 +40,15 @@ export interface GuStackProps extends StackProps { * ``` */ export class GuStack extends Stack { - private readonly _stage: GuStageParameter; private readonly _stack: string; private readonly _app: string; + private params: Map; + public readonly migratedFromCloudFormation: boolean; get stage(): string { - return this._stage.valueAsString; + return this.getParam(GuStageParameter.defaultId).valueAsString; } get stack(): string { @@ -73,13 +75,27 @@ export class GuStack extends Stack { Tags.of(this).add(key, value, { applyToLaunchedInstances }); } + setParam(value: GuParameter): void { + this.params.set(value.id, value); + } + + getParam(key: string): T { + if (!this.params.has(key)) { + throw new Error(`Attempting to read parameter ${key} which does not exist`); + } + + return this.params.get(key) as T; + } + // eslint-disable-next-line custom-rules/valid-constructors -- GuStack is the exception as it must take an App constructor(app: App, id: string, props: GuStackProps) { super(app, id, props); this.migratedFromCloudFormation = !!props.migratedFromCloudFormation; - this._stage = new GuStageParameter(this); + this.params = new Map(); + + new GuStageParameter(this); this._stack = props.stack; this._app = props.app;