@aws-mdaa/dataops-job-l3-construct 1.5.0 → 1.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.
Files changed (90) hide show
  1. package/.jsii +38 -28
  2. package/README.md +5 -0
  3. package/lib/dataops-job-l3-construct.d.ts +8 -1
  4. package/lib/dataops-job-l3-construct.js +40 -13
  5. package/node_modules/@aws-mdaa/config/README.md +3 -0
  6. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.d.ts +20 -0
  7. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.js +70 -0
  8. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.ts +88 -0
  9. package/node_modules/@aws-mdaa/config/lib/config.d.ts +87 -0
  10. package/node_modules/@aws-mdaa/config/lib/config.js +7 -0
  11. package/node_modules/@aws-mdaa/config/lib/config.ts +92 -0
  12. package/node_modules/@aws-mdaa/config/lib/index.d.ts +11 -0
  13. package/node_modules/@aws-mdaa/config/lib/index.js +28 -0
  14. package/node_modules/@aws-mdaa/config/lib/index.ts +12 -0
  15. package/node_modules/@aws-mdaa/config/lib/param-transformer.d.ts +49 -0
  16. package/node_modules/@aws-mdaa/config/lib/param-transformer.js +160 -0
  17. package/node_modules/@aws-mdaa/config/lib/param-transformer.ts +159 -0
  18. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.d.ts +10 -0
  19. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.js +30 -0
  20. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.ts +27 -0
  21. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.d.ts +44 -0
  22. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.js +243 -0
  23. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.ts +302 -0
  24. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.d.ts +8 -0
  25. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.js +22 -0
  26. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.ts +21 -0
  27. package/node_modules/@aws-mdaa/config/lib/transformer.d.ts +35 -0
  28. package/node_modules/@aws-mdaa/config/lib/transformer.js +66 -0
  29. package/node_modules/@aws-mdaa/config/lib/transformer.ts +74 -0
  30. package/node_modules/@aws-mdaa/config/package.json +42 -0
  31. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.js +224 -0
  32. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.ts +259 -0
  33. package/node_modules/@aws-mdaa/config/test/config-nt.test.d.ts +5 -0
  34. package/node_modules/@aws-mdaa/config/test/config-nt.test.js +129 -0
  35. package/node_modules/@aws-mdaa/config/test/config-nt.test.ts +163 -0
  36. package/node_modules/@aws-mdaa/config/test/config.test.d.ts +5 -0
  37. package/node_modules/@aws-mdaa/config/test/config.test.js +409 -0
  38. package/node_modules/@aws-mdaa/config/test/config.test.ts +517 -0
  39. package/node_modules/@aws-mdaa/config/test/param-transformer.test.d.ts +5 -0
  40. package/node_modules/@aws-mdaa/config/test/param-transformer.test.js +216 -0
  41. package/node_modules/@aws-mdaa/config/test/param-transformer.test.ts +234 -0
  42. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.d.ts +5 -0
  43. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.js +59 -0
  44. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.ts +68 -0
  45. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.d.ts +5 -0
  46. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.js +254 -0
  47. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.ts +304 -0
  48. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.d.ts +5 -0
  49. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.js +66 -0
  50. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.ts +79 -0
  51. package/node_modules/@aws-mdaa/config/tsconfig.tsbuildinfo +1 -0
  52. package/node_modules/lodash/README.md +2 -2
  53. package/node_modules/lodash/_baseOrderBy.js +1 -1
  54. package/node_modules/lodash/_baseUnset.js +7 -20
  55. package/node_modules/lodash/_setCacheHas.js +1 -1
  56. package/node_modules/lodash/compact.js +1 -1
  57. package/node_modules/lodash/core.js +3 -3
  58. package/node_modules/lodash/core.min.js +26 -25
  59. package/node_modules/lodash/fromPairs.js +3 -1
  60. package/node_modules/lodash/lodash.js +38 -27
  61. package/node_modules/lodash/lodash.min.js +125 -129
  62. package/node_modules/lodash/package.json +4 -2
  63. package/node_modules/lodash/random.js +9 -0
  64. package/node_modules/lodash/template.js +16 -4
  65. package/node_modules/lodash/templateSettings.js +4 -0
  66. package/package.json +27 -32
  67. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/README.md +0 -185
  68. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.d.ts +0 -57
  69. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.js +0 -198
  70. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.ts +0 -241
  71. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/package.json +0 -44
  72. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.js +0 -200
  73. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.ts +0 -215
  74. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/tsconfig.tsbuildinfo +0 -1
  75. package/node_modules/@aws-mdaa/s3-inventory-helper/.npmignore +0 -34
  76. package/node_modules/@aws-mdaa/s3-inventory-helper/README.md +0 -3
  77. package/node_modules/@aws-mdaa/s3-inventory-helper/jest.config.js +0 -5
  78. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.d.ts +0 -48
  79. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.js +0 -213
  80. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.ts +0 -241
  81. package/node_modules/@aws-mdaa/s3-inventory-helper/package.json +0 -44
  82. package/node_modules/@aws-mdaa/s3-inventory-helper/test/TODO +0 -0
  83. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.json +0 -40
  84. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.tsbuildinfo +0 -1
  85. package/node_modules/@aws-mdaa/s3-inventory-helper/typedoc.json +0 -7
  86. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/.npmignore +0 -0
  87. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/jest.config.js +0 -0
  88. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper/test/bucketpolicy-helper.test.d.ts → config/test/blueprint-value-transformer.test.d.ts} +0 -0
  89. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/tsconfig.json +0 -0
  90. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/typedoc.json +0 -0
