@friggframework/devtools 2.0.0-next.6 → 2.0.0-next.61

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 (357) hide show
  1. package/frigg-cli/README.md +1289 -0
  2. package/frigg-cli/__tests__/unit/commands/build.test.js +279 -0
  3. package/frigg-cli/__tests__/unit/commands/db-setup.test.js +649 -0
  4. package/frigg-cli/__tests__/unit/commands/deploy.test.js +320 -0
  5. package/frigg-cli/__tests__/unit/commands/doctor.test.js +309 -0
  6. package/frigg-cli/__tests__/unit/commands/install.test.js +400 -0
  7. package/frigg-cli/__tests__/unit/commands/ui.test.js +346 -0
  8. package/frigg-cli/__tests__/unit/dependencies.test.js +74 -0
  9. package/frigg-cli/__tests__/unit/utils/database-validator.test.js +397 -0
  10. package/frigg-cli/__tests__/unit/utils/error-messages.test.js +345 -0
  11. package/frigg-cli/__tests__/unit/version-detection.test.js +171 -0
  12. package/frigg-cli/__tests__/utils/mock-factory.js +270 -0
  13. package/frigg-cli/__tests__/utils/prisma-mock.js +194 -0
  14. package/frigg-cli/__tests__/utils/test-fixtures.js +463 -0
  15. package/frigg-cli/__tests__/utils/test-setup.js +287 -0
  16. package/frigg-cli/build-command/index.js +53 -14
  17. package/frigg-cli/db-setup-command/index.js +246 -0
  18. package/frigg-cli/deploy-command/SPEC-DEPLOY-DRY-RUN.md +981 -0
  19. package/frigg-cli/deploy-command/index.js +295 -17
  20. package/frigg-cli/doctor-command/index.js +335 -0
  21. package/frigg-cli/generate-command/__tests__/generate-command.test.js +301 -0
  22. package/frigg-cli/generate-command/azure-generator.js +43 -0
  23. package/frigg-cli/generate-command/gcp-generator.js +47 -0
  24. package/frigg-cli/generate-command/index.js +332 -0
  25. package/frigg-cli/generate-command/terraform-generator.js +555 -0
  26. package/frigg-cli/generate-iam-command.js +118 -0
  27. package/frigg-cli/index.js +142 -1
  28. package/frigg-cli/index.test.js +1 -4
  29. package/frigg-cli/init-command/backend-first-handler.js +756 -0
  30. package/frigg-cli/init-command/index.js +93 -0
  31. package/frigg-cli/init-command/template-handler.js +143 -0
  32. package/frigg-cli/install-command/index.js +1 -4
  33. package/frigg-cli/jest.config.js +124 -0
  34. package/frigg-cli/package.json +63 -0
  35. package/frigg-cli/repair-command/index.js +564 -0
  36. package/frigg-cli/start-command/index.js +125 -6
  37. package/frigg-cli/start-command/start-command.test.js +297 -0
  38. package/frigg-cli/test/init-command.test.js +180 -0
  39. package/frigg-cli/test/npm-registry.test.js +319 -0
  40. package/frigg-cli/ui-command/index.js +154 -0
  41. package/frigg-cli/utils/app-resolver.js +319 -0
  42. package/frigg-cli/utils/backend-path.js +16 -17
  43. package/frigg-cli/utils/database-validator.js +167 -0
  44. package/frigg-cli/utils/error-messages.js +329 -0
  45. package/frigg-cli/utils/npm-registry.js +167 -0
  46. package/frigg-cli/utils/process-manager.js +199 -0
  47. package/frigg-cli/utils/repo-detection.js +405 -0
  48. package/infrastructure/ARCHITECTURE.md +487 -0
  49. package/infrastructure/CLAUDE.md +481 -0
  50. package/infrastructure/HEALTH.md +468 -0
  51. package/infrastructure/README.md +522 -0
  52. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +391 -0
  53. package/infrastructure/__tests__/helpers/test-utils.js +277 -0
  54. package/infrastructure/__tests__/postgres-config.test.js +914 -0
  55. package/infrastructure/__tests__/template-generation.test.js +687 -0
  56. package/infrastructure/create-frigg-infrastructure.js +129 -20
  57. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
  58. package/infrastructure/docs/PRE-DEPLOYMENT-HEALTH-CHECK-SPEC.md +1317 -0
  59. package/infrastructure/docs/WEBSOCKET-CONFIGURATION.md +105 -0
  60. package/infrastructure/docs/deployment-instructions.md +268 -0
  61. package/infrastructure/docs/generate-iam-command.md +278 -0
  62. package/infrastructure/docs/iam-policy-templates.md +193 -0
  63. package/infrastructure/domains/database/aurora-builder.js +809 -0
  64. package/infrastructure/domains/database/aurora-builder.test.js +950 -0
  65. package/infrastructure/domains/database/aurora-discovery.js +87 -0
  66. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  67. package/infrastructure/domains/database/aurora-resolver.js +210 -0
  68. package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
  69. package/infrastructure/domains/database/migration-builder.js +701 -0
  70. package/infrastructure/domains/database/migration-builder.test.js +321 -0
  71. package/infrastructure/domains/database/migration-resolver.js +163 -0
  72. package/infrastructure/domains/database/migration-resolver.test.js +337 -0
  73. package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
  74. package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
  75. package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
  76. package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
  77. package/infrastructure/domains/health/application/ports/index.js +26 -0
  78. package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
  79. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  80. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
  81. package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
  82. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
  83. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
  84. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
  85. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
  86. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
  87. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
  88. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  89. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  90. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  91. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  92. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  93. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  94. package/infrastructure/domains/health/domain/entities/issue.js +299 -0
  95. package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
  96. package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
  97. package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
  98. package/infrastructure/domains/health/domain/entities/resource.js +159 -0
  99. package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
  100. package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
  101. package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
  102. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  103. package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
  104. package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
  105. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
  106. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  107. package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
  108. package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
  109. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
  110. package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
  111. package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
  112. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
  113. package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
  114. package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
  115. package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
  116. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  117. package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
  118. package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
  119. package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
  120. package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
  121. package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
  122. package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
  123. package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
  124. package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
  125. package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
  126. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  127. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  128. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  129. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
  130. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
  131. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
  132. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
  133. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
  134. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
  135. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
  136. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
  137. package/infrastructure/domains/integration/integration-builder.js +404 -0
  138. package/infrastructure/domains/integration/integration-builder.test.js +690 -0
  139. package/infrastructure/domains/integration/integration-resolver.js +170 -0
  140. package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
  141. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  142. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  143. package/infrastructure/domains/networking/vpc-builder.js +2051 -0
  144. package/infrastructure/domains/networking/vpc-builder.test.js +1960 -0
  145. package/infrastructure/domains/networking/vpc-discovery.js +177 -0
  146. package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
  147. package/infrastructure/domains/networking/vpc-resolver.js +505 -0
  148. package/infrastructure/domains/networking/vpc-resolver.test.js +801 -0
  149. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  150. package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
  151. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  152. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  153. package/infrastructure/domains/security/iam-generator.js +816 -0
  154. package/infrastructure/domains/security/iam-generator.test.js +204 -0
  155. package/infrastructure/domains/security/kms-builder.js +415 -0
  156. package/infrastructure/domains/security/kms-builder.test.js +392 -0
  157. package/infrastructure/domains/security/kms-discovery.js +80 -0
  158. package/infrastructure/domains/security/kms-discovery.test.js +177 -0
  159. package/infrastructure/domains/security/kms-resolver.js +96 -0
  160. package/infrastructure/domains/security/kms-resolver.test.js +216 -0
  161. package/infrastructure/domains/security/templates/frigg-deployment-iam-stack.yaml +401 -0
  162. package/infrastructure/domains/security/templates/iam-policy-basic.json +218 -0
  163. package/infrastructure/domains/security/templates/iam-policy-full.json +288 -0
  164. package/infrastructure/domains/shared/base-builder.js +112 -0
  165. package/infrastructure/domains/shared/base-resolver.js +186 -0
  166. package/infrastructure/domains/shared/base-resolver.test.js +305 -0
  167. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  168. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  169. package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
  170. package/infrastructure/domains/shared/cloudformation-discovery.js +672 -0
  171. package/infrastructure/domains/shared/cloudformation-discovery.test.js +985 -0
  172. package/infrastructure/domains/shared/environment-builder.js +119 -0
  173. package/infrastructure/domains/shared/environment-builder.test.js +247 -0
  174. package/infrastructure/domains/shared/providers/aws-provider-adapter.js +579 -0
  175. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +416 -0
  176. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  177. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  178. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  179. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  180. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  181. package/infrastructure/domains/shared/resource-discovery.enhanced.test.js +306 -0
  182. package/infrastructure/domains/shared/resource-discovery.js +233 -0
  183. package/infrastructure/domains/shared/resource-discovery.test.js +588 -0
  184. package/infrastructure/domains/shared/types/app-definition.js +205 -0
  185. package/infrastructure/domains/shared/types/discovery-result.js +106 -0
  186. package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
  187. package/infrastructure/domains/shared/types/index.js +46 -0
  188. package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
  189. package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
  190. package/infrastructure/domains/shared/utilities/base-definition-factory.js +394 -0
  191. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  192. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +291 -0
  193. package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
  194. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
  195. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +159 -0
  196. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +444 -0
  197. package/infrastructure/domains/shared/validation/env-validator.js +78 -0
  198. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  199. package/infrastructure/domains/shared/validation/plugin-validator.js +187 -0
  200. package/infrastructure/domains/shared/validation/plugin-validator.test.js +323 -0
  201. package/infrastructure/esbuild.config.js +53 -0
  202. package/infrastructure/infrastructure-composer.js +117 -0
  203. package/infrastructure/infrastructure-composer.test.js +1895 -0
  204. package/infrastructure/integration.test.js +383 -0
  205. package/infrastructure/scripts/build-prisma-layer.js +701 -0
  206. package/infrastructure/scripts/build-prisma-layer.test.js +170 -0
  207. package/infrastructure/scripts/build-time-discovery.js +238 -0
  208. package/infrastructure/scripts/build-time-discovery.test.js +379 -0
  209. package/infrastructure/scripts/run-discovery.js +110 -0
  210. package/infrastructure/scripts/verify-prisma-layer.js +72 -0
  211. package/layers/prisma/.build-complete +3 -0
  212. package/layers/prisma/nodejs/package.json +8 -0
  213. package/management-ui/.eslintrc.js +22 -0
  214. package/management-ui/README.md +203 -0
  215. package/management-ui/components.json +21 -0
  216. package/management-ui/docs/phase2-integration-guide.md +320 -0
  217. package/management-ui/index.html +13 -0
  218. package/management-ui/package.json +76 -0
  219. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +302 -0
  220. package/management-ui/postcss.config.js +6 -0
  221. package/management-ui/server/api/backend.js +256 -0
  222. package/management-ui/server/api/cli.js +315 -0
  223. package/management-ui/server/api/codegen.js +663 -0
  224. package/management-ui/server/api/connections.js +857 -0
  225. package/management-ui/server/api/discovery.js +185 -0
  226. package/management-ui/server/api/environment/index.js +1 -0
  227. package/management-ui/server/api/environment/router.js +378 -0
  228. package/management-ui/server/api/environment.js +328 -0
  229. package/management-ui/server/api/integrations.js +876 -0
  230. package/management-ui/server/api/logs.js +248 -0
  231. package/management-ui/server/api/monitoring.js +282 -0
  232. package/management-ui/server/api/open-ide.js +31 -0
  233. package/management-ui/server/api/project.js +1029 -0
  234. package/management-ui/server/api/users/sessions.js +371 -0
  235. package/management-ui/server/api/users/simulation.js +254 -0
  236. package/management-ui/server/api/users.js +362 -0
  237. package/management-ui/server/api-contract.md +275 -0
  238. package/management-ui/server/index.js +873 -0
  239. package/management-ui/server/middleware/errorHandler.js +93 -0
  240. package/management-ui/server/middleware/security.js +32 -0
  241. package/management-ui/server/processManager.js +296 -0
  242. package/management-ui/server/server.js +346 -0
  243. package/management-ui/server/services/aws-monitor.js +413 -0
  244. package/management-ui/server/services/npm-registry.js +347 -0
  245. package/management-ui/server/services/template-engine.js +538 -0
  246. package/management-ui/server/utils/cliIntegration.js +220 -0
  247. package/management-ui/server/utils/environment/auditLogger.js +471 -0
  248. package/management-ui/server/utils/environment/awsParameterStore.js +275 -0
  249. package/management-ui/server/utils/environment/encryption.js +278 -0
  250. package/management-ui/server/utils/environment/envFileManager.js +286 -0
  251. package/management-ui/server/utils/import-commonjs.js +28 -0
  252. package/management-ui/server/utils/response.js +83 -0
  253. package/management-ui/server/websocket/handler.js +325 -0
  254. package/management-ui/src/App.jsx +25 -0
  255. package/management-ui/src/assets/FriggLogo.svg +1 -0
  256. package/management-ui/src/components/AppRouter.jsx +65 -0
  257. package/management-ui/src/components/Button.jsx +70 -0
  258. package/management-ui/src/components/Card.jsx +97 -0
  259. package/management-ui/src/components/EnvironmentCompare.jsx +400 -0
  260. package/management-ui/src/components/EnvironmentEditor.jsx +372 -0
  261. package/management-ui/src/components/EnvironmentImportExport.jsx +469 -0
  262. package/management-ui/src/components/EnvironmentSchema.jsx +491 -0
  263. package/management-ui/src/components/EnvironmentSecurity.jsx +463 -0
  264. package/management-ui/src/components/ErrorBoundary.jsx +73 -0
  265. package/management-ui/src/components/IntegrationCard.jsx +481 -0
  266. package/management-ui/src/components/IntegrationCardEnhanced.jsx +770 -0
  267. package/management-ui/src/components/IntegrationExplorer.jsx +379 -0
  268. package/management-ui/src/components/IntegrationStatus.jsx +336 -0
  269. package/management-ui/src/components/Layout.jsx +716 -0
  270. package/management-ui/src/components/LoadingSpinner.jsx +113 -0
  271. package/management-ui/src/components/RepositoryPicker.jsx +248 -0
  272. package/management-ui/src/components/SessionMonitor.jsx +350 -0
  273. package/management-ui/src/components/StatusBadge.jsx +208 -0
  274. package/management-ui/src/components/UserContextSwitcher.jsx +212 -0
  275. package/management-ui/src/components/UserSimulation.jsx +327 -0
  276. package/management-ui/src/components/Welcome.jsx +434 -0
  277. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +637 -0
  278. package/management-ui/src/components/codegen/APIModuleSelector.jsx +227 -0
  279. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +247 -0
  280. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +316 -0
  281. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +271 -0
  282. package/management-ui/src/components/codegen/FormBuilder.jsx +737 -0
  283. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +855 -0
  284. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +797 -0
  285. package/management-ui/src/components/codegen/SchemaBuilder.jsx +303 -0
  286. package/management-ui/src/components/codegen/TemplateSelector.jsx +586 -0
  287. package/management-ui/src/components/codegen/index.js +10 -0
  288. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +362 -0
  289. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +182 -0
  290. package/management-ui/src/components/connections/ConnectionTester.jsx +200 -0
  291. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +292 -0
  292. package/management-ui/src/components/connections/OAuthFlow.jsx +204 -0
  293. package/management-ui/src/components/connections/index.js +5 -0
  294. package/management-ui/src/components/index.js +21 -0
  295. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +222 -0
  296. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +169 -0
  297. package/management-ui/src/components/monitoring/MetricsChart.jsx +197 -0
  298. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +393 -0
  299. package/management-ui/src/components/monitoring/SQSMetrics.jsx +246 -0
  300. package/management-ui/src/components/monitoring/index.js +6 -0
  301. package/management-ui/src/components/monitoring/monitoring.css +218 -0
  302. package/management-ui/src/components/theme-provider.jsx +52 -0
  303. package/management-ui/src/components/theme-toggle.jsx +39 -0
  304. package/management-ui/src/components/ui/badge.tsx +36 -0
  305. package/management-ui/src/components/ui/button.test.jsx +56 -0
  306. package/management-ui/src/components/ui/button.tsx +57 -0
  307. package/management-ui/src/components/ui/card.tsx +76 -0
  308. package/management-ui/src/components/ui/dropdown-menu.tsx +199 -0
  309. package/management-ui/src/components/ui/select.tsx +157 -0
  310. package/management-ui/src/components/ui/skeleton.jsx +15 -0
  311. package/management-ui/src/hooks/useFrigg.jsx +387 -0
  312. package/management-ui/src/hooks/useSocket.jsx +58 -0
  313. package/management-ui/src/index.css +193 -0
  314. package/management-ui/src/lib/utils.ts +6 -0
  315. package/management-ui/src/main.jsx +10 -0
  316. package/management-ui/src/pages/CodeGeneration.jsx +14 -0
  317. package/management-ui/src/pages/Connections.jsx +252 -0
  318. package/management-ui/src/pages/ConnectionsEnhanced.jsx +633 -0
  319. package/management-ui/src/pages/Dashboard.jsx +311 -0
  320. package/management-ui/src/pages/Environment.jsx +314 -0
  321. package/management-ui/src/pages/IntegrationConfigure.jsx +669 -0
  322. package/management-ui/src/pages/IntegrationDiscovery.jsx +567 -0
  323. package/management-ui/src/pages/IntegrationTest.jsx +742 -0
  324. package/management-ui/src/pages/Integrations.jsx +253 -0
  325. package/management-ui/src/pages/Monitoring.jsx +17 -0
  326. package/management-ui/src/pages/Simulation.jsx +155 -0
  327. package/management-ui/src/pages/Users.jsx +492 -0
  328. package/management-ui/src/services/api.js +41 -0
  329. package/management-ui/src/services/apiModuleService.js +193 -0
  330. package/management-ui/src/services/websocket-handlers.js +120 -0
  331. package/management-ui/src/test/api/project.test.js +273 -0
  332. package/management-ui/src/test/components/Welcome.test.jsx +378 -0
  333. package/management-ui/src/test/mocks/server.js +178 -0
  334. package/management-ui/src/test/setup.js +61 -0
  335. package/management-ui/src/test/utils/test-utils.jsx +134 -0
  336. package/management-ui/src/utils/repository.js +98 -0
  337. package/management-ui/src/utils/repository.test.js +118 -0
  338. package/management-ui/src/workflows/phase2-integration-workflows.js +884 -0
  339. package/management-ui/tailwind.config.js +63 -0
  340. package/management-ui/tsconfig.json +37 -0
  341. package/management-ui/tsconfig.node.json +10 -0
  342. package/management-ui/vite.config.js +26 -0
  343. package/management-ui/vitest.config.js +38 -0
  344. package/package.json +35 -14
  345. package/test/index.js +2 -4
  346. package/test/mock-integration.js +4 -14
  347. package/infrastructure/app-handler-helpers.js +0 -57
  348. package/infrastructure/backend-utils.js +0 -87
  349. package/infrastructure/routers/auth.js +0 -26
  350. package/infrastructure/routers/integration-defined-routers.js +0 -42
  351. package/infrastructure/routers/middleware/loadUser.js +0 -15
  352. package/infrastructure/routers/middleware/requireLoggedInUser.js +0 -12
  353. package/infrastructure/routers/user.js +0 -41
  354. package/infrastructure/routers/websocket.js +0 -55
  355. package/infrastructure/serverless-template.js +0 -291
  356. package/infrastructure/workers/integration-defined-workers.js +0 -24
  357. package/test/auther-definition-tester.js +0 -125
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Tests for BuilderOrchestrator
3
+ *
4
+ * Tests orchestration, dependency resolution, and parallel execution
5
+ */
6
+
7
+ const { BuilderOrchestrator } = require('./builder-orchestrator');
8
+ const { InfrastructureBuilder, ValidationResult } = require('./base-builder');
9
+
10
+ // Mock builders for testing
11
+ class MockBuilderA extends InfrastructureBuilder {
12
+ getName() { return 'MockBuilderA'; }
13
+ shouldExecute(appDef) { return appDef.featureA === true; }
14
+ validate(appDef) { return new ValidationResult(); }
15
+ async build(appDef, discovered) {
16
+ return {
17
+ resources: { ResourceA: { Type: 'Test' } },
18
+ iamStatements: [{ Effect: 'Allow', Action: 'test:A' }],
19
+ };
20
+ }
21
+ }
22
+
23
+ class MockBuilderB extends InfrastructureBuilder {
24
+ getName() { return 'MockBuilderB'; }
25
+ shouldExecute(appDef) { return appDef.featureB === true; }
26
+ validate(appDef) { return new ValidationResult(); }
27
+ getDependencies() { return ['MockBuilderA']; } // Depends on A
28
+ async build(appDef, discovered) {
29
+ return {
30
+ resources: { ResourceB: { Type: 'Test' } },
31
+ environment: { VAR_B: 'value-b' },
32
+ };
33
+ }
34
+ }
35
+
36
+ class MockBuilderC extends InfrastructureBuilder {
37
+ getName() { return 'MockBuilderC'; }
38
+ shouldExecute() { return false; } // Never executes
39
+ validate() { return new ValidationResult(); }
40
+ async build() {
41
+ throw new Error('Should not be called');
42
+ }
43
+ }
44
+
45
+ jest.mock('./resource-discovery', () => ({
46
+ gatherDiscoveredResources: jest.fn().mockResolvedValue({ discovered: true }),
47
+ }));
48
+
49
+ jest.mock('./environment-builder', () => ({
50
+ getAppEnvironmentVars: jest.fn().mockReturnValue({ ENV_VAR: 'value' }),
51
+ buildEnvironment: jest.fn().mockReturnValue({ ENV_VAR: 'value' }),
52
+ }));
53
+
54
+ describe('BuilderOrchestrator', () => {
55
+ let orchestrator;
56
+
57
+ beforeEach(() => {
58
+ jest.clearAllMocks();
59
+ });
60
+
61
+ describe('registerBuilder()', () => {
62
+ it('should register builders', () => {
63
+ orchestrator = new BuilderOrchestrator();
64
+ const builder = new MockBuilderA();
65
+
66
+ orchestrator.registerBuilder(builder);
67
+
68
+ expect(orchestrator.builders.has('MockBuilderA')).toBe(true);
69
+ });
70
+
71
+ it('should register multiple builders via constructor', () => {
72
+ orchestrator = new BuilderOrchestrator([
73
+ new MockBuilderA(),
74
+ new MockBuilderB(),
75
+ ]);
76
+
77
+ expect(orchestrator.builders.size).toBe(2);
78
+ });
79
+ });
80
+
81
+ describe('validateAll()', () => {
82
+ it('should validate all applicable builders', async () => {
83
+ orchestrator = new BuilderOrchestrator([
84
+ new MockBuilderA(),
85
+ new MockBuilderB(),
86
+ ]);
87
+
88
+ const appDef = { featureA: true, featureB: true };
89
+
90
+ await expect(orchestrator.validateAll(appDef)).resolves.toBeDefined();
91
+ });
92
+
93
+ it('should skip builders that shouldNotExecute', async () => {
94
+ orchestrator = new BuilderOrchestrator([
95
+ new MockBuilderA(),
96
+ new MockBuilderC(), // Should not execute
97
+ ]);
98
+
99
+ const appDef = { featureA: true };
100
+
101
+ const results = await orchestrator.validateAll(appDef);
102
+
103
+ // Should only validate MockBuilderA
104
+ expect(results).toHaveLength(1);
105
+ expect(results[0].builder).toBe('MockBuilderA');
106
+ });
107
+
108
+ it('should throw error if validation fails', async () => {
109
+ class FailingBuilder extends InfrastructureBuilder {
110
+ getName() { return 'FailingBuilder'; }
111
+ shouldExecute() { return true; }
112
+ validate() {
113
+ const result = new ValidationResult();
114
+ result.addError('Test error');
115
+ return result;
116
+ }
117
+ }
118
+
119
+ orchestrator = new BuilderOrchestrator([new FailingBuilder()]);
120
+
121
+ await expect(orchestrator.validateAll({})).rejects.toThrow('Infrastructure validation failed');
122
+ });
123
+ });
124
+
125
+ describe('resolveBuildOrder()', () => {
126
+ it('should resolve dependencies correctly', () => {
127
+ orchestrator = new BuilderOrchestrator([
128
+ new MockBuilderB(), // Depends on A
129
+ new MockBuilderA(), // No dependencies
130
+ ]);
131
+
132
+ const appDef = { featureA: true, featureB: true };
133
+ const order = orchestrator.resolveBuildOrder(appDef);
134
+
135
+ // A should come before B
136
+ expect(order).toEqual(['MockBuilderA', 'MockBuilderB']);
137
+ });
138
+
139
+ it('should handle builders with no dependencies', () => {
140
+ orchestrator = new BuilderOrchestrator([
141
+ new MockBuilderA(),
142
+ ]);
143
+
144
+ const appDef = { featureA: true };
145
+ const order = orchestrator.resolveBuildOrder(appDef);
146
+
147
+ expect(order).toEqual(['MockBuilderA']);
148
+ });
149
+
150
+ it('should skip builders that should not execute', () => {
151
+ orchestrator = new BuilderOrchestrator([
152
+ new MockBuilderA(),
153
+ new MockBuilderC(), // Should not execute
154
+ ]);
155
+
156
+ const appDef = { featureA: true };
157
+ const order = orchestrator.resolveBuildOrder(appDef);
158
+
159
+ expect(order).toEqual(['MockBuilderA']);
160
+ });
161
+ });
162
+
163
+ describe('buildAll()', () => {
164
+ it('should build all infrastructure and merge results', async () => {
165
+ orchestrator = new BuilderOrchestrator([
166
+ new MockBuilderA(),
167
+ new MockBuilderB(),
168
+ ]);
169
+
170
+ const appDef = { featureA: true, featureB: true };
171
+
172
+ const result = await orchestrator.buildAll(appDef);
173
+
174
+ expect(result.merged).toBeDefined();
175
+ expect(result.merged.resources).toMatchObject({
176
+ ResourceA: { Type: 'Test' },
177
+ ResourceB: { Type: 'Test' },
178
+ });
179
+ expect(result.merged.iamStatements).toHaveLength(1);
180
+ expect(result.merged.environment).toMatchObject({ VAR_B: 'value-b' });
181
+ });
182
+
183
+ it('should skip builders that should not execute', async () => {
184
+ orchestrator = new BuilderOrchestrator([
185
+ new MockBuilderA(),
186
+ new MockBuilderC(), // Should not execute
187
+ ]);
188
+
189
+ const appDef = { featureA: true };
190
+
191
+ const result = await orchestrator.buildAll(appDef);
192
+
193
+ // Should only have results from A
194
+ expect(Object.keys(result.merged.resources)).toEqual(['ResourceA']);
195
+ });
196
+
197
+ it('should throw error if builder fails', async () => {
198
+ class FailingBuilder extends InfrastructureBuilder {
199
+ getName() { return 'FailingBuilder'; }
200
+ shouldExecute() { return true; }
201
+ validate() { return new ValidationResult(); }
202
+ async build() {
203
+ throw new Error('Build failed');
204
+ }
205
+ }
206
+
207
+ orchestrator = new BuilderOrchestrator([new FailingBuilder()]);
208
+
209
+ await expect(orchestrator.buildAll({})).rejects.toThrow('Build failed');
210
+ });
211
+ });
212
+ });
213
+
@@ -0,0 +1,334 @@
1
+ /**
2
+ * CloudFormation-based Resource Discovery v2
3
+ *
4
+ * Refactored to return structured DiscoveryResult instead of flat object.
5
+ * Part of the clean resource ownership architecture.
6
+ *
7
+ * Domain Service - Hexagonal Architecture
8
+ */
9
+
10
+ const { createEmptyDiscoveryResult } = require('./types');
11
+
12
+ class CloudFormationDiscoveryV2 {
13
+ constructor(provider, config = {}) {
14
+ this.provider = provider;
15
+ this.serviceName = config.serviceName;
16
+ this.stage = config.stage;
17
+ }
18
+
19
+ /**
20
+ * Discover resources from an existing CloudFormation stack
21
+ *
22
+ * @param {string} stackName - Name of the CloudFormation stack
23
+ * @returns {Promise<Object>} DiscoveryResult or empty result if stack doesn't exist
24
+ */
25
+ async discoverFromStack(stackName) {
26
+ try {
27
+ // Try to get the stack
28
+ const stack = await this.provider.describeStack(stackName);
29
+
30
+ // Get stack resources
31
+ const resources = await this.provider.listStackResources(stackName);
32
+
33
+ // Create structured discovery result
34
+ const discovery = createEmptyDiscoveryResult();
35
+ discovery.fromCloudFormation = true;
36
+ discovery.stackName = stackName;
37
+ discovery.region = this.provider.region;
38
+
39
+ // Extract stack-managed resources
40
+ await this._extractStackManagedResources(resources || [], discovery);
41
+
42
+ // Also keep flat structure for backwards compatibility (temporarily)
43
+ const flatDiscovered = {
44
+ fromCloudFormationStack: true,
45
+ stackName: stackName,
46
+ existingLogicalIds: discovery.stackManaged.map(r => r.logicalId)
47
+ };
48
+
49
+ // Extract from outputs (legacy)
50
+ if (stack.Outputs && stack.Outputs.length > 0) {
51
+ this._extractFromOutputs(stack.Outputs, flatDiscovered);
52
+ }
53
+
54
+ // Extract flat properties from stackManaged resources
55
+ this._createFlatPropertiesFromStackManaged(discovery, flatDiscovered);
56
+
57
+ // Return both structures (flat for backwards compat, structured for new code)
58
+ return {
59
+ ...flatDiscovered,
60
+ _structured: discovery // New structured format
61
+ };
62
+ } catch (error) {
63
+ // Stack doesn't exist - return empty discovery
64
+ if (error.message && error.message.includes('does not exist')) {
65
+ const empty = createEmptyDiscoveryResult();
66
+ return {
67
+ fromCloudFormationStack: false,
68
+ _structured: empty
69
+ };
70
+ }
71
+
72
+ // Other errors - log and return empty
73
+ console.warn(`⚠️ CloudFormation discovery failed: ${error.message}`);
74
+ const empty = createEmptyDiscoveryResult();
75
+ return {
76
+ fromCloudFormationStack: false,
77
+ _structured: empty
78
+ };
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Extract stack-managed resources into structured format
84
+ * @private
85
+ */
86
+ async _extractStackManagedResources(resources, discovery) {
87
+ console.log(` DEBUG: Processing ${resources.length} CloudFormation resources...`);
88
+
89
+ for (const resource of resources) {
90
+ const { LogicalResourceId, PhysicalResourceId, ResourceType } = resource;
91
+
92
+ // Only track Frigg-managed resources
93
+ if (!LogicalResourceId.startsWith('Frigg') && !LogicalResourceId.includes('Migration')) {
94
+ continue;
95
+ }
96
+
97
+ // Add to stack-managed list
98
+ const stackResource = {
99
+ logicalId: LogicalResourceId,
100
+ physicalId: PhysicalResourceId,
101
+ resourceType: ResourceType,
102
+ properties: {} // Will be populated as needed
103
+ };
104
+
105
+ discovery.stackManaged.push(stackResource);
106
+
107
+ // Query AWS for detailed properties for certain resources
108
+ await this._enrichResourceProperties(stackResource, discovery);
109
+ }
110
+
111
+ console.log(` ✓ Discovered ${discovery.stackManaged.length} stack-managed resources`);
112
+ }
113
+
114
+ /**
115
+ * Enrich resource properties by querying AWS APIs
116
+ * @private
117
+ */
118
+ async _enrichResourceProperties(stackResource, discovery) {
119
+ const { logicalId, physicalId, resourceType } = stackResource;
120
+
121
+ // Security Group - query to get VPC ID
122
+ if (logicalId === 'FriggLambdaSecurityGroup' && resourceType === 'AWS::EC2::SecurityGroup') {
123
+ console.log(` ✓ Found security group in stack: ${physicalId}`);
124
+
125
+ if (this.provider && this.provider.getEC2Client) {
126
+ try {
127
+ console.log(` Querying EC2 to get VPC ID from security group...`);
128
+ const { DescribeSecurityGroupsCommand } = require('@aws-sdk/client-ec2');
129
+ const ec2Client = this.provider.getEC2Client();
130
+ const sgDetails = await ec2Client.send(
131
+ new DescribeSecurityGroupsCommand({
132
+ GroupIds: [physicalId]
133
+ })
134
+ );
135
+
136
+ if (sgDetails.SecurityGroups && sgDetails.SecurityGroups.length > 0) {
137
+ const sg = sgDetails.SecurityGroups[0];
138
+ stackResource.properties.VpcId = sg.VpcId;
139
+ console.log(` ✓ Extracted VPC ID from security group: ${sg.VpcId}`);
140
+
141
+ // Also add VPC to stack-managed if not already there
142
+ const vpcExists = discovery.stackManaged.some(r => r.logicalId === 'FriggVPC');
143
+ if (!vpcExists && sg.VpcId) {
144
+ // Note: VPC was created by stack, just not listed in resources yet
145
+ // We'll add it when we encounter it, or infer it here
146
+ }
147
+ }
148
+ } catch (error) {
149
+ console.warn(` ⚠️ Could not get VPC from security group: ${error.message}`);
150
+ }
151
+ }
152
+ }
153
+
154
+ // Aurora Cluster - query to get endpoint
155
+ if (logicalId === 'FriggAuroraCluster' && resourceType === 'AWS::RDS::DBCluster') {
156
+ console.log(` ✓ Found Aurora cluster in stack: ${physicalId}`);
157
+
158
+ if (this.provider) {
159
+ try {
160
+ console.log(` Querying RDS to get Aurora endpoint...`);
161
+ const { DescribeDBClustersCommand, RDSClient } = require('@aws-sdk/client-rds');
162
+
163
+ const rdsClient = new RDSClient({ region: this.provider.region });
164
+ const clusterDetails = await rdsClient.send(
165
+ new DescribeDBClustersCommand({
166
+ DBClusterIdentifier: physicalId
167
+ })
168
+ );
169
+
170
+ if (clusterDetails.DBClusters && clusterDetails.DBClusters.length > 0) {
171
+ const cluster = clusterDetails.DBClusters[0];
172
+ stackResource.properties.Endpoint = cluster.Endpoint;
173
+ stackResource.properties.Port = cluster.Port;
174
+ stackResource.properties.DBClusterIdentifier = cluster.DBClusterIdentifier;
175
+ console.log(` ✓ Extracted Aurora endpoint: ${cluster.Endpoint}:${cluster.Port}`);
176
+ }
177
+ } catch (error) {
178
+ console.warn(` ⚠️ Could not get endpoint from Aurora cluster: ${error.message}`);
179
+ }
180
+ }
181
+ }
182
+
183
+ // KMS Key Alias - query to get ARN
184
+ if (logicalId === 'FriggKMSKeyAlias' && resourceType === 'AWS::KMS::Alias') {
185
+ console.log(` ✓ Found KMS key alias in stack: ${physicalId}`);
186
+
187
+ if (this.provider && this.provider.describeKmsKey) {
188
+ try {
189
+ console.log(` Querying KMS for alias: ${physicalId}...`);
190
+ const keyMetadata = await this.provider.describeKmsKey(physicalId);
191
+
192
+ if (keyMetadata) {
193
+ stackResource.properties.KeyArn = keyMetadata.Arn;
194
+ console.log(` ✓ Found KMS key via alias query: ${keyMetadata.Arn}`);
195
+ }
196
+ } catch (error) {
197
+ console.warn(` ⚠️ Could not get key ARN from alias: ${error.message}`);
198
+ }
199
+ }
200
+ }
201
+
202
+ // VPC - just log
203
+ if (logicalId === 'FriggVPC' && resourceType === 'AWS::EC2::VPC') {
204
+ console.log(` ✓ Found VPC in stack: ${physicalId}`);
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Create flat properties from stack-managed resources (backwards compatibility)
210
+ * @private
211
+ */
212
+ _createFlatPropertiesFromStackManaged(discovery, flatDiscovered) {
213
+ for (const resource of discovery.stackManaged) {
214
+ const { logicalId, physicalId, properties } = resource;
215
+
216
+ // Map to flat property names
217
+ switch (logicalId) {
218
+ case 'FriggVPC':
219
+ flatDiscovered.defaultVpcId = physicalId;
220
+ break;
221
+ case 'FriggLambdaSecurityGroup':
222
+ flatDiscovered.securityGroupId = physicalId;
223
+ if (properties.VpcId) {
224
+ flatDiscovered.defaultVpcId = properties.VpcId;
225
+ }
226
+ break;
227
+ case 'FriggPrivateSubnet1':
228
+ flatDiscovered.privateSubnetId1 = physicalId;
229
+ break;
230
+ case 'FriggPrivateSubnet2':
231
+ flatDiscovered.privateSubnetId2 = physicalId;
232
+ break;
233
+ case 'FriggPublicSubnet':
234
+ flatDiscovered.publicSubnetId1 = physicalId;
235
+ break;
236
+ case 'FriggPublicSubnet2':
237
+ flatDiscovered.publicSubnetId2 = physicalId;
238
+ break;
239
+ case 'FriggNatGateway':
240
+ flatDiscovered.natGatewayId = physicalId;
241
+ break;
242
+ case 'FriggLambdaRouteTable':
243
+ flatDiscovered.routeTableId = physicalId;
244
+ break;
245
+ case 'FriggVPCEndpointSecurityGroup':
246
+ flatDiscovered.vpcEndpointSecurityGroupId = physicalId;
247
+ break;
248
+ case 'FriggS3VPCEndpoint':
249
+ flatDiscovered.s3VpcEndpointId = physicalId;
250
+ break;
251
+ case 'FriggDynamoDBVPCEndpoint':
252
+ flatDiscovered.dynamoDbVpcEndpointId = physicalId;
253
+ break;
254
+ case 'FriggKMSVPCEndpoint':
255
+ flatDiscovered.kmsVpcEndpointId = physicalId;
256
+ break;
257
+ case 'FriggSecretsManagerVPCEndpoint':
258
+ flatDiscovered.secretsManagerVpcEndpointId = physicalId;
259
+ break;
260
+ case 'FriggSQSVPCEndpoint':
261
+ flatDiscovered.sqsVpcEndpointId = physicalId;
262
+ break;
263
+ case 'FriggAuroraCluster':
264
+ flatDiscovered.auroraClusterId = physicalId;
265
+ if (properties.Endpoint) {
266
+ flatDiscovered.auroraClusterEndpoint = properties.Endpoint;
267
+ }
268
+ if (properties.Port) {
269
+ flatDiscovered.auroraClusterPort = properties.Port;
270
+ flatDiscovered.auroraPort = properties.Port;
271
+ }
272
+ if (properties.DBClusterIdentifier) {
273
+ flatDiscovered.auroraClusterIdentifier = properties.DBClusterIdentifier;
274
+ }
275
+ break;
276
+ case 'FriggKMSKey':
277
+ flatDiscovered.defaultKmsKeyId = physicalId;
278
+ break;
279
+ case 'FriggKMSKeyAlias':
280
+ flatDiscovered.kmsKeyAlias = physicalId;
281
+ if (properties.KeyArn) {
282
+ flatDiscovered.defaultKmsKeyId = properties.KeyArn;
283
+ }
284
+ break;
285
+ case 'FriggMigrationStatusBucket':
286
+ flatDiscovered.migrationStatusBucket = physicalId;
287
+ break;
288
+ case 'DbMigrationQueue':
289
+ flatDiscovered.migrationQueueUrl = physicalId;
290
+ break;
291
+ }
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Extract discovered resources from CloudFormation stack outputs (legacy)
297
+ * @private
298
+ */
299
+ _extractFromOutputs(outputs, discovered) {
300
+ const outputMap = outputs.reduce((acc, output) => {
301
+ acc[output.OutputKey] = output.OutputValue;
302
+ return acc;
303
+ }, {});
304
+
305
+ // VPC outputs
306
+ if (outputMap.VpcId) {
307
+ discovered.defaultVpcId = outputMap.VpcId;
308
+ }
309
+
310
+ if (outputMap.PrivateSubnetIds) {
311
+ discovered.privateSubnetIds = outputMap.PrivateSubnetIds.split(',').map(id => id.trim());
312
+ }
313
+
314
+ if (outputMap.PublicSubnetId) {
315
+ discovered.publicSubnetId = outputMap.PublicSubnetId;
316
+ }
317
+
318
+ if (outputMap.SecurityGroupId) {
319
+ discovered.securityGroupId = outputMap.SecurityGroupId;
320
+ }
321
+
322
+ // KMS outputs
323
+ if (outputMap.KMS_KEY_ARN) {
324
+ discovered.defaultKmsKeyId = outputMap.KMS_KEY_ARN;
325
+ }
326
+
327
+ // Database outputs
328
+ if (outputMap.DatabaseEndpoint) {
329
+ discovered.databaseEndpoint = outputMap.DatabaseEndpoint;
330
+ }
331
+ }
332
+ }
333
+
334
+ module.exports = CloudFormationDiscoveryV2;