@cdklabs/cdk-appmod-catalog-blueprints 1.2.2 → 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 (69) hide show
  1. package/.jsii +804 -173
  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.d.ts +5 -28
  5. package/lib/document-processing/agentic-document-processing.js +8 -63
  6. package/lib/document-processing/base-document-processing.js +4 -20
  7. package/lib/document-processing/bedrock-document-processing.d.ts +4 -32
  8. package/lib/document-processing/bedrock-document-processing.js +10 -37
  9. package/lib/document-processing/default-document-processing-config.js +1 -1
  10. package/lib/document-processing/tests/agentic-document-processing-nag.test.js +12 -11
  11. package/lib/document-processing/tests/agentic-document-processing.test.js +136 -67
  12. package/lib/document-processing/tests/base-document-processing-nag.test.d.ts +1 -0
  13. package/lib/document-processing/tests/base-document-processing-nag.test.js +161 -0
  14. package/lib/document-processing/tests/base-document-processing.test.d.ts +1 -0
  15. package/lib/document-processing/tests/base-document-processing.test.js +499 -0
  16. package/lib/document-processing/tests/bedrock-document-processing-nag.test.js +3 -2
  17. package/lib/document-processing/tests/bedrock-document-processing.test.js +221 -40
  18. package/lib/document-processing/tests/queued-s3-adapter-nag.test.d.ts +1 -0
  19. package/lib/document-processing/tests/queued-s3-adapter-nag.test.js +122 -0
  20. package/lib/document-processing/tests/queued-s3-adapter.test.d.ts +1 -0
  21. package/lib/document-processing/tests/queued-s3-adapter.test.js +276 -0
  22. package/lib/framework/agents/base-agent.d.ts +90 -0
  23. package/lib/framework/agents/base-agent.js +55 -0
  24. package/lib/framework/agents/batch-agent.d.ts +11 -0
  25. package/lib/framework/agents/batch-agent.js +64 -0
  26. package/lib/framework/agents/default-agent-config.d.ts +3 -0
  27. package/lib/framework/agents/default-agent-config.js +12 -0
  28. package/lib/framework/agents/index.d.ts +3 -0
  29. package/lib/framework/agents/index.js +20 -0
  30. package/lib/framework/agents/resources/default-strands-agent/batch.py +99 -0
  31. package/lib/framework/agents/resources/default-strands-agent/models.py +7 -0
  32. package/lib/framework/agents/resources/default-strands-agent/requirements.txt +7 -0
  33. package/lib/framework/agents/resources/default-strands-agent/utils.py +36 -0
  34. package/lib/framework/bedrock/bedrock.d.ts +38 -0
  35. package/lib/framework/bedrock/bedrock.js +54 -0
  36. package/lib/framework/bedrock/index.d.ts +1 -0
  37. package/lib/framework/bedrock/index.js +18 -0
  38. package/lib/framework/custom-resource/default-runtimes.js +1 -1
  39. package/lib/framework/foundation/access-log.js +1 -1
  40. package/lib/framework/foundation/eventbridge-broker.js +1 -1
  41. package/lib/framework/foundation/network.js +1 -1
  42. package/lib/framework/index.d.ts +2 -0
  43. package/lib/framework/index.js +3 -1
  44. package/lib/framework/tests/access-log.test.d.ts +1 -0
  45. package/lib/framework/tests/access-log.test.js +146 -0
  46. package/lib/framework/tests/batch-agent.test.d.ts +1 -0
  47. package/lib/framework/tests/batch-agent.test.js +164 -0
  48. package/lib/framework/tests/bedrock.test.d.ts +1 -0
  49. package/lib/framework/tests/bedrock.test.js +68 -0
  50. package/lib/framework/tests/eventbridge-broker.test.d.ts +1 -0
  51. package/lib/framework/tests/eventbridge-broker.test.js +73 -0
  52. package/lib/framework/tests/framework-nag.test.d.ts +1 -0
  53. package/lib/framework/tests/framework-nag.test.js +155 -0
  54. package/lib/framework/tests/network.test.d.ts +1 -0
  55. package/lib/framework/tests/network.test.js +120 -0
  56. package/lib/tsconfig.tsbuildinfo +1 -1
  57. package/lib/utilities/data-loader.js +1 -1
  58. package/lib/utilities/lambda-iam-utils.js +4 -3
  59. package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +1 -1
  60. package/lib/utilities/observability/default-observability-config.js +1 -1
  61. package/lib/utilities/observability/index.d.ts +1 -0
  62. package/lib/utilities/observability/index.js +2 -1
  63. package/lib/utilities/observability/lambda-observability-property-injector.js +1 -1
  64. package/lib/utilities/observability/log-group-data-protection-utils.d.ts +6 -0
  65. package/lib/utilities/observability/log-group-data-protection-utils.js +37 -0
  66. package/lib/utilities/observability/powertools-config.js +1 -1
  67. package/lib/utilities/observability/state-machine-observability-property-injector.js +1 -1
  68. package/lib/webapp/frontend-construct.js +1 -1
  69. package/package.json +8 -8
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("path");
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const assertions_1 = require("aws-cdk-lib/assertions");
6
+ const aws_bedrock_1 = require("aws-cdk-lib/aws-bedrock");
7
+ const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets");
8
+ const batch_agent_1 = require("../agents/batch-agent");
9
+ const network_1 = require("../foundation/network");
10
+ describe('BatchAgent', () => {
11
+ let stack;
12
+ let systemPrompt;
13
+ const testModel = aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0;
14
+ beforeEach(() => {
15
+ stack = new aws_cdk_lib_1.Stack(undefined, 'TestStack', {
16
+ env: { account: '123456789012', region: 'us-east-1' },
17
+ });
18
+ systemPrompt = new aws_s3_assets_1.Asset(stack, 'SystemPrompt', {
19
+ path: path.join(__dirname, '../agents/resources/default-strands-agent/batch.py'),
20
+ });
21
+ });
22
+ test('creates Lambda function with correct configuration', () => {
23
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
24
+ agentName: 'TestAgent',
25
+ prompt: 'Test prompt',
26
+ agentDefinition: {
27
+ bedrockModel: { fmModelId: testModel },
28
+ systemPrompt,
29
+ },
30
+ });
31
+ const template = assertions_1.Template.fromStack(stack);
32
+ template.resourceCountIs('AWS::Lambda::Function', 1);
33
+ template.hasResourceProperties('AWS::Lambda::Function', {
34
+ Runtime: assertions_1.Match.stringLikeRegexp('python3\\.1[23]'),
35
+ Timeout: 600,
36
+ MemorySize: 1024,
37
+ Environment: {
38
+ Variables: assertions_1.Match.objectLike({
39
+ MODEL_ID: testModel.modelId,
40
+ INVOKE_TYPE: 'batch',
41
+ PROMPT: 'Test prompt',
42
+ }),
43
+ },
44
+ });
45
+ });
46
+ test('creates IAM role with Bedrock permissions', () => {
47
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
48
+ agentName: 'TestAgent',
49
+ prompt: 'Test prompt',
50
+ agentDefinition: {
51
+ bedrockModel: { fmModelId: testModel },
52
+ systemPrompt,
53
+ },
54
+ });
55
+ const template = assertions_1.Template.fromStack(stack);
56
+ template.hasResourceProperties('AWS::IAM::Role', {
57
+ AssumeRolePolicyDocument: {
58
+ Statement: assertions_1.Match.arrayWith([
59
+ assertions_1.Match.objectLike({
60
+ Principal: { Service: 'lambda.amazonaws.com' },
61
+ }),
62
+ ]),
63
+ },
64
+ });
65
+ template.hasResourceProperties('AWS::IAM::Policy', {
66
+ PolicyDocument: {
67
+ Statement: assertions_1.Match.arrayWith([
68
+ assertions_1.Match.objectLike({
69
+ Action: assertions_1.Match.arrayWith(['bedrock:InvokeModel']),
70
+ }),
71
+ ]),
72
+ },
73
+ });
74
+ });
75
+ test('creates KMS key for environment encryption', () => {
76
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
77
+ agentName: 'TestAgent',
78
+ prompt: 'Test prompt',
79
+ agentDefinition: {
80
+ bedrockModel: { fmModelId: testModel },
81
+ systemPrompt,
82
+ },
83
+ });
84
+ const template = assertions_1.Template.fromStack(stack);
85
+ // At least one KMS key exists (agent encryption key, plus potentially asset deployment key)
86
+ const keys = template.findResources('AWS::KMS::Key');
87
+ expect(Object.keys(keys).length).toBeGreaterThanOrEqual(1);
88
+ // Verify at least one key has rotation enabled
89
+ const hasRotationEnabled = Object.values(keys).some((key) => key.Properties.EnableKeyRotation === true);
90
+ expect(hasRotationEnabled).toBe(true);
91
+ });
92
+ test('configures VPC when network provided', () => {
93
+ const network = new network_1.Network(stack, 'Network');
94
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
95
+ agentName: 'TestAgent',
96
+ prompt: 'Test prompt',
97
+ network,
98
+ agentDefinition: {
99
+ bedrockModel: { fmModelId: testModel },
100
+ systemPrompt,
101
+ },
102
+ });
103
+ const template = assertions_1.Template.fromStack(stack);
104
+ template.hasResourceProperties('AWS::Lambda::Function', {
105
+ VpcConfig: assertions_1.Match.objectLike({
106
+ SubnetIds: assertions_1.Match.anyValue(),
107
+ }),
108
+ });
109
+ });
110
+ test('sets EXPECT_JSON environment variable when expectJson is true', () => {
111
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
112
+ agentName: 'TestAgent',
113
+ prompt: 'Test prompt',
114
+ expectJson: true,
115
+ agentDefinition: {
116
+ bedrockModel: { fmModelId: testModel },
117
+ systemPrompt,
118
+ },
119
+ });
120
+ const template = assertions_1.Template.fromStack(stack);
121
+ template.hasResourceProperties('AWS::Lambda::Function', {
122
+ Environment: {
123
+ Variables: assertions_1.Match.objectLike({
124
+ EXPECT_JSON: 'True',
125
+ }),
126
+ },
127
+ });
128
+ });
129
+ test('enables observability with Powertools configuration', () => {
130
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
131
+ agentName: 'TestAgent',
132
+ prompt: 'Test prompt',
133
+ enableObservability: true,
134
+ agentDefinition: {
135
+ bedrockModel: { fmModelId: testModel },
136
+ systemPrompt,
137
+ },
138
+ });
139
+ const template = assertions_1.Template.fromStack(stack);
140
+ template.hasResourceProperties('AWS::Lambda::Function', {
141
+ Environment: {
142
+ Variables: assertions_1.Match.objectLike({
143
+ POWERTOOLS_SERVICE_NAME: assertions_1.Match.anyValue(),
144
+ POWERTOOLS_METRICS_NAMESPACE: assertions_1.Match.anyValue(),
145
+ }),
146
+ },
147
+ });
148
+ });
149
+ test('grants read access to system prompt asset', () => {
150
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
151
+ agentName: 'TestAgent',
152
+ prompt: 'Test prompt',
153
+ agentDefinition: {
154
+ bedrockModel: { fmModelId: testModel },
155
+ systemPrompt,
156
+ },
157
+ });
158
+ const template = assertions_1.Template.fromStack(stack);
159
+ // Verify that IAM policies exist (S3 permissions are granted via Asset construct)
160
+ const policies = template.findResources('AWS::IAM::Policy');
161
+ expect(Object.keys(policies).length).toBeGreaterThan(0);
162
+ });
163
+ });
164
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0Y2gtYWdlbnQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3VzZS1jYXNlcy9mcmFtZXdvcmsvdGVzdHMvYmF0Y2gtYWdlbnQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE2QjtBQUM3Qiw2Q0FBb0M7QUFDcEMsdURBQXlEO0FBQ3pELHlEQUFvRTtBQUNwRSw2REFBa0Q7QUFDbEQsdURBQW1EO0FBQ25ELG1EQUFnRDtBQUVoRCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtJQUMxQixJQUFJLEtBQVksQ0FBQztJQUNqQixJQUFJLFlBQW1CLENBQUM7SUFDeEIsTUFBTSxTQUFTLEdBQUcsdUNBQXlCLENBQUMsdUNBQXVDLENBQUM7SUFFcEYsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEtBQUssR0FBRyxJQUFJLG1CQUFLLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRTtZQUN4QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7U0FDdEQsQ0FBQyxDQUFDO1FBRUgsWUFBWSxHQUFHLElBQUkscUJBQUssQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFO1lBQzlDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxvREFBb0QsQ0FBQztTQUNqRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxvREFBb0QsRUFBRSxHQUFHLEVBQUU7UUFDOUQsSUFBSSx3QkFBVSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUU7WUFDN0IsU0FBUyxFQUFFLFdBQVc7WUFDdEIsTUFBTSxFQUFFLGFBQWE7WUFDckIsZUFBZSxFQUFFO2dCQUNmLFlBQVksRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUU7Z0JBQ3RDLFlBQVk7YUFDYjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFR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LENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgVGVtcGxhdGUsIE1hdGNoIH0gZnJvbSAnYXdzLWNkay1saWIvYXNzZXJ0aW9ucyc7XG5pbXBvcnQgeyBGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWJlZHJvY2snO1xuaW1wb3J0IHsgQXNzZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMtYXNzZXRzJztcbmltcG9ydCB7IEJhdGNoQWdlbnQgfSBmcm9tICcuLi9hZ2VudHMvYmF0Y2gtYWdlbnQnO1xuaW1wb3J0IHsgTmV0d29yayB9IGZyb20gJy4uL2ZvdW5kYXRpb24vbmV0d29yayc7XG5cbmRlc2NyaWJlKCdCYXRjaEFnZW50JywgKCkgPT4ge1xuICBsZXQgc3RhY2s6IFN0YWNrO1xuICBsZXQgc3lzdGVtUHJvbXB0OiBBc3NldDtcbiAgY29uc3QgdGVzdE1vZGVsID0gRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllci5BTlRIUk9QSUNfQ0xBVURFXzNfU09OTkVUXzIwMjQwMjI5X1YxXzA7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgc3RhY2sgPSBuZXcgU3RhY2sodW5kZWZpbmVkLCAnVGVzdFN0YWNrJywge1xuICAgICAgZW52OiB7IGFjY291bnQ6ICcxMjM0NTY3ODkwMTInLCByZWdpb246ICd1cy1lYXN0LTEnIH0sXG4gICAgfSk7XG5cbiAgICBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoc3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICBwYXRoOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vYWdlbnRzL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQvYmF0Y2gucHknKSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgdGVzdCgnY3JlYXRlcyBMYW1iZGEgZnVuY3Rpb24gd2l0aCBjb3JyZWN0IGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgbmV3IEJhdGNoQWdlbnQoc3RhY2ssICdBZ2VudCcsIHtcbiAgICAgIGFnZW50TmFtZTogJ1Rlc3RBZ2VudCcsXG4gICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgYmVkcm9ja01vZGVsOiB7IGZtTW9kZWxJZDogdGVzdE1vZGVsIH0sXG4gICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCAxKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgIFJ1bnRpbWU6IE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ3B5dGhvbjNcXFxcLjFbMjNdJyksXG4gICAgICBUaW1lb3V0OiA2MDAsXG4gICAgICBNZW1vcnlTaXplOiAxMDI0LFxuICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgVmFyaWFibGVzOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICBNT0RFTF9JRDogdGVzdE1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgSU5WT0tFX1RZUEU6ICdiYXRjaCcsXG4gICAgICAgICAgUFJPTVBUOiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2NyZWF0ZXMgSUFNIHJvbGUgd2l0aCBCZWRyb2NrIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgIG5ldyBCYXRjaEFnZW50KHN0YWNrLCAnQWdlbnQnLCB7XG4gICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgIGJlZHJvY2tNb2RlbDogeyBmbU1vZGVsSWQ6IHRlc3RNb2RlbCB9LFxuICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICBBc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgUHJpbmNpcGFsOiB7IFNlcnZpY2U6ICdsYW1iZGEuYW1hem9uYXdzLmNvbScgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6UG9saWN5Jywge1xuICAgICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgQWN0aW9uOiBNYXRjaC5hcnJheVdpdGgoWydiZWRyb2NrOkludm9rZU1vZGVsJ10pLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2NyZWF0ZXMgS01TIGtleSBmb3IgZW52aXJvbm1lbnQgZW5jcnlwdGlvbicsICgpID0+IHtcbiAgICBuZXcgQmF0Y2hBZ2VudChzdGFjaywgJ0FnZW50Jywge1xuICAgICAgYWdlbnROYW1lOiAnVGVzdEFnZW50JyxcbiAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICBiZWRyb2NrTW9kZWw6IHsgZm1Nb2RlbElkOiB0ZXN0TW9kZWwgfSxcbiAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAvLyBBdCBsZWFzdCBvbmUgS01TIGtleSBleGlzdHMgKGFnZW50IGVuY3J5cHRpb24ga2V5LCBwbHVzIHBvdGVudGlhbGx5IGFzc2V0IGRlcGxveW1lbnQga2V5KVxuICAgIGNvbnN0IGtleXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OktNUzo6S2V5Jyk7XG4gICAgZXhwZWN0KE9iamVjdC5rZXlzKGtleXMpLmxlbmd0aCkudG9CZUdyZWF0ZXJUaGFuT3JFcXVhbCgxKTtcblxuICAgIC8vIFZlcmlmeSBhdCBsZWFzdCBvbmUga2V5IGhhcyByb3RhdGlvbiBlbmFibGVkXG4gICAgY29uc3QgaGFzUm90YXRpb25FbmFibGVkID0gT2JqZWN0LnZhbHVlcyhrZXlzKS5zb21lKChrZXk6IGFueSkgPT5cbiAgICAgIGtleS5Qcm9wZXJ0aWVzLkVuYWJsZUtleVJvdGF0aW9uID09PSB0cnVlLFxuICAgICk7XG4gICAgZXhwZWN0KGhhc1JvdGF0aW9uRW5hYmxlZCkudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgdGVzdCgnY29uZmlndXJlcyBWUEMgd2hlbiBuZXR3b3JrIHByb3ZpZGVkJywgKCkgPT4ge1xuICAgIGNvbnN0IG5ldHdvcmsgPSBuZXcgTmV0d29yayhzdGFjaywgJ05ldHdvcmsnKTtcblxuICAgIG5ldyBCYXRjaEFnZW50KHN0YWNrLCAnQWdlbnQnLCB7XG4gICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgbmV0d29yayxcbiAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICBiZWRyb2NrTW9kZWw6IHsgZm1Nb2RlbElkOiB0ZXN0TW9kZWwgfSxcbiAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgIFZwY0NvbmZpZzogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgIFN1Ym5ldElkczogTWF0Y2guYW55VmFsdWUoKSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCdzZXRzIEVYUEVDVF9KU09OIGVudmlyb25tZW50IHZhcmlhYmxlIHdoZW4gZXhwZWN0SnNvbiBpcyB0cnVlJywgKCkgPT4ge1xuICAgIG5ldyBCYXRjaEFnZW50KHN0YWNrLCAnQWdlbnQnLCB7XG4gICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgZXhwZWN0SnNvbjogdHJ1ZSxcbiAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICBiZWRyb2NrTW9kZWw6IHsgZm1Nb2RlbElkOiB0ZXN0TW9kZWwgfSxcbiAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgIFZhcmlhYmxlczogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgRVhQRUNUX0pTT046ICdUcnVlJyxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCdlbmFibGVzIG9ic2VydmFiaWxpdHkgd2l0aCBQb3dlcnRvb2xzIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgbmV3IEJhdGNoQWdlbnQoc3RhY2ssICdBZ2VudCcsIHtcbiAgICAgIGFnZW50TmFtZTogJ1Rlc3RBZ2VudCcsXG4gICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICBlbmFibGVPYnNlcnZhYmlsaXR5OiB0cnVlLFxuICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgIGJlZHJvY2tNb2RlbDogeyBmbU1vZGVsSWQ6IHRlc3RNb2RlbCB9LFxuICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgVmFyaWFibGVzOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICBQT1dFUlRPT0xTX1NFUlZJQ0VfTkFNRTogTWF0Y2guYW55VmFsdWUoKSxcbiAgICAgICAgICBQT1dFUlRPT0xTX01FVFJJQ1NfTkFNRVNQQUNFOiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2dyYW50cyByZWFkIGFjY2VzcyB0byBzeXN0ZW0gcHJvbXB0IGFzc2V0JywgKCkgPT4ge1xuICAgIG5ldyBCYXRjaEFnZW50KHN0YWNrLCAnQWdlbnQnLCB7XG4gICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgIGJlZHJvY2tNb2RlbDogeyBmbU1vZGVsSWQ6IHRlc3RNb2RlbCB9LFxuICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIC8vIFZlcmlmeSB0aGF0IElBTSBwb2xpY2llcyBleGlzdCAoUzMgcGVybWlzc2lvbnMgYXJlIGdyYW50ZWQgdmlhIEFzc2V0IGNvbnN0cnVjdClcbiAgICBjb25zdCBwb2xpY2llcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6SUFNOjpQb2xpY3knKTtcbiAgICBleHBlY3QoT2JqZWN0LmtleXMocG9saWNpZXMpLmxlbmd0aCkudG9CZUdyZWF0ZXJUaGFuKDApO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
4
+ const aws_bedrock_1 = require("aws-cdk-lib/aws-bedrock");
5
+ const bedrock_1 = require("../bedrock/bedrock");
6
+ describe('BedrockModelUtils', () => {
7
+ let stack;
8
+ const testModel = aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0;
9
+ beforeEach(() => {
10
+ stack = new aws_cdk_lib_1.Stack(undefined, 'TestStack', {
11
+ env: { account: '123456789012', region: 'us-east-1' },
12
+ });
13
+ });
14
+ test('deriveActualModelId returns model ID without cross-region inference', () => {
15
+ const modelId = bedrock_1.BedrockModelUtils.deriveActualModelId({
16
+ fmModelId: testModel,
17
+ useCrossRegionInference: false,
18
+ });
19
+ expect(modelId).toBe(testModel.modelId);
20
+ });
21
+ test('deriveActualModelId returns prefixed model ID with cross-region inference', () => {
22
+ const modelId = bedrock_1.BedrockModelUtils.deriveActualModelId({
23
+ fmModelId: testModel,
24
+ useCrossRegionInference: true,
25
+ crossRegionInferencePrefix: bedrock_1.BedrockCrossRegionInferencePrefix.US,
26
+ });
27
+ expect(modelId).toBe(`us.${testModel.modelId}`);
28
+ });
29
+ test('deriveActualModelId uses EU prefix when specified', () => {
30
+ const modelId = bedrock_1.BedrockModelUtils.deriveActualModelId({
31
+ fmModelId: testModel,
32
+ useCrossRegionInference: true,
33
+ crossRegionInferencePrefix: bedrock_1.BedrockCrossRegionInferencePrefix.EU,
34
+ });
35
+ expect(modelId).toBe(`eu.${testModel.modelId}`);
36
+ });
37
+ test('deriveActualModelId uses default model when not specified', () => {
38
+ const modelId = bedrock_1.BedrockModelUtils.deriveActualModelId();
39
+ expect(modelId).toBe(aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_SONNET_4_20250514_V1_0.modelId);
40
+ });
41
+ test('generateModelIAMPermissions creates policy for foundation model', () => {
42
+ const policy = bedrock_1.BedrockModelUtils.generateModelIAMPermissions(stack, {
43
+ fmModelId: testModel,
44
+ });
45
+ const statement = policy.toJSON();
46
+ expect(statement.Effect).toBe('Allow');
47
+ expect(statement.Action).toEqual([
48
+ 'bedrock:InvokeModel',
49
+ 'bedrock:InvokeModelWithResponseStream',
50
+ ]);
51
+ expect(statement.Resource).toContainEqual(`arn:aws:bedrock:*::foundation-model/${testModel.modelId}`);
52
+ });
53
+ test('generateModelIAMPermissions includes inference profile ARN', () => {
54
+ const policy = bedrock_1.BedrockModelUtils.generateModelIAMPermissions(stack, {
55
+ fmModelId: testModel,
56
+ useCrossRegionInference: true,
57
+ crossRegionInferencePrefix: bedrock_1.BedrockCrossRegionInferencePrefix.US,
58
+ });
59
+ const statement = policy.toJSON();
60
+ expect(statement.Resource).toContainEqual(`arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.${testModel.modelId}`);
61
+ });
62
+ test('generateModelIAMPermissions uses default US prefix', () => {
63
+ const policy = bedrock_1.BedrockModelUtils.generateModelIAMPermissions(stack);
64
+ const statement = policy.toJSON();
65
+ expect(statement.Resource).toContainEqual(expect.stringContaining('inference-profile/us.'));
66
+ });
67
+ });
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9jay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL2ZyYW1ld29yay90ZXN0cy9iZWRyb2NrLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2Q0FBb0M7QUFDcEMseURBQW9FO0FBQ3BFLGdEQUEwRjtBQUUxRixRQUFRLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFO0lBQ2pDLElBQUksS0FBWSxDQUFDO0lBQ2pCLE1BQU0sU0FBUyxHQUFHLHVDQUF5QixDQUFDLHVDQUF1QyxDQUFDO0lBRXBGLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUU7WUFDeEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHFFQUFxRSxFQUFFLEdBQUcsRUFBRTtRQUMvRSxNQUFNLE9BQU8sR0FBRywyQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQztZQUNwRCxTQUFTLEVBQUUsU0FBUztZQUNwQix1QkFBdUIsRUFBRSxLQUFLO1NBQy9CLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDJFQUEyRSxFQUFFLEdBQUcsRUFBRTtRQUNyRixNQUFNLE9BQU8sR0FBRywyQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQztZQUNwRCxTQUFTLEVBQUUsU0FBUztZQUNwQix1QkFBdUIsRUFBRSxJQUFJO1lBQzdCLDBCQUEwQixFQUFFLDJDQUFpQyxDQUFDLEVBQUU7U0FDakUsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtRQUM3RCxNQUFNLE9BQU8sR0FBRywyQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQztZQUNwRCxTQUFTLEVBQUUsU0FBUztZQUNwQix1QkFBdUIsRUFBRSxJQUFJO1lBQzdCLDBCQUEwQixFQUFFLDJDQUFpQyxDQUFDLEVBQUU7U0FDakUsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDJEQUEyRCxFQUFFLEdBQUcsRUFBRTtRQUNyRSxNQUFNLE9BQU8sR0FBRywyQkFBaUIsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBRXhELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsdUNBQXlCLENBQUMsdUNBQXVDLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEcsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsaUVBQWlFLEVBQUUsR0FBRyxFQUFFO1FBQzNFLE1BQU0sTUFBTSxHQUFHLDJCQUFpQixDQUFDLDJCQUEyQixDQUFDLEtBQUssRUFBRTtZQUNsRSxTQUFTLEVBQUUsU0FBUztTQUNyQixDQUFDLENBQUM7UUFFSCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDL0IscUJBQXFCO1lBQ3JCLHVDQUF1QztTQUN4QyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLGNBQWMsQ0FDdkMsdUNBQXVDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FDM0QsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDREQUE0RCxFQUFFLEdBQUcsRUFBRTtRQUN0RSxNQUFNLE1BQU0sR0FBRywyQkFBaUIsQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLEVBQUU7WUFDbEUsU0FBUyxFQUFFLFNBQVM7WUFDcEIsdUJBQXVCLEVBQUUsSUFBSTtZQUM3QiwwQkFBMEIsRUFBRSwyQ0FBaUMsQ0FBQyxFQUFFO1NBQ2pFLENBQUMsQ0FBQztRQUVILE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNsQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLGNBQWMsQ0FDdkMsK0RBQStELFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FDbkYsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEdBQUcsRUFBRTtRQUM5RCxNQUFNLE1BQU0sR0FBRywyQkFBaUIsQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVwRSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxjQUFjLENBQ3ZDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUNqRCxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllciB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1iZWRyb2NrJztcbmltcG9ydCB7IEJlZHJvY2tDcm9zc1JlZ2lvbkluZmVyZW5jZVByZWZpeCwgQmVkcm9ja01vZGVsVXRpbHMgfSBmcm9tICcuLi9iZWRyb2NrL2JlZHJvY2snO1xuXG5kZXNjcmliZSgnQmVkcm9ja01vZGVsVXRpbHMnLCAoKSA9PiB7XG4gIGxldCBzdGFjazogU3RhY2s7XG4gIGNvbnN0IHRlc3RNb2RlbCA9IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIuQU5USFJPUElDX0NMQVVERV8zX1NPTk5FVF8yMDI0MDIyOV9WMV8wO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIHN0YWNrID0gbmV3IFN0YWNrKHVuZGVmaW5lZCwgJ1Rlc3RTdGFjaycsIHtcbiAgICAgIGVudjogeyBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJywgcmVnaW9uOiAndXMtZWFzdC0xJyB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCdkZXJpdmVBY3R1YWxNb2RlbElkIHJldHVybnMgbW9kZWwgSUQgd2l0aG91dCBjcm9zcy1yZWdpb24gaW5mZXJlbmNlJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsSWQgPSBCZWRyb2NrTW9kZWxVdGlscy5kZXJpdmVBY3R1YWxNb2RlbElkKHtcbiAgICAgIGZtTW9kZWxJZDogdGVzdE1vZGVsLFxuICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KG1vZGVsSWQpLnRvQmUodGVzdE1vZGVsLm1vZGVsSWQpO1xuICB9KTtcblxuICB0ZXN0KCdkZXJpdmVBY3R1YWxNb2RlbElkIHJldHVybnMgcHJlZml4ZWQgbW9kZWwgSUQgd2l0aCBjcm9zcy1yZWdpb24gaW5mZXJlbmNlJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsSWQgPSBCZWRyb2NrTW9kZWxVdGlscy5kZXJpdmVBY3R1YWxNb2RlbElkKHtcbiAgICAgIGZtTW9kZWxJZDogdGVzdE1vZGVsLFxuICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IHRydWUsXG4gICAgICBjcm9zc1JlZ2lvbkluZmVyZW5jZVByZWZpeDogQmVkcm9ja0Nyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4LlVTLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KG1vZGVsSWQpLnRvQmUoYHVzLiR7dGVzdE1vZGVsLm1vZGVsSWR9YCk7XG4gIH0pO1xuXG4gIHRlc3QoJ2Rlcml2ZUFjdHVhbE1vZGVsSWQgdXNlcyBFVSBwcmVmaXggd2hlbiBzcGVjaWZpZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9kZWxJZCA9IEJlZHJvY2tNb2RlbFV0aWxzLmRlcml2ZUFjdHVhbE1vZGVsSWQoe1xuICAgICAgZm1Nb2RlbElkOiB0ZXN0TW9kZWwsXG4gICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogdHJ1ZSxcbiAgICAgIGNyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4OiBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXguRVUsXG4gICAgfSk7XG5cbiAgICBleHBlY3QobW9kZWxJZCkudG9CZShgZXUuJHt0ZXN0TW9kZWwubW9kZWxJZH1gKTtcbiAgfSk7XG5cbiAgdGVzdCgnZGVyaXZlQWN0dWFsTW9kZWxJZCB1c2VzIGRlZmF1bHQgbW9kZWwgd2hlbiBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vZGVsSWQgPSBCZWRyb2NrTW9kZWxVdGlscy5kZXJpdmVBY3R1YWxNb2RlbElkKCk7XG5cbiAgICBleHBlY3QobW9kZWxJZCkudG9CZShGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyLkFOVEhST1BJQ19DTEFVREVfU09OTkVUXzRfMjAyNTA1MTRfVjFfMC5tb2RlbElkKTtcbiAgfSk7XG5cbiAgdGVzdCgnZ2VuZXJhdGVNb2RlbElBTVBlcm1pc3Npb25zIGNyZWF0ZXMgcG9saWN5IGZvciBmb3VuZGF0aW9uIG1vZGVsJywgKCkgPT4ge1xuICAgIGNvbnN0IHBvbGljeSA9IEJlZHJvY2tNb2RlbFV0aWxzLmdlbmVyYXRlTW9kZWxJQU1QZXJtaXNzaW9ucyhzdGFjaywge1xuICAgICAgZm1Nb2RlbElkOiB0ZXN0TW9kZWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBwb2xpY3kudG9KU09OKCk7XG4gICAgZXhwZWN0KHN0YXRlbWVudC5FZmZlY3QpLnRvQmUoJ0FsbG93Jyk7XG4gICAgZXhwZWN0KHN0YXRlbWVudC5BY3Rpb24pLnRvRXF1YWwoW1xuICAgICAgJ2JlZHJvY2s6SW52b2tlTW9kZWwnLFxuICAgICAgJ2JlZHJvY2s6SW52b2tlTW9kZWxXaXRoUmVzcG9uc2VTdHJlYW0nLFxuICAgIF0pO1xuICAgIGV4cGVjdChzdGF0ZW1lbnQuUmVzb3VyY2UpLnRvQ29udGFpbkVxdWFsKFxuICAgICAgYGFybjphd3M6YmVkcm9jazoqOjpmb3VuZGF0aW9uLW1vZGVsLyR7dGVzdE1vZGVsLm1vZGVsSWR9YCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KCdnZW5lcmF0ZU1vZGVsSUFNUGVybWlzc2lvbnMgaW5jbHVkZXMgaW5mZXJlbmNlIHByb2ZpbGUgQVJOJywgKCkgPT4ge1xuICAgIGNvbnN0IHBvbGljeSA9IEJlZHJvY2tNb2RlbFV0aWxzLmdlbmVyYXRlTW9kZWxJQU1QZXJtaXNzaW9ucyhzdGFjaywge1xuICAgICAgZm1Nb2RlbElkOiB0ZXN0TW9kZWwsXG4gICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogdHJ1ZSxcbiAgICAgIGNyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4OiBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXguVVMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBwb2xpY3kudG9KU09OKCk7XG4gICAgZXhwZWN0KHN0YXRlbWVudC5SZXNvdXJjZSkudG9Db250YWluRXF1YWwoXG4gICAgICBgYXJuOmF3czpiZWRyb2NrOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6aW5mZXJlbmNlLXByb2ZpbGUvdXMuJHt0ZXN0TW9kZWwubW9kZWxJZH1gLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoJ2dlbmVyYXRlTW9kZWxJQU1QZXJtaXNzaW9ucyB1c2VzIGRlZmF1bHQgVVMgcHJlZml4JywgKCkgPT4ge1xuICAgIGNvbnN0IHBvbGljeSA9IEJlZHJvY2tNb2RlbFV0aWxzLmdlbmVyYXRlTW9kZWxJQU1QZXJtaXNzaW9ucyhzdGFjayk7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBwb2xpY3kudG9KU09OKCk7XG4gICAgZXhwZWN0KHN0YXRlbWVudC5SZXNvdXJjZSkudG9Db250YWluRXF1YWwoXG4gICAgICBleHBlY3Quc3RyaW5nQ29udGFpbmluZygnaW5mZXJlbmNlLXByb2ZpbGUvdXMuJyksXG4gICAgKTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,73 @@
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_kms_1 = require("aws-cdk-lib/aws-kms");
6
+ const eventbridge_broker_1 = require("../foundation/eventbridge-broker");
7
+ describe('EventbridgeBroker', () => {
8
+ let stack;
9
+ beforeEach(() => {
10
+ stack = new aws_cdk_lib_1.Stack();
11
+ });
12
+ test('creates EventBus with KMS encryption', () => {
13
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
14
+ eventSource: 'test.source',
15
+ });
16
+ const template = assertions_1.Template.fromStack(stack);
17
+ template.resourceCountIs('AWS::Events::EventBus', 1);
18
+ template.resourceCountIs('AWS::KMS::Key', 1);
19
+ template.hasResourceProperties('AWS::KMS::Key', {
20
+ EnableKeyRotation: true,
21
+ });
22
+ });
23
+ test('uses custom KMS key when provided', () => {
24
+ const customKey = new aws_kms_1.Key(stack, 'CustomKey');
25
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
26
+ eventSource: 'test.source',
27
+ kmsKey: customKey,
28
+ });
29
+ const template = assertions_1.Template.fromStack(stack);
30
+ template.resourceCountIs('AWS::KMS::Key', 1);
31
+ });
32
+ test('sets custom event bus name', () => {
33
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
34
+ eventSource: 'test.source',
35
+ name: 'CustomEventBus',
36
+ });
37
+ const template = assertions_1.Template.fromStack(stack);
38
+ template.hasResourceProperties('AWS::Events::EventBus', {
39
+ Name: 'CustomEventBus',
40
+ });
41
+ });
42
+ test('applies RETAIN removal policy', () => {
43
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
44
+ eventSource: 'test.source',
45
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.RETAIN,
46
+ });
47
+ const template = assertions_1.Template.fromStack(stack);
48
+ template.hasResource('AWS::KMS::Key', {
49
+ DeletionPolicy: 'Retain',
50
+ });
51
+ });
52
+ test('applies DESTROY removal policy by default', () => {
53
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
54
+ eventSource: 'test.source',
55
+ });
56
+ const template = assertions_1.Template.fromStack(stack);
57
+ template.hasResource('AWS::KMS::Key', {
58
+ DeletionPolicy: 'Delete',
59
+ });
60
+ });
61
+ test('sendViaSfnChain creates EventBridge PutEvents task', () => {
62
+ const broker = new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
63
+ eventSource: 'test.source',
64
+ });
65
+ const task = broker.sendViaSfnChain('TestEvent', { key: 'value' });
66
+ expect(task).toBeDefined();
67
+ const stateJson = task.toStateJson();
68
+ expect(stateJson.Type).toBe('Task');
69
+ expect(stateJson.Parameters.Entries[0].Source).toBe('test.source');
70
+ expect(stateJson.Parameters.Entries[0].DetailType).toBe('TestEvent');
71
+ });
72
+ });
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRicmlkZ2UtYnJva2VyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZnJhbWV3b3JrL3Rlc3RzL2V2ZW50YnJpZGdlLWJyb2tlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQW1EO0FBQ25ELHVEQUFrRDtBQUNsRCxpREFBMEM7QUFDMUMseUVBQXFFO0FBRXJFLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUU7SUFDakMsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsSUFBSSxzQ0FBaUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ3JDLFdBQVcsRUFBRSxhQUFhO1NBQzNCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckQsUUFBUSxDQUFDLGVBQWUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFN0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLGVBQWUsRUFBRTtZQUM5QyxpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsRUFBRTtRQUM3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLGFBQUcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDOUMsSUFBSSxzQ0FBaUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ3JDLFdBQVcsRUFBRSxhQUFhO1lBQzFCLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDRCQUE0QixFQUFFLEdBQUcsRUFBRTtRQUN0QyxJQUFJLHNDQUFpQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUU7WUFDckMsV0FBVyxFQUFFLGFBQWE7WUFDMUIsSUFBSSxFQUFFLGdCQUFnQjtTQUN2QixDQUFDLENBQUM7UUFFSCxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLEVBQUU7WUFDdEQsSUFBSSxFQUFFLGdCQUFnQjtTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7UUFDekMsSUFBSSxzQ0FBaUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ3JDLFdBQVcsRUFBRSxhQUFhO1lBQzFCLGFBQWEsRUFBRSwyQkFBYSxDQUFDLE1BQU07U0FDcEMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsUUFBUSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUU7WUFDcEMsY0FBYyxFQUFFLFFBQVE7U0FDekIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1FBQ3JELElBQUksc0NBQWlCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRTtZQUNyQyxXQUFXLEVBQUUsYUFBYTtTQUMzQixDQUFDLENBQUM7UUFFSCxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxRQUFRLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRTtZQUNwQyxjQUFjLEVBQUUsUUFBUTtTQUN6QixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxvREFBb0QsRUFBRSxHQUFHLEVBQUU7UUFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxzQ0FBaUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ3BELFdBQVcsRUFBRSxhQUFhO1NBQzNCLENBQUMsQ0FBQztRQUVILE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFbkUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQVMsQ0FBQztRQUM1QyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdkUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlbW92YWxQb2xpY3ksIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IEtleSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1rbXMnO1xuaW1wb3J0IHsgRXZlbnRicmlkZ2VCcm9rZXIgfSBmcm9tICcuLi9mb3VuZGF0aW9uL2V2ZW50YnJpZGdlLWJyb2tlcic7XG5cbmRlc2NyaWJlKCdFdmVudGJyaWRnZUJyb2tlcicsICgpID0+IHtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBzdGFjayA9IG5ldyBTdGFjaygpO1xuICB9KTtcblxuICB0ZXN0KCdjcmVhdGVzIEV2ZW50QnVzIHdpdGggS01TIGVuY3J5cHRpb24nLCAoKSA9PiB7XG4gICAgbmV3IEV2ZW50YnJpZGdlQnJva2VyKHN0YWNrLCAnQnJva2VyJywge1xuICAgICAgZXZlbnRTb3VyY2U6ICd0ZXN0LnNvdXJjZScsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkV2ZW50czo6RXZlbnRCdXMnLCAxKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6S01TOjpLZXknLCAxKTtcblxuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpLTVM6OktleScsIHtcbiAgICAgIEVuYWJsZUtleVJvdGF0aW9uOiB0cnVlLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCd1c2VzIGN1c3RvbSBLTVMga2V5IHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgY3VzdG9tS2V5ID0gbmV3IEtleShzdGFjaywgJ0N1c3RvbUtleScpO1xuICAgIG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ0Jyb2tlcicsIHtcbiAgICAgIGV2ZW50U291cmNlOiAndGVzdC5zb3VyY2UnLFxuICAgICAga21zS2V5OiBjdXN0b21LZXksXG4gICAgfSk7XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OktNUzo6S2V5JywgMSk7XG4gIH0pO1xuXG4gIHRlc3QoJ3NldHMgY3VzdG9tIGV2ZW50IGJ1cyBuYW1lJywgKCkgPT4ge1xuICAgIG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ0Jyb2tlcicsIHtcbiAgICAgIGV2ZW50U291cmNlOiAndGVzdC5zb3VyY2UnLFxuICAgICAgbmFtZTogJ0N1c3RvbUV2ZW50QnVzJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RXZlbnRzOjpFdmVudEJ1cycsIHtcbiAgICAgIE5hbWU6ICdDdXN0b21FdmVudEJ1cycsXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2FwcGxpZXMgUkVUQUlOIHJlbW92YWwgcG9saWN5JywgKCkgPT4ge1xuICAgIG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ0Jyb2tlcicsIHtcbiAgICAgIGV2ZW50U291cmNlOiAndGVzdC5zb3VyY2UnLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5SRVRBSU4sXG4gICAgfSk7XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgdGVtcGxhdGUuaGFzUmVzb3VyY2UoJ0FXUzo6S01TOjpLZXknLCB7XG4gICAgICBEZWxldGlvblBvbGljeTogJ1JldGFpbicsXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2FwcGxpZXMgREVTVFJPWSByZW1vdmFsIHBvbGljeSBieSBkZWZhdWx0JywgKCkgPT4ge1xuICAgIG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ0Jyb2tlcicsIHtcbiAgICAgIGV2ZW50U291cmNlOiAndGVzdC5zb3VyY2UnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlKCdBV1M6OktNUzo6S2V5Jywge1xuICAgICAgRGVsZXRpb25Qb2xpY3k6ICdEZWxldGUnLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KCdzZW5kVmlhU2ZuQ2hhaW4gY3JlYXRlcyBFdmVudEJyaWRnZSBQdXRFdmVudHMgdGFzaycsICgpID0+IHtcbiAgICBjb25zdCBicm9rZXIgPSBuZXcgRXZlbnRicmlkZ2VCcm9rZXIoc3RhY2ssICdCcm9rZXInLCB7XG4gICAgICBldmVudFNvdXJjZTogJ3Rlc3Quc291cmNlJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRhc2sgPSBicm9rZXIuc2VuZFZpYVNmbkNoYWluKCdUZXN0RXZlbnQnLCB7IGtleTogJ3ZhbHVlJyB9KTtcblxuICAgIGV4cGVjdCh0YXNrKS50b0JlRGVmaW5lZCgpO1xuICAgIGNvbnN0IHN0YXRlSnNvbiA9IHRhc2sudG9TdGF0ZUpzb24oKSBhcyBhbnk7XG4gICAgZXhwZWN0KHN0YXRlSnNvbi5UeXBlKS50b0JlKCdUYXNrJyk7XG4gICAgZXhwZWN0KHN0YXRlSnNvbi5QYXJhbWV0ZXJzLkVudHJpZXNbMF0uU291cmNlKS50b0JlKCd0ZXN0LnNvdXJjZScpO1xuICAgIGV4cGVjdChzdGF0ZUpzb24uUGFyYW1ldGVycy5FbnRyaWVzWzBdLkRldGFpbFR5cGUpLnRvQmUoJ1Rlc3RFdmVudCcpO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("path");
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const assertions_1 = require("aws-cdk-lib/assertions");
6
+ const aws_bedrock_1 = require("aws-cdk-lib/aws-bedrock");
7
+ const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets");
8
+ const cdk_nag_1 = require("cdk-nag");
9
+ const batch_agent_1 = require("../agents/batch-agent");
10
+ const access_log_1 = require("../foundation/access-log");
11
+ const eventbridge_broker_1 = require("../foundation/eventbridge-broker");
12
+ const network_1 = require("../foundation/network");
13
+ const testModel = aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0;
14
+ describe('Framework CDK Nag Tests', () => {
15
+ describe('AccessLog', () => {
16
+ test('passes CDK Nag checks', () => {
17
+ const stack = new aws_cdk_lib_1.Stack(undefined, 'TestStack', {
18
+ env: { account: '123456789012', region: 'us-east-1' },
19
+ });
20
+ new access_log_1.AccessLog(stack, 'AccessLog');
21
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
22
+ cdk_nag_1.NagSuppressions.addStackSuppressions(stack, [
23
+ {
24
+ id: 'AwsSolutions-S1',
25
+ reason: 'Access log bucket does not need its own access logging to avoid circular dependency',
26
+ },
27
+ ]);
28
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
29
+ expect(errors).toHaveLength(0);
30
+ });
31
+ });
32
+ describe('Network', () => {
33
+ test('passes CDK Nag checks for public VPC', () => {
34
+ const stack = new aws_cdk_lib_1.Stack();
35
+ new network_1.Network(stack, 'Network');
36
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
37
+ cdk_nag_1.NagSuppressions.addStackSuppressions(stack, [
38
+ {
39
+ id: 'AwsSolutions-VPC7',
40
+ reason: 'VPC Flow Logs are optional and should be enabled by users based on requirements',
41
+ },
42
+ ]);
43
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
44
+ expect(errors).toHaveLength(0);
45
+ });
46
+ test('passes CDK Nag checks for private VPC', () => {
47
+ const stack = new aws_cdk_lib_1.Stack();
48
+ new network_1.Network(stack, 'Network', { private: true });
49
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
50
+ cdk_nag_1.NagSuppressions.addStackSuppressions(stack, [
51
+ {
52
+ id: 'AwsSolutions-VPC7',
53
+ reason: 'VPC Flow Logs are optional and should be enabled by users based on requirements',
54
+ },
55
+ ]);
56
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
57
+ expect(errors).toHaveLength(0);
58
+ });
59
+ });
60
+ describe('EventbridgeBroker', () => {
61
+ test('passes CDK Nag checks', () => {
62
+ const stack = new aws_cdk_lib_1.Stack();
63
+ new eventbridge_broker_1.EventbridgeBroker(stack, 'Broker', {
64
+ eventSource: 'test.source',
65
+ });
66
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
67
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
68
+ expect(errors).toHaveLength(0);
69
+ });
70
+ });
71
+ describe('BatchAgent', () => {
72
+ test('passes CDK Nag checks', () => {
73
+ const stack = new aws_cdk_lib_1.Stack(undefined, 'TestStack', {
74
+ env: { account: '123456789012', region: 'us-east-1' },
75
+ });
76
+ const systemPrompt = new aws_s3_assets_1.Asset(stack, 'SystemPrompt', {
77
+ path: path.join(__dirname, '../agents/resources/default-strands-agent/batch.py'),
78
+ });
79
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
80
+ agentName: 'TestAgent',
81
+ prompt: 'Test prompt',
82
+ agentDefinition: {
83
+ bedrockModel: { fmModelId: testModel },
84
+ systemPrompt,
85
+ },
86
+ });
87
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
88
+ cdk_nag_1.NagSuppressions.addStackSuppressions(stack, [
89
+ {
90
+ id: 'AwsSolutions-IAM4',
91
+ reason: 'Managed policies are acceptable for Lambda execution role',
92
+ appliesTo: ['Policy::arn:<AWS::Partition>:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'],
93
+ },
94
+ {
95
+ id: 'AwsSolutions-IAM5',
96
+ reason: 'Wildcard permissions required for S3 asset access, Bedrock model invocation, and CloudWatch Logs',
97
+ appliesTo: [
98
+ 'Action::s3:GetObject*',
99
+ 'Action::s3:GetBucket*',
100
+ 'Action::s3:List*',
101
+ 'Resource::*',
102
+ 'Resource::arn:aws:bedrock:*::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0',
103
+ 'Resource::arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/TestAgent-teststackagentaa2af0c4:*',
104
+ ],
105
+ },
106
+ {
107
+ id: 'AwsSolutions-L1',
108
+ reason: 'Lambda runtime is managed by construct defaults',
109
+ },
110
+ ]);
111
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
112
+ expect(errors).toHaveLength(0);
113
+ });
114
+ test('passes CDK Nag checks with VPC configuration', () => {
115
+ const stack = new aws_cdk_lib_1.Stack(undefined, 'TestStack', {
116
+ env: { account: '123456789012', region: 'us-east-1' },
117
+ });
118
+ const network = new network_1.Network(stack, 'Network');
119
+ const systemPrompt = new aws_s3_assets_1.Asset(stack, 'SystemPrompt', {
120
+ path: path.join(__dirname, '../agents/resources/default-strands-agent/batch.py'),
121
+ });
122
+ new batch_agent_1.BatchAgent(stack, 'Agent', {
123
+ agentName: 'TestAgent',
124
+ prompt: 'Test prompt',
125
+ network,
126
+ agentDefinition: {
127
+ bedrockModel: { fmModelId: testModel },
128
+ systemPrompt,
129
+ },
130
+ });
131
+ aws_cdk_lib_1.Aspects.of(stack).add(new cdk_nag_1.AwsSolutionsChecks({ verbose: true }));
132
+ cdk_nag_1.NagSuppressions.addStackSuppressions(stack, [
133
+ {
134
+ id: 'AwsSolutions-IAM4',
135
+ reason: 'Managed policies are acceptable for Lambda execution role',
136
+ },
137
+ {
138
+ id: 'AwsSolutions-IAM5',
139
+ reason: 'Wildcard permissions required for VPC, S3, and Bedrock access',
140
+ },
141
+ {
142
+ id: 'AwsSolutions-L1',
143
+ reason: 'Lambda runtime is managed by construct defaults',
144
+ },
145
+ {
146
+ id: 'AwsSolutions-VPC7',
147
+ reason: 'VPC Flow Logs are optional',
148
+ },
149
+ ]);
150
+ const errors = assertions_1.Annotations.fromStack(stack).findError('*', assertions_1.Match.stringLikeRegexp('AwsSolutions-.*'));
151
+ expect(errors).toHaveLength(0);
152
+ });
153
+ });
154
+ });
155
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhbWV3b3JrLW5hZy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL2ZyYW1ld29yay90ZXN0cy9mcmFtZXdvcmstbmFnLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNkI7QUFDN0IsNkNBQTZDO0FBQzdDLHVEQUE0RDtBQUM1RCx5REFBb0U7QUFDcEUsNkRBQWtEO0FBQ2xELHFDQUE4RDtBQUM5RCx1REFBbUQ7QUFDbkQseURBQXFEO0FBQ3JELHlFQUFxRTtBQUNyRSxtREFBZ0Q7QUFFaEQsTUFBTSxTQUFTLEdBQUcsdUNBQXlCLENBQUMsdUNBQXVDLENBQUM7QUFFcEYsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRTtJQUN2QyxRQUFRLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRTtRQUN6QixJQUFJLENBQUMsdUJBQXVCLEVBQUUsR0FBRyxFQUFFO1lBQ2pDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFO2dCQUM5QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7YUFDdEQsQ0FBQyxDQUFDO1lBRUgsSUFBSSxzQkFBUyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztZQUVsQyxxQkFBTyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSw0QkFBa0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFakUseUJBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUU7Z0JBQzFDO29CQUNFLEVBQUUsRUFBRSxpQkFBaUI7b0JBQ3JCLE1BQU0sRUFBRSxxRkFBcUY7aUJBQzlGO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxNQUFNLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENB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YjthQUNGLENBQUMsQ0FBQztZQUVILHFCQUFPLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLDRCQUFrQixDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUVqRSx5QkFBZSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRTtnQkFDMUM7b0JBQ0UsRUFBRSxFQUFFLG1CQUFtQjtvQkFDdkIsTUFBTSxFQUFFLDJEQUEyRDtpQkFDcEU7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLG1CQUFtQjtvQkFDdkIsTUFBTSxFQUFFLCtEQUErRDtpQkFDeEU7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLGlCQUFpQjtvQkFDckIsTUFBTSxFQUFFLGlEQUFpRDtpQkFDMUQ7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLG1CQUFtQjtvQkFDdkIsTUFBTSxFQUFFLDRCQUE0QjtpQkFDckM7YUFDRixDQUFDLENBQUM7WUFFSCxNQUFNLE1BQU0sR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLGtCQUFLLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1lBQ3RHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEFzcGVjdHMsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQW5ub3RhdGlvbnMsIE1hdGNoIH0gZnJvbSAnYXdzLWNkay1saWIvYXNzZXJ0aW9ucyc7XG5pbXBvcnQgeyBGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWJlZHJvY2snO1xuaW1wb3J0IHsgQXNzZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMtYXNzZXRzJztcbmltcG9ydCB7IEF3c1NvbHV0aW9uc0NoZWNrcywgTmFnU3VwcHJlc3Npb25zIH0gZnJvbSAnY2RrLW5hZyc7XG5pbXBvcnQgeyBCYXRjaEFnZW50IH0gZnJvbSAnLi4vYWdlbnRzL2JhdGNoLWFnZW50JztcbmltcG9ydCB7IEFjY2Vzc0xvZyB9IGZyb20gJy4uL2ZvdW5kYXRpb24vYWNjZXNzLWxvZyc7XG5pbXBvcnQgeyBFdmVudGJyaWRnZUJyb2tlciB9IGZyb20gJy4uL2ZvdW5kYXRpb24vZXZlbnRicmlkZ2UtYnJva2VyJztcbmltcG9ydCB7IE5ldHdvcmsgfSBmcm9tICcuLi9mb3VuZGF0aW9uL25ldHdvcmsnO1xuXG5jb25zdCB0ZXN0TW9kZWwgPSBGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyLkFOVEhST1BJQ19DTEFVREVfM19TT05ORVRfMjAyNDAyMjlfVjFfMDtcblxuZGVzY3JpYmUoJ0ZyYW1ld29yayBDREsgTmFnIFRlc3RzJywgKCkgPT4ge1xuICBkZXNjcmliZSgnQWNjZXNzTG9nJywgKCkgPT4ge1xuICAgIHRlc3QoJ3Bhc3NlcyBDREsgTmFnIGNoZWNrcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHVuZGVmaW5lZCwgJ1Rlc3RTdGFjaycsIHtcbiAgICAgICAgZW52OiB7IGFjY291bnQ6ICcxMjM0NTY3ODkwMTInLCByZWdpb246ICd1cy1lYXN0LTEnIH0sXG4gICAgICB9KTtcblxuICAgICAgbmV3IEFjY2Vzc0xvZyhzdGFjaywgJ0FjY2Vzc0xvZycpO1xuXG4gICAgICBBc3BlY3RzLm9mKHN0YWNrKS5hZGQobmV3IEF3c1NvbHV0aW9uc0NoZWNrcyh7IHZlcmJvc2U6IHRydWUgfSkpO1xuXG4gICAgICBOYWdTdXBwcmVzc2lvbnMuYWRkU3RhY2tTdXBwcmVzc2lvbnMoc3RhY2ssIFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnQXdzU29sdXRpb25zLVMxJyxcbiAgICAgICAgICByZWFzb246ICdBY2Nlc3MgbG9nIGJ1Y2tldCBkb2VzIG5vdCBuZWVkIGl0cyBvd24gYWNjZXNzIGxvZ2dpbmcgdG8gYXZvaWQgY2lyY3VsYXIgZGVwZW5kZW5jeScsXG4gICAgICAgIH0sXG4gICAgICBdKTtcblxuICAgICAgY29uc3QgZXJyb3JzID0gQW5ub3RhdGlvbnMuZnJvbVN0YWNrKHN0YWNrKS5maW5kRXJyb3IoJyonLCBNYXRjaC5zdHJpbmdMaWtlUmVnZXhwKCdBd3NTb2x1dGlvbnMtLionKSk7XG4gICAgICBleHBlY3QoZXJyb3JzKS50b0hhdmVMZW5ndGgoMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdOZXR3b3JrJywgKCkgPT4ge1xuICAgIHRlc3QoJ3Bhc3NlcyBDREsgTmFnIGNoZWNrcyBmb3IgcHVibGljIFZQQycsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgICBuZXcgTmV0d29yayhzdGFjaywgJ05ldHdvcmsnKTtcblxuICAgICAgQXNwZWN0cy5vZihzdGFjaykuYWRkKG5ldyBBd3NTb2x1dGlvbnNDaGVja3MoeyB2ZXJib3NlOiB0cnVlIH0pKTtcblxuICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFN0YWNrU3VwcHJlc3Npb25zKHN0YWNrLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJ0F3c1NvbHV0aW9ucy1WUEM3JyxcbiAgICAgICAgICByZWFzb246ICdWUEMgRmxvdyBMb2dzIGFyZSBvcHRpb25hbCBhbmQgc2hvdWxkIGJlIGVuYWJsZWQgYnkgdXNlcnMgYmFzZWQgb24gcmVxdWlyZW1lbnRzJyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBlcnJvcnMgPSBBbm5vdGF0aW9ucy5mcm9tU3RhY2soc3RhY2spLmZpbmRFcnJvcignKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcbiAgICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Bhc3NlcyBDREsgTmFnIGNoZWNrcyBmb3IgcHJpdmF0ZSBWUEMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgICAgbmV3IE5ldHdvcmsoc3RhY2ssICdOZXR3b3JrJywgeyBwcml2YXRlOiB0cnVlIH0pO1xuXG4gICAgICBBc3BlY3RzLm9mKHN0YWNrKS5hZGQobmV3IEF3c1NvbHV0aW9uc0NoZWNrcyh7IHZlcmJvc2U6IHRydWUgfSkpO1xuXG4gICAgICBOYWdTdXBwcmVzc2lvbnMuYWRkU3RhY2tTdXBwcmVzc2lvbnMoc3RhY2ssIFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnQXdzU29sdXRpb25zLVZQQzcnLFxuICAgICAgICAgIHJlYXNvbjogJ1ZQQyBGbG93IExvZ3MgYXJlIG9wdGlvbmFsIGFuZCBzaG91bGQgYmUgZW5hYmxlZCBieSB1c2VycyBiYXNlZCBvbiByZXF1aXJlbWVudHMnLFxuICAgICAgICB9LFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IGVycm9ycyA9IEFubm90YXRpb25zLmZyb21TdGFjayhzdGFjaykuZmluZEVycm9yKCcqJywgTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cCgnQXdzU29sdXRpb25zLS4qJykpO1xuICAgICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXZlbnRicmlkZ2VCcm9rZXInLCAoKSA9PiB7XG4gICAgdGVzdCgncGFzc2VzIENESyBOYWcgY2hlY2tzJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICAgIG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ0Jyb2tlcicsIHtcbiAgICAgICAgZXZlbnRTb3VyY2U6ICd0ZXN0LnNvdXJjZScsXG4gICAgICB9KTtcblxuICAgICAgQXNwZWN0cy5vZihzdGFjaykuYWRkKG5ldyBBd3NTb2x1dGlvbnNDaGVja3MoeyB2ZXJib3NlOiB0cnVlIH0pKTtcbiAgICAgIGNvbnN0IGVycm9ycyA9IEFubm90YXRpb25zLmZyb21TdGFjayhzdGFjaykuZmluZEVycm9yKCcqJywgTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cCgnQXdzU29sdXRpb25zLS4qJykpO1xuICAgICAgZXhwZWN0KGVycm9ycykudG9IYXZlTGVuZ3RoKDApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQmF0Y2hBZ2VudCcsICgpID0+IHtcbiAgICB0ZXN0KCdwYXNzZXMgQ0RLIE5hZyBjaGVja3MnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh1bmRlZmluZWQsICdUZXN0U3RhY2snLCB7XG4gICAgICAgIGVudjogeyBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJywgcmVnaW9uOiAndXMtZWFzdC0xJyB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChzdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgcGF0aDogcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2FnZW50cy9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50L2JhdGNoLnB5JyksXG4gICAgICB9KTtcblxuICAgICAgbmV3IEJhdGNoQWdlbnQoc3RhY2ssICdBZ2VudCcsIHtcbiAgICAgICAgYWdlbnROYW1lOiAnVGVzdEFnZW50JyxcbiAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICBiZWRyb2NrTW9kZWw6IHsgZm1Nb2RlbElkOiB0ZXN0TW9kZWwgfSxcbiAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgQXNwZWN0cy5vZihzdGFjaykuYWRkKG5ldyBBd3NTb2x1dGlvbnNDaGVja3MoeyB2ZXJib3NlOiB0cnVlIH0pKTtcblxuICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFN0YWNrU3VwcHJlc3Npb25zKHN0YWNrLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU00JyxcbiAgICAgICAgICByZWFzb246ICdNYW5hZ2VkIHBvbGljaWVzIGFyZSBhY2NlcHRhYmxlIGZvciBMYW1iZGEgZXhlY3V0aW9uIHJvbGUnLFxuICAgICAgICAgIGFwcGxpZXNUbzogWydQb2xpY3k6OmFybjo8QVdTOjpQYXJ0aXRpb24+OmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJ10sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgICAgICByZWFzb246ICdXaWxkY2FyZCBwZXJtaXNzaW9ucyByZXF1aXJlZCBmb3IgUzMgYXNzZXQgYWNjZXNzLCBCZWRyb2NrIG1vZGVsIGludm9jYXRpb24sIGFuZCBDbG91ZFdhdGNoIExvZ3MnLFxuICAgICAgICAgIGFwcGxpZXNUbzogW1xuICAgICAgICAgICAgJ0FjdGlvbjo6czM6R2V0T2JqZWN0KicsXG4gICAgICAgICAgICAnQWN0aW9uOjpzMzpHZXRCdWNrZXQqJyxcbiAgICAgICAgICAgICdBY3Rpb246OnMzOkxpc3QqJyxcbiAgICAgICAgICAgICdSZXNvdXJjZTo6KicsXG4gICAgICAgICAgICAnUmVzb3VyY2U6OmFybjphd3M6YmVkcm9jazoqOjpmb3VuZGF0aW9uLW1vZGVsL2FudGhyb3BpYy5jbGF1ZGUtMy1zb25uZXQtMjAyNDAyMjktdjE6MCcsXG4gICAgICAgICAgICAnUmVzb3VyY2U6OmFybjphd3M6bG9nczp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmxvZy1ncm91cDovYXdzL2xhbWJkYS9UZXN0QWdlbnQtdGVzdHN0YWNrYWdlbnRhYTJhZjBjNDoqJyxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtTDEnLFxuICAgICAgICAgIHJlYXNvbjogJ0xhbWJkYSBydW50aW1lIGlzIG1hbmFnZWQgYnkgY29uc3RydWN0IGRlZmF1bHRzJyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBlcnJvcnMgPSBBbm5vdGF0aW9ucy5mcm9tU3RhY2soc3RhY2spLmZpbmRFcnJvcignKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcbiAgICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Bhc3NlcyBDREsgTmFnIGNoZWNrcyB3aXRoIFZQQyBjb25maWd1cmF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodW5kZWZpbmVkLCAnVGVzdFN0YWNrJywge1xuICAgICAgICBlbnY6IHsgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsIHJlZ2lvbjogJ3VzLWVhc3QtMScgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXR3b3JrID0gbmV3IE5ldHdvcmsoc3RhY2ssICdOZXR3b3JrJyk7XG4gICAgICBjb25zdCBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoc3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICAgIHBhdGg6IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi9hZ2VudHMvcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudC9iYXRjaC5weScpLFxuICAgICAgfSk7XG5cbiAgICAgIG5ldyBCYXRjaEFnZW50KHN0YWNrLCAnQWdlbnQnLCB7XG4gICAgICAgIGFnZW50TmFtZTogJ1Rlc3RBZ2VudCcsXG4gICAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgYmVkcm9ja01vZGVsOiB7IGZtTW9kZWxJZDogdGVzdE1vZGVsIH0sXG4gICAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIEFzcGVjdHMub2Yoc3RhY2spLmFkZChuZXcgQXdzU29sdXRpb25zQ2hlY2tzKHsgdmVyYm9zZTogdHJ1ZSB9KSk7XG5cbiAgICAgIE5hZ1N1cHByZXNzaW9ucy5hZGRTdGFja1N1cHByZXNzaW9ucyhzdGFjaywgW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNCcsXG4gICAgICAgICAgcmVhc29uOiAnTWFuYWdlZCBwb2xpY2llcyBhcmUgYWNjZXB0YWJsZSBmb3IgTGFtYmRhIGV4ZWN1dGlvbiByb2xlJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnQXdzU29sdXRpb25zLUlBTTUnLFxuICAgICAgICAgIHJlYXNvbjogJ1dpbGRjYXJkIHBlcm1pc3Npb25zIHJlcXVpcmVkIGZvciBWUEMsIFMzLCBhbmQgQmVkcm9jayBhY2Nlc3MnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtTDEnLFxuICAgICAgICAgIHJlYXNvbjogJ0xhbWJkYSBydW50aW1lIGlzIG1hbmFnZWQgYnkgY29uc3RydWN0IGRlZmF1bHRzJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnQXdzU29sdXRpb25zLVZQQzcnLFxuICAgICAgICAgIHJlYXNvbjogJ1ZQQyBGbG93IExvZ3MgYXJlIG9wdGlvbmFsJyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBlcnJvcnMgPSBBbm5vdGF0aW9ucy5mcm9tU3RhY2soc3RhY2spLmZpbmRFcnJvcignKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcbiAgICAgIGV4cGVjdChlcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};