@@ -0,0 +1,304 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { Stack } from 'aws-cdk-lib';
7
+ import { MdaaConfigRefValueTransformer } from '../lib/ref-value-transformer';
8
+
9
+ describe('MdaaConfigRefValueTransformer', () => {
10
+ const baseProps = {
11
+ org: 'test-org',
12
+ env: 'dev',
13
+ domain: 'test-domain',
14
+ module_name: 'test-module',
15
+ };
16
+
17
+ test('returns unchanged value without refs', () => {
18
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
19
+ expect(transformer.transformValue('plain-value')).toBe('plain-value');
20
+ });
21
+
22
+ test('transforms org ref', () => {
23
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
24
+ expect(transformer.transformValue('{{org}}')).toBe('test-org');
25
+ });
26
+
27
+ test('transforms env ref', () => {
28
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
29
+ expect(transformer.transformValue('{{env}}')).toBe('dev');
30
+ });
31
+
32
+ test('transforms domain ref', () => {
33
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
34
+ expect(transformer.transformValue('{{domain}}')).toBe('test-domain');
35
+ });
36
+
37
+ test('transforms module_name ref', () => {
38
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
39
+ expect(transformer.transformValue('{{module_name}}')).toBe('test-module');
40
+ });
41
+
42
+ test('transforms partition ref with scope', () => {
43
+ const stack = new Stack();
44
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
45
+ const result = transformer.transformValue('{{partition}}');
46
+ expect(result).toBeDefined();
47
+ });
48
+
49
+ test('transforms region ref with scope', () => {
50
+ const stack = new Stack();
51
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
52
+ const result = transformer.transformValue('{{region}}');
53
+ expect(result).toBeDefined();
54
+ });
55
+
56
+ test('transforms account ref with scope', () => {
57
+ const stack = new Stack();
58
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
59
+ const result = transformer.transformValue('{{account}}');
60
+ expect(result).toBeDefined();
61
+ });
62
+
63
+ test('transforms env_var ref', () => {
64
+ process.env.TEST_VAR = 'test-value';
65
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
66
+ expect(transformer.transformValue('{{env_var:TEST_VAR}}')).toBe('test-value');
67
+ delete process.env.TEST_VAR;
68
+ });
69
+
70
+ test('transforms context ref from scope', () => {
71
+ const stack = new Stack();
72
+ stack.node.setContext('test_key', 'test-value');
73
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
74
+ expect(transformer.transformValue('{{context:test_key}}')).toBe('test-value');
75
+ });
76
+
77
+ test('transforms context ref from context prop', () => {
78
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, context: { test_key: 'test-value' } });
79
+ expect(transformer.transformValue('{{context:test_key}}')).toBe('test-value');
80
+ });
81
+
82
+ test('throws when context ref not found', () => {
83
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
84
+ expect(() => transformer.transformValue('{{context:missing_key}}')).toThrow(
85
+ 'Failed to resolve context: missing_key',
86
+ );
87
+ });
88
+
89
+ test('throws when org ref without naming', () => {
90
+ const stack = new Stack();
91
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
92
+ expect(() => transformer.transformValue('{{ssm-org:param}}')).toThrow(
93
+ 'Unable to resolve ssm-org:param ssm param outside of a naming context',
94
+ );
95
+ });
96
+
97
+ test('throws when resolve:ssm without scope', () => {
98
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
99
+ expect(() => transformer.transformValue('{{resolve:ssm:/test/param}}')).toThrow(
100
+ 'Unable to resolve ssm param outside of a Construct',
101
+ );
102
+ });
103
+
104
+ test('handles nested refs', () => {
105
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
106
+ expect(transformer.transformValue('prefix-{{org}}-{{env}}-suffix')).toBe('prefix-test-org-dev-suffix');
107
+ });
108
+
109
+ test('transforms partition ref with awsEnvironment', () => {
110
+ const transformer = new MdaaConfigRefValueTransformer({
111
+ ...baseProps,
112
+ awsEnvironment: { partition: 'aws-us-gov' },
113
+ });
114
+ expect(transformer.transformValue('{{partition}}')).toBe('aws-us-gov');
115
+ });
116
+
117
+ test('transforms region ref with awsEnvironment', () => {
118
+ const transformer = new MdaaConfigRefValueTransformer({
119
+ ...baseProps,
120
+ awsEnvironment: { region: 'us-west-2' },
121
+ });
122
+ expect(transformer.transformValue('{{region}}')).toBe('us-west-2');
123
+ });
124
+
125
+ test('transforms account ref with awsEnvironment', () => {
126
+ const transformer = new MdaaConfigRefValueTransformer({
127
+ ...baseProps,
128
+ awsEnvironment: { account: '123456789012' },
129
+ });
130
+ expect(transformer.transformValue('{{account}}')).toBe('123456789012');
131
+ });
132
+
133
+ test('returns undefined for missing env_var', () => {
134
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
135
+ expect(transformer.transformValue('{{env_var:MISSING_VAR}}')).toBe('{{env_var:MISSING_VAR}}');
136
+ });
137
+
138
+ test('resolves env_var JSON array to actual array', () => {
139
+ process.env.TEST_JSON_ARRAY = '["subnet-aaa","subnet-bbb"]';
140
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
141
+ expect(transformer.transformValue('{{env_var:TEST_JSON_ARRAY}}')).toEqual(['subnet-aaa', 'subnet-bbb']);
142
+ delete process.env.TEST_JSON_ARRAY;
143
+ });
144
+
145
+ test('resolves env_var JSON object to actual object', () => {
146
+ process.env.TEST_JSON_OBJ = '{"key":"value"}';
147
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
148
+ expect(transformer.transformValue('{{env_var:TEST_JSON_OBJ}}')).toEqual({ key: 'value' });
149
+ delete process.env.TEST_JSON_OBJ;
150
+ });
151
+
152
+ test('falls through to string for invalid JSON starting with [', () => {
153
+ process.env.TEST_BAD_JSON = '[not valid json';
154
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
155
+ expect(transformer.transformValue('{{env_var:TEST_BAD_JSON}}')).toBe('[not valid json');
156
+ delete process.env.TEST_BAD_JSON;
157
+ });
158
+
159
+ test('handles naked reference with object context', () => {
160
+ const transformer = new MdaaConfigRefValueTransformer({
161
+ ...baseProps,
162
+ context: { test_obj: { key: 'value' } },
163
+ });
164
+ const result = transformer.transformValue('{{context:test_obj}}');
165
+ expect(result).toEqual({ key: 'value' });
166
+ });
167
+
168
+ test('handles naked reference with array context', () => {
169
+ const transformer = new MdaaConfigRefValueTransformer({
170
+ ...baseProps,
171
+ context: { test_array: ['item1', 'item2'] },
172
+ });
173
+ const result = transformer.transformValue('{{context:test_array}}');
174
+ expect(result).toEqual(['item1', 'item2']);
175
+ });
176
+
177
+ test('throws when embedding object context in string', () => {
178
+ const transformer = new MdaaConfigRefValueTransformer({
179
+ ...baseProps,
180
+ context: { test_obj: { key: 'value' } },
181
+ });
182
+ expect(() => transformer.transformValue('prefix-{{context:test_obj}}-suffix')).toThrow(
183
+ 'Cannot embed array or object context value in string',
184
+ );
185
+ });
186
+
187
+ test('throws when embedding array context in string', () => {
188
+ const transformer = new MdaaConfigRefValueTransformer({
189
+ ...baseProps,
190
+ context: { test_array: ['item1', 'item2'] },
191
+ });
192
+ expect(() => transformer.transformValue('prefix-{{context:test_array}}-suffix')).toThrow(
193
+ 'Cannot embed array or object context value in string',
194
+ );
195
+ });
196
+
197
+ test('handles context with encoded object string', () => {
198
+ const stack = new Stack();
199
+ stack.node.setContext('test_key', '"obj:{"key":"value"}"');
200
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
201
+ const result = transformer.transformValue('{{context:test_key}}');
202
+ expect(result).toEqual({ key: 'value' });
203
+ });
204
+
205
+ test('handles context with encoded list string', () => {
206
+ const stack = new Stack();
207
+ stack.node.setContext('test_key', '"list:["item1","item2"]"');
208
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
209
+ const result = transformer.transformValue('{{context:test_key}}');
210
+ expect(result).toEqual(['item1', 'item2']);
211
+ });
212
+
213
+ test('converts number to string in substitution', () => {
214
+ const transformer = new MdaaConfigRefValueTransformer({
215
+ ...baseProps,
216
+ context: { test_num: 42 },
217
+ });
218
+ const result = transformer.transformValue('value-{{context:test_num}}');
219
+ expect(result).toBe('value-42');
220
+ });
221
+
222
+ test('converts boolean to string in substitution', () => {
223
+ const transformer = new MdaaConfigRefValueTransformer({
224
+ ...baseProps,
225
+ context: { test_bool: true },
226
+ });
227
+ const result = transformer.transformValue('value-{{context:test_bool}}');
228
+ expect(result).toBe('value-true');
229
+ });
230
+
231
+ test('handles ref: with attribute', () => {
232
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
233
+ const result = transformer.transformValue('{{ref:MyResource:Arn}}');
234
+ expect(result).toBeDefined();
235
+ expect(typeof result).toBe('string');
236
+ });
237
+
238
+ test('handles ref: without attribute', () => {
239
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
240
+ const result = transformer.transformValue('{{ref:MyResource}}');
241
+ expect(result).toBeDefined();
242
+ expect(typeof result).toBe('string');
243
+ });
244
+
245
+ test('handles ref: with leading slash', () => {
246
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
247
+ const result = transformer.transformValue('{{ref:/MyResource}}');
248
+ expect(result).toBeDefined();
249
+ expect(typeof result).toBe('string');
250
+ });
251
+
252
+ test('handles ref: with nested path', () => {
253
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
254
+ const result = transformer.transformValue('{{ref:Parent/Child}}');
255
+ expect(result).toBeDefined();
256
+ });
257
+
258
+ test('handles ssm-domain ref with naming', () => {
259
+ const mockNaming = {
260
+ ssmDomainPath: jest.fn().mockReturnValue('/test/domain/path'),
261
+ };
262
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
263
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming as any });
264
+ const result = transformer.transformValue('{{ssm-domain:param}}');
265
+ expect(result).toBe('{{resolve:ssm:/test/domain/path}}');
266
+ expect(mockNaming.ssmDomainPath).toHaveBeenCalledWith('param');
267
+ });
268
+
269
+ test('handles ssm-env ref with naming', () => {
270
+ const mockNaming = {
271
+ ssmEnvPath: jest.fn().mockReturnValue('/test/env/path'),
272
+ };
273
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming as any });
275
+ const result = transformer.transformValue('{{ssm-env:param}}');
276
+ expect(result).toBe('{{resolve:ssm:/test/env/path}}');
277
+ expect(mockNaming.ssmEnvPath).toHaveBeenCalledWith('param');
278
+ });
279
+
280
+ test('handles ssm-org ref with leading slash', () => {
281
+ const mockNaming = {
282
+ ssmOrgPath: jest.fn().mockReturnValue('/test/org/path'),
283
+ };
284
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
285
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming as any });
286
+ const result = transformer.transformValue('{{ssm-org:/param}}');
287
+ expect(result).toBe('{{resolve:ssm:/test/org/path}}');
288
+ expect(mockNaming.ssmOrgPath).toHaveBeenCalledWith('param');
289
+ });
290
+
291
+ test('handles resolve:ssm with ARN path', () => {
292
+ const stack = new Stack();
293
+ const transformer = new MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
294
+ const result = transformer.transformValue('{{resolve:ssm:arn:aws:ssm:us-east-1:123456789012:parameter/test}}');
295
+ expect(result).toBeDefined();
296
+ });
297
+
298
+ test('throws when getSsmValue called without scope', () => {
299
+ const transformer = new MdaaConfigRefValueTransformer(baseProps);
300
+ expect(() => transformer.transformValue('{{resolve:ssm:/test/param}}')).toThrow(
301
+ 'Unable to resolve ssm param outside of a Construct',
302
+ );
303
+ });
304
+ });
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const lib_1 = require("../lib");
8
+ describe('MdaaConfigSSMValueTransformer', () => {
9
+ let transformer;
10
+ beforeEach(() => {
11
+ transformer = new lib_1.MdaaConfigSSMValueTransformer();
12
+ });
13
+ test('transforms ssm: prefix to resolve:ssm format', () => {
14
+ const result = transformer.transformValue('ssm:/my/param/name', 'some/path');
15
+ expect(result).toBe('{{resolve:ssm:/my/param/name}}');
16
+ });
17
+ test('handles whitespace after ssm: prefix', () => {
18
+ const result = transformer.transformValue('ssm: /my/param/name', 'some/path');
19
+ expect(result).toBe('{{resolve:ssm:/my/param/name}}');
20
+ });
21
+ test('returns unchanged value without ssm: prefix', () => {
22
+ const result = transformer.transformValue('plain-value', 'some/path');
23
+ expect(result).toBe('plain-value');
24
+ });
25
+ test('returns unchanged value for empty string', () => {
26
+ const result = transformer.transformValue('', 'some/path');
27
+ expect(result).toBe('');
28
+ });
29
+ test('ignores ssm: values in policyDocument/Statement/Action path', () => {
30
+ const result = transformer.transformValue('ssm:GetParameter', 'policyDocument/Statement/Action');
31
+ expect(result).toBe('ssm:GetParameter');
32
+ });
33
+ test('ignores ssm: values in policyDocument/Statement/Action path (case insensitive)', () => {
34
+ const result = transformer.transformValue('ssm:GetParameter', 'PolicyDocument/Statement/ACTION');
35
+ expect(result).toBe('ssm:GetParameter');
36
+ });
37
+ test('ignores ssm: values when path ends with policyDocument/Statement/Action', () => {
38
+ const result = transformer.transformValue('ssm:PutParameter', 'some/nested/policyDocument/Statement/Action');
39
+ expect(result).toBe('ssm:PutParameter');
40
+ });
41
+ test('transforms ssm: values when path contains but does not end with ignored path', () => {
42
+ const result = transformer.transformValue('ssm:/my/param', 'policyDocument/Statement/Action/something');
43
+ expect(result).toBe('{{resolve:ssm:/my/param}}');
44
+ });
45
+ test('transforms ssm: values for non-ignored paths', () => {
46
+ const result = transformer.transformValue('ssm:/config/database/host', 'resources/database/config');
47
+ expect(result).toBe('{{resolve:ssm:/config/database/host}}');
48
+ });
49
+ test('handles ssm: prefix with no additional content', () => {
50
+ const result = transformer.transformValue('ssm:', 'some/path');
51
+ expect(result).toBe('{{resolve:ssm:}}');
52
+ });
53
+ test('does not transform values that contain ssm: but do not start with it', () => {
54
+ const result = transformer.transformValue('prefix-ssm:/param', 'some/path');
55
+ expect(result).toBe('prefix-ssm:/param');
56
+ });
57
+ test('handles complex SSM parameter paths', () => {
58
+ const result = transformer.transformValue('ssm:/org/env/domain/module/param-name', 'config/settings');
59
+ expect(result).toBe('{{resolve:ssm:/org/env/domain/module/param-name}}');
60
+ });
61
+ test('handles SSM parameter with special characters', () => {
62
+ const result = transformer.transformValue('ssm:/my-param_name.v1', 'some/path');
63
+ expect(result).toBe('{{resolve:ssm:/my-param_name.v1}}');
64
+ });
65
+ });
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NtLXJlZi10cmFuc2Zvcm1lci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3NtLXJlZi10cmFuc2Zvcm1lci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7O0FBRUgsZ0NBQXVEO0FBRXZELFFBQVEsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7SUFDN0MsSUFBSSxXQUEwQyxDQUFDO0lBRS9DLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxXQUFXLEdBQUcsSUFBSSxtQ0FBNkIsRUFBRSxDQUFDO0lBQ3BELENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsRUFBRTtRQUN4RCxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLG9CQUFvQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUN4RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUMvRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7SUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNkNBQTZDLEVBQUUsR0FBRyxFQUFFO1FBQ3ZELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1FBQ3BELE1BQU0sTUFB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QUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0IHsgTWRhYUNvbmZpZ1NTTVZhbHVlVHJhbnNmb3JtZXIgfSBmcm9tICcuLi9saWInO1xuXG5kZXNjcmliZSgnTWRhYUNvbmZpZ1NTTVZhbHVlVHJhbnNmb3JtZXInLCAoKSA9PiB7XG4gIGxldCB0cmFuc2Zvcm1lcjogTWRhYUNvbmZpZ1NTTVZhbHVlVHJhbnNmb3JtZXI7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1NTTVZhbHVlVHJhbnNmb3JtZXIoKTtcbiAgfSk7XG5cbiAgdGVzdCgndHJhbnNmb3JtcyBzc206IHByZWZpeCB0byByZXNvbHZlOnNzbSBmb3JtYXQnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3NzbTovbXkvcGFyYW0vbmFtZScsICdzb21lL3BhdGgnKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOi9teS9wYXJhbS9uYW1lfX0nKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFuZGxlcyB3aGl0ZXNwYWNlIGFmdGVyIHNzbTogcHJlZml4JywgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCdzc206ICAvbXkvcGFyYW0vbmFtZScsICdzb21lL3BhdGgnKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOi9teS9wYXJhbS9uYW1lfX0nKTtcbiAgfSk7XG5cbiAgdGVzdCgncmV0dXJucyB1bmNoYW5nZWQgdmFsdWUgd2l0aG91dCBzc206IHByZWZpeCcsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgncGxhaW4tdmFsdWUnLCAnc29tZS9wYXRoJyk7XG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZSgncGxhaW4tdmFsdWUnKTtcbiAgfSk7XG5cbiAgdGVzdCgncmV0dXJucyB1bmNoYW5nZWQgdmFsdWUgZm9yIGVtcHR5IHN0cmluZycsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnJywgJ3NvbWUvcGF0aCcpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJycpO1xuICB9KTtcblxuICB0ZXN0KCdpZ25vcmVzIHNzbTogdmFsdWVzIGluIHBvbGljeURvY3VtZW50L1N0YXRlbWVudC9BY3Rpb24gcGF0aCcsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnc3NtOkdldFBhcmFtZXRlcicsICdwb2xpY3lEb2N1bWVudC9TdGF0ZW1lbnQvQWN0aW9uJyk7XG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnc3NtOkdldFBhcmFtZXRlcicpO1xuICB9KTtcblxuICB0ZXN0KCdpZ25vcmVzIHNzbTogdmFsdWVzIGluIHBvbGljeURvY3VtZW50L1N0YXRlbWVudC9BY3Rpb24gcGF0aCAoY2FzZSBpbnNlbnNpdGl2ZSknLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3NzbTpHZXRQYXJhbWV0ZXInLCAnUG9saWN5RG9jdW1lbnQvU3RhdGVtZW50L0FDVElPTicpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3NzbTpHZXRQYXJhbWV0ZXInKTtcbiAgfSk7XG5cbiAgdGVzdCgnaWdub3JlcyBzc206IHZhbHVlcyB3aGVuIHBhdGggZW5kcyB3aXRoIHBvbGljeURvY3VtZW50L1N0YXRlbWVudC9BY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3NzbTpQdXRQYXJhbWV0ZXInLCAnc29tZS9uZXN0ZWQvcG9saWN5RG9jdW1lbnQvU3RhdGVtZW50L0FjdGlvbicpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3NzbTpQdXRQYXJhbWV0ZXInKTtcbiAgfSk7XG5cbiAgdGVzdCgndHJhbnNmb3JtcyBzc206IHZhbHVlcyB3aGVuIHBhdGggY29udGFpbnMgYnV0IGRvZXMgbm90IGVuZCB3aXRoIGlnbm9yZWQgcGF0aCcsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnc3NtOi9teS9wYXJhbScsICdwb2xpY3lEb2N1bWVudC9TdGF0ZW1lbnQvQWN0aW9uL3NvbWV0aGluZycpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3t7cmVzb2x2ZTpzc206L215L3BhcmFtfX0nKTtcbiAgfSk7XG5cbiAgdGVzdCgndHJhbnNmb3JtcyBzc206IHZhbHVlcyBmb3Igbm9uLWlnbm9yZWQgcGF0aHMnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3NzbTovY29uZmlnL2RhdGFiYXNlL2hvc3QnLCAncmVzb3VyY2VzL2RhdGFiYXNlL2NvbmZpZycpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3t7cmVzb2x2ZTpzc206L2NvbmZpZy9kYXRhYmFzZS9ob3N0fX0nKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFuZGxlcyBzc206IHByZWZpeCB3aXRoIG5vIGFkZGl0aW9uYWwgY29udGVudCcsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnc3NtOicsICdzb21lL3BhdGgnKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOn19Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ2RvZXMgbm90IHRyYW5zZm9ybSB2YWx1ZXMgdGhhdCBjb250YWluIHNzbTogYnV0IGRvIG5vdCBzdGFydCB3aXRoIGl0JywgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCdwcmVmaXgtc3NtOi9wYXJhbScsICdzb21lL3BhdGgnKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCdwcmVmaXgtc3NtOi9wYXJhbScpO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIGNvbXBsZXggU1NNIHBhcmFtZXRlciBwYXRocycsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnc3NtOi9vcmcvZW52L2RvbWFpbi9tb2R1bGUvcGFyYW0tbmFtZScsICdjb25maWcvc2V0dGluZ3MnKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOi9vcmcvZW52L2RvbWFpbi9tb2R1bGUvcGFyYW0tbmFtZX19Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgU1NNIHBhcmFtZXRlciB3aXRoIHNwZWNpYWwgY2hhcmFjdGVycycsICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgnc3NtOi9teS1wYXJhbV9uYW1lLnYxJywgJ3NvbWUvcGF0aCcpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3t7cmVzb2x2ZTpzc206L215LXBhcmFtX25hbWUudjF9fScpO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,79 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { MdaaConfigSSMValueTransformer } from '../lib';
7
+
8
+ describe('MdaaConfigSSMValueTransformer', () => {
9
+ let transformer: MdaaConfigSSMValueTransformer;
10
+
11
+ beforeEach(() => {
12
+ transformer = new MdaaConfigSSMValueTransformer();
13
+ });
14
+
15
+ test('transforms ssm: prefix to resolve:ssm format', () => {
16
+ const result = transformer.transformValue('ssm:/my/param/name', 'some/path');
17
+ expect(result).toBe('{{resolve:ssm:/my/param/name}}');
18
+ });
19
+
20
+ test('handles whitespace after ssm: prefix', () => {
21
+ const result = transformer.transformValue('ssm: /my/param/name', 'some/path');
22
+ expect(result).toBe('{{resolve:ssm:/my/param/name}}');
23
+ });
24
+
25
+ test('returns unchanged value without ssm: prefix', () => {
26
+ const result = transformer.transformValue('plain-value', 'some/path');
27
+ expect(result).toBe('plain-value');
28
+ });
29
+
30
+ test('returns unchanged value for empty string', () => {
31
+ const result = transformer.transformValue('', 'some/path');
32
+ expect(result).toBe('');
33
+ });
34
+
35
+ test('ignores ssm: values in policyDocument/Statement/Action path', () => {
36
+ const result = transformer.transformValue('ssm:GetParameter', 'policyDocument/Statement/Action');
37
+ expect(result).toBe('ssm:GetParameter');
38
+ });
39
+
40
+ test('ignores ssm: values in policyDocument/Statement/Action path (case insensitive)', () => {
41
+ const result = transformer.transformValue('ssm:GetParameter', 'PolicyDocument/Statement/ACTION');
42
+ expect(result).toBe('ssm:GetParameter');
43
+ });
44
+
45
+ test('ignores ssm: values when path ends with policyDocument/Statement/Action', () => {
46
+ const result = transformer.transformValue('ssm:PutParameter', 'some/nested/policyDocument/Statement/Action');
47
+ expect(result).toBe('ssm:PutParameter');
48
+ });
49
+
50
+ test('transforms ssm: values when path contains but does not end with ignored path', () => {
51
+ const result = transformer.transformValue('ssm:/my/param', 'policyDocument/Statement/Action/something');
52
+ expect(result).toBe('{{resolve:ssm:/my/param}}');
53
+ });
54
+
55
+ test('transforms ssm: values for non-ignored paths', () => {
56
+ const result = transformer.transformValue('ssm:/config/database/host', 'resources/database/config');
57
+ expect(result).toBe('{{resolve:ssm:/config/database/host}}');
58
+ });
59
+
60
+ test('handles ssm: prefix with no additional content', () => {
61
+ const result = transformer.transformValue('ssm:', 'some/path');
62
+ expect(result).toBe('{{resolve:ssm:}}');
63
+ });
64
+
65
+ test('does not transform values that contain ssm: but do not start with it', () => {
66
+ const result = transformer.transformValue('prefix-ssm:/param', 'some/path');
67
+ expect(result).toBe('prefix-ssm:/param');
68
+ });
69
+
70
+ test('handles complex SSM parameter paths', () => {
71
+ const result = transformer.transformValue('ssm:/org/env/domain/module/param-name', 'config/settings');
72
+ expect(result).toBe('{{resolve:ssm:/org/env/domain/module/param-name}}');
73
+ });
74
+
75
+ test('handles SSM parameter with special characters', () => {
76
+ const result = transformer.transformValue('ssm:/my-param_name.v1', 'some/path');
77
+ expect(result).toBe('{{resolve:ssm:/my-param_name.v1}}');
78
+ });
79
+ });