@friggframework/devtools 2.0.0--canary.461.c930ee6.0 → 2.0.0--canary.461.fb1228a.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.
|
@@ -88,6 +88,10 @@ class AuroraBuilder extends InfrastructureBuilder {
|
|
|
88
88
|
const globalMode = appDefinition.managementMode || 'discover';
|
|
89
89
|
const vpcIsolation = appDefinition.vpcIsolation || 'shared';
|
|
90
90
|
|
|
91
|
+
// Debug logging
|
|
92
|
+
console.log(` 🔍 DEBUG: Aurora globalMode = '${globalMode}', vpcIsolation = '${vpcIsolation}'`);
|
|
93
|
+
console.log(` 🔍 DEBUG: Aurora discoveredResources.auroraClusterId = ${discoveredResources?.auroraClusterId}`);
|
|
94
|
+
|
|
91
95
|
let management = dbConfig.management;
|
|
92
96
|
|
|
93
97
|
if (globalMode === 'managed') {
|
|
@@ -106,6 +110,8 @@ class AuroraBuilder extends InfrastructureBuilder {
|
|
|
106
110
|
const hasStackAurora = discoveredResources?.auroraClusterId &&
|
|
107
111
|
typeof discoveredResources.auroraClusterId === 'string';
|
|
108
112
|
|
|
113
|
+
console.log(` 🔍 DEBUG: Aurora hasStackAurora = ${hasStackAurora}`);
|
|
114
|
+
|
|
109
115
|
if (hasStackAurora) {
|
|
110
116
|
// Stack has Aurora - reuse it (standard flow: stack → orphaned → create)
|
|
111
117
|
management = 'discover';
|
|
@@ -862,23 +862,82 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
862
862
|
console.log(' ✅ Route table and subnet associations created');
|
|
863
863
|
}
|
|
864
864
|
|
|
865
|
+
/**
|
|
866
|
+
* Ensure subnet associations with route table
|
|
867
|
+
* Called to heal missing associations when route table exists but associations don't
|
|
868
|
+
*/
|
|
869
|
+
ensureSubnetAssociations(appDefinition, discoveredResources, result) {
|
|
870
|
+
// Skip if associations already created (by NAT Gateway routing)
|
|
871
|
+
if (result.resources.FriggPrivateSubnet1RouteTableAssociation) {
|
|
872
|
+
return; // Already handled by NAT Gateway routing
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
const routeTableId = discoveredResources.routeTableId || { Ref: 'FriggLambdaRouteTable' };
|
|
876
|
+
const subnet1Id = discoveredResources.privateSubnetId1 || { Ref: 'FriggPrivateSubnet1' };
|
|
877
|
+
const subnet2Id = discoveredResources.privateSubnetId2 || { Ref: 'FriggPrivateSubnet2' };
|
|
878
|
+
|
|
879
|
+
result.resources.FriggPrivateSubnet1RouteTableAssociation = {
|
|
880
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
881
|
+
Properties: {
|
|
882
|
+
SubnetId: subnet1Id,
|
|
883
|
+
RouteTableId: routeTableId,
|
|
884
|
+
},
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
result.resources.FriggPrivateSubnet2RouteTableAssociation = {
|
|
888
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
889
|
+
Properties: {
|
|
890
|
+
SubnetId: subnet2Id,
|
|
891
|
+
RouteTableId: routeTableId,
|
|
892
|
+
},
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
console.log(' ✓ Ensured subnet associations with route table');
|
|
896
|
+
}
|
|
897
|
+
|
|
865
898
|
/**
|
|
866
899
|
* Build VPC Endpoints for AWS services
|
|
867
900
|
*/
|
|
868
901
|
buildVpcEndpoints(appDefinition, discoveredResources, result, existingEndpoints = {}) {
|
|
902
|
+
// Check if endpoints are from CloudFormation stack (string IDs)
|
|
903
|
+
// Stack-managed resources should be reused, not recreated
|
|
904
|
+
const stackManagedEndpoints = {
|
|
905
|
+
s3: discoveredResources.s3VpcEndpointId && typeof discoveredResources.s3VpcEndpointId === 'string',
|
|
906
|
+
dynamodb: discoveredResources.dynamoDbVpcEndpointId && typeof discoveredResources.dynamoDbVpcEndpointId === 'string',
|
|
907
|
+
kms: discoveredResources.kmsVpcEndpointId && typeof discoveredResources.kmsVpcEndpointId === 'string',
|
|
908
|
+
secretsManager: discoveredResources.secretsManagerVpcEndpointId && typeof discoveredResources.secretsManagerVpcEndpointId === 'string',
|
|
909
|
+
sqs: discoveredResources.sqsVpcEndpointId && typeof discoveredResources.sqsVpcEndpointId === 'string',
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
// Build list of what needs creation (not stack-managed, not existing elsewhere)
|
|
869
913
|
const missing = [];
|
|
870
|
-
if (!existingEndpoints.s3) missing.push('S3');
|
|
871
|
-
if (!existingEndpoints.dynamodb) missing.push('DynamoDB');
|
|
872
|
-
if (!existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') missing.push('KMS');
|
|
873
|
-
if (!existingEndpoints.secretsManager) missing.push('Secrets Manager');
|
|
914
|
+
if (!stackManagedEndpoints.s3 && !existingEndpoints.s3) missing.push('S3');
|
|
915
|
+
if (!stackManagedEndpoints.dynamodb && !existingEndpoints.dynamodb) missing.push('DynamoDB');
|
|
916
|
+
if (!stackManagedEndpoints.kms && !existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') missing.push('KMS');
|
|
917
|
+
if (!stackManagedEndpoints.secretsManager && !existingEndpoints.secretsManager) missing.push('Secrets Manager');
|
|
874
918
|
// SQS endpoint needed for database migrations (migration queue)
|
|
875
|
-
if (!existingEndpoints.sqs && appDefinition.database?.postgres?.enable) missing.push('SQS');
|
|
919
|
+
if (!stackManagedEndpoints.sqs && !existingEndpoints.sqs && appDefinition.database?.postgres?.enable) missing.push('SQS');
|
|
920
|
+
|
|
921
|
+
// Log reused stack-managed endpoints
|
|
922
|
+
const reused = [];
|
|
923
|
+
if (stackManagedEndpoints.s3) reused.push('S3');
|
|
924
|
+
if (stackManagedEndpoints.dynamodb) reused.push('DynamoDB');
|
|
925
|
+
if (stackManagedEndpoints.kms) reused.push('KMS');
|
|
926
|
+
if (stackManagedEndpoints.secretsManager) reused.push('Secrets Manager');
|
|
927
|
+
if (stackManagedEndpoints.sqs) reused.push('SQS');
|
|
928
|
+
|
|
929
|
+
if (reused.length > 0) {
|
|
930
|
+
console.log(` ✓ Reusing stack-managed VPC endpoints: ${reused.join(', ')}`);
|
|
931
|
+
}
|
|
876
932
|
|
|
877
933
|
if (missing.length > 0) {
|
|
878
934
|
console.log(` Creating missing VPC Endpoints: ${missing.join(', ')}...`);
|
|
879
|
-
} else {
|
|
935
|
+
} else if (reused.length === 0) {
|
|
880
936
|
console.log(' All required VPC Endpoints already exist - skipping creation');
|
|
881
937
|
return;
|
|
938
|
+
} else {
|
|
939
|
+
// All endpoints are stack-managed, no creation needed
|
|
940
|
+
return;
|
|
882
941
|
}
|
|
883
942
|
|
|
884
943
|
const vpcId = result.vpcId || discoveredResources.defaultVpcId;
|
|
@@ -898,8 +957,13 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
898
957
|
};
|
|
899
958
|
}
|
|
900
959
|
|
|
901
|
-
//
|
|
902
|
-
if (
|
|
960
|
+
// Ensure subnet associations exist (healing for VPC endpoints without NAT Gateway)
|
|
961
|
+
if (result.resources.FriggLambdaRouteTable || discoveredResources.routeTableId) {
|
|
962
|
+
this.ensureSubnetAssociations(appDefinition, discoveredResources, result);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// S3 Gateway Endpoint (only if not stack-managed and missing)
|
|
966
|
+
if (!stackManagedEndpoints.s3 && !existingEndpoints.s3) {
|
|
903
967
|
result.resources.FriggS3VPCEndpoint = {
|
|
904
968
|
Type: 'AWS::EC2::VPCEndpoint',
|
|
905
969
|
Properties: {
|
|
@@ -911,8 +975,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
911
975
|
};
|
|
912
976
|
}
|
|
913
977
|
|
|
914
|
-
// DynamoDB Gateway Endpoint (only if missing)
|
|
915
|
-
if (!existingEndpoints.dynamodb) {
|
|
978
|
+
// DynamoDB Gateway Endpoint (only if not stack-managed and missing)
|
|
979
|
+
if (!stackManagedEndpoints.dynamodb && !existingEndpoints.dynamodb) {
|
|
916
980
|
result.resources.FriggDynamoDBVPCEndpoint = {
|
|
917
981
|
Type: 'AWS::EC2::VPCEndpoint',
|
|
918
982
|
Properties: {
|
|
@@ -924,8 +988,13 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
924
988
|
};
|
|
925
989
|
}
|
|
926
990
|
|
|
927
|
-
// VPC Endpoint Security Group (only if KMS, Secrets Manager, or SQS are missing)
|
|
928
|
-
|
|
991
|
+
// VPC Endpoint Security Group (only if KMS, Secrets Manager, or SQS are not stack-managed and missing)
|
|
992
|
+
const needsSecurityGroup =
|
|
993
|
+
(!stackManagedEndpoints.kms && !existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') ||
|
|
994
|
+
(!stackManagedEndpoints.secretsManager && !existingEndpoints.secretsManager) ||
|
|
995
|
+
(!stackManagedEndpoints.sqs && !existingEndpoints.sqs && appDefinition.database?.postgres?.enable);
|
|
996
|
+
|
|
997
|
+
if (needsSecurityGroup) {
|
|
929
998
|
result.resources.FriggVPCEndpointSecurityGroup = {
|
|
930
999
|
Type: 'AWS::EC2::SecurityGroup',
|
|
931
1000
|
Properties: {
|
|
@@ -948,8 +1017,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
948
1017
|
};
|
|
949
1018
|
}
|
|
950
1019
|
|
|
951
|
-
// KMS Interface Endpoint (only if missing AND KMS encryption is enabled)
|
|
952
|
-
if (!existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') {
|
|
1020
|
+
// KMS Interface Endpoint (only if not stack-managed, missing, AND KMS encryption is enabled)
|
|
1021
|
+
if (!stackManagedEndpoints.kms && !existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') {
|
|
953
1022
|
result.resources.FriggKMSVPCEndpoint = {
|
|
954
1023
|
Type: 'AWS::EC2::VPCEndpoint',
|
|
955
1024
|
Properties: {
|
|
@@ -963,8 +1032,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
963
1032
|
};
|
|
964
1033
|
}
|
|
965
1034
|
|
|
966
|
-
// Secrets Manager Interface Endpoint (only if missing)
|
|
967
|
-
if (!existingEndpoints.secretsManager) {
|
|
1035
|
+
// Secrets Manager Interface Endpoint (only if not stack-managed and missing)
|
|
1036
|
+
if (!stackManagedEndpoints.secretsManager && !existingEndpoints.secretsManager) {
|
|
968
1037
|
result.resources.FriggSecretsManagerVPCEndpoint = {
|
|
969
1038
|
Type: 'AWS::EC2::VPCEndpoint',
|
|
970
1039
|
Properties: {
|
|
@@ -978,8 +1047,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
978
1047
|
};
|
|
979
1048
|
}
|
|
980
1049
|
|
|
981
|
-
// SQS Interface Endpoint (only if missing AND database migrations are enabled)
|
|
982
|
-
if (!existingEndpoints.sqs && appDefinition.database?.postgres?.enable) {
|
|
1050
|
+
// SQS Interface Endpoint (only if not stack-managed, missing, AND database migrations are enabled)
|
|
1051
|
+
if (!stackManagedEndpoints.sqs && !existingEndpoints.sqs && appDefinition.database?.postgres?.enable) {
|
|
983
1052
|
result.resources.FriggSQSVPCEndpoint = {
|
|
984
1053
|
Type: 'AWS::EC2::VPCEndpoint',
|
|
985
1054
|
Properties: {
|
|
@@ -398,6 +398,59 @@ describe('VpcBuilder', () => {
|
|
|
398
398
|
expect(result.resources.FriggS3VPCEndpoint.Properties.VpcId).toBe('vpc-123');
|
|
399
399
|
});
|
|
400
400
|
|
|
401
|
+
it('should reuse stack-managed VPC endpoints without creating CloudFormation resources', async () => {
|
|
402
|
+
const appDefinition = {
|
|
403
|
+
vpc: { enable: true, enableVPCEndpoints: true },
|
|
404
|
+
encryption: { fieldLevelEncryptionMethod: 'kms' },
|
|
405
|
+
database: { postgres: { enable: true } },
|
|
406
|
+
};
|
|
407
|
+
const discoveredResources = {
|
|
408
|
+
defaultVpcId: 'vpc-123',
|
|
409
|
+
privateSubnetId1: 'subnet-1',
|
|
410
|
+
privateSubnetId2: 'subnet-2',
|
|
411
|
+
// VPC endpoints from CloudFormation stack (string IDs)
|
|
412
|
+
s3VpcEndpointId: 'vpce-s3-stack',
|
|
413
|
+
dynamoDbVpcEndpointId: 'vpce-ddb-stack',
|
|
414
|
+
kmsVpcEndpointId: 'vpce-kms-stack',
|
|
415
|
+
secretsManagerVpcEndpointId: 'vpce-sm-stack',
|
|
416
|
+
sqsVpcEndpointId: 'vpce-sqs-stack',
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const result = await vpcBuilder.build(appDefinition, discoveredResources);
|
|
420
|
+
|
|
421
|
+
// Should NOT create CloudFormation resources (reuse stack endpoints)
|
|
422
|
+
expect(result.resources.FriggS3VPCEndpoint).toBeUndefined();
|
|
423
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint).toBeUndefined();
|
|
424
|
+
expect(result.resources.FriggKMSVPCEndpoint).toBeUndefined();
|
|
425
|
+
expect(result.resources.FriggSecretsManagerVPCEndpoint).toBeUndefined();
|
|
426
|
+
expect(result.resources.FriggSQSVPCEndpoint).toBeUndefined();
|
|
427
|
+
|
|
428
|
+
// Should still NOT create VPC Endpoint Security Group
|
|
429
|
+
expect(result.resources.FriggVPCEndpointSecurityGroup).toBeUndefined();
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it('should create VPC endpoints when discovered from AWS but not stack', async () => {
|
|
433
|
+
const appDefinition = {
|
|
434
|
+
vpc: { enable: true, enableVPCEndpoints: true, selfHeal: true },
|
|
435
|
+
encryption: { fieldLevelEncryptionMethod: 'kms' },
|
|
436
|
+
};
|
|
437
|
+
const discoveredResources = {
|
|
438
|
+
defaultVpcId: 'vpc-123',
|
|
439
|
+
privateSubnetId1: 'subnet-1',
|
|
440
|
+
privateSubnetId2: 'subnet-2',
|
|
441
|
+
// No VPC endpoints in stack (would be strings)
|
|
442
|
+
// existingEndpoints will be passed as empty
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const result = await vpcBuilder.build(appDefinition, discoveredResources);
|
|
446
|
+
|
|
447
|
+
// Should create CloudFormation resources (not in stack)
|
|
448
|
+
expect(result.resources.FriggS3VPCEndpoint).toBeDefined();
|
|
449
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint).toBeDefined();
|
|
450
|
+
expect(result.resources.FriggKMSVPCEndpoint).toBeDefined();
|
|
451
|
+
expect(result.resources.FriggSecretsManagerVPCEndpoint).toBeDefined();
|
|
452
|
+
});
|
|
453
|
+
|
|
401
454
|
it('should skip VPC endpoints when disabled', async () => {
|
|
402
455
|
const appDefinition = {
|
|
403
456
|
vpc: {
|
|
@@ -418,6 +471,32 @@ describe('VpcBuilder', () => {
|
|
|
418
471
|
expect(result.resources.FriggS3VPCEndpoint).toBeUndefined();
|
|
419
472
|
});
|
|
420
473
|
|
|
474
|
+
it('should create route table associations when VPC endpoints exist but no NAT Gateway', async () => {
|
|
475
|
+
const appDefinition = {
|
|
476
|
+
vpc: { enable: true, enableVPCEndpoints: true, selfHeal: true },
|
|
477
|
+
};
|
|
478
|
+
const discoveredResources = {
|
|
479
|
+
defaultVpcId: 'vpc-123',
|
|
480
|
+
privateSubnetId1: 'subnet-1',
|
|
481
|
+
privateSubnetId2: 'subnet-2',
|
|
482
|
+
// No NAT Gateway, so associations won't be created by NAT Gateway routing
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const result = await vpcBuilder.build(appDefinition, discoveredResources);
|
|
486
|
+
|
|
487
|
+
// Route table should be created for VPC endpoints
|
|
488
|
+
expect(result.resources.FriggLambdaRouteTable).toBeDefined();
|
|
489
|
+
expect(result.resources.FriggLambdaRouteTable.Type).toBe('AWS::EC2::RouteTable');
|
|
490
|
+
|
|
491
|
+
// Subnet associations should be created (healing)
|
|
492
|
+
expect(result.resources.FriggPrivateSubnet1RouteTableAssociation).toBeDefined();
|
|
493
|
+
expect(result.resources.FriggPrivateSubnet1RouteTableAssociation.Type).toBe('AWS::EC2::SubnetRouteTableAssociation');
|
|
494
|
+
expect(result.resources.FriggPrivateSubnet1RouteTableAssociation.Properties.SubnetId).toBe('subnet-1');
|
|
495
|
+
|
|
496
|
+
expect(result.resources.FriggPrivateSubnet2RouteTableAssociation).toBeDefined();
|
|
497
|
+
expect(result.resources.FriggPrivateSubnet2RouteTableAssociation.Properties.SubnetId).toBe('subnet-2');
|
|
498
|
+
});
|
|
499
|
+
|
|
421
500
|
it('should include IAM permissions for VPC operations', async () => {
|
|
422
501
|
const appDefinition = {
|
|
423
502
|
vpc: {
|
|
@@ -894,8 +973,9 @@ describe('VpcBuilder', () => {
|
|
|
894
973
|
};
|
|
895
974
|
|
|
896
975
|
// No VPC in CloudFormation stack (fresh deployment)
|
|
976
|
+
// Default VPC might exist in AWS, but not stack-managed
|
|
897
977
|
const discoveredResources = {
|
|
898
|
-
defaultVpcId
|
|
978
|
+
// No defaultVpcId means no VPC in CloudFormation stack
|
|
899
979
|
};
|
|
900
980
|
|
|
901
981
|
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
@@ -137,9 +137,38 @@ class CloudFormationDiscovery {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
// Aurora cluster
|
|
140
|
+
// Aurora cluster - query AWS to get endpoint details
|
|
141
141
|
if (LogicalResourceId === 'FriggAuroraCluster' && ResourceType === 'AWS::RDS::DBCluster') {
|
|
142
142
|
discovered.auroraClusterId = PhysicalResourceId;
|
|
143
|
+
console.log(` ✓ Found Aurora cluster in stack: ${PhysicalResourceId}`);
|
|
144
|
+
|
|
145
|
+
// Query RDS to get cluster endpoint
|
|
146
|
+
if (this.provider && !discovered.auroraClusterEndpoint) {
|
|
147
|
+
try {
|
|
148
|
+
console.log(` Querying RDS to get Aurora endpoint...`);
|
|
149
|
+
const { DescribeDBClustersCommand } = require('@aws-sdk/client-rds');
|
|
150
|
+
const { RDSClient } = require('@aws-sdk/client-rds');
|
|
151
|
+
|
|
152
|
+
const rdsClient = new RDSClient({ region: this.provider.region });
|
|
153
|
+
const clusterDetails = await rdsClient.send(
|
|
154
|
+
new DescribeDBClustersCommand({
|
|
155
|
+
DBClusterIdentifier: PhysicalResourceId
|
|
156
|
+
})
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
if (clusterDetails.DBClusters && clusterDetails.DBClusters.length > 0) {
|
|
160
|
+
const cluster = clusterDetails.DBClusters[0];
|
|
161
|
+
discovered.auroraClusterEndpoint = cluster.Endpoint;
|
|
162
|
+
discovered.auroraClusterPort = cluster.Port;
|
|
163
|
+
discovered.auroraClusterIdentifier = cluster.DBClusterIdentifier;
|
|
164
|
+
console.log(` ✓ Extracted Aurora endpoint: ${cluster.Endpoint}:${cluster.Port}`);
|
|
165
|
+
} else {
|
|
166
|
+
console.warn(` ⚠️ RDS cluster query returned no results`);
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.warn(` ⚠️ Could not get endpoint from Aurora cluster: ${error.message}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
143
172
|
}
|
|
144
173
|
|
|
145
174
|
// Migration status bucket
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.461.
|
|
4
|
+
"version": "2.0.0--canary.461.fb1228a.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.835.0",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"@babel/eslint-parser": "^7.18.9",
|
|
12
12
|
"@babel/parser": "^7.25.3",
|
|
13
13
|
"@babel/traverse": "^7.25.3",
|
|
14
|
-
"@friggframework/schemas": "2.0.0--canary.461.
|
|
15
|
-
"@friggframework/test": "2.0.0--canary.461.
|
|
14
|
+
"@friggframework/schemas": "2.0.0--canary.461.fb1228a.0",
|
|
15
|
+
"@friggframework/test": "2.0.0--canary.461.fb1228a.0",
|
|
16
16
|
"@hapi/boom": "^10.0.1",
|
|
17
17
|
"@inquirer/prompts": "^5.3.8",
|
|
18
18
|
"axios": "^1.7.2",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"serverless-http": "^2.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@friggframework/eslint-config": "2.0.0--canary.461.
|
|
38
|
-
"@friggframework/prettier-config": "2.0.0--canary.461.
|
|
37
|
+
"@friggframework/eslint-config": "2.0.0--canary.461.fb1228a.0",
|
|
38
|
+
"@friggframework/prettier-config": "2.0.0--canary.461.fb1228a.0",
|
|
39
39
|
"aws-sdk-client-mock": "^4.1.0",
|
|
40
40
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
41
41
|
"jest": "^30.1.3",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "fb1228abb7a26c860a458d4fbf27a70be53d1683"
|
|
74
74
|
}
|