@friggframework/devtools 2.0.0--canary.398.53eac55.0 → 2.0.0--canary.397.878fefa.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.
@@ -1,644 +0,0 @@
1
- const fs = require('fs-extra');
2
- const path = require('path');
3
-
4
- /**
5
- * Generate IAM CloudFormation template based on AppDefinition
6
- * @param {Object} appDefinition - Application definition object
7
- * @param {Object} options - Generation options
8
- * @param {string} [options.deploymentUserName='frigg-deployment-user'] - IAM user name
9
- * @param {string} [options.stackName='frigg-deployment-iam'] - CloudFormation stack name
10
- * @returns {string} CloudFormation YAML template
11
- */
12
- function generateIAMCloudFormation(appDefinition, options = {}) {
13
- const {
14
- deploymentUserName = 'frigg-deployment-user',
15
- stackName = 'frigg-deployment-iam'
16
- } = options;
17
-
18
- // Determine which features are enabled
19
- const features = {
20
- vpc: appDefinition.vpc?.enable === true,
21
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
22
- ssm: appDefinition.ssm?.enable === true,
23
- websockets: appDefinition.websockets?.enable === true
24
- };
25
-
26
- // Build the CloudFormation template
27
- const template = {
28
- AWSTemplateFormatVersion: '2010-09-09',
29
- Description: `IAM roles and policies for ${appDefinition.name || 'Frigg'} application deployment pipeline`,
30
-
31
- Parameters: {
32
- DeploymentUserName: {
33
- Type: 'String',
34
- Default: deploymentUserName,
35
- Description: 'Name for the IAM user that will deploy Frigg applications'
36
- },
37
- EnableVPCSupport: {
38
- Type: 'String',
39
- Default: features.vpc ? 'true' : 'false',
40
- AllowedValues: ['true', 'false'],
41
- Description: 'Enable VPC-related permissions for Frigg applications'
42
- },
43
- EnableKMSSupport: {
44
- Type: 'String',
45
- Default: features.kms ? 'true' : 'false',
46
- AllowedValues: ['true', 'false'],
47
- Description: 'Enable KMS encryption permissions for Frigg applications'
48
- },
49
- EnableSSMSupport: {
50
- Type: 'String',
51
- Default: features.ssm ? 'true' : 'false',
52
- AllowedValues: ['true', 'false'],
53
- Description: 'Enable SSM Parameter Store permissions for Frigg applications'
54
- }
55
- },
56
-
57
- Conditions: {
58
- CreateVPCPermissions: { 'Fn::Equals': [{ Ref: 'EnableVPCSupport' }, 'true'] },
59
- CreateKMSPermissions: { 'Fn::Equals': [{ Ref: 'EnableKMSSupport' }, 'true'] },
60
- CreateSSMPermissions: { 'Fn::Equals': [{ Ref: 'EnableSSMSupport' }, 'true'] }
61
- },
62
-
63
- Resources: {}
64
- };
65
-
66
- // Add IAM User
67
- template.Resources.FriggDeploymentUser = {
68
- Type: 'AWS::IAM::User',
69
- Properties: {
70
- UserName: { Ref: 'DeploymentUserName' },
71
- ManagedPolicyArns: [
72
- { Ref: 'FriggDiscoveryPolicy' },
73
- { Ref: 'FriggCoreDeploymentPolicy' }
74
- ]
75
- }
76
- };
77
-
78
- // Conditionally add feature-specific policies
79
- if (features.vpc) {
80
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
81
- 'Fn::If': ['CreateVPCPermissions', { Ref: 'FriggVPCPolicy' }, { Ref: 'AWS::NoValue' }]
82
- });
83
- }
84
- if (features.kms) {
85
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
86
- 'Fn::If': ['CreateKMSPermissions', { Ref: 'FriggKMSPolicy' }, { Ref: 'AWS::NoValue' }]
87
- });
88
- }
89
- if (features.ssm) {
90
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
91
- 'Fn::If': ['CreateSSMPermissions', { Ref: 'FriggSSMPolicy' }, { Ref: 'AWS::NoValue' }]
92
- });
93
- }
94
-
95
- // Add Access Key
96
- template.Resources.FriggDeploymentAccessKey = {
97
- Type: 'AWS::IAM::AccessKey',
98
- Properties: {
99
- UserName: { Ref: 'FriggDeploymentUser' }
100
- }
101
- };
102
-
103
- // Add Discovery Policy (always needed)
104
- template.Resources.FriggDiscoveryPolicy = {
105
- Type: 'AWS::IAM::ManagedPolicy',
106
- Properties: {
107
- ManagedPolicyName: 'FriggDiscoveryPolicy',
108
- Description: 'Permissions for AWS resource discovery during Frigg build process',
109
- PolicyDocument: {
110
- Version: '2012-10-17',
111
- Statement: [
112
- {
113
- Sid: 'AWSDiscoveryPermissions',
114
- Effect: 'Allow',
115
- Action: [
116
- 'sts:GetCallerIdentity',
117
- 'ec2:DescribeVpcs',
118
- 'ec2:DescribeSubnets',
119
- 'ec2:DescribeSecurityGroups',
120
- 'ec2:DescribeRouteTables',
121
- 'kms:ListKeys',
122
- 'kms:DescribeKey'
123
- ],
124
- Resource: '*'
125
- }
126
- ]
127
- }
128
- }
129
- };
130
-
131
- // Add Core Deployment Policy (always needed)
132
- const coreActions = [
133
- // CloudFormation permissions
134
- 'cloudformation:CreateStack',
135
- 'cloudformation:UpdateStack',
136
- 'cloudformation:DeleteStack',
137
- 'cloudformation:DescribeStacks',
138
- 'cloudformation:DescribeStackEvents',
139
- 'cloudformation:DescribeStackResources',
140
- 'cloudformation:DescribeStackResource',
141
- 'cloudformation:ListStackResources',
142
- 'cloudformation:GetTemplate',
143
- 'cloudformation:DescribeChangeSet',
144
- 'cloudformation:CreateChangeSet',
145
- 'cloudformation:DeleteChangeSet',
146
- 'cloudformation:ExecuteChangeSet',
147
- 'cloudformation:ValidateTemplate',
148
-
149
- // Lambda permissions
150
- 'lambda:CreateFunction',
151
- 'lambda:UpdateFunctionCode',
152
- 'lambda:UpdateFunctionConfiguration',
153
- 'lambda:DeleteFunction',
154
- 'lambda:GetFunction',
155
- 'lambda:ListFunctions',
156
- 'lambda:PublishVersion',
157
- 'lambda:CreateAlias',
158
- 'lambda:UpdateAlias',
159
- 'lambda:DeleteAlias',
160
- 'lambda:GetAlias',
161
- 'lambda:AddPermission',
162
- 'lambda:RemovePermission',
163
- 'lambda:GetPolicy',
164
- 'lambda:PutProvisionedConcurrencyConfig',
165
- 'lambda:DeleteProvisionedConcurrencyConfig',
166
- 'lambda:PutConcurrency',
167
- 'lambda:DeleteConcurrency',
168
- 'lambda:TagResource',
169
- 'lambda:UntagResource',
170
- 'lambda:ListVersionsByFunction',
171
-
172
- // IAM permissions
173
- 'iam:CreateRole',
174
- 'iam:DeleteRole',
175
- 'iam:GetRole',
176
- 'iam:PassRole',
177
- 'iam:PutRolePolicy',
178
- 'iam:DeleteRolePolicy',
179
- 'iam:GetRolePolicy',
180
- 'iam:AttachRolePolicy',
181
- 'iam:DetachRolePolicy',
182
- 'iam:TagRole',
183
- 'iam:UntagRole',
184
- 'iam:ListPolicyVersions',
185
-
186
- // S3 permissions
187
- 's3:CreateBucket',
188
- 's3:PutObject',
189
- 's3:GetObject',
190
- 's3:DeleteObject',
191
- 's3:PutBucketPolicy',
192
- 's3:PutBucketVersioning',
193
- 's3:PutBucketPublicAccessBlock',
194
- 's3:GetBucketLocation',
195
- 's3:ListBucket',
196
-
197
- // SQS permissions
198
- 'sqs:CreateQueue',
199
- 'sqs:DeleteQueue',
200
- 'sqs:GetQueueAttributes',
201
- 'sqs:SetQueueAttributes',
202
- 'sqs:GetQueueUrl',
203
- 'sqs:TagQueue',
204
- 'sqs:UntagQueue',
205
-
206
- // SNS permissions
207
- 'sns:CreateTopic',
208
- 'sns:DeleteTopic',
209
- 'sns:GetTopicAttributes',
210
- 'sns:SetTopicAttributes',
211
- 'sns:Subscribe',
212
- 'sns:Unsubscribe',
213
- 'sns:ListSubscriptionsByTopic',
214
- 'sns:TagResource',
215
- 'sns:UntagResource',
216
-
217
- // CloudWatch and Logs permissions
218
- 'cloudwatch:PutMetricAlarm',
219
- 'cloudwatch:DeleteAlarms',
220
- 'cloudwatch:DescribeAlarms',
221
- 'logs:CreateLogGroup',
222
- 'logs:CreateLogStream',
223
- 'logs:DeleteLogGroup',
224
- 'logs:DescribeLogGroups',
225
- 'logs:DescribeLogStreams',
226
- 'logs:FilterLogEvents',
227
- 'logs:PutLogEvents',
228
- 'logs:PutRetentionPolicy',
229
-
230
- // API Gateway permissions
231
- 'apigateway:POST',
232
- 'apigateway:PUT',
233
- 'apigateway:DELETE',
234
- 'apigateway:GET',
235
- 'apigateway:PATCH'
236
- ];
237
-
238
- const coreStatements = [
239
- {
240
- Sid: 'CloudFormationFriggStacks',
241
- Effect: 'Allow',
242
- Action: [
243
- 'cloudformation:CreateStack',
244
- 'cloudformation:UpdateStack',
245
- 'cloudformation:DeleteStack',
246
- 'cloudformation:DescribeStacks',
247
- 'cloudformation:DescribeStackEvents',
248
- 'cloudformation:DescribeStackResources',
249
- 'cloudformation:DescribeStackResource',
250
- 'cloudformation:ListStackResources',
251
- 'cloudformation:GetTemplate',
252
- 'cloudformation:DescribeChangeSet',
253
- 'cloudformation:CreateChangeSet',
254
- 'cloudformation:DeleteChangeSet',
255
- 'cloudformation:ExecuteChangeSet'
256
- ],
257
- Resource: [
258
- { 'Fn::Sub': 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*' }
259
- ]
260
- },
261
- {
262
- Sid: 'CloudFormationValidateTemplate',
263
- Effect: 'Allow',
264
- Action: ['cloudformation:ValidateTemplate'],
265
- Resource: '*'
266
- },
267
- {
268
- Sid: 'S3DeploymentBucket',
269
- Effect: 'Allow',
270
- Action: [
271
- 's3:CreateBucket',
272
- 's3:PutObject',
273
- 's3:GetObject',
274
- 's3:DeleteObject',
275
- 's3:PutBucketPolicy',
276
- 's3:PutBucketVersioning',
277
- 's3:PutBucketPublicAccessBlock',
278
- 's3:GetBucketLocation',
279
- 's3:ListBucket'
280
- ],
281
- Resource: [
282
- 'arn:aws:s3:::*serverless*',
283
- 'arn:aws:s3:::*serverless*/*'
284
- ]
285
- },
286
- {
287
- Sid: 'LambdaFriggFunctions',
288
- Effect: 'Allow',
289
- Action: [
290
- 'lambda:CreateFunction',
291
- 'lambda:UpdateFunctionCode',
292
- 'lambda:UpdateFunctionConfiguration',
293
- 'lambda:DeleteFunction',
294
- 'lambda:GetFunction',
295
- 'lambda:ListFunctions',
296
- 'lambda:PublishVersion',
297
- 'lambda:CreateAlias',
298
- 'lambda:UpdateAlias',
299
- 'lambda:DeleteAlias',
300
- 'lambda:GetAlias',
301
- 'lambda:AddPermission',
302
- 'lambda:RemovePermission',
303
- 'lambda:GetPolicy',
304
- 'lambda:PutProvisionedConcurrencyConfig',
305
- 'lambda:DeleteProvisionedConcurrencyConfig',
306
- 'lambda:PutConcurrency',
307
- 'lambda:DeleteConcurrency',
308
- 'lambda:TagResource',
309
- 'lambda:UntagResource',
310
- 'lambda:ListVersionsByFunction'
311
- ],
312
- Resource: [
313
- { 'Fn::Sub': 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*' }
314
- ]
315
- },
316
- {
317
- Sid: 'IAMRolesForFriggLambda',
318
- Effect: 'Allow',
319
- Action: [
320
- 'iam:CreateRole',
321
- 'iam:DeleteRole',
322
- 'iam:GetRole',
323
- 'iam:PassRole',
324
- 'iam:PutRolePolicy',
325
- 'iam:DeleteRolePolicy',
326
- 'iam:GetRolePolicy',
327
- 'iam:AttachRolePolicy',
328
- 'iam:DetachRolePolicy',
329
- 'iam:TagRole',
330
- 'iam:UntagRole'
331
- ],
332
- Resource: [
333
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*' },
334
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*' }
335
- ]
336
- },
337
- {
338
- Sid: 'IAMPolicyVersionPermissions',
339
- Effect: 'Allow',
340
- Action: ['iam:ListPolicyVersions'],
341
- Resource: [{ 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' }]
342
- },
343
- {
344
- Sid: 'FriggMessagingServices',
345
- Effect: 'Allow',
346
- Action: [
347
- 'sqs:CreateQueue',
348
- 'sqs:DeleteQueue',
349
- 'sqs:GetQueueAttributes',
350
- 'sqs:SetQueueAttributes',
351
- 'sqs:GetQueueUrl',
352
- 'sqs:TagQueue',
353
- 'sqs:UntagQueue'
354
- ],
355
- Resource: [
356
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:*frigg*' },
357
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*' }
358
- ]
359
- },
360
- {
361
- Sid: 'FriggSNSTopics',
362
- Effect: 'Allow',
363
- Action: [
364
- 'sns:CreateTopic',
365
- 'sns:DeleteTopic',
366
- 'sns:GetTopicAttributes',
367
- 'sns:SetTopicAttributes',
368
- 'sns:Subscribe',
369
- 'sns:Unsubscribe',
370
- 'sns:ListSubscriptionsByTopic',
371
- 'sns:TagResource',
372
- 'sns:UntagResource'
373
- ],
374
- Resource: [
375
- { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' }
376
- ]
377
- },
378
- {
379
- Sid: 'FriggMonitoringAndLogs',
380
- Effect: 'Allow',
381
- Action: [
382
- 'cloudwatch:PutMetricAlarm',
383
- 'cloudwatch:DeleteAlarms',
384
- 'cloudwatch:DescribeAlarms',
385
- 'logs:CreateLogGroup',
386
- 'logs:CreateLogStream',
387
- 'logs:DeleteLogGroup',
388
- 'logs:DescribeLogGroups',
389
- 'logs:DescribeLogStreams',
390
- 'logs:FilterLogEvents',
391
- 'logs:PutLogEvents',
392
- 'logs:PutRetentionPolicy'
393
- ],
394
- Resource: [
395
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*' },
396
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*' },
397
- { 'Fn::Sub': 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*' }
398
- ]
399
- },
400
- {
401
- Sid: 'FriggAPIGateway',
402
- Effect: 'Allow',
403
- Action: [
404
- 'apigateway:POST',
405
- 'apigateway:PUT',
406
- 'apigateway:DELETE',
407
- 'apigateway:GET',
408
- 'apigateway:PATCH'
409
- ],
410
- Resource: [
411
- 'arn:aws:apigateway:*::/restapis',
412
- 'arn:aws:apigateway:*::/restapis/*',
413
- 'arn:aws:apigateway:*::/domainnames',
414
- 'arn:aws:apigateway:*::/domainnames/*'
415
- ]
416
- }
417
- ];
418
-
419
- template.Resources.FriggCoreDeploymentPolicy = {
420
- Type: 'AWS::IAM::ManagedPolicy',
421
- Properties: {
422
- ManagedPolicyName: 'FriggCoreDeploymentPolicy',
423
- Description: 'Core permissions for deploying Frigg applications',
424
- PolicyDocument: {
425
- Version: '2012-10-17',
426
- Statement: coreStatements
427
- }
428
- }
429
- };
430
-
431
- // Add feature-specific policies only if needed
432
- if (features.vpc) {
433
- template.Resources.FriggVPCPolicy = {
434
- Type: 'AWS::IAM::ManagedPolicy',
435
- Condition: 'CreateVPCPermissions',
436
- Properties: {
437
- ManagedPolicyName: 'FriggVPCPolicy',
438
- Description: 'VPC-related permissions for Frigg applications',
439
- PolicyDocument: {
440
- Version: '2012-10-17',
441
- Statement: [
442
- {
443
- Sid: 'FriggVPCEndpointManagement',
444
- Effect: 'Allow',
445
- Action: [
446
- 'ec2:CreateVpcEndpoint',
447
- 'ec2:DeleteVpcEndpoint',
448
- 'ec2:DescribeVpcEndpoints',
449
- 'ec2:ModifyVpcEndpoint',
450
- 'ec2:CreateNatGateway',
451
- 'ec2:DeleteNatGateway',
452
- 'ec2:DescribeNatGateways',
453
- 'ec2:AllocateAddress',
454
- 'ec2:ReleaseAddress',
455
- 'ec2:DescribeAddresses',
456
- 'ec2:CreateRouteTable',
457
- 'ec2:DeleteRouteTable',
458
- 'ec2:DescribeRouteTables',
459
- 'ec2:CreateRoute',
460
- 'ec2:DeleteRoute',
461
- 'ec2:AssociateRouteTable',
462
- 'ec2:DisassociateRouteTable',
463
- 'ec2:CreateSecurityGroup',
464
- 'ec2:DeleteSecurityGroup',
465
- 'ec2:AuthorizeSecurityGroupEgress',
466
- 'ec2:AuthorizeSecurityGroupIngress',
467
- 'ec2:RevokeSecurityGroupEgress',
468
- 'ec2:RevokeSecurityGroupIngress'
469
- ],
470
- Resource: '*',
471
- Condition: {
472
- StringLike: {
473
- 'ec2:CreateAction': [
474
- 'CreateVpcEndpoint',
475
- 'CreateNatGateway',
476
- 'CreateRouteTable',
477
- 'CreateRoute',
478
- 'CreateSecurityGroup'
479
- ]
480
- }
481
- }
482
- }
483
- ]
484
- }
485
- }
486
- };
487
- }
488
-
489
- if (features.kms) {
490
- template.Resources.FriggKMSPolicy = {
491
- Type: 'AWS::IAM::ManagedPolicy',
492
- Condition: 'CreateKMSPermissions',
493
- Properties: {
494
- ManagedPolicyName: 'FriggKMSPolicy',
495
- Description: 'KMS encryption permissions for Frigg applications',
496
- PolicyDocument: {
497
- Version: '2012-10-17',
498
- Statement: [
499
- {
500
- Sid: 'FriggKMSEncryptionRuntime',
501
- Effect: 'Allow',
502
- Action: [
503
- 'kms:GenerateDataKey',
504
- 'kms:Decrypt'
505
- ],
506
- Resource: [
507
- { 'Fn::Sub': 'arn:aws:kms:*:${AWS::AccountId}:key/*' }
508
- ],
509
- Condition: {
510
- StringEquals: {
511
- 'kms:ViaService': [
512
- 'lambda.*.amazonaws.com',
513
- 's3.*.amazonaws.com'
514
- ]
515
- }
516
- }
517
- }
518
- ]
519
- }
520
- }
521
- };
522
- }
523
-
524
- if (features.ssm) {
525
- template.Resources.FriggSSMPolicy = {
526
- Type: 'AWS::IAM::ManagedPolicy',
527
- Condition: 'CreateSSMPermissions',
528
- Properties: {
529
- ManagedPolicyName: 'FriggSSMPolicy',
530
- Description: 'SSM Parameter Store permissions for Frigg applications',
531
- PolicyDocument: {
532
- Version: '2012-10-17',
533
- Statement: [
534
- {
535
- Sid: 'FriggSSMParameterAccess',
536
- Effect: 'Allow',
537
- Action: [
538
- 'ssm:GetParameter',
539
- 'ssm:GetParameters',
540
- 'ssm:GetParametersByPath'
541
- ],
542
- Resource: [
543
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*' },
544
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*' }
545
- ]
546
- }
547
- ]
548
- }
549
- }
550
- };
551
- }
552
-
553
- // Add Secrets Manager for credentials
554
- template.Resources.FriggDeploymentCredentials = {
555
- Type: 'AWS::SecretsManager::Secret',
556
- Properties: {
557
- Name: 'frigg-deployment-credentials',
558
- Description: 'Access credentials for Frigg deployment user',
559
- SecretString: {
560
- 'Fn::Sub': JSON.stringify({
561
- AccessKeyId: '${FriggDeploymentAccessKey}',
562
- SecretAccessKey: '${FriggDeploymentAccessKey.SecretAccessKey}'
563
- })
564
- }
565
- }
566
- };
567
-
568
- // Add Outputs
569
- template.Outputs = {
570
- DeploymentUserArn: {
571
- Description: 'ARN of the Frigg deployment user',
572
- Value: { 'Fn::GetAtt': ['FriggDeploymentUser', 'Arn'] },
573
- Export: {
574
- Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' }
575
- }
576
- },
577
- AccessKeyId: {
578
- Description: 'Access Key ID for the deployment user',
579
- Value: { Ref: 'FriggDeploymentAccessKey' },
580
- Export: {
581
- Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' }
582
- }
583
- },
584
- SecretAccessKeyCommand: {
585
- Description: 'Command to retrieve the secret access key',
586
- Value: {
587
- 'Fn::Sub': 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey'
588
- }
589
- },
590
- CredentialsSecretArn: {
591
- Description: 'ARN of the secret containing deployment credentials',
592
- Value: { Ref: 'FriggDeploymentCredentials' },
593
- Export: {
594
- Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' }
595
- }
596
- }
597
- };
598
-
599
- // Convert to YAML
600
- return convertToYAML(template);
601
- }
602
-
603
- /**
604
- * Convert JavaScript object to CloudFormation YAML
605
- * @param {Object} obj - JavaScript object
606
- * @returns {string} YAML string
607
- */
608
- function convertToYAML(obj) {
609
- const yaml = require('js-yaml');
610
- return yaml.dump(obj, {
611
- indent: 2,
612
- lineWidth: 120,
613
- noRefs: true,
614
- sortKeys: false
615
- });
616
- }
617
-
618
- /**
619
- * Generate summary of what features will be included in the IAM policy
620
- * @param {Object} appDefinition - Application definition
621
- * @returns {Object} Feature summary
622
- */
623
- function getFeatureSummary(appDefinition) {
624
- const features = {
625
- core: true, // Always enabled
626
- vpc: appDefinition.vpc?.enable === true,
627
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
628
- ssm: appDefinition.ssm?.enable === true,
629
- websockets: appDefinition.websockets?.enable === true
630
- };
631
-
632
- const integrationCount = appDefinition.integrations?.length || 0;
633
-
634
- return {
635
- features,
636
- integrationCount,
637
- appName: appDefinition.name || 'Unnamed Frigg App'
638
- };
639
- }
640
-
641
- module.exports = {
642
- generateIAMCloudFormation,
643
- getFeatureSummary
644
- };