cdk-ssm-refs 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DanielCaz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # cdk-ssm-refs
2
+
3
+ Typed registry for AWS Systems Manager parameters and Secrets Manager secrets in AWS CDK.
4
+
5
+ Declare your parameters and secrets once, and get a consistent path prefix, compile-time
6
+ checked keys, ready-made dynamic references, and IAM read policies scoped to exactly that
7
+ prefix.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ bun add cdk-ssm-refs
13
+ ```
14
+
15
+ `aws-cdk-lib`, `constructs`, and `typescript` are peer dependencies, so your CDK app
16
+ supplies them.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import { defineParamRegistry } from 'cdk-ssm-refs';
22
+
23
+ export const params = defineParamRegistry({
24
+ prefix: '/team/my-app', // must start with '/'; trailing slashes are ignored
25
+ parameters: {
26
+ vpcId: 'vpc-id',
27
+ subnetIds: 'subnet-ids',
28
+ },
29
+ secrets: {
30
+ dbPassword: 'db-password',
31
+ },
32
+ });
33
+ ```
34
+
35
+ The keys of `parameters` and `secrets` are the only values accepted by the `key` argument
36
+ of every method, so an unknown key is a compile error.
37
+
38
+ ### Writing parameters
39
+
40
+ ```ts
41
+ import { ParameterTier } from 'aws-cdk-lib/aws-ssm';
42
+
43
+ // Creates /team/my-app/vpc-id
44
+ params.putParameter(this, 'VpcIdParam', 'vpcId', vpc.vpcId);
45
+
46
+ // Any other StringParameterProps are passed through
47
+ params.putParameter(this, 'SubnetIdsParam', 'subnetIds', subnetIds.join(','), {
48
+ description: 'Private subnet ids',
49
+ tier: ParameterTier.STANDARD,
50
+ });
51
+ ```
52
+
53
+ `putParameter` returns the `StringParameter` it creates, so you can keep working with the
54
+ construct. To pin one, call `applyRemovalPolicy(RemovalPolicy.RETAIN)` on the return value,
55
+ importing `RemovalPolicy` from `aws-cdk-lib/core`.
56
+
57
+ ### Emitting stack outputs
58
+
59
+ ```ts
60
+ const params = defineParamRegistry({
61
+ prefix: '/team/my-app',
62
+ parameters: { vpcId: 'vpc-id' },
63
+ emitOutputs: true,
64
+ });
65
+
66
+ params.putParameter(this, 'VpcIdParam', 'vpcId', vpc.vpcId);
67
+ // Also creates a CfnOutput from the construct id 'VpcIdParam-output'
68
+ ```
69
+
70
+ With `emitOutputs` enabled every `putParameter` call additionally emits a `CfnOutput` whose
71
+ value is the raw parameter value. See the caveats below before turning this on.
72
+
73
+ ### Reading parameters from another stack
74
+
75
+ ```ts
76
+ // '{{resolve:ssm:/team/my-app/vpc-id}}'
77
+ const vpcId = params.parameterRef('vpcId');
78
+
79
+ // Pinned to a specific version, for drift detection
80
+ const pinned = params.parameterRef('vpcId', { version: 3 });
81
+
82
+ // Encrypted reference - requires a SecureString parameter
83
+ const secure = params.secureParameterRef('vpcId');
84
+ ```
85
+
86
+ ### Secrets
87
+
88
+ ```ts
89
+ const secret = params.createSecret(this, 'DbPassword', 'dbPassword', {
90
+ description: 'Database password',
91
+ generateSecretString: { excludePunctuation: true },
92
+ });
93
+
94
+ // Use secret.secretValue directly within the creating stack
95
+ ```
96
+
97
+ ### IAM read policies
98
+
99
+ ```ts
100
+ import { Stack } from 'aws-cdk-lib';
101
+ import * as iam from 'aws-cdk-lib/aws-iam';
102
+
103
+ const role = new iam.Role(this, 'Reader', {
104
+ assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
105
+ });
106
+
107
+ // ssm:GetParameter(s) plus secretsmanager:GetSecretValue, both scoped
108
+ // to the registry prefix in the region and account of the stack.
109
+ for (const statement of params.readPolicyStatements(Stack.of(this))) {
110
+ role.addToPolicy(statement);
111
+ }
112
+ ```
113
+
114
+ The ARN patterns are also exposed on their own via `parameterArnPattern(stack)` and
115
+ `secretArnPattern(stack)` if you need to build a different policy.
116
+
117
+ ## API
118
+
119
+ | Member | Description |
120
+ | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
121
+ | `defineParamRegistry(config)` | Creates a `ParamRegistry`. |
122
+ | `ParamRegistry` | The class itself, if you need it as a type. |
123
+ | `config.prefix` | Path prefix. Must start with `/`; trailing slashes ignored. |
124
+ | `config.parameters` | Key to path-segment map for SSM parameters. |
125
+ | `config.secrets` | Key to path-segment map for Secrets Manager secrets. Optional. |
126
+ | `config.emitOutputs` | Emit a `CfnOutput` per `putParameter` call. Defaults to `false`. |
127
+ | `parameterName(key)` → `string` | Fully qualified parameter name, e.g. `/team/my-app/vpc-id`. |
128
+ | `putParameter(scope, id, key, value, props?)` → `StringParameter` | Creates a `StringParameter`. |
129
+ | `parameterRef(key, options?)` → `string` | `{{resolve:ssm:...}}` dynamic reference. |
130
+ | `secureParameterRef(key, options?)` → `string` | `{{resolve:ssm-secure:...}}` dynamic reference. |
131
+ | `createSecret(scope, id, key, props?)` → `Secret` | Creates a `Secret`. |
132
+ | `parameterArnPattern(stack)` → `string` | ARN pattern for every parameter under the prefix. |
133
+ | `secretArnPattern(stack)` → `string` | ARN pattern for every secret under the prefix. |
134
+ | `readPolicyStatements(stack)` → `PolicyStatement[]` | Read-only IAM statements for both patterns. |
135
+ | `normalizePrefix(prefix)` → `{ withSlash, withoutSlash }` | Low-level prefix normalizer used by the constructor. |
136
+
137
+ `ParamRegistryConfig` and `DynamicRefOptions` are also exported as types, for annotating
138
+ your own helpers.
139
+
140
+ ## Caveats
141
+
142
+ - **`prefix` must start with `/`.** `defineParamRegistry` throws on `'team/my-app'`, so write
143
+ `'/team/my-app'`. Trailing slashes are ignored, and empty segments (`//`) are rejected.
144
+ - **Dynamic references resolve at deploy time.** The parameter must already exist in the
145
+ target account and region, so calling `putParameter` and `parameterRef` for the same
146
+ key in one stack will not work — the reference is resolved before the parameter is
147
+ created.
148
+ - **References are not version-pinned by default.** `parameterRef('vpcId')` resolves
149
+ whatever version is current at deploy time and will not report drift when the value
150
+ changes. Pass `{ version }` if you want that.
151
+ - **`version` must be an integer from 1 to 100.** CloudFormation accepts no other
152
+ parameter versions, so `parameterRef('vpcId', { version: 0 })` throws.
153
+ - **`emitOutputs` writes the value into the template.** Each `CfnOutput` carries the raw
154
+ parameter value, which anyone who can read the stack can see, so leave it off for
155
+ sensitive values. CloudFormation logical ids cannot contain `-`, so CDK strips it during
156
+ synthesis and the `'VpcIdParam-output'` construct id is deployed as `VpcIdParamoutput`.
157
+ - **`secureParameterRef` requires a `SecureString` parameter.** Plain `String`
158
+ parameters cannot be read through `ssm-secure`.
159
+ - **Secret names get a random suffix.** CloudFormation appends six characters to every
160
+ secret name it creates, so a secret cannot be looked up by its exact name from another
161
+ stack.
162
+ - **`StringParameterProps` has no `removalPolicy`.** Call
163
+ `parameter.applyRemovalPolicy(...)` on the construct returned by `putParameter`
164
+ instead.
165
+ - **`readPolicyStatements` grants `GetParameter`/`GetParameters` only.** Add
166
+ `ssm:GetParametersByPath` yourself if you load the whole subtree by path.
167
+ - **ARN patterns are pinned to the `aws` partition.** `parameterArnPattern` and
168
+ `secretArnPattern` return `arn:aws:...` strings built from the stack's region and account,
169
+ with no partition lookup, feature flag or partition pseudo parameter involved, so for a
170
+ stack with an explicit environment they are plain strings that are easy to assert on.
171
+ - **ESM only.** The package ships ESM and requires Node >= 20.19.0, which is the
172
+ first release where `require(esm)` works without a flag.
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ bun install
178
+ bun run test
179
+ bun run typecheck
180
+ bun run build
181
+ ```
182
+
183
+ # License
184
+
185
+ MIT License
186
+
187
+ # Contributing
188
+
189
+ Contributions are welcome! Please open an issue or submit a pull request on GitHub. Make sure to follow the existing code style and include tests for any new functionality.
@@ -0,0 +1,4 @@
1
+ export { defineParamRegistry, ParamRegistry } from './registry.js';
2
+ export { normalizePrefix } from './paths.js';
3
+ export type { DynamicRefOptions, ParamRegistryConfig } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,110 @@
1
+ // src/registry.ts
2
+ import * as cdk from "aws-cdk-lib/core";
3
+ import * as iam from "aws-cdk-lib/aws-iam";
4
+ import * as sm from "aws-cdk-lib/aws-secretsmanager";
5
+ import * as ssm from "aws-cdk-lib/aws-ssm";
6
+
7
+ // src/paths.ts
8
+ function normalizePrefix(prefix) {
9
+ if (!prefix.startsWith("/")) {
10
+ throw new Error(`[cdk-ssm-refs] prefix must start with "/", received ${JSON.stringify(prefix)}`);
11
+ }
12
+ const trimmed = prefix.replace(/\/+$/, "");
13
+ if (trimmed.length === 0) {
14
+ throw new Error(`[cdk-ssm-refs] prefix must contain at least one path segment, received ${JSON.stringify(prefix)}`);
15
+ }
16
+ if (trimmed.includes("//")) {
17
+ throw new Error(`[cdk-ssm-refs] prefix must not contain empty path segments, received ${JSON.stringify(prefix)}`);
18
+ }
19
+ return { withSlash: trimmed, withoutSlash: trimmed.slice(1) };
20
+ }
21
+
22
+ // src/registry.ts
23
+ var MIN_PARAM_VERSION = 1;
24
+ var MAX_PARAM_VERSION = 100;
25
+
26
+ class ParamRegistry {
27
+ config;
28
+ parameterPath;
29
+ arnPath;
30
+ emitOutputs;
31
+ constructor(config) {
32
+ this.config = config;
33
+ const { withSlash, withoutSlash } = normalizePrefix(config.prefix);
34
+ this.parameterPath = withSlash;
35
+ this.arnPath = withoutSlash;
36
+ this.emitOutputs = config.emitOutputs ?? false;
37
+ }
38
+ parameterName(key) {
39
+ const segment = this.config.parameters[key];
40
+ if (typeof segment !== "string" || segment.length === 0) {
41
+ throw new Error(`[cdk-ssm-refs] unknown parameter key: ${String(key)}`);
42
+ }
43
+ return `${this.parameterPath}/${segment}`;
44
+ }
45
+ putParameter(scope, id, key, value, props = {}) {
46
+ const parameterName = this.parameterName(key);
47
+ const parameter = new ssm.StringParameter(scope, `${id}-param`, {
48
+ ...props,
49
+ parameterName,
50
+ stringValue: value
51
+ });
52
+ if (this.emitOutputs) {
53
+ new cdk.CfnOutput(scope, `${id}-output`, {
54
+ value,
55
+ description: parameterName
56
+ });
57
+ }
58
+ return parameter;
59
+ }
60
+ parameterRef(key, options = {}) {
61
+ return this.dynamicRef("ssm", key, options);
62
+ }
63
+ secureParameterRef(key, options = {}) {
64
+ return this.dynamicRef("ssm-secure", key, options);
65
+ }
66
+ dynamicRef(service, key, options) {
67
+ const { version } = options;
68
+ if (version !== undefined && (!Number.isInteger(version) || version < MIN_PARAM_VERSION || version > MAX_PARAM_VERSION)) {
69
+ throw new Error(`[cdk-ssm-refs] version must be an integer between ${MIN_PARAM_VERSION} and ${MAX_PARAM_VERSION}, received ${version}`);
70
+ }
71
+ const suffix = version === undefined ? "" : `:${version}`;
72
+ return `{{resolve:${service}:${this.parameterName(key)}${suffix}}}`;
73
+ }
74
+ createSecret(scope, id, key, props = {}) {
75
+ const segment = this.config.secrets?.[key];
76
+ if (typeof segment !== "string" || segment.length === 0) {
77
+ throw new Error(`[cdk-ssm-refs] unknown secret key: ${String(key)}`);
78
+ }
79
+ return new sm.Secret(scope, `${id}-secret`, {
80
+ ...props,
81
+ secretName: `${this.parameterPath}/${segment}`
82
+ });
83
+ }
84
+ parameterArnPattern(stack) {
85
+ return `arn:aws:ssm:${stack.region}:${stack.account}:parameter/${this.arnPath}/*`;
86
+ }
87
+ secretArnPattern(stack) {
88
+ return `arn:aws:secretsmanager:${stack.region}:${stack.account}:secret:${this.parameterPath}/*`;
89
+ }
90
+ readPolicyStatements(stack) {
91
+ return [
92
+ new iam.PolicyStatement({
93
+ actions: ["ssm:GetParameter", "ssm:GetParameters"],
94
+ resources: [this.parameterArnPattern(stack)]
95
+ }),
96
+ new iam.PolicyStatement({
97
+ actions: ["secretsmanager:GetSecretValue"],
98
+ resources: [this.secretArnPattern(stack)]
99
+ })
100
+ ];
101
+ }
102
+ }
103
+ function defineParamRegistry(config) {
104
+ return new ParamRegistry(config);
105
+ }
106
+ export {
107
+ ParamRegistry,
108
+ defineParamRegistry,
109
+ normalizePrefix
110
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Validates and normalizes an SSM / Secrets Manager path prefix.
3
+ *
4
+ * A prefix must start with `/` and contain at least one path segment, so
5
+ * `/team/my-app` is accepted and `team/my-app` is rejected. Trailing slashes are
6
+ * ignored, and empty path segments (`//`) are rejected.
7
+ *
8
+ * Returns both of the forms the AWS APIs need: the leading-slash form used in
9
+ * parameter and secret names, and that same value with the single leading
10
+ * slash removed, which is how ARN resource names are written.
11
+ *
12
+ * @throws If `prefix` does not start with `/`, has no path segment, or
13
+ * contains an empty path segment.
14
+ */
15
+ export declare function normalizePrefix(prefix: string): {
16
+ withSlash: string;
17
+ withoutSlash: string;
18
+ };
19
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,CAsBA"}
@@ -0,0 +1,83 @@
1
+ import type { Construct } from 'constructs';
2
+ import * as cdk from 'aws-cdk-lib/core';
3
+ import * as iam from 'aws-cdk-lib/aws-iam';
4
+ import * as sm from 'aws-cdk-lib/aws-secretsmanager';
5
+ import * as ssm from 'aws-cdk-lib/aws-ssm';
6
+ import type { DynamicRefOptions, ParamRegistryConfig } from './types.js';
7
+ export declare class ParamRegistry<P extends Record<string, string>, S extends Record<string, string>> {
8
+ private readonly config;
9
+ private readonly parameterPath;
10
+ private readonly arnPath;
11
+ private readonly emitOutputs;
12
+ constructor(config: ParamRegistryConfig<P, S>);
13
+ /**
14
+ * The fully qualified SSM parameter name for `key`,
15
+ * e.g. `/team/my-app/vpc-id`.
16
+ */
17
+ parameterName(key: keyof P): string;
18
+ /**
19
+ * Creates an SSM `StringParameter` for `key` under the registry prefix.
20
+ *
21
+ * Any other `StringParameterProps` (`description`, `tier`,
22
+ * `allowedPattern`, `type`, `dataType`, ...) are passed straight through.
23
+ *
24
+ * Note that `StringParameterProps` does not accept a `removalPolicy`; call
25
+ * `parameter.applyRemovalPolicy(...)` on the returned construct instead.
26
+ */
27
+ putParameter(scope: Construct, id: string, key: keyof P, value: string, props?: Omit<ssm.StringParameterProps, 'parameterName' | 'stringValue'>): ssm.StringParameter;
28
+ /**
29
+ * A CloudFormation dynamic reference to the parameter, e.g.
30
+ * `{{resolve:ssm:/team/my-app/vpc-id}}`.
31
+ *
32
+ * Dynamic references are resolved at deploy time, so the parameter must
33
+ * already exist in the target account and region. Calling `putParameter` and
34
+ * `parameterRef` for the same key in a single stack does not work: the
35
+ * reference is resolved before the parameter is created.
36
+ */
37
+ parameterRef(key: keyof P, options?: DynamicRefOptions): string;
38
+ /**
39
+ * An encrypted dynamic reference to the parameter, e.g.
40
+ * `{{resolve:ssm-secure:/team/my-app/vpc-id}}`.
41
+ *
42
+ * The referenced parameter must have been created as a `SecureString`.
43
+ */
44
+ secureParameterRef(key: keyof P, options?: DynamicRefOptions): string;
45
+ private dynamicRef;
46
+ /**
47
+ * Creates a Secrets Manager secret for `key` under the registry prefix.
48
+ *
49
+ * CloudFormation appends a random six character suffix to every secret
50
+ * name it creates, so the resulting name is not exactly
51
+ * `prefix/key` and cannot be referenced by name from another stack.
52
+ */
53
+ createSecret(scope: Construct, id: string, key: keyof S, props?: Omit<sm.SecretProps, 'secretName'>): sm.Secret;
54
+ /**
55
+ * ARN pattern matching every parameter under the registry prefix, in the
56
+ * region and account of `stack`.
57
+ *
58
+ * The partition is fixed to `aws`, the US commercial partition, so no
59
+ * partition lookup, feature flag or pseudo parameter is involved. For a
60
+ * stack with an explicit environment the result is a plain string with no
61
+ * tokens in it; an environment agnostic stack still yields the
62
+ * `AWS::Region` and `AWS::AccountId` tokens. The pattern carries no
63
+ * permissions by itself: `readPolicyStatements` attaches read actions to
64
+ * it, and you can reuse it for custom read or write policies.
65
+ */
66
+ parameterArnPattern(stack: cdk.Stack): string;
67
+ /**
68
+ * ARN pattern matching every secret under the registry prefix.
69
+ *
70
+ * Secrets Manager separates the name from the resource type with `:`
71
+ * rather than `/`, hence the `secret:` prefix, and the trailing wildcard
72
+ * covers the suffix CloudFormation appends to each name.
73
+ */
74
+ secretArnPattern(stack: cdk.Stack): string;
75
+ /**
76
+ * Read-only IAM statements scoped to the registry prefix: `ssm:GetParameter`
77
+ * and `ssm:GetParameters` for the parameters, and
78
+ * `secretsmanager:GetSecretValue` for the secrets.
79
+ */
80
+ readPolicyStatements(stack: cdk.Stack): iam.PolicyStatement[];
81
+ }
82
+ export declare function defineParamRegistry<P extends Record<string, string>, S extends Record<string, string> = Record<never, string>>(config: ParamRegistryConfig<P, S>): ParamRegistry<P, S>;
83
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACrD,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMzE,qBAAa,aAAa,CACxB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;gBAET,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;IAO9D;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM;IAUnC;;;;;;;;OAQG;IACH,YAAY,CACV,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,CAAC,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,eAAe,GAAG,aAAa,CAAM,GAC1E,GAAG,CAAC,eAAe;IAmBtB;;;;;;;;OAQG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM;IAInE;;;;;OAKG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM;IAIzE,OAAO,CAAC,UAAU;IAuBlB;;;;;;OAMG;IACH,YAAY,CACV,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,CAAC,EACZ,KAAK,GAAE,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAM,GAC7C,EAAE,CAAC,MAAM;IAaZ;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,MAAM;IAI7C;;;;;;OAMG;IACH,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,MAAM;IAI1C;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,eAAe,EAAE;CAY9D;AAED,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EACxD,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAExD"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Configuration for a {@link ParamRegistry}.
3
+ */
4
+ export interface ParamRegistryConfig<P extends Record<string, string> = Record<string, string>, S extends Record<string, string> = Record<never, string>> {
5
+ /**
6
+ * Path prefix shared by every parameter and secret in this registry.
7
+ *
8
+ * Must start with `/` and contain at least one path segment, so
9
+ * `/team/my-app` is valid while `team/my-app` throws. Trailing slashes are
10
+ * ignored.
11
+ */
12
+ readonly prefix: string;
13
+ /**
14
+ * Maps a logical key to the final path segment of an SSM parameter.
15
+ *
16
+ * These keys become the only values accepted by the `key` argument of
17
+ * {@link ParamRegistry.putParameter}, {@link ParamRegistry.parameterRef}
18
+ * and {@link ParamRegistry.secureParameterRef}, so an unknown key is a
19
+ * compile error.
20
+ */
21
+ readonly parameters: P;
22
+ /**
23
+ * Maps a logical key to the final path segment of a Secrets Manager secret.
24
+ *
25
+ * Omit this entirely if the registry has no secrets, which also makes
26
+ * {@link ParamRegistry.createSecret} uncallable.
27
+ */
28
+ readonly secrets?: S;
29
+ /**
30
+ * Emit a `CfnOutput` containing the raw value for every `putParameter`
31
+ * call.
32
+ *
33
+ * Defaults to `false`. When enabled the value is rendered into the stack
34
+ * outputs, where anyone with stack read access can see it, so only turn
35
+ * this on for non-sensitive values you actually want surfaced.
36
+ */
37
+ readonly emitOutputs?: boolean;
38
+ }
39
+ /**
40
+ * Options accepted by {@link ParamRegistry.parameterRef} and
41
+ * {@link ParamRegistry.secureParameterRef}.
42
+ */
43
+ export interface DynamicRefOptions {
44
+ /**
45
+ * Pin the dynamic reference to a specific parameter version.
46
+ *
47
+ * Without this, CloudFormation resolves whatever version is current at
48
+ * deploy time and never reports drift when the value changes.
49
+ */
50
+ readonly version?: number;
51
+ }
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAClC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;IAExD;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAErB;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "cdk-ssm-refs",
3
+ "version": "0.1.0",
4
+ "description": "Typed registry for SSM parameters and Secrets Manager secrets in AWS CDK.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "engines": {
8
+ "node": ">=20.19.0"
9
+ },
10
+ "scripts": {
11
+ "build": "bun build ./src/index.ts --outdir ./dist --target node --format esm --packages external && tsc -p tsconfig.build.json",
12
+ "typecheck": "tsc --noEmit",
13
+ "test": "vitest run",
14
+ "prepack": "bun run build"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "devDependencies": {
29
+ "@types/bun": "latest",
30
+ "aws-cdk-lib": "^2.271.0",
31
+ "constructs": "^10.8.1",
32
+ "prettier": "^3.9.9",
33
+ "vitest": "^5.0.2"
34
+ },
35
+ "peerDependencies": {
36
+ "typescript": "^5.9.3",
37
+ "aws-cdk-lib": "^2.271.0",
38
+ "constructs": "^10.8.1"
39
+ }
40
+ }