@friggframework/devtools 2.0.0-next.29 → 2.0.0-next.30
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.
- package/frigg-cli/.eslintrc.js +141 -0
- package/frigg-cli/__tests__/jest.config.js +102 -0
- package/frigg-cli/__tests__/unit/commands/build.test.js +483 -0
- package/frigg-cli/__tests__/unit/commands/install.test.js +418 -0
- package/frigg-cli/__tests__/unit/commands/ui.test.js +592 -0
- package/frigg-cli/__tests__/utils/command-tester.js +170 -0
- package/frigg-cli/__tests__/utils/mock-factory.js +270 -0
- package/frigg-cli/__tests__/utils/test-fixtures.js +463 -0
- package/frigg-cli/__tests__/utils/test-setup.js +286 -0
- package/frigg-cli/generate-command/__tests__/generate-command.test.js +312 -0
- package/frigg-cli/generate-command/azure-generator.js +43 -0
- package/frigg-cli/generate-command/gcp-generator.js +47 -0
- package/frigg-cli/generate-command/index.js +332 -0
- package/frigg-cli/generate-command/terraform-generator.js +555 -0
- package/frigg-cli/index.js +19 -1
- package/frigg-cli/init-command/backend-first-handler.js +756 -0
- package/frigg-cli/init-command/index.js +93 -0
- package/frigg-cli/init-command/template-handler.js +143 -0
- package/frigg-cli/package.json +51 -0
- package/frigg-cli/test/init-command.test.js +180 -0
- package/frigg-cli/test/npm-registry.test.js +319 -0
- package/frigg-cli/ui-command/index.js +154 -0
- package/frigg-cli/utils/app-resolver.js +319 -0
- package/frigg-cli/utils/backend-path.js +25 -0
- package/frigg-cli/utils/npm-registry.js +167 -0
- package/frigg-cli/utils/process-manager.js +199 -0
- package/frigg-cli/utils/repo-detection.js +405 -0
- package/infrastructure/serverless-template.js +177 -292
- package/management-ui/.eslintrc.js +22 -0
- package/management-ui/README.md +203 -0
- package/management-ui/components.json +21 -0
- package/management-ui/docs/phase2-integration-guide.md +320 -0
- package/management-ui/{dist/index.html → index.html} +1 -2
- package/management-ui/package-lock.json +16517 -0
- package/management-ui/package.json +76 -0
- package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +302 -0
- package/management-ui/postcss.config.js +6 -0
- package/management-ui/server/api/backend.js +256 -0
- package/management-ui/server/api/cli.js +315 -0
- package/management-ui/server/api/codegen.js +663 -0
- package/management-ui/server/api/connections.js +857 -0
- package/management-ui/server/api/discovery.js +185 -0
- package/management-ui/server/api/environment/index.js +1 -0
- package/management-ui/server/api/environment/router.js +378 -0
- package/management-ui/server/api/environment.js +328 -0
- package/management-ui/server/api/integrations.js +876 -0
- package/management-ui/server/api/logs.js +248 -0
- package/management-ui/server/api/monitoring.js +282 -0
- package/management-ui/server/api/open-ide.js +31 -0
- package/management-ui/server/api/project.js +1029 -0
- package/management-ui/server/api/users/sessions.js +371 -0
- package/management-ui/server/api/users/simulation.js +254 -0
- package/management-ui/server/api/users.js +362 -0
- package/management-ui/server/api-contract.md +275 -0
- package/management-ui/server/index.js +873 -0
- package/management-ui/server/middleware/errorHandler.js +93 -0
- package/management-ui/server/middleware/security.js +32 -0
- package/management-ui/server/processManager.js +296 -0
- package/management-ui/server/server.js +346 -0
- package/management-ui/server/services/aws-monitor.js +413 -0
- package/management-ui/server/services/npm-registry.js +347 -0
- package/management-ui/server/services/template-engine.js +538 -0
- package/management-ui/server/utils/cliIntegration.js +220 -0
- package/management-ui/server/utils/environment/auditLogger.js +471 -0
- package/management-ui/server/utils/environment/awsParameterStore.js +264 -0
- package/management-ui/server/utils/environment/encryption.js +278 -0
- package/management-ui/server/utils/environment/envFileManager.js +286 -0
- package/management-ui/server/utils/import-commonjs.js +28 -0
- package/management-ui/server/utils/response.js +83 -0
- package/management-ui/server/websocket/handler.js +325 -0
- package/management-ui/src/App.jsx +109 -0
- package/management-ui/src/components/AppRouter.jsx +65 -0
- package/management-ui/src/components/Button.jsx +70 -0
- package/management-ui/src/components/Card.jsx +97 -0
- package/management-ui/src/components/EnvironmentCompare.jsx +400 -0
- package/management-ui/src/components/EnvironmentEditor.jsx +372 -0
- package/management-ui/src/components/EnvironmentImportExport.jsx +469 -0
- package/management-ui/src/components/EnvironmentSchema.jsx +491 -0
- package/management-ui/src/components/EnvironmentSecurity.jsx +463 -0
- package/management-ui/src/components/ErrorBoundary.jsx +73 -0
- package/management-ui/src/components/IntegrationCard.jsx +481 -0
- package/management-ui/src/components/IntegrationCardEnhanced.jsx +770 -0
- package/management-ui/src/components/IntegrationExplorer.jsx +379 -0
- package/management-ui/src/components/IntegrationStatus.jsx +336 -0
- package/management-ui/src/components/Layout.jsx +716 -0
- package/management-ui/src/components/LoadingSpinner.jsx +113 -0
- package/management-ui/src/components/RepositoryPicker.jsx +248 -0
- package/management-ui/src/components/SessionMonitor.jsx +350 -0
- package/management-ui/src/components/StatusBadge.jsx +208 -0
- package/management-ui/src/components/UserContextSwitcher.jsx +212 -0
- package/management-ui/src/components/UserSimulation.jsx +327 -0
- package/management-ui/src/components/Welcome.jsx +434 -0
- package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +637 -0
- package/management-ui/src/components/codegen/APIModuleSelector.jsx +227 -0
- package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +247 -0
- package/management-ui/src/components/codegen/CodePreviewEditor.jsx +316 -0
- package/management-ui/src/components/codegen/DynamicModuleForm.jsx +271 -0
- package/management-ui/src/components/codegen/FormBuilder.jsx +737 -0
- package/management-ui/src/components/codegen/IntegrationGenerator.jsx +855 -0
- package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +797 -0
- package/management-ui/src/components/codegen/SchemaBuilder.jsx +303 -0
- package/management-ui/src/components/codegen/TemplateSelector.jsx +586 -0
- package/management-ui/src/components/codegen/index.js +10 -0
- package/management-ui/src/components/connections/ConnectionConfigForm.jsx +362 -0
- package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +182 -0
- package/management-ui/src/components/connections/ConnectionTester.jsx +200 -0
- package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +292 -0
- package/management-ui/src/components/connections/OAuthFlow.jsx +204 -0
- package/management-ui/src/components/connections/index.js +5 -0
- package/management-ui/src/components/index.js +21 -0
- package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +222 -0
- package/management-ui/src/components/monitoring/LambdaMetrics.jsx +169 -0
- package/management-ui/src/components/monitoring/MetricsChart.jsx +197 -0
- package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +393 -0
- package/management-ui/src/components/monitoring/SQSMetrics.jsx +246 -0
- package/management-ui/src/components/monitoring/index.js +6 -0
- package/management-ui/src/components/monitoring/monitoring.css +218 -0
- package/management-ui/src/components/theme-provider.jsx +52 -0
- package/management-ui/src/components/theme-toggle.jsx +39 -0
- package/management-ui/src/components/ui/badge.tsx +36 -0
- package/management-ui/src/components/ui/button.test.jsx +56 -0
- package/management-ui/src/components/ui/button.tsx +57 -0
- package/management-ui/src/components/ui/card.tsx +76 -0
- package/management-ui/src/components/ui/dropdown-menu.tsx +199 -0
- package/management-ui/src/components/ui/select.tsx +157 -0
- package/management-ui/src/components/ui/skeleton.jsx +15 -0
- package/management-ui/src/hooks/useFrigg.jsx +601 -0
- package/management-ui/src/hooks/useSocket.jsx +58 -0
- package/management-ui/src/index.css +193 -0
- package/management-ui/src/lib/utils.ts +6 -0
- package/management-ui/src/main.jsx +10 -0
- package/management-ui/src/pages/CodeGeneration.jsx +14 -0
- package/management-ui/src/pages/Connections.jsx +252 -0
- package/management-ui/src/pages/ConnectionsEnhanced.jsx +633 -0
- package/management-ui/src/pages/Dashboard.jsx +311 -0
- package/management-ui/src/pages/Environment.jsx +314 -0
- package/management-ui/src/pages/IntegrationConfigure.jsx +669 -0
- package/management-ui/src/pages/IntegrationDiscovery.jsx +567 -0
- package/management-ui/src/pages/IntegrationTest.jsx +742 -0
- package/management-ui/src/pages/Integrations.jsx +253 -0
- package/management-ui/src/pages/Monitoring.jsx +17 -0
- package/management-ui/src/pages/Simulation.jsx +155 -0
- package/management-ui/src/pages/Users.jsx +492 -0
- package/management-ui/src/services/api.js +41 -0
- package/management-ui/src/services/apiModuleService.js +193 -0
- package/management-ui/src/services/websocket-handlers.js +120 -0
- package/management-ui/src/test/api/project.test.js +273 -0
- package/management-ui/src/test/components/Welcome.test.jsx +378 -0
- package/management-ui/src/test/mocks/server.js +178 -0
- package/management-ui/src/test/setup.js +61 -0
- package/management-ui/src/test/utils/test-utils.jsx +134 -0
- package/management-ui/src/utils/repository.js +98 -0
- package/management-ui/src/utils/repository.test.js +118 -0
- package/management-ui/src/workflows/phase2-integration-workflows.js +884 -0
- package/management-ui/tailwind.config.js +63 -0
- package/management-ui/tsconfig.json +37 -0
- package/management-ui/tsconfig.node.json +10 -0
- package/management-ui/vite.config.js +26 -0
- package/management-ui/vitest.config.js +38 -0
- package/package.json +5 -5
- package/management-ui/dist/assets/index-BA21WgFa.js +0 -1221
- package/management-ui/dist/assets/index-CbM64Oba.js +0 -1221
- package/management-ui/dist/assets/index-CkvseXTC.css +0 -1
- /package/management-ui/{dist/assets/FriggLogo-B7Xx8ZW1.svg → src/assets/FriggLogo.svg} +0 -0
|
@@ -94,12 +94,6 @@ const findNodeModulesPath = () => {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* Modify handler paths to point to the correct node_modules location
|
|
99
|
-
* Only modifies paths when running in offline mode
|
|
100
|
-
* @param {Object} functions - Serverless functions configuration object
|
|
101
|
-
* @returns {Object} Modified functions object with updated handler paths
|
|
102
|
-
*/
|
|
103
97
|
/**
|
|
104
98
|
* Modify handler paths to point to the correct node_modules location
|
|
105
99
|
* Only modifies paths when running in offline mode
|
|
@@ -126,8 +120,6 @@ const modifyHandlerPaths = (functions) => {
|
|
|
126
120
|
// Replace node_modules/ with the actual path to node_modules/
|
|
127
121
|
const relativePath = path.relative(process.cwd(), nodeModulesPath);
|
|
128
122
|
functionDef.handler = functionDef.handler.replace('node_modules/', `${relativePath}/`);
|
|
129
|
-
const relativePath = path.relative(process.cwd(), nodeModulesPath);
|
|
130
|
-
functionDef.handler = functionDef.handler.replace('node_modules/', `${relativePath}/`);
|
|
131
123
|
console.log(`Updated handler for ${functionName}: ${functionDef.handler}`);
|
|
132
124
|
}
|
|
133
125
|
}
|
|
@@ -135,14 +127,6 @@ const modifyHandlerPaths = (functions) => {
|
|
|
135
127
|
return modifiedFunctions;
|
|
136
128
|
};
|
|
137
129
|
|
|
138
|
-
/**
|
|
139
|
-
* Create VPC infrastructure resources for CloudFormation
|
|
140
|
-
* Creates VPC, subnets, NAT gateway, route tables, and security groups
|
|
141
|
-
* @param {Object} AppDefinition - Application definition object
|
|
142
|
-
* @param {Object} AppDefinition.vpc - VPC configuration
|
|
143
|
-
* @param {string} [AppDefinition.vpc.cidrBlock='10.0.0.0/16'] - CIDR block for VPC
|
|
144
|
-
* @returns {Object} CloudFormation resources for VPC infrastructure
|
|
145
|
-
*/
|
|
146
130
|
/**
|
|
147
131
|
* Create VPC infrastructure resources for CloudFormation
|
|
148
132
|
* Creates VPC, subnets, NAT gateway, route tables, and security groups
|
|
@@ -517,7 +501,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
517
501
|
runtime: 'nodejs20.x',
|
|
518
502
|
timeout: 30,
|
|
519
503
|
region: process.env.AWS_REGION || 'us-east-1',
|
|
520
|
-
region: process.env.AWS_REGION || 'us-east-1',
|
|
521
504
|
stage: '${opt:stage}',
|
|
522
505
|
environment: {
|
|
523
506
|
STAGE: '${opt:stage, "dev"}',
|
|
@@ -530,14 +513,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
530
513
|
...(discoveredResources.publicSubnetId && { AWS_DISCOVERY_PUBLIC_SUBNET_ID: discoveredResources.publicSubnetId }),
|
|
531
514
|
...(discoveredResources.defaultRouteTableId && { AWS_DISCOVERY_ROUTE_TABLE_ID: discoveredResources.defaultRouteTableId }),
|
|
532
515
|
...(discoveredResources.defaultKmsKeyId && { AWS_DISCOVERY_KMS_KEY_ID: discoveredResources.defaultKmsKeyId }),
|
|
533
|
-
// Add discovered resources to environment if available
|
|
534
|
-
...(discoveredResources.defaultVpcId && { AWS_DISCOVERY_VPC_ID: discoveredResources.defaultVpcId }),
|
|
535
|
-
...(discoveredResources.defaultSecurityGroupId && { AWS_DISCOVERY_SECURITY_GROUP_ID: discoveredResources.defaultSecurityGroupId }),
|
|
536
|
-
...(discoveredResources.privateSubnetId1 && { AWS_DISCOVERY_SUBNET_ID_1: discoveredResources.privateSubnetId1 }),
|
|
537
|
-
...(discoveredResources.privateSubnetId2 && { AWS_DISCOVERY_SUBNET_ID_2: discoveredResources.privateSubnetId2 }),
|
|
538
|
-
...(discoveredResources.publicSubnetId && { AWS_DISCOVERY_PUBLIC_SUBNET_ID: discoveredResources.publicSubnetId }),
|
|
539
|
-
...(discoveredResources.defaultRouteTableId && { AWS_DISCOVERY_ROUTE_TABLE_ID: discoveredResources.defaultRouteTableId }),
|
|
540
|
-
...(discoveredResources.defaultKmsKeyId && { AWS_DISCOVERY_KMS_KEY_ID: discoveredResources.defaultKmsKeyId }),
|
|
541
516
|
},
|
|
542
517
|
iamRoleStatements: [
|
|
543
518
|
{
|
|
@@ -600,7 +575,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
600
575
|
apiVersion: '2012-11-05',
|
|
601
576
|
endpoint: 'http://localhost:4566',
|
|
602
577
|
region: process.env.AWS_REGION || 'us-east-1',
|
|
603
|
-
region: process.env.AWS_REGION || 'us-east-1',
|
|
604
578
|
accessKeyId: 'root',
|
|
605
579
|
secretAccessKey: 'root',
|
|
606
580
|
skipCacheInvalidation: false,
|
|
@@ -669,7 +643,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
669
643
|
Properties: {
|
|
670
644
|
QueueName:
|
|
671
645
|
'${self:service}-internal-error-queue-${self:provider.stage}',
|
|
672
|
-
'${self:service}-internal-error-queue-${self:provider.stage}',
|
|
673
646
|
MessageRetentionPeriod: 300,
|
|
674
647
|
},
|
|
675
648
|
},
|
|
@@ -749,8 +722,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
749
722
|
},
|
|
750
723
|
};
|
|
751
724
|
|
|
752
|
-
|
|
753
|
-
|
|
754
725
|
// KMS Configuration based on App Definition
|
|
755
726
|
if (AppDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true) {
|
|
756
727
|
// Provision a dedicated KMS key and wire it automatically
|
|
@@ -783,11 +754,9 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
783
754
|
|
|
784
755
|
definition.plugins.push('serverless-kms-grants');
|
|
785
756
|
|
|
786
|
-
// Configure KMS grants with discovered default key
|
|
787
757
|
// Configure KMS grants with discovered default key
|
|
788
758
|
definition.custom.kmsGrants = {
|
|
789
759
|
kmsKeyId: discoveredResources.defaultKmsKeyId || '${env:AWS_DISCOVERY_KMS_KEY_ID}'
|
|
790
|
-
kmsKeyId: discoveredResources.defaultKmsKeyId || '${env:AWS_DISCOVERY_KMS_KEY_ID}'
|
|
791
760
|
};
|
|
792
761
|
}
|
|
793
762
|
|
|
@@ -810,290 +779,231 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
810
779
|
if (AppDefinition.vpc.createNew === true) {
|
|
811
780
|
// Option 1: Create new VPC infrastructure (explicit opt-in)
|
|
812
781
|
const vpcConfig = {};
|
|
813
|
-
// Add VPC-related IAM permissions
|
|
814
|
-
definition.provider.iamRoleStatements.push({
|
|
815
|
-
Effect: 'Allow',
|
|
816
|
-
Action: [
|
|
817
|
-
'ec2:CreateNetworkInterface',
|
|
818
|
-
'ec2:DescribeNetworkInterfaces',
|
|
819
|
-
'ec2:DeleteNetworkInterface',
|
|
820
|
-
'ec2:AttachNetworkInterface',
|
|
821
|
-
'ec2:DetachNetworkInterface'
|
|
822
|
-
],
|
|
823
|
-
Resource: '*'
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
// Default approach: Use AWS Discovery to find existing VPC resources
|
|
827
|
-
if (AppDefinition.vpc.createNew === true) {
|
|
828
|
-
// Option 1: Create new VPC infrastructure (explicit opt-in)
|
|
829
|
-
const vpcConfig = {};
|
|
830
|
-
|
|
831
|
-
if (AppDefinition.vpc.securityGroupIds) {
|
|
832
|
-
// User provided custom security groups
|
|
833
|
-
vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
|
|
834
|
-
} else {
|
|
835
|
-
// Use auto-created security group
|
|
836
|
-
vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
|
|
837
|
-
}
|
|
838
|
-
if (AppDefinition.vpc.securityGroupIds) {
|
|
839
|
-
// User provided custom security groups
|
|
840
|
-
vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
|
|
841
|
-
} else {
|
|
842
|
-
// Use auto-created security group
|
|
843
|
-
vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
|
|
844
|
-
}
|
|
845
782
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
{ Ref: 'FriggPrivateSubnet2' }
|
|
854
|
-
];
|
|
855
|
-
}
|
|
856
|
-
if (AppDefinition.vpc.subnetIds) {
|
|
857
|
-
// User provided custom subnets
|
|
858
|
-
vpcConfig.subnetIds = AppDefinition.vpc.subnetIds;
|
|
859
|
-
} else {
|
|
860
|
-
// Use auto-created private subnets
|
|
861
|
-
vpcConfig.subnetIds = [
|
|
862
|
-
{ Ref: 'FriggPrivateSubnet1' },
|
|
863
|
-
{ Ref: 'FriggPrivateSubnet2' }
|
|
864
|
-
];
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
// Set VPC config for Lambda functions
|
|
868
|
-
definition.provider.vpc = vpcConfig;
|
|
869
|
-
// Set VPC config for Lambda functions
|
|
870
|
-
definition.provider.vpc = vpcConfig;
|
|
783
|
+
if (AppDefinition.vpc.securityGroupIds) {
|
|
784
|
+
// User provided custom security groups
|
|
785
|
+
vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
|
|
786
|
+
} else {
|
|
787
|
+
// Use auto-created security group
|
|
788
|
+
vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
|
|
789
|
+
}
|
|
871
790
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
791
|
+
if (AppDefinition.vpc.subnetIds) {
|
|
792
|
+
// User provided custom subnets
|
|
793
|
+
vpcConfig.subnetIds = AppDefinition.vpc.subnetIds;
|
|
875
794
|
} else {
|
|
876
|
-
//
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
(discoveredResources.privateSubnetId1 && discoveredResources.privateSubnetId2 ?
|
|
883
|
-
[discoveredResources.privateSubnetId1, discoveredResources.privateSubnetId2] :
|
|
884
|
-
[])
|
|
885
|
-
};
|
|
795
|
+
// Use auto-created private subnets
|
|
796
|
+
vpcConfig.subnetIds = [
|
|
797
|
+
{ Ref: 'FriggPrivateSubnet1' },
|
|
798
|
+
{ Ref: 'FriggPrivateSubnet2' }
|
|
799
|
+
];
|
|
800
|
+
}
|
|
886
801
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
802
|
+
// Set VPC config for Lambda functions
|
|
803
|
+
definition.provider.vpc = vpcConfig;
|
|
804
|
+
|
|
805
|
+
// Add VPC infrastructure resources to CloudFormation
|
|
806
|
+
const vpcResources = createVPCInfrastructure(AppDefinition);
|
|
807
|
+
Object.assign(definition.resources.Resources, vpcResources);
|
|
808
|
+
} else {
|
|
809
|
+
// Option 2: Use AWS Discovery (default behavior)
|
|
810
|
+
// VPC configuration using discovered or explicitly provided resources
|
|
811
|
+
const vpcConfig = {
|
|
812
|
+
securityGroupIds: AppDefinition.vpc.securityGroupIds ||
|
|
813
|
+
(discoveredResources.defaultSecurityGroupId ? [discoveredResources.defaultSecurityGroupId] : []),
|
|
814
|
+
subnetIds: AppDefinition.vpc.subnetIds ||
|
|
815
|
+
(discoveredResources.privateSubnetId1 && discoveredResources.privateSubnetId2 ?
|
|
816
|
+
[discoveredResources.privateSubnetId1, discoveredResources.privateSubnetId2] :
|
|
817
|
+
[])
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
// Set VPC config for Lambda functions only if we have valid subnet IDs
|
|
821
|
+
if (vpcConfig.subnetIds.length >= 2 && vpcConfig.securityGroupIds.length > 0) {
|
|
822
|
+
definition.provider.vpc = vpcConfig;
|
|
823
|
+
|
|
824
|
+
// Check if we have an existing NAT Gateway to use
|
|
825
|
+
if (!discoveredResources.existingNatGatewayId) {
|
|
826
|
+
// No existing NAT Gateway, create new resources
|
|
907
827
|
|
|
908
|
-
|
|
909
|
-
|
|
828
|
+
// Only create EIP if we don't have an existing one available
|
|
829
|
+
if (!discoveredResources.existingElasticIpAllocationId) {
|
|
830
|
+
definition.resources.Resources.FriggNATGatewayEIP = {
|
|
831
|
+
Type: 'AWS::EC2::EIP',
|
|
910
832
|
Properties: {
|
|
911
|
-
|
|
912
|
-
{ 'Fn::GetAtt': ['FriggNATGatewayEIP', 'AllocationId'] },
|
|
913
|
-
SubnetId: discoveredResources.publicSubnetId || discoveredResources.privateSubnetId1, // Use first discovered subnet if no public subnet found
|
|
833
|
+
Domain: 'vpc',
|
|
914
834
|
Tags: [
|
|
915
|
-
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-
|
|
835
|
+
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-eip' }
|
|
916
836
|
]
|
|
917
837
|
}
|
|
918
838
|
};
|
|
919
839
|
}
|
|
920
840
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
Type: 'AWS::EC2::RouteTable',
|
|
841
|
+
definition.resources.Resources.FriggNATGateway = {
|
|
842
|
+
Type: 'AWS::EC2::NatGateway',
|
|
924
843
|
Properties: {
|
|
925
|
-
|
|
844
|
+
AllocationId: discoveredResources.existingElasticIpAllocationId ||
|
|
845
|
+
{ 'Fn::GetAtt': ['FriggNATGatewayEIP', 'AllocationId'] },
|
|
846
|
+
SubnetId: discoveredResources.publicSubnetId || discoveredResources.privateSubnetId1, // Use first discovered subnet if no public subnet found
|
|
926
847
|
Tags: [
|
|
927
|
-
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-
|
|
848
|
+
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-gateway' }
|
|
928
849
|
]
|
|
929
850
|
}
|
|
930
851
|
};
|
|
852
|
+
}
|
|
931
853
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
854
|
+
// Create route table for Lambda subnets to use NAT Gateway
|
|
855
|
+
definition.resources.Resources.FriggLambdaRouteTable = {
|
|
856
|
+
Type: 'AWS::EC2::RouteTable',
|
|
857
|
+
Properties: {
|
|
858
|
+
VpcId: discoveredResources.defaultVpcId || { Ref: 'FriggVPC' },
|
|
859
|
+
Tags: [
|
|
860
|
+
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-lambda-rt' }
|
|
861
|
+
]
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
definition.resources.Resources.FriggNATRoute = {
|
|
866
|
+
Type: 'AWS::EC2::Route',
|
|
867
|
+
Properties: {
|
|
868
|
+
RouteTableId: { Ref: 'FriggLambdaRouteTable' },
|
|
869
|
+
DestinationCidrBlock: '0.0.0.0/0',
|
|
870
|
+
NatGatewayId: discoveredResources.existingNatGatewayId || { Ref: 'FriggNATGateway' }
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
// Associate Lambda subnets with NAT Gateway route table
|
|
875
|
+
definition.resources.Resources.FriggSubnet1RouteAssociation = {
|
|
876
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
877
|
+
Properties: {
|
|
878
|
+
SubnetId: vpcConfig.subnetIds[0],
|
|
879
|
+
RouteTableId: { Ref: 'FriggLambdaRouteTable' }
|
|
880
|
+
}
|
|
881
|
+
};
|
|
940
882
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
883
|
+
definition.resources.Resources.FriggSubnet2RouteAssociation = {
|
|
884
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
885
|
+
Properties: {
|
|
886
|
+
SubnetId: vpcConfig.subnetIds[1],
|
|
887
|
+
RouteTableId: { Ref: 'FriggLambdaRouteTable' }
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
// Add VPC endpoints for AWS service optimization (optional but recommended)
|
|
892
|
+
if (AppDefinition.vpc.enableVPCEndpoints !== false) {
|
|
893
|
+
definition.resources.Resources.VPCEndpointS3 = {
|
|
894
|
+
Type: 'AWS::EC2::VPCEndpoint',
|
|
944
895
|
Properties: {
|
|
945
|
-
|
|
946
|
-
|
|
896
|
+
VpcId: discoveredResources.defaultVpcId,
|
|
897
|
+
ServiceName: 'com.amazonaws.${self:provider.region}.s3',
|
|
898
|
+
VpcEndpointType: 'Gateway',
|
|
899
|
+
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
947
900
|
}
|
|
948
901
|
};
|
|
949
902
|
|
|
950
|
-
definition.resources.Resources.
|
|
951
|
-
Type: 'AWS::EC2::
|
|
903
|
+
definition.resources.Resources.VPCEndpointDynamoDB = {
|
|
904
|
+
Type: 'AWS::EC2::VPCEndpoint',
|
|
952
905
|
Properties: {
|
|
953
|
-
|
|
954
|
-
|
|
906
|
+
VpcId: discoveredResources.defaultVpcId,
|
|
907
|
+
ServiceName: 'com.amazonaws.${self:provider.region}.dynamodb',
|
|
908
|
+
VpcEndpointType: 'Gateway',
|
|
909
|
+
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
955
910
|
}
|
|
956
911
|
};
|
|
957
|
-
|
|
958
|
-
// Add VPC endpoints for AWS service optimization (optional but recommended)
|
|
959
|
-
if (AppDefinition.vpc.enableVPCEndpoints !== false) {
|
|
960
|
-
definition.resources.Resources.VPCEndpointS3 = {
|
|
961
|
-
Type: 'AWS::EC2::VPCEndpoint',
|
|
962
|
-
Properties: {
|
|
963
|
-
VpcId: discoveredResources.defaultVpcId,
|
|
964
|
-
ServiceName: 'com.amazonaws.${self:provider.region}.s3',
|
|
965
|
-
VpcEndpointType: 'Gateway',
|
|
966
|
-
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
|
|
970
|
-
definition.resources.Resources.VPCEndpointDynamoDB = {
|
|
971
|
-
Type: 'AWS::EC2::VPCEndpoint',
|
|
972
|
-
Properties: {
|
|
973
|
-
VpcId: discoveredResources.defaultVpcId,
|
|
974
|
-
ServiceName: 'com.amazonaws.${self:provider.region}.dynamodb',
|
|
975
|
-
VpcEndpointType: 'Gateway',
|
|
976
|
-
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
977
|
-
}
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
912
|
}
|
|
981
913
|
}
|
|
982
914
|
}
|
|
983
915
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
'ssm:GetParameter',
|
|
996
|
-
'ssm:GetParameters',
|
|
997
|
-
'ssm:GetParametersByPath'
|
|
998
|
-
],
|
|
999
|
-
Resource: [
|
|
1000
|
-
'arn:aws:ssm:${self:provider.region}:*:parameter/${self:service}/${self:provider.stage}/*'
|
|
1001
|
-
]
|
|
916
|
+
// SSM Parameter Store Configuration based on App Definition
|
|
917
|
+
if (AppDefinition.ssm?.enable === true) {
|
|
918
|
+
// Add AWS Parameters and Secrets Lambda Extension layer
|
|
919
|
+
definition.provider.layers = [
|
|
920
|
+
'arn:aws:lambda:${self:provider.region}:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11'
|
|
921
|
+
];
|
|
922
|
+
|
|
923
|
+
// Add SSM IAM permissions
|
|
924
|
+
definition.provider.iamRoleStatements.push({
|
|
925
|
+
Effect: 'Allow',
|
|
926
|
+
Action: [
|
|
1002
927
|
'ssm:GetParameter',
|
|
1003
928
|
'ssm:GetParameters',
|
|
1004
929
|
'ssm:GetParametersByPath'
|
|
1005
930
|
],
|
|
1006
|
-
Resource: [
|
|
1007
|
-
|
|
1008
|
-
]
|
|
931
|
+
Resource: [
|
|
932
|
+
'arn:aws:ssm:${self:provider.region}:*:parameter/${self:service}/${self:provider.stage}/*'
|
|
933
|
+
]
|
|
1009
934
|
});
|
|
1010
935
|
|
|
1011
|
-
// Add environment variable for SSM parameter prefix
|
|
1012
|
-
definition.provider.environment.SSM_PARAMETER_PREFIX = '/${self:service}/${self:provider.stage}';
|
|
1013
|
-
// Add environment variable for SSM parameter prefix
|
|
1014
|
-
definition.provider.environment.SSM_PARAMETER_PREFIX = '/${self:service}/${self:provider.stage}';
|
|
936
|
+
// Add environment variable for SSM parameter prefix
|
|
937
|
+
definition.provider.environment.SSM_PARAMETER_PREFIX = '/${self:service}/${self:provider.stage}';
|
|
1015
938
|
}
|
|
1016
939
|
|
|
1017
|
-
// Add integration-specific functions and resources
|
|
1018
|
-
if (AppDefinition.integrations && Array.isArray(AppDefinition.integrations)) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
if (AppDefinition.integrations && Array.isArray(AppDefinition.integrations)) {
|
|
1025
|
-
for (const integration of AppDefinition.integrations) {
|
|
1026
|
-
if (!integration || !integration.Definition || !integration.Definition.name) {
|
|
1027
|
-
throw new Error('Invalid integration: missing Definition or name');
|
|
1028
|
-
}
|
|
1029
|
-
const integrationName = integration.Definition.name;
|
|
940
|
+
// Add integration-specific functions and resources
|
|
941
|
+
if (AppDefinition.integrations && Array.isArray(AppDefinition.integrations)) {
|
|
942
|
+
for (const integration of AppDefinition.integrations) {
|
|
943
|
+
if (!integration || !integration.Definition || !integration.Definition.name) {
|
|
944
|
+
throw new Error('Invalid integration: missing Definition or name');
|
|
945
|
+
}
|
|
946
|
+
const integrationName = integration.Definition.name;
|
|
1030
947
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
},
|
|
948
|
+
// Add function for the integration
|
|
949
|
+
definition.functions[integrationName] = {
|
|
950
|
+
handler: `node_modules/@friggframework/core/handlers/routers/integration-defined-routers.handlers.${integrationName}.handler`,
|
|
951
|
+
events: [
|
|
952
|
+
{
|
|
953
|
+
httpApi: {
|
|
954
|
+
path: `/api/${integrationName}-integration/{proxy+}`,
|
|
955
|
+
method: 'ANY',
|
|
1040
956
|
},
|
|
1041
|
-
|
|
1042
|
-
|
|
957
|
+
},
|
|
958
|
+
],
|
|
959
|
+
};
|
|
1043
960
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
},
|
|
961
|
+
// Add SQS Queue for the integration
|
|
962
|
+
const queueReference = `${integrationName.charAt(0).toUpperCase() + integrationName.slice(1)
|
|
963
|
+
}Queue`;
|
|
964
|
+
const queueName = `\${self:service}--\${self:provider.stage}-${queueReference}`;
|
|
965
|
+
definition.resources.Resources[queueReference] = {
|
|
966
|
+
Type: 'AWS::SQS::Queue',
|
|
967
|
+
Properties: {
|
|
968
|
+
QueueName: `\${self:custom.${queueReference}}`,
|
|
969
|
+
MessageRetentionPeriod: 60,
|
|
970
|
+
VisibilityTimeout: 1800, // 30 minutes
|
|
971
|
+
RedrivePolicy: {
|
|
972
|
+
maxReceiveCount: 1,
|
|
973
|
+
deadLetterTargetArn: {
|
|
974
|
+
'Fn::GetAtt': ['InternalErrorQueue', 'Arn'],
|
|
1059
975
|
},
|
|
1060
976
|
},
|
|
1061
|
-
}
|
|
977
|
+
},
|
|
978
|
+
};
|
|
1062
979
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
},
|
|
1074
|
-
batchSize: 1,
|
|
980
|
+
// Add Queue Worker for the integration
|
|
981
|
+
const queueWorkerName = `${integrationName}QueueWorker`;
|
|
982
|
+
definition.functions[queueWorkerName] = {
|
|
983
|
+
handler: `node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.${integrationName}.queueWorker`,
|
|
984
|
+
reservedConcurrency: 5,
|
|
985
|
+
events: [
|
|
986
|
+
{
|
|
987
|
+
sqs: {
|
|
988
|
+
arn: {
|
|
989
|
+
'Fn::GetAtt': [queueReference, 'Arn'],
|
|
1075
990
|
},
|
|
991
|
+
batchSize: 1,
|
|
1076
992
|
},
|
|
1077
|
-
],
|
|
1078
|
-
timeout: 600,
|
|
1079
|
-
};
|
|
1080
|
-
|
|
1081
|
-
// Add Queue URL for the integration to the ENVironment variables
|
|
1082
|
-
definition.provider.environment = {
|
|
1083
|
-
...definition.provider.environment,
|
|
1084
|
-
[`${integrationName.toUpperCase()}_QUEUE_URL`]: {
|
|
1085
|
-
Ref: queueReference,
|
|
1086
|
-
},
|
|
1087
|
-
};
|
|
1088
|
-
// Add Queue URL for the integration to the ENVironment variables
|
|
1089
|
-
definition.provider.environment = {
|
|
1090
|
-
...definition.provider.environment,
|
|
1091
|
-
[`${integrationName.toUpperCase()}_QUEUE_URL`]: {
|
|
1092
|
-
Ref: queueReference,
|
|
1093
993
|
},
|
|
1094
|
-
|
|
994
|
+
],
|
|
995
|
+
timeout: 600,
|
|
996
|
+
};
|
|
1095
997
|
|
|
1096
|
-
|
|
998
|
+
// Add Queue URL for the integration to the ENVironment variables
|
|
999
|
+
definition.provider.environment = {
|
|
1000
|
+
...definition.provider.environment,
|
|
1001
|
+
[`${integrationName.toUpperCase()}_QUEUE_URL`]: {
|
|
1002
|
+
Ref: queueReference,
|
|
1003
|
+
},
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
definition.custom[queueReference] = queueName;
|
|
1097
1007
|
}
|
|
1098
1008
|
}
|
|
1099
1009
|
|
|
@@ -1149,7 +1059,6 @@ if (AppDefinition.integrations && Array.isArray(AppDefinition.integrations)) {
|
|
|
1149
1059
|
},
|
|
1150
1060
|
],
|
|
1151
1061
|
};
|
|
1152
|
-
definition.custom[queueReference] = queueName;
|
|
1153
1062
|
}
|
|
1154
1063
|
}
|
|
1155
1064
|
|
|
@@ -1183,30 +1092,6 @@ if (AppDefinition.integrations && Array.isArray(AppDefinition.integrations)) {
|
|
|
1183
1092
|
// Discovery has already run successfully at this point if needed
|
|
1184
1093
|
// The discoveredResources object contains all the necessary AWS resources
|
|
1185
1094
|
|
|
1186
|
-
// Add websocket function if enabled
|
|
1187
|
-
if (AppDefinition.websockets?.enable === true) {
|
|
1188
|
-
definition.functions.defaultWebsocket = {
|
|
1189
|
-
handler: 'node_modules/@friggframework/core/handlers/routers/websocket.handler',
|
|
1190
|
-
events: [
|
|
1191
|
-
{
|
|
1192
|
-
websocket: {
|
|
1193
|
-
route: '$connect',
|
|
1194
|
-
},
|
|
1195
|
-
},
|
|
1196
|
-
{
|
|
1197
|
-
websocket: {
|
|
1198
|
-
route: '$default',
|
|
1199
|
-
},
|
|
1200
|
-
},
|
|
1201
|
-
{
|
|
1202
|
-
websocket: {
|
|
1203
|
-
route: '$disconnect',
|
|
1204
|
-
},
|
|
1205
|
-
},
|
|
1206
|
-
],
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
1095
|
// Modify handler paths to point to the correct node_modules location
|
|
1211
1096
|
definition.functions = modifyHandlerPaths(definition.functions);
|
|
1212
1097
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: { browser: true, es2020: true },
|
|
4
|
+
extends: [
|
|
5
|
+
'eslint:recommended',
|
|
6
|
+
'@eslint/js/recommended',
|
|
7
|
+
'plugin:react/recommended',
|
|
8
|
+
'plugin:react/jsx-runtime',
|
|
9
|
+
'plugin:react-hooks/recommended',
|
|
10
|
+
],
|
|
11
|
+
ignorePatterns: ['dist', '.eslintrc.js'],
|
|
12
|
+
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
|
13
|
+
settings: { react: { version: '18.3' } },
|
|
14
|
+
plugins: ['react-refresh'],
|
|
15
|
+
rules: {
|
|
16
|
+
'react/jsx-no-target-blank': 'off',
|
|
17
|
+
'react-refresh/only-export-components': [
|
|
18
|
+
'warn',
|
|
19
|
+
{ allowConstantExport: true },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
}
|