@cdklabs/cdk-appmod-catalog-blueprints 1.3.0 → 1.4.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 (48) hide show
  1. package/.jsii +4 -4
  2. package/README.md +76 -98
  3. package/lib/document-processing/adapter/queued-s3-adapter.js +1 -1
  4. package/lib/document-processing/agentic-document-processing.js +1 -1
  5. package/lib/document-processing/base-document-processing.js +1 -1
  6. package/lib/document-processing/bedrock-document-processing.js +1 -1
  7. package/lib/document-processing/default-document-processing-config.js +1 -1
  8. package/lib/document-processing/tests/agentic-document-processing.test.js +104 -60
  9. package/lib/document-processing/tests/base-document-processing-nag.test.d.ts +1 -0
  10. package/lib/document-processing/tests/base-document-processing-nag.test.js +161 -0
  11. package/lib/document-processing/tests/base-document-processing.test.d.ts +1 -0
  12. package/lib/document-processing/tests/base-document-processing.test.js +499 -0
  13. package/lib/document-processing/tests/bedrock-document-processing.test.js +212 -36
  14. package/lib/document-processing/tests/queued-s3-adapter-nag.test.d.ts +1 -0
  15. package/lib/document-processing/tests/queued-s3-adapter-nag.test.js +122 -0
  16. package/lib/document-processing/tests/queued-s3-adapter.test.d.ts +1 -0
  17. package/lib/document-processing/tests/queued-s3-adapter.test.js +276 -0
  18. package/lib/framework/agents/base-agent.js +1 -1
  19. package/lib/framework/agents/batch-agent.js +1 -1
  20. package/lib/framework/agents/default-agent-config.js +1 -1
  21. package/lib/framework/bedrock/bedrock.js +1 -1
  22. package/lib/framework/custom-resource/default-runtimes.js +1 -1
  23. package/lib/framework/foundation/access-log.js +1 -1
  24. package/lib/framework/foundation/eventbridge-broker.js +1 -1
  25. package/lib/framework/foundation/network.js +1 -1
  26. package/lib/framework/tests/access-log.test.d.ts +1 -0
  27. package/lib/framework/tests/access-log.test.js +146 -0
  28. package/lib/framework/tests/batch-agent.test.d.ts +1 -0
  29. package/lib/framework/tests/batch-agent.test.js +164 -0
  30. package/lib/framework/tests/bedrock.test.d.ts +1 -0
  31. package/lib/framework/tests/bedrock.test.js +68 -0
  32. package/lib/framework/tests/eventbridge-broker.test.d.ts +1 -0
  33. package/lib/framework/tests/eventbridge-broker.test.js +73 -0
  34. package/lib/framework/tests/framework-nag.test.d.ts +1 -0
  35. package/lib/framework/tests/framework-nag.test.js +155 -0
  36. package/lib/framework/tests/network.test.d.ts +1 -0
  37. package/lib/framework/tests/network.test.js +120 -0
  38. package/lib/tsconfig.tsbuildinfo +1 -1
  39. package/lib/utilities/data-loader.js +1 -1
  40. package/lib/utilities/lambda-iam-utils.js +1 -1
  41. package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +1 -1
  42. package/lib/utilities/observability/default-observability-config.js +1 -1
  43. package/lib/utilities/observability/lambda-observability-property-injector.js +1 -1
  44. package/lib/utilities/observability/log-group-data-protection-utils.js +1 -1
  45. package/lib/utilities/observability/powertools-config.js +1 -1
  46. package/lib/utilities/observability/state-machine-observability-property-injector.js +1 -1
  47. package/lib/webapp/frontend-construct.js +1 -1
  48. package/package.json +8 -8
@@ -3,17 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const aws_cdk_lib_1 = require("aws-cdk-lib");
4
4
  const assertions_1 = require("aws-cdk-lib/assertions");
5
5
  const aws_bedrock_1 = require("aws-cdk-lib/aws-bedrock");
6
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
6
7
  const framework_1 = require("../../framework");
7
8
  const bedrock_document_processing_1 = require("../bedrock-document-processing");
8
9
  describe('BedrockDocumentProcessing', () => {
9
10
  let defaultStack;
10
11
  let customStack;
11
12
  let crossRegionStack;
13
+ let enrichmentStack;
14
+ let postProcessingStack;
15
+ let customPromptsStack;
16
+ let customTimeoutStack;
12
17
  let defaultTemplate;
13
18
  let customTemplate;
14
19
  let crossRegionTemplate;
20
+ let enrichmentTemplate;
21
+ let postProcessingTemplate;
22
+ let customPromptsTemplate;
23
+ let customTimeoutTemplate;
15
24
  beforeAll(() => {
16
- // Create all stacks and constructs first
17
25
  defaultStack = new aws_cdk_lib_1.Stack();
18
26
  new bedrock_document_processing_1.BedrockDocumentProcessing(defaultStack, 'DefaultTest', {});
19
27
  customStack = new aws_cdk_lib_1.Stack();
@@ -22,6 +30,10 @@ describe('BedrockDocumentProcessing', () => {
22
30
  fmModelId: aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_HAIKU_20240307_V1_0,
23
31
  useCrossRegionInference: false,
24
32
  },
33
+ processingBedrockModel: {
34
+ fmModelId: aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_HAIKU_20240307_V1_0,
35
+ useCrossRegionInference: false,
36
+ },
25
37
  });
26
38
  crossRegionStack = new aws_cdk_lib_1.Stack();
27
39
  new bedrock_document_processing_1.BedrockDocumentProcessing(crossRegionStack, 'CrossRegionTest', {
@@ -30,55 +42,219 @@ describe('BedrockDocumentProcessing', () => {
30
42
  crossRegionInferencePrefix: framework_1.BedrockCrossRegionInferencePrefix.EU,
31
43
  },
32
44
  });
33
- // Generate templates once after all constructs are created
45
+ enrichmentStack = new aws_cdk_lib_1.Stack();
46
+ const enrichmentFn = new aws_lambda_1.Function(enrichmentStack, 'EnrichmentFn', {
47
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
48
+ handler: 'index.handler',
49
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ enriched: true });'),
50
+ });
51
+ new bedrock_document_processing_1.BedrockDocumentProcessing(enrichmentStack, 'EnrichmentTest', {
52
+ enrichmentLambdaFunction: enrichmentFn,
53
+ });
54
+ postProcessingStack = new aws_cdk_lib_1.Stack();
55
+ const postProcessingFn = new aws_lambda_1.Function(postProcessingStack, 'PostProcessingFn', {
56
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
57
+ handler: 'index.handler',
58
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ processed: true });'),
59
+ });
60
+ new bedrock_document_processing_1.BedrockDocumentProcessing(postProcessingStack, 'PostProcessingTest', {
61
+ postProcessingLambdaFunction: postProcessingFn,
62
+ });
63
+ customPromptsStack = new aws_cdk_lib_1.Stack();
64
+ new bedrock_document_processing_1.BedrockDocumentProcessing(customPromptsStack, 'CustomPromptsTest', {
65
+ classificationPrompt: 'Custom classification prompt',
66
+ processingPrompt: 'Custom processing prompt',
67
+ });
68
+ customTimeoutStack = new aws_cdk_lib_1.Stack();
69
+ new bedrock_document_processing_1.BedrockDocumentProcessing(customTimeoutStack, 'CustomTimeoutTest', {
70
+ stepTimeouts: aws_cdk_lib_1.Duration.minutes(10),
71
+ });
34
72
  defaultTemplate = assertions_1.Template.fromStack(defaultStack);
35
73
  customTemplate = assertions_1.Template.fromStack(customStack);
36
74
  crossRegionTemplate = assertions_1.Template.fromStack(crossRegionStack);
75
+ enrichmentTemplate = assertions_1.Template.fromStack(enrichmentStack);
76
+ postProcessingTemplate = assertions_1.Template.fromStack(postProcessingStack);
77
+ customPromptsTemplate = assertions_1.Template.fromStack(customPromptsStack);
78
+ customTimeoutTemplate = assertions_1.Template.fromStack(customTimeoutStack);
37
79
  });
38
- test('creates basic infrastructure', () => {
39
- defaultTemplate.hasResourceProperties('AWS::S3::Bucket', {});
40
- defaultTemplate.hasResourceProperties('AWS::SQS::Queue', {});
41
- defaultTemplate.hasResourceProperties('AWS::DynamoDB::Table', { BillingMode: 'PAY_PER_REQUEST' });
42
- defaultTemplate.hasResourceProperties('AWS::StepFunctions::StateMachine', {});
43
- defaultTemplate.resourceCountIs('AWS::Lambda::Function', 5);
80
+ describe('Basic infrastructure', () => {
81
+ test('creates basic infrastructure', () => {
82
+ defaultTemplate.hasResourceProperties('AWS::S3::Bucket', {});
83
+ defaultTemplate.hasResourceProperties('AWS::SQS::Queue', {});
84
+ defaultTemplate.hasResourceProperties('AWS::DynamoDB::Table', { BillingMode: 'PAY_PER_REQUEST' });
85
+ defaultTemplate.hasResourceProperties('AWS::StepFunctions::StateMachine', {});
86
+ defaultTemplate.resourceCountIs('AWS::Lambda::Function', 5);
87
+ });
88
+ test('creates classification and processing Lambda functions', () => {
89
+ defaultTemplate.resourceCountIs('AWS::Lambda::Function', 5);
90
+ });
44
91
  });
45
- test('uses default model with cross-region prefix disabled', () => {
46
- defaultTemplate.hasResourceProperties('AWS::Lambda::Function', {
47
- Environment: {
48
- Variables: {
49
- MODEL_ID: 'anthropic.claude-sonnet-4-20250514-v1:0',
92
+ describe('Model configuration', () => {
93
+ test('uses default model with cross-region prefix disabled', () => {
94
+ defaultTemplate.hasResourceProperties('AWS::Lambda::Function', {
95
+ Environment: {
96
+ Variables: {
97
+ MODEL_ID: 'anthropic.claude-sonnet-4-20250514-v1:0',
98
+ },
50
99
  },
51
- },
100
+ });
101
+ });
102
+ test('uses custom model without cross-region prefix', () => {
103
+ customTemplate.hasResourceProperties('AWS::Lambda::Function', {
104
+ Environment: {
105
+ Variables: {
106
+ MODEL_ID: 'anthropic.claude-3-haiku-20240307-v1:0',
107
+ },
108
+ },
109
+ });
110
+ });
111
+ test('configures custom cross-region prefix', () => {
112
+ crossRegionTemplate.hasResourceProperties('AWS::Lambda::Function', {
113
+ Environment: {
114
+ Variables: {
115
+ MODEL_ID: 'eu.anthropic.claude-sonnet-4-20250514-v1:0',
116
+ },
117
+ },
118
+ });
119
+ });
120
+ test('configures different models for classification and processing', () => {
121
+ customTemplate.hasResourceProperties('AWS::Lambda::Function', {
122
+ Environment: {
123
+ Variables: {
124
+ MODEL_ID: 'anthropic.claude-3-haiku-20240307-v1:0',
125
+ INVOKE_TYPE: 'classification',
126
+ },
127
+ },
128
+ });
129
+ customTemplate.hasResourceProperties('AWS::Lambda::Function', {
130
+ Environment: {
131
+ Variables: {
132
+ MODEL_ID: 'anthropic.claude-3-haiku-20240307-v1:0',
133
+ INVOKE_TYPE: 'processing',
134
+ },
135
+ },
136
+ });
52
137
  });
53
138
  });
54
- test('uses custom model without cross-region prefix', () => {
55
- customTemplate.hasResourceProperties('AWS::Lambda::Function', {
56
- Environment: {
57
- Variables: {
58
- MODEL_ID: 'anthropic.claude-3-haiku-20240307-v1:0',
139
+ describe('IAM permissions', () => {
140
+ test('creates bedrock permissions', () => {
141
+ defaultTemplate.hasResourceProperties('AWS::IAM::Role', {
142
+ AssumeRolePolicyDocument: {
143
+ Statement: [{
144
+ Action: 'sts:AssumeRole',
145
+ Effect: 'Allow',
146
+ Principal: { Service: 'lambda.amazonaws.com' },
147
+ }],
59
148
  },
60
- },
149
+ });
150
+ });
151
+ test('grants Bedrock invoke permissions', () => {
152
+ defaultTemplate.hasResourceProperties('AWS::IAM::Role', {
153
+ Policies: assertions_1.Match.arrayWith([
154
+ assertions_1.Match.objectLike({
155
+ PolicyDocument: {
156
+ Statement: assertions_1.Match.arrayWith([
157
+ assertions_1.Match.objectLike({
158
+ Action: ['bedrock:InvokeModel', 'bedrock:InvokeModelWithResponseStream'],
159
+ Effect: 'Allow',
160
+ }),
161
+ ]),
162
+ },
163
+ }),
164
+ ]),
165
+ });
166
+ });
167
+ test('grants S3 access permissions', () => {
168
+ defaultTemplate.hasResourceProperties('AWS::IAM::Role', {
169
+ Policies: assertions_1.Match.arrayWith([
170
+ assertions_1.Match.objectLike({
171
+ PolicyDocument: {
172
+ Statement: assertions_1.Match.arrayWith([
173
+ assertions_1.Match.objectLike({
174
+ Action: assertions_1.Match.arrayWith(['s3:GetObject']),
175
+ Effect: 'Allow',
176
+ }),
177
+ ]),
178
+ },
179
+ }),
180
+ ]),
181
+ });
61
182
  });
62
183
  });
63
- test('configures custom cross-region prefix', () => {
64
- crossRegionTemplate.hasResourceProperties('AWS::Lambda::Function', {
65
- Environment: {
66
- Variables: {
67
- MODEL_ID: 'eu.anthropic.claude-sonnet-4-20250514-v1:0',
184
+ describe('Optional workflow steps', () => {
185
+ test('includes enrichment Lambda when provided', () => {
186
+ enrichmentTemplate.hasResourceProperties('AWS::Lambda::Function', {
187
+ Handler: 'index.handler',
188
+ });
189
+ enrichmentTemplate.hasResourceProperties('AWS::StepFunctions::StateMachine', {
190
+ DefinitionString: assertions_1.Match.objectLike({
191
+ 'Fn::Join': assertions_1.Match.arrayWith(['']),
192
+ }),
193
+ });
194
+ });
195
+ test('includes post-processing Lambda when provided', () => {
196
+ postProcessingTemplate.hasResourceProperties('AWS::Lambda::Function', {
197
+ Handler: 'index.handler',
198
+ });
199
+ postProcessingTemplate.hasResourceProperties('AWS::StepFunctions::StateMachine', {
200
+ DefinitionString: assertions_1.Match.objectLike({
201
+ 'Fn::Join': assertions_1.Match.arrayWith(['']),
202
+ }),
203
+ });
204
+ });
205
+ });
206
+ describe('Custom configuration', () => {
207
+ test('uses custom classification prompt', () => {
208
+ customPromptsTemplate.hasResourceProperties('AWS::Lambda::Function', {
209
+ Environment: {
210
+ Variables: {
211
+ PROMPT: 'Custom classification prompt',
212
+ INVOKE_TYPE: 'classification',
213
+ },
68
214
  },
69
- },
215
+ });
216
+ });
217
+ test('uses custom processing prompt', () => {
218
+ customPromptsTemplate.hasResourceProperties('AWS::Lambda::Function', {
219
+ Environment: {
220
+ Variables: {
221
+ PROMPT: 'Custom processing prompt',
222
+ INVOKE_TYPE: 'processing',
223
+ },
224
+ },
225
+ });
226
+ });
227
+ test('configures custom step timeout', () => {
228
+ customTimeoutTemplate.hasResourceProperties('AWS::Lambda::Function', {
229
+ Timeout: 600,
230
+ });
70
231
  });
71
232
  });
72
- test('creates bedrock permissions', () => {
73
- defaultTemplate.hasResourceProperties('AWS::IAM::Role', {
74
- AssumeRolePolicyDocument: {
75
- Statement: [{
76
- Action: 'sts:AssumeRole',
77
- Effect: 'Allow',
78
- Principal: { Service: 'lambda.amazonaws.com' },
79
- }],
80
- },
233
+ describe('Lambda configuration', () => {
234
+ test('configures Lambda memory and timeout', () => {
235
+ defaultTemplate.hasResourceProperties('AWS::Lambda::Function', {
236
+ MemorySize: 512,
237
+ Timeout: 300,
238
+ });
239
+ });
240
+ test('sets correct invoke type for classification', () => {
241
+ defaultTemplate.hasResourceProperties('AWS::Lambda::Function', {
242
+ Environment: {
243
+ Variables: {
244
+ INVOKE_TYPE: 'classification',
245
+ },
246
+ },
247
+ });
248
+ });
249
+ test('sets correct invoke type for processing', () => {
250
+ defaultTemplate.hasResourceProperties('AWS::Lambda::Function', {
251
+ Environment: {
252
+ Variables: {
253
+ INVOKE_TYPE: 'processing',
254
+ },
255
+ },
256
+ });
81
257
  });
82
258
  });
83
259
  });
84
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9iZWRyb2NrLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFvQztBQUNwQyx1REFBa0Q7QUFDbEQseURBQW9FO0FBQ3BFLCtDQUFvRTtBQUNwRSxnRkFBMkU7QUFFM0UsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN6QyxJQUFJLFlBQW1CLENBQUM7SUFDeEIsSUFBSSxXQUFrQixDQUFDO0lBQ3ZCLElBQUksZ0JBQXVCLENBQUM7SUFDNUIsSUFBSSxlQUF5QixDQUFDO0lBQzlCLElBQUksY0FBd0IsQ0FBQztJQUM3QixJQUFJLG1CQUE2QixDQUFDO0lBRWxDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYix5Q0FBeUM7UUFDekMsWUFBWSxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzNCLElBQUksdURBQXlCLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUUvRCxXQUFXLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDMUIsSUFBSSx1REFBeUIsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFO1lBQ3ZELDBCQUEwQixFQUFFO2dCQUMxQixTQUFTLEVBQUUsdUNBQXlCLENBQUMsc0NBQXNDO2dCQUMzRSx1QkFBdUIsRUFBRSxLQUFLO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsZ0JBQWdCLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDL0IsSUFBSSx1REFBeUIsQ0FBQyxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRTtZQUNqRSwwQkFBMEIsRUFBRTtnQkFDMUIsdUJBQXVCLEVBQUUsSUFBSTtnQkFDN0IsMEJBQTBCLEVBQUUsNkNBQWlDLENBQUMsRUFBRTthQUNqRTtTQUNGLENBQUMsQ0FBQztRQUVILDJEQUEyRDtRQUMzRCxlQUFlLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbkQsY0FBYyxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pELG1CQUFtQixHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0QsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsOEJBQThCLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3RCxlQUFlLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0QsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHNCQUFzQixFQUFFLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUNsRyxlQUFlLENBQUMscUJBQXFCLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUUsZUFBZSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzREFBc0QsRUFBRSxHQUFHLEVBQUU7UUFDaEUsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO1lBQzdELFdBQVcsRUFBRTtnQkFDWCxTQUFTLEVBQUU7b0JBQ1QsUUFBUSxFQUFFLHlDQUF5QztpQkFDcEQ7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLCtDQUErQyxFQUFFLEdBQUcsRUFBRTtRQUN6RCxjQUFjLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLEVBQUU7WUFDNUQsV0FBVyxFQUFFO2dCQUNYLFNBQVMsRUFBRTtvQkFDVCxRQUFRLEVBQUUsd0NBQXdDO2lCQUNuRDthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFO1FBQ2pELG1CQUFtQixDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO1lBQ2pFLFdBQVcsRUFBRTtnQkFDWCxTQUFTLEVBQUU7b0JBQ1QsUUFBUSxFQUFFLDRDQUE0QztpQkFDdkQ7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDZCQUE2QixFQUFFLEdBQUcsRUFBRTtRQUN2QyxlQUFlLENBQUMscUJBQXFCLENBQUMsZ0JBQWdCLEVBQUU7WUFDdEQsd0JBQXdCLEVBQUU7Z0JBQ3hCLFNBQVMsRUFBRSxDQUFDO3dCQUNWLE1BQU0sRUFBRSxnQkFBZ0I7d0JBQ3hCLE1BQU0sRUFBRSxPQUFPO3dCQUNmLFNBQVMsRUFBRSxFQUFFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRTtxQkFDL0MsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYmVkcm9jayc7XG5pbXBvcnQgeyBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXggfSBmcm9tICcuLi8uLi9mcmFtZXdvcmsnO1xuaW1wb3J0IHsgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyB9IGZyb20gJy4uL2JlZHJvY2stZG9jdW1lbnQtcHJvY2Vzc2luZyc7XG5cbmRlc2NyaWJlKCdCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nJywgKCkgPT4ge1xuICBsZXQgZGVmYXVsdFN0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVN0YWNrOiBTdGFjaztcbiAgbGV0IGNyb3NzUmVnaW9uU3RhY2s6IFN0YWNrO1xuICBsZXQgZGVmYXVsdFRlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgbGV0IGN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgbGV0IGNyb3NzUmVnaW9uVGVtcGxhdGU6IFRlbXBsYXRlO1xuXG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgLy8gQ3JlYXRlIGFsbCBzdGFja3MgYW5kIGNvbnN0cnVjdHMgZmlyc3RcbiAgICBkZWZhdWx0U3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhkZWZhdWx0U3RhY2ssICdEZWZhdWx0VGVzdCcsIHt9KTtcblxuICAgIGN1c3RvbVN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY3VzdG9tU3RhY2ssICdDdXN0b21UZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25CZWRyb2NrTW9kZWw6IHtcbiAgICAgICAgZm1Nb2RlbElkOiBGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyLkFOVEhST1BJQ19DTEFVREVfM19IQUlLVV8yMDI0MDMwN19WMV8wLFxuICAgICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY3Jvc3NSZWdpb25TdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGNyb3NzUmVnaW9uU3RhY2ssICdDcm9zc1JlZ2lvblRlc3QnLCB7XG4gICAgICBjbGFzc2lmaWNhdGlvbkJlZHJvY2tNb2RlbDoge1xuICAgICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogdHJ1ZSxcbiAgICAgICAgY3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXg6IEJlZHJvY2tDcm9zc1JlZ2lvbkluZmVyZW5jZVByZWZpeC5FVSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBHZW5lcmF0ZSB0ZW1wbGF0ZXMgb25jZSBhZnRlciBhbGwgY29uc3RydWN0cyBhcmUgY3JlYXRlZFxuICAgIGRlZmF1bHRUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhkZWZhdWx0U3RhY2spO1xuICAgIGN1c3RvbVRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGN1c3RvbVN0YWNrKTtcbiAgICBjcm9zc1JlZ2lvblRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNyb3NzUmVnaW9uU3RhY2spO1xuICB9KTtcblxuICB0ZXN0KCdjcmVhdGVzIGJhc2ljIGluZnJhc3RydWN0dXJlJywgKCkgPT4ge1xuICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6UzM6OkJ1Y2tldCcsIHt9KTtcbiAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlNRUzo6UXVldWUnLCB7fSk7XG4gICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpEeW5hbW9EQjo6VGFibGUnLCB7IEJpbGxpbmdNb2RlOiAnUEFZX1BFUl9SRVFVRVNUJyB9KTtcbiAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHt9KTtcbiAgICBkZWZhdWx0VGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCA1KTtcbiAgfSk7XG5cbiAgdGVzdCgndXNlcyBkZWZhdWx0IG1vZGVsIHdpdGggY3Jvc3MtcmVnaW9uIHByZWZpeCBkaXNhYmxlZCcsICgpID0+IHtcbiAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTQtdjE6MCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCd1c2VzIGN1c3RvbSBtb2RlbCB3aXRob3V0IGNyb3NzLXJlZ2lvbiBwcmVmaXgnLCAoKSA9PiB7XG4gICAgY3VzdG9tVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtMy1oYWlrdS0yMDI0MDMwNy12MTowJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2NvbmZpZ3VyZXMgY3VzdG9tIGNyb3NzLXJlZ2lvbiBwcmVmaXgnLCAoKSA9PiB7XG4gICAgY3Jvc3NSZWdpb25UZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgIE1PREVMX0lEOiAnZXUuYW50aHJvcGljLmNsYXVkZS1zb25uZXQtNC0yMDI1MDUxNC12MTowJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2NyZWF0ZXMgYmVkcm9jayBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6Um9sZScsIHtcbiAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICBTdGF0ZW1lbnQ6IFt7XG4gICAgICAgICAgQWN0aW9uOiAnc3RzOkFzc3VtZVJvbGUnLFxuICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICBQcmluY2lwYWw6IHsgU2VydmljZTogJ2xhbWJkYS5hbWF6b25hd3MuY29tJyB9LFxuICAgICAgICB9XSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9iZWRyb2NrLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUE4QztBQUM5Qyx1REFBeUQ7QUFDekQseURBQW9FO0FBQ3BFLHVEQUFpRTtBQUNqRSwrQ0FBb0U7QUFDcEUsZ0ZBQTJFO0FBRTNFLFFBQVEsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7SUFDekMsSUFBSSxZQUFtQixDQUFDO0lBQ3hCLElBQUksV0FBa0IsQ0FBQztJQUN2QixJQUFJLGdCQUF1QixDQUFDO0lBQzVCLElBQUksZUFBc0IsQ0FBQztJQUMzQixJQUFJLG1CQUEwQixDQUFDO0lBQy9CLElBQUksa0JBQXlCLENBQUM7SUFDOUIsSUFBSSxrQkFBeUIsQ0FBQztJQUM5QixJQUFJLGVBQXlCLENBQUM7SUFDOUIsSUFBSSxjQUF3QixDQUFDO0lBQzdCLElBQUksbUJBQTZCLENBQUM7SUFDbEMsSUFBSSxrQkFBNEIsQ0FBQztJQUNqQyxJQUFJLHNCQUFnQyxDQUFDO0lBQ3JDLElBQUkscUJBQStCLENBQUM7SUFDcEMsSUFBSSxxQkFBK0IsQ0FBQztJQUVwQyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsWUFBWSxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzNCLElBQUksdURBQXlCLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUUvRCxXQUFXLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDMUIsSUFBSSx1REFBeUIsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFO1lBQ3ZELDBCQUEwQixFQUFFO2dCQUMxQixTQUFTLEVBQUUsdUNBQXlCLENBQUMsc0NBQXNDO2dCQUMzRSx1QkFBdUIsRUFBRSxL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O0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO1FBQ3BDLElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7WUFDaEQsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO2dCQUM3RCxVQUFVLEVBQUUsR0FBRztnQkFDZixPQUFPLEVBQUUsR0FBRzthQUNiLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLDZDQUE2QyxFQUFFLEdBQUcsRUFBRTtZQUN2RCxlQUFlLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLEVBQUU7Z0JBQzdELFdBQVcsRUFBRTtvQkFDWCxTQUFTLEVBQUU7d0JBQ1QsV0FBVyxFQUFFLGdCQUFnQjtxQkFDOUI7aUJBQ0Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7WUFDbkQsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO2dCQUM3RCxXQUFXLEVBQUU7b0JBQ1gsU0FBUyxFQUFFO3dCQUNULFdBQVcsRUFBRSxZQUFZO3FCQUMxQjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uLCBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IE1hdGNoLCBUZW1wbGF0ZSB9IGZyb20gJ2F3cy1jZGstbGliL2Fzc2VydGlvbnMnO1xuaW1wb3J0IHsgRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllciB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1iZWRyb2NrJztcbmltcG9ydCB7IENvZGUsIEZ1bmN0aW9uLCBSdW50aW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXggfSBmcm9tICcuLi8uLi9mcmFtZXdvcmsnO1xuaW1wb3J0IHsgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyB9IGZyb20gJy4uL2JlZHJvY2stZG9jdW1lbnQtcHJvY2Vzc2luZyc7XG5cbmRlc2NyaWJlKCdCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nJywgKCkgPT4ge1xuICBsZXQgZGVmYXVsdFN0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVN0YWNrOiBTdGFjaztcbiAgbGV0IGNyb3NzUmVnaW9uU3RhY2s6IFN0YWNrO1xuICBsZXQgZW5yaWNobWVudFN0YWNrOiBTdGFjaztcbiAgbGV0IHBvc3RQcm9jZXNzaW5nU3RhY2s6IFN0YWNrO1xuICBsZXQgY3VzdG9tUHJvbXB0c1N0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVRpbWVvdXRTdGFjazogU3RhY2s7XG4gIGxldCBkZWZhdWx0VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3Jvc3NSZWdpb25UZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBlbnJpY2htZW50VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBjdXN0b21Qcm9tcHRzVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGltZW91dFRlbXBsYXRlOiBUZW1wbGF0ZTtcblxuICBiZWZvcmVBbGwoKCkgPT4ge1xuICAgIGRlZmF1bHRTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGRlZmF1bHRTdGFjaywgJ0RlZmF1bHRUZXN0Jywge30pO1xuXG4gICAgY3VzdG9tU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjdXN0b21TdGFjaywgJ0N1c3RvbVRlc3QnLCB7XG4gICAgICBjbGFzc2lmaWNhdGlvbkJlZHJvY2tNb2RlbDoge1xuICAgICAgICBmbU1vZGVsSWQ6IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIuQU5USFJPUElDX0NMQVVERV8zX0hBSUtVXzIwMjQwMzA3X1YxXzAsXG4gICAgICAgIHVzZUNyb3NzUmVnaW9uSW5mZXJlbmNlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBwcm9jZXNzaW5nQmVkcm9ja01vZGVsOiB7XG4gICAgICAgIGZtTW9kZWxJZDogRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllci5BTlRIUk9QSUNfQ0xBVURFXzNfSEFJS1VfMjAyNDAzMDdfVjFfMCxcbiAgICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNyb3NzUmVnaW9uU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjcm9zc1JlZ2lvblN0YWNrLCAnQ3Jvc3NSZWdpb25UZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25CZWRyb2NrTW9kZWw6IHtcbiAgICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IHRydWUsXG4gICAgICAgIGNyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4OiBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXguRVUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgZW5yaWNobWVudFN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgZW5yaWNobWVudEZuID0gbmV3IEZ1bmN0aW9uKGVucmljaG1lbnRTdGFjaywgJ0VucmljaG1lbnRGbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoJ2V4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+ICh7IGVucmljaGVkOiB0cnVlIH0pOycpLFxuICAgIH0pO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGVucmljaG1lbnRTdGFjaywgJ0VucmljaG1lbnRUZXN0Jywge1xuICAgICAgZW5yaWNobWVudExhbWJkYUZ1bmN0aW9uOiBlbnJpY2htZW50Rm4sXG4gICAgfSk7XG5cbiAgICBwb3N0UHJvY2Vzc2luZ1N0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgcG9zdFByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbihwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdGbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoJ2V4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+ICh7IHByb2Nlc3NlZDogdHJ1ZSB9KTsnKSxcbiAgICB9KTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdUZXN0Jywge1xuICAgICAgcG9zdFByb2Nlc3NpbmdMYW1iZGFGdW5jdGlvbjogcG9zdFByb2Nlc3NpbmdGbixcbiAgICB9KTtcblxuICAgIGN1c3RvbVByb21wdHNTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGN1c3RvbVByb21wdHNTdGFjaywgJ0N1c3RvbVByb21wdHNUZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25Qcm9tcHQ6ICdDdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0JyxcbiAgICAgIHByb2Nlc3NpbmdQcm9tcHQ6ICdDdXN0b20gcHJvY2Vzc2luZyBwcm9tcHQnLFxuICAgIH0pO1xuXG4gICAgY3VzdG9tVGltZW91dFN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY3VzdG9tVGltZW91dFN0YWNrLCAnQ3VzdG9tVGltZW91dFRlc3QnLCB7XG4gICAgICBzdGVwVGltZW91dHM6IER1cmF0aW9uLm1pbnV0ZXMoMTApLFxuICAgIH0pO1xuXG4gICAgZGVmYXVsdFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGRlZmF1bHRTdGFjayk7XG4gICAgY3VzdG9tVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tU3RhY2spO1xuICAgIGNyb3NzUmVnaW9uVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3Jvc3NSZWdpb25TdGFjayk7XG4gICAgZW5yaWNobWVudFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGVucmljaG1lbnRTdGFjayk7XG4gICAgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhwb3N0UHJvY2Vzc2luZ1N0YWNrKTtcbiAgICBjdXN0b21Qcm9tcHRzVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tUHJvbXB0c1N0YWNrKTtcbiAgICBjdXN0b21UaW1lb3V0VGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tVGltZW91dFN0YWNrKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Jhc2ljIGluZnJhc3RydWN0dXJlJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NyZWF0ZXMgYmFzaWMgaW5mcmFzdHJ1Y3R1cmUnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlMzOjpCdWNrZXQnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlNRUzo6UXVldWUnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHsgQmlsbGluZ01vZGU6ICdQQVlfUEVSX1JFUVVFU1QnIH0pO1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCA1KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NyZWF0ZXMgY2xhc3NpZmljYXRpb24gYW5kIHByb2Nlc3NpbmcgTGFtYmRhIGZ1bmN0aW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIDUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTW9kZWwgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCd1c2VzIGRlZmF1bHQgbW9kZWwgd2l0aCBjcm9zcy1yZWdpb24gcHJlZml4IGRpc2FibGVkJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0LXYxOjAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgY3VzdG9tIG1vZGVsIHdpdGhvdXQgY3Jvc3MtcmVnaW9uIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLTMtaGFpa3UtMjAyNDAzMDctdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyBjdXN0b20gY3Jvc3MtcmVnaW9uIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGNyb3NzUmVnaW9uVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2V1LmFudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTQtdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyBkaWZmZXJlbnQgbW9kZWxzIGZvciBjbGFzc2lmaWNhdGlvbiBhbmQgcHJvY2Vzc2luZycsICgpID0+IHtcbiAgICAgIGN1c3RvbVRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLTMtaGFpa3UtMjAyNDAzMDctdjE6MCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBjdXN0b21UZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiAnYW50aHJvcGljLmNsYXVkZS0zLWhhaWt1LTIwMjQwMzA3LXYxOjAnLFxuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdwcm9jZXNzaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdJQU0gcGVybWlzc2lvbnMnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBiZWRyb2NrIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgIFN0YXRlbWVudDogW3tcbiAgICAgICAgICAgIEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJyxcbiAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgIFByaW5jaXBhbDogeyBTZXJ2aWNlOiAnbGFtYmRhLmFtYXpvbmF3cy5jb20nIH0sXG4gICAgICAgICAgfV0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2dyYW50cyBCZWRyb2NrIGludm9rZSBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogWydiZWRyb2NrOkludm9rZU1vZGVsJywgJ2JlZHJvY2s6SW52b2tlTW9kZWxXaXRoUmVzcG9uc2VTdHJlYW0nXSxcbiAgICAgICAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnZ3JhbnRzIFMzIGFjY2VzcyBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogTWF0Y2guYXJyYXlXaXRoKFsnczM6R2V0T2JqZWN0J10pLFxuICAgICAgICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdPcHRpb25hbCB3b3JrZmxvdyBzdGVwcycsICgpID0+IHtcbiAgICB0ZXN0KCdpbmNsdWRlcyBlbnJpY2htZW50IExhbWJkYSB3aGVuIHByb3ZpZGVkJywgKCkgPT4ge1xuICAgICAgZW5yaWNobWVudFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBIYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICB9KTtcbiAgICAgIGVucmljaG1lbnRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICBEZWZpbml0aW9uU3RyaW5nOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAnRm46OkpvaW4nOiBNYXRjaC5hcnJheVdpdGgoWycnXSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdpbmNsdWRlcyBwb3N0LXByb2Nlc3NpbmcgTGFtYmRhIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICBwb3N0UHJvY2Vzc2luZ1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBIYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICB9KTtcbiAgICAgIHBvc3RQcm9jZXNzaW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHtcbiAgICAgICAgRGVmaW5pdGlvblN0cmluZzogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgJ0ZuOjpKb2luJzogTWF0Y2guYXJyYXlXaXRoKFsnJ10pLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ3VzdG9tIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgdGVzdCgndXNlcyBjdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0JywgKCkgPT4ge1xuICAgICAgY3VzdG9tUHJvbXB0c1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgUFJPTVBUOiAnQ3VzdG9tIGNsYXNzaWZpY2F0aW9uIHByb21wdCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd1c2VzIGN1c3RvbSBwcm9jZXNzaW5nIHByb21wdCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVByb21wdHNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIFBST01QVDogJ0N1c3RvbSBwcm9jZXNzaW5nIHByb21wdCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ3Byb2Nlc3NpbmcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NvbmZpZ3VyZXMgY3VzdG9tIHN0ZXAgdGltZW91dCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVRpbWVvdXRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgVGltZW91dDogNjAwLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdMYW1iZGEgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCdjb25maWd1cmVzIExhbWJkYSBtZW1vcnkgYW5kIHRpbWVvdXQnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIE1lbW9yeVNpemU6IDUxMixcbiAgICAgICAgVGltZW91dDogMzAwLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzZXRzIGNvcnJlY3QgaW52b2tlIHR5cGUgZm9yIGNsYXNzaWZpY2F0aW9uJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdjbGFzc2lmaWNhdGlvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2V0cyBjb3JyZWN0IGludm9rZSB0eXBlIGZvciBwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdwcm9jZXNzaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
4
+ const assertions_1 = require("aws-cdk-lib/assertions");
5
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
6
+ const aws_s3_1 = require("aws-cdk-lib/aws-s3");
7
+ const aws_stepfunctions_tasks_1 = require("aws-cdk-lib/aws-stepfunctions-tasks");
8
+ const cdk_nag_1 = require("cdk-nag");
9
+ const framework_1 = require("../../framework");
10
+ const adapter_1 = require("../adapter");
11
+ const base_document_processing_1 = require("../base-document-processing");
12
+ class TestDocumentProcessing extends base_document_processing_1.BaseDocumentProcessing {
13
+ constructor(scope, id, props) {
14
+ super(scope, id, props);
15
+ this.classificationFn = new aws_lambda_1.Function(this, 'ClassificationFn', {
16
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
17
+ handler: 'index.handler',
18
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ documentClassification: "TEST" });'),
19
+ });
20
+ this.processingFn = new aws_lambda_1.Function(this, 'ProcessingFn', {
21
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
22
+ handler: 'index.handler',
23
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ result: {} });'),
24
+ });
25
+ }
26
+ classificationStep() {
27
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockClassification', {
28
+ lambdaFunction: this.classificationFn,
29
+ resultPath: '$.classificationResult',
30
+ });
31
+ }
32
+ processingStep() {
33
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockProcessing', {
34
+ lambdaFunction: this.processingFn,
35
+ resultPath: '$.processingResult',
36
+ });
37
+ }
38
+ enrichmentStep() {
39
+ return undefined;
40
+ }
41
+ postProcessingStep() {
42
+ return undefined;
43
+ }
44
+ createStateMachine() {
45
+ return this.handleStateMachineCreation('test-state-machine');
46
+ }
47
+ }
48
+ const app = new aws_cdk_lib_1.App();
49
+ const stack = new aws_cdk_lib_1.Stack(app, 'TestStack', {
50
+ env: {
51
+ account: '123456789012',
52
+ region: 'us-east-1',
53
+ },
54
+ });
55
+ const accessLog = new framework_1.AccessLog(stack, 'AccessLog');
56
+ const bucket = new aws_s3_1.Bucket(stack, 'QueuedS3AdapterBucket', {
57
+ serverAccessLogsBucket: accessLog.bucket,
58
+ serverAccessLogsPrefix: accessLog.bucketPrefix,
59
+ enforceSSL: true,
60
+ });
61
+ const adapter = new adapter_1.QueuedS3Adapter({ bucket });
62
+ const construct = new TestDocumentProcessing(stack, 'QueuedS3AdapterTest', {
63
+ ingressAdapter: adapter,
64
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
65
+ enableObservability: true,
66
+ });
67
+ construct.createStateMachine();
68
+ cdk_nag_1.NagSuppressions.addResourceSuppressionsByPath(stack, '/TestStack/BucketNotificationsHandler050a0587b7544547bf325f094a3db834/Role', [
69
+ {
70
+ id: 'AwsSolutions-IAM4',
71
+ reason: 'CDK-managed BucketNotificationsHandler requires AWSLambdaBasicExecutionRole for S3 event processing',
72
+ appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'],
73
+ },
74
+ ]);
75
+ cdk_nag_1.NagSuppressions.addResourceSuppressions(stack, [
76
+ {
77
+ id: 'AwsSolutions-IAM5',
78
+ reason: 'Lambda functions require wildcard access to S3 bucket objects for document processing',
79
+ appliesTo: ['Resource::<QueuedS3AdapterBucketE8A9C7F1.Arn>/*'],
80
+ },
81
+ ], true);
82
+ cdk_nag_1.NagSuppressions.addResourceSuppressions(stack, [
83
+ {
84
+ id: 'AwsSolutions-IAM5',
85
+ reason: 'Lambda log stream ARN is only known at runtime, wildcard required for CloudWatch Logs access',
86
+ },
87
+ ], true);
88
+ cdk_nag_1.NagSuppressions.addResourceSuppressions(stack, [
89
+ {
90
+ id: 'AwsSolutions-IAM5',
91
+ reason: 'Step Functions requires wildcard permissions to invoke Lambda functions with version-specific ARNs',
92
+ },
93
+ ], true);
94
+ cdk_nag_1.NagSuppressions.addResourceSuppressions(stack, [
95
+ {
96
+ id: 'AwsSolutions-IAM4',
97
+ reason: 'Test Lambda functions use AWS managed policies for basic execution',
98
+ appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'],
99
+ },
100
+ ], true);
101
+ cdk_nag_1.NagSuppressions.addResourceSuppressions(stack, [
102
+ {
103
+ id: 'AwsSolutions-L1',
104
+ reason: 'Test Lambda functions use Node.js 20 which is a supported runtime',
105
+ },
106
+ ], true);
107
+ aws_cdk_lib_1.Aspects.of(app).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
108
+ const warnings = assertions_1.Annotations.fromStack(stack).findWarning('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
109
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
110
+ test('No unsuppressed warnings', () => {
111
+ if (warnings.length > 0) {
112
+ console.log('CDK Nag Warnings:', JSON.stringify(warnings, null, 2));
113
+ }
114
+ expect(warnings).toHaveLength(0);
115
+ });
116
+ test('No unsuppressed errors', () => {
117
+ if (errors.length > 0) {
118
+ console.log('CDK Nag Errors:', JSON.stringify(errors, null, 2));
119
+ }
120
+ expect(errors).toHaveLength(0);
121
+ });
122
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVldWVkLXMzLWFkYXB0ZXItbmFnLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9xdWV1ZWQtczMtYWRhcHRlci1uYWcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFpRTtBQUNqRSx1REFBNEQ7QUFDNUQsdURBQWlFO0FBQ2pFLCtDQUE0QztBQUM1QyxpRkFBbUU7QUFDbkUscUNBQThEO0FBQzlELCtDQUE0QztBQUM1Qyx3Q0FBNkM7QUFDN0MsMEVBQWlHO0FBRWpHLE1BQU0sc0JBQXVCLFNBQVEsaURBQXNCO0lBSXpELFlBQVksS0FBVSxFQUFFLEVBQVUsRUFBRSxLQUFVO1FBQzVDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXhCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLHFCQUFRLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1lBQzdELE9BQU8sRUFBRSxvQkFBTyxDQUFDLFdBQVc7WUFDNUIsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsVUFBVSxDQUFDLHFFQUFxRSxDQUFDO1NBQzdGLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUU7WUFDckQsT0FBTyxFQUFFLG9CQUFPLENBQUMsV0FBVztZQUM1QixPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsaUJBQUksQ0FBQyxVQUFVLENBQUMsaURBQWlELENBQUM7U0FDekUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLGtCQUFrQjtRQUMxQixPQUFPLElBQUksc0NBQVksQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLEVBQUU7WUFDbEQsY0FBYyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7WUFDckMsVUFBVSxFQUFFLHdC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bnRlbnQiOlsiaW1wb3J0IHsgQXBwLCBBc3BlY3RzLCBSZW1vdmFsUG9saWN5LCBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IEFubm90YXRpb25zLCBNYXRjaCB9IGZyb20gJ2F3cy1jZGstbGliL2Fzc2VydGlvbnMnO1xuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24sIFJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBMYW1iZGFJbnZva2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucy10YXNrcyc7XG5pbXBvcnQgeyBBd3NTb2x1dGlvbnNDaGVja3MsIE5hZ1N1cHByZXNzaW9ucyB9IGZyb20gJ2Nkay1uYWcnO1xuaW1wb3J0IHsgQWNjZXNzTG9nIH0gZnJvbSAnLi4vLi4vZnJhbWV3b3JrJztcbmltcG9ydCB7IFF1ZXVlZFMzQWRhcHRlciB9IGZyb20gJy4uL2FkYXB0ZXInO1xuaW1wb3J0IHsgQmFzZURvY3VtZW50UHJvY2Vzc2luZywgRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfSBmcm9tICcuLi9iYXNlLWRvY3VtZW50LXByb2Nlc3NpbmcnO1xuXG5jbGFzcyBUZXN0RG9jdW1lbnRQcm9jZXNzaW5nIGV4dGVuZHMgQmFzZURvY3VtZW50UHJvY2Vzc2luZyB7XG4gIHByaXZhdGUgY2xhc3NpZmljYXRpb25GbjogRnVuY3Rpb247XG4gIHByaXZhdGUgcHJvY2Vzc2luZ0ZuOiBGdW5jdGlvbjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogYW55LCBpZDogc3RyaW5nLCBwcm9wczogYW55KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLmNsYXNzaWZpY2F0aW9uRm4gPSBuZXcgRnVuY3Rpb24odGhpcywgJ0NsYXNzaWZpY2F0aW9uRm4nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKCdleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiAoeyBkb2N1bWVudENsYXNzaWZpY2F0aW9uOiBcIlRFU1RcIiB9KTsnKSxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvY2Vzc2luZ0ZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdQcm9jZXNzaW5nRm4nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKCdleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiAoeyByZXN1bHQ6IHt9IH0pOycpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNsYXNzaWZpY2F0aW9uU3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB7XG4gICAgcmV0dXJuIG5ldyBMYW1iZGFJbnZva2UodGhpcywgJ01vY2tDbGFzc2lmaWNhdGlvbicsIHtcbiAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNsYXNzaWZpY2F0aW9uRm4sXG4gICAgICByZXN1bHRQYXRoOiAnJC5jbGFzc2lmaWNhdGlvblJlc3VsdCcsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc2luZ1N0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUge1xuICAgIHJldHVybiBuZXcgTGFtYmRhSW52b2tlKHRoaXMsICdNb2NrUHJvY2Vzc2luZycsIHtcbiAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLnByb2Nlc3NpbmdGbixcbiAgICAgIHJlc3VsdFBhdGg6ICckLnByb2Nlc3NpbmdSZXN1bHQnLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGVucmljaG1lbnRTdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBvc3RQcm9jZXNzaW5nU3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVTdGF0ZU1hY2hpbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlU3RhdGVNYWNoaW5lQ3JlYXRpb24oJ3Rlc3Qtc3RhdGUtbWFjaGluZScpO1xuICB9XG59XG5cbmNvbnN0IGFwcCA9IG5ldyBBcHAoKTtcbmNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ1Rlc3RTdGFjaycsIHtcbiAgZW52OiB7XG4gICAgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsXG4gICAgcmVnaW9uOiAndXMtZWFzdC0xJyxcbiAgfSxcbn0pO1xuXG5jb25zdCBhY2Nlc3NMb2cgPSBuZXcgQWNjZXNzTG9nKHN0YWNrLCAnQWNjZXNzTG9nJyk7XG5jb25zdCBidWNrZXQgPSBuZXcgQnVja2V0KHN0YWNrLCAnUXVldWVkUzNBZGFwdGVyQnVja2V0Jywge1xuICBzZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0OiBhY2Nlc3NMb2cuYnVja2V0LFxuICBzZXJ2ZXJBY2Nlc3NMb2dzUHJlZml4OiBhY2Nlc3NMb2cuYnVja2V0UHJlZml4LFxuICBlbmZvcmNlU1NMOiB0cnVlLFxufSk7XG5cbmNvbnN0IGFkYXB0ZXIgPSBuZXcgUXVldWVkUzNBZGFwdGVyKHsgYnVja2V0IH0pO1xuY29uc3QgY29uc3RydWN0ID0gbmV3IFRlc3REb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdRdWV1ZWRTM0FkYXB0ZXJUZXN0Jywge1xuICBpbmdyZXNzQWRhcHRlcjogYWRhcHRlcixcbiAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICBlbmFibGVPYnNlcnZhYmlsaXR5OiB0cnVlLFxufSk7XG5jb25zdHJ1Y3QuY3JlYXRlU3RhdGVNYWNoaW5lKCk7XG5cbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9uc0J5UGF0aChcbiAgc3RhY2ssXG4gICcvVGVzdFN0YWNrL0J1Y2tldE5vdGlmaWNhdGlvbnNIYW5kbGVyMDUwYTA1ODdiNzU0NDU0N2JmMzI1ZjA5NGEzZGI4MzQvUm9sZScsXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU00JyxcbiAgICAgIHJlYXNvbjogJ0NESy1tYW5hZ2VkIEJ1Y2tldE5vdGlmaWNhdGlvbnNIYW5kbGVyIHJlcXVpcmVzIEFXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZSBmb3IgUzMgZXZlbnQgcHJvY2Vzc2luZycsXG4gICAgICBhcHBsaWVzVG86IFsnUG9saWN5Ojphcm46PEFXUzo6UGFydGl0aW9uPjppYW06OmF3czpwb2xpY3kvc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZSddLFxuICAgIH0sXG4gIF0sXG4pO1xuXG5OYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnMoXG4gIHN0YWNrLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNScsXG4gICAgICByZWFzb246ICdMYW1iZGEgZnVuY3Rpb25zIHJlcXVpcmUgd2lsZGNhcmQgYWNjZXNzIHRvIFMzIGJ1Y2tldCBvYmplY3RzIGZvciBkb2N1bWVudCBwcm9jZXNzaW5nJyxcbiAgICAgIGFwcGxpZXNUbzogWydSZXNvdXJjZTo6PFF1ZXVlZFMzQWRhcHRlckJ1Y2tldEU4QTlDN0YxLkFybj4vKiddLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG5OYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnMoXG4gIHN0YWNrLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNScsXG4gICAgICByZWFzb246ICdMYW1iZGEgbG9nIHN0cmVhbSBBUk4gaXMgb25seSBrbm93biBhdCBydW50aW1lLCB3aWxkY2FyZCByZXF1aXJlZCBmb3IgQ2xvdWRXYXRjaCBMb2dzIGFjY2VzcycsXG4gICAgfSxcbiAgXSxcbiAgdHJ1ZSxcbik7XG5cbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgIHJlYXNvbjogJ1N0ZXAgRnVuY3Rpb25zIHJlcXVpcmVzIHdpbGRjYXJkIHBlcm1pc3Npb25zIHRvIGludm9rZSBMYW1iZGEgZnVuY3Rpb25zIHdpdGggdmVyc2lvbi1zcGVjaWZpYyBBUk5zJyxcbiAgICB9LFxuICBdLFxuICB0cnVlLFxuKTtcblxuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUlBTTQnLFxuICAgICAgcmVhc29uOiAnVGVzdCBMYW1iZGEgZnVuY3Rpb25zIHVzZSBBV1MgbWFuYWdlZCBwb2xpY2llcyBmb3IgYmFzaWMgZXhlY3V0aW9uJyxcbiAgICAgIGFwcGxpZXNUbzogWydQb2xpY3k6OmFybjo8QVdTOjpQYXJ0aXRpb24+OmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJ10sXG4gICAgfSxcbiAgXSxcbiAgdHJ1ZSxcbik7XG5cbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1MMScsXG4gICAgICByZWFzb246ICdUZXN0IExhbWJkYSBmdW5jdGlvbnMgdXNlIE5vZGUuanMgMjAgd2hpY2ggaXMgYSBzdXBwb3J0ZWQgcnVudGltZScsXG4gICAgfSxcbiAgXSxcbiAgdHJ1ZSxcbik7XG5cbkFzcGVjdHMub2YoYXBwKS5hZGQobmV3IEF3c1NvbHV0aW9uc0NoZWNrcyh7IHZlcmJvc2U6IHRydWUgfSkpO1xuXG5jb25zdCB3YXJuaW5ncyA9IEFubm90YXRpb25zLmZyb21TdGFjayhzdGFjaykuZmluZFdhcm5pbmcoJyonLCBNYXRjaC5zdHJpbmdMaWtlUmVnZXhwKCdBd3NTb2x1dGlvbnMtLionKSk7XG5jb25zdCBlcnJvcnMgPSBBbm5vdGF0aW9ucy5mcm9tU3RhY2soc3RhY2spLmZpbmRFcnJvcignKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcblxudGVzdCgnTm8gdW5zdXBwcmVzc2VkIHdhcm5pbmdzJywgKCkgPT4ge1xuICBpZiAod2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgIGNvbnNvbGUubG9nKCdDREsgTmFnIFdhcm5pbmdzOicsIEpTT04uc3RyaW5naWZ5KHdhcm5pbmdzLCBudWxsLCAyKSk7XG4gIH1cbiAgZXhwZWN0KHdhcm5pbmdzKS50b0hhdmVMZW5ndGgoMCk7XG59KTtcblxudGVzdCgnTm8gdW5zdXBwcmVzc2VkIGVycm9ycycsICgpID0+IHtcbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgY29uc29sZS5sb2coJ0NESyBOYWcgRXJyb3JzOicsIEpTT04uc3RyaW5naWZ5KGVycm9ycywgbnVsbCwgMikpO1xuICB9XG4gIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKTtcbn0pO1xuIl19