@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,329 @@
1
+ const chalk = require('chalk');
2
+
3
+ /**
4
+ * Error Messages Module
5
+ * Provides helpful, context-aware error messages for database setup issues
6
+ */
7
+
8
+ /**
9
+ * Normalizes MongoDB-compatible database types to 'mongodb'
10
+ * DocumentDB uses the same Prisma client as MongoDB
11
+ * @param {'mongodb'|'postgresql'|'documentdb'} dbType - Database type
12
+ * @returns {'mongodb'|'postgresql'} Normalized database type
13
+ */
14
+ function normalizeMongoCompatible(dbType) {
15
+ return dbType === 'documentdb' ? 'mongodb' : dbType;
16
+ }
17
+
18
+ /**
19
+ * Database URL examples for supported database types
20
+ */
21
+ const DATABASE_URL_EXAMPLES = {
22
+ mongodb: 'mongodb://localhost:27017/frigg?replicaSet=rs0',
23
+ documentdb: 'mongodb://frigg-user:yourPassword@docdb-cluster.cluster-xyz123.us-east-1.docdb.amazonaws.com:27017/frigg?tls=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false',
24
+ postgresql: 'postgresql://postgres:postgres@localhost:5432/frigg?schema=public'
25
+ };
26
+
27
+ function getDatabaseDisplayName(dbType) {
28
+ switch (dbType) {
29
+ case 'mongodb':
30
+ return 'MongoDB';
31
+ case 'documentdb':
32
+ return 'AWS DocumentDB (MongoDB-compatible)';
33
+ case 'postgresql':
34
+ return 'PostgreSQL';
35
+ default:
36
+ return dbType;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Gets helpful error message for missing DATABASE_URL
42
+ * @returns {string} Formatted error message
43
+ */
44
+ function getDatabaseUrlMissingError() {
45
+ return `
46
+ ${chalk.red('❌ DATABASE_URL environment variable not found')}
47
+
48
+ ${chalk.bold('Add DATABASE_URL to your .env file:')}
49
+
50
+ ${chalk.cyan('For MongoDB:')}
51
+ ${chalk.gray('DATABASE_URL')}=${chalk.green(`"${DATABASE_URL_EXAMPLES.mongodb}"`)}
52
+
53
+ ${chalk.cyan('For AWS DocumentDB (MongoDB-compatible):')}
54
+ ${chalk.gray('DATABASE_URL')}=${chalk.green(`"${DATABASE_URL_EXAMPLES.documentdb}"`)}
55
+
56
+ ${chalk.cyan('For PostgreSQL:')}
57
+ ${chalk.gray('DATABASE_URL')}=${chalk.green(`"${DATABASE_URL_EXAMPLES.postgresql}"`)}
58
+
59
+ ${chalk.yellow('Then run:')} ${chalk.cyan('frigg db:setup')}
60
+ `;
61
+ }
62
+
63
+ /**
64
+ * Gets helpful error message for missing database type configuration
65
+ * @returns {string} Formatted error message
66
+ */
67
+ function getDatabaseTypeNotConfiguredError() {
68
+ return `
69
+ ${chalk.red('❌ Database type not configured in app definition')}
70
+
71
+ ${chalk.bold('Add database configuration to your app definition file:')}
72
+ ${chalk.gray('(backend/index.js or index.js)')}
73
+
74
+ ${chalk.cyan('For PostgreSQL:')}
75
+ ${chalk.gray(`
76
+ const appDefinition = {
77
+ // ... other configuration
78
+ database: {
79
+ postgres: { enable: true }
80
+ }
81
+ };
82
+ `)}
83
+
84
+ ${chalk.cyan('For MongoDB:')}
85
+ ${chalk.gray(`
86
+ const appDefinition = {
87
+ // ... other configuration
88
+ database: {
89
+ mongoDB: { enable: true }
90
+ }
91
+ };
92
+ `)}
93
+
94
+ ${chalk.cyan('For AWS DocumentDB (MongoDB-compatible):')}
95
+ ${chalk.gray(`
96
+ const appDefinition = {
97
+ // ... other configuration
98
+ database: {
99
+ documentDB: { enable: true }
100
+ }
101
+ };
102
+ `)}
103
+
104
+ ${chalk.gray('DocumentDB uses the MongoDB Prisma client. Make sure TLS is enabled and replica set compatibility is configured on your cluster.')}
105
+ `;
106
+ }
107
+
108
+ /**
109
+ * Gets helpful error message for database connection failure
110
+ * @param {string} error - Connection error message
111
+ * @param {'mongodb'|'postgresql'|'documentdb'} dbType - Database type
112
+ * @returns {string} Formatted error message
113
+ */
114
+ function getDatabaseConnectionError(error, dbType) {
115
+ let troubleshootingSteps;
116
+ if (dbType === 'documentdb') {
117
+ troubleshootingSteps = getDocumentDbTroubleshooting();
118
+ } else if (dbType === 'mongodb') {
119
+ troubleshootingSteps = getMongoDatabaseTroubleshooting();
120
+ } else {
121
+ troubleshootingSteps = getPostgresTroubleshooting();
122
+ }
123
+
124
+ return `
125
+ ${chalk.red('❌ Failed to connect to database')}
126
+
127
+ ${chalk.bold('Connection error:')}
128
+ ${chalk.gray(error)}
129
+
130
+ ${chalk.bold('Database:')} ${chalk.cyan(getDatabaseDisplayName(dbType))}
131
+
132
+ ${chalk.bold('Troubleshooting steps:')}
133
+ ${troubleshootingSteps}
134
+
135
+ ${chalk.yellow('Verify your DATABASE_URL:')} ${chalk.cyan(process.env.DATABASE_URL || 'not set')}
136
+ `;
137
+ }
138
+
139
+ /**
140
+ * Gets MongoDB-specific troubleshooting steps
141
+ * @returns {string} Formatted troubleshooting steps
142
+ */
143
+ function getMongoDatabaseTroubleshooting() {
144
+ return `
145
+ ${chalk.gray('1.')} Verify MongoDB is running
146
+ ${chalk.cyan('docker ps')} ${chalk.gray('(if using Docker)')}
147
+ ${chalk.cyan('mongosh --eval "db.version()"')} ${chalk.gray('(test connection)')}
148
+
149
+ ${chalk.gray('2.')} Check if replica set is initialized
150
+ ${chalk.gray('MongoDB requires a replica set for Prisma')}
151
+ ${chalk.cyan('mongosh')}
152
+ ${chalk.cyan('rs.status()')} ${chalk.gray('(should show replica set info)')}
153
+
154
+ ${chalk.gray('3.')} Initialize replica set if needed
155
+ ${chalk.cyan('docker exec -it <mongodb-container> mongosh')}
156
+ ${chalk.cyan('rs.initiate()')}
157
+
158
+ ${chalk.gray('4.')} Verify connection string format
159
+ ${chalk.gray('mongodb://[username:password@]host[:port]/database[?options]')}
160
+ ${chalk.green('Example: mongodb://localhost:27017/frigg?replicaSet=rs0')}
161
+
162
+ ${chalk.gray('5.')} Check network/firewall settings
163
+ ${chalk.gray('Ensure port 27017 (default) is accessible')}
164
+ `;
165
+ }
166
+
167
+ function getDocumentDbTroubleshooting() {
168
+ return `
169
+ ${chalk.gray('1.')} Verify DocumentDB cluster is available
170
+ ${chalk.cyan('aws docdb describe-db-clusters --db-cluster-identifier <name>')}
171
+
172
+ ${chalk.gray('2.')} Use TLS with the AWS CA bundle
173
+ ${chalk.gray('Download: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem')}
174
+ ${chalk.gray('Add ?tls=true&tlsCAFile=/path/to/global-bundle.pem to DATABASE_URL')}
175
+
176
+ ${chalk.gray('3.')} Disable retryable writes (DocumentDB limitation)
177
+ ${chalk.gray('Add retryWrites=false to DATABASE_URL query string')}
178
+
179
+ ${chalk.gray('4.')} Include replicaSet parameter
180
+ ${chalk.gray('DocumentDB requires replicaSet=rs0 even for single-node clusters')}
181
+
182
+ ${chalk.gray('5.')} Allow inbound access from your Lambda or local IP
183
+ ${chalk.gray('Update security groups / VPC rules for port 27017')}
184
+ `;
185
+ }
186
+
187
+ /**
188
+ * Gets PostgreSQL-specific troubleshooting steps
189
+ * @returns {string} Formatted troubleshooting steps
190
+ */
191
+ function getPostgresTroubleshooting() {
192
+ return `
193
+ ${chalk.gray('1.')} Verify PostgreSQL is running
194
+ ${chalk.cyan('docker ps')} ${chalk.gray('(if using Docker)')}
195
+ ${chalk.cyan('pg_isready')} ${chalk.gray('(test if server is ready)')}
196
+
197
+ ${chalk.gray('2.')} Check connection string format
198
+ ${chalk.gray('postgresql://[username:password@]host[:port]/database[?options]')}
199
+ ${chalk.green('Example: postgresql://postgres:postgres@localhost:5432/frigg?schema=public')}
200
+
201
+ ${chalk.gray('3.')} Verify database exists
202
+ ${chalk.cyan('psql -U postgres -l')} ${chalk.gray('(list databases)')}
203
+ ${chalk.cyan('CREATE DATABASE frigg;')} ${chalk.gray('(if needed)')}
204
+
205
+ ${chalk.gray('4.')} Check pg_hba.conf allows connections
206
+ ${chalk.gray('Location: /var/lib/postgresql/data/pg_hba.conf (Docker)')}
207
+ ${chalk.gray('Ensure trust/md5 authentication is enabled for your host')}
208
+
209
+ ${chalk.gray('5.')} Verify network/firewall settings
210
+ ${chalk.gray('Ensure port 5432 (default) is accessible')}
211
+ `;
212
+ }
213
+
214
+ /**
215
+ * Gets helpful error message for missing Prisma client
216
+ * @param {'mongodb'|'postgresql'|'documentdb'} dbType - Database type
217
+ * @returns {string} Formatted error message
218
+ */
219
+ function getPrismaClientNotGeneratedError(dbType) {
220
+ // Normalize DocumentDB to MongoDB (they use the same Prisma client)
221
+ const normalizedType = normalizeMongoCompatible(dbType);
222
+ const clientName = `@prisma-${normalizedType}/client`;
223
+ const documentDbNote = dbType === 'documentdb'
224
+ ? [
225
+ chalk.gray(' • DocumentDB reuses the MongoDB Prisma client (prisma-mongodb)'),
226
+ chalk.gray(' • Confirm your connection string includes tls=true and retryWrites=false')
227
+ ].join('\n')
228
+ : '';
229
+
230
+ return `
231
+ ${chalk.red(`❌ Prisma client not generated for ${dbType}`)}
232
+
233
+ ${chalk.bold('The Prisma client needs to be generated before starting the application.')}
234
+
235
+ ${chalk.yellow('Run:')} ${chalk.cyan('frigg db:setup')}
236
+
237
+ ${chalk.gray('This will:')}
238
+ ${chalk.gray(' • Generate the Prisma client')} ${chalk.gray(`(${clientName})`)}
239
+ ${chalk.gray(' • Set up database schema')}
240
+ ${chalk.gray(' • Run migrations (PostgreSQL) or db push (MongoDB)')}
241
+ ${documentDbNote ? `${documentDbNote}\n` : ''}
242
+ `;
243
+ }
244
+
245
+ /**
246
+ * Gets helpful error message for Prisma command failures
247
+ * @param {string} command - Command that failed (generate, migrate, push)
248
+ * @param {string} error - Error message
249
+ * @returns {string} Formatted error message
250
+ */
251
+ function getPrismaCommandError(command, error) {
252
+ return `
253
+ ${chalk.red(`❌ Prisma ${command} failed`)}
254
+
255
+ ${chalk.bold('Error:')}
256
+ ${chalk.gray(error)}
257
+
258
+ ${chalk.bold('Common causes:')}
259
+ ${chalk.gray(' • Database schema has conflicts')}
260
+ ${chalk.gray(' • Database connection lost during operation')}
261
+ ${chalk.gray(' • Insufficient permissions')}
262
+ ${chalk.gray(' • Schema file is invalid')}
263
+
264
+ ${chalk.yellow('Try:')}
265
+ ${chalk.cyan(' frigg db:setup')} ${chalk.gray('(re-run setup)')}
266
+ ${chalk.cyan(' Check your DATABASE_URL')} ${chalk.gray('(verify connection string)')}
267
+ ${chalk.cyan(' Review Prisma schema')} ${chalk.gray('(node_modules/@friggframework/core/prisma-*/schema.prisma)')}
268
+ `;
269
+ }
270
+
271
+ /**
272
+ * Gets success message for database setup completion
273
+ * @param {'mongodb'|'postgresql'|'documentdb'} dbType - Database type
274
+ * @param {string} stage - Deployment stage
275
+ * @returns {string} Formatted success message
276
+ */
277
+ function getDatabaseSetupSuccess(dbType, stage) {
278
+ const databaseDisplayName = getDatabaseDisplayName(dbType);
279
+ const schemaAction = dbType === 'postgresql'
280
+ ? 'Migrations applied'
281
+ : dbType === 'documentdb'
282
+ ? 'Schema pushed to DocumentDB'
283
+ : 'Schema pushed to database';
284
+
285
+ return `
286
+ ${chalk.green('✅ Database setup completed successfully!')}
287
+
288
+ ${chalk.bold('Configuration:')}
289
+ ${chalk.gray(' Database type:')} ${chalk.cyan(databaseDisplayName)}
290
+ ${chalk.gray(' Stage:')} ${chalk.cyan(stage)}
291
+ ${chalk.gray(' Connection:')} ${chalk.green('verified')}
292
+
293
+ ${chalk.bold('What happened:')}
294
+ ${chalk.gray(' ✓')} Prisma client generated
295
+ ${chalk.gray(' ✓')} Database connection verified
296
+ ${chalk.gray(' ✓')} ${schemaAction}
297
+
298
+ ${chalk.yellow('Next steps:')}
299
+ ${chalk.cyan(' frigg start')} ${chalk.gray('(start your application)')}
300
+ `;
301
+ }
302
+
303
+ /**
304
+ * Gets warning message for database already up-to-date
305
+ * @returns {string} Formatted warning message
306
+ */
307
+ function getDatabaseAlreadyUpToDate() {
308
+ return `
309
+ ${chalk.yellow('⚠️ Database is already up-to-date')}
310
+
311
+ ${chalk.gray('No migrations or schema changes detected.')}
312
+
313
+ ${chalk.yellow('If you expected changes:')}
314
+ ${chalk.gray(' • Check if schema was modified in node_modules/@friggframework/core/prisma-*/')}
315
+ ${chalk.gray(' • Verify DATABASE_URL points to the correct database')}
316
+ ${chalk.gray(' • Check if you\'re in the correct project directory')}
317
+ `;
318
+ }
319
+
320
+ module.exports = {
321
+ DATABASE_URL_EXAMPLES,
322
+ getDatabaseUrlMissingError,
323
+ getDatabaseTypeNotConfiguredError,
324
+ getDatabaseConnectionError,
325
+ getPrismaClientNotGeneratedError,
326
+ getPrismaCommandError,
327
+ getDatabaseSetupSuccess,
328
+ getDatabaseAlreadyUpToDate
329
+ };
@@ -0,0 +1,167 @@
1
+ /**
2
+ * NPM Registry Service for CLI
3
+ * CommonJS version of the npm-registry service
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const axios = require('axios');
9
+ const NodeCache = require('node-cache');
10
+ const semver = require('semver');
11
+
12
+ class NPMRegistryService {
13
+ constructor() {
14
+ // Cache with 1 hour TTL by default
15
+ this.cache = new NodeCache({
16
+ stdTTL: 3600,
17
+ checkperiod: 600,
18
+ useClones: false
19
+ });
20
+
21
+ this.npmRegistryUrl = 'https://registry.npmjs.org';
22
+ this.searchUrl = `${this.npmRegistryUrl}/-/v1/search`;
23
+ this.packageScope = '@friggframework';
24
+ this.modulePrefix = 'api-module-';
25
+ }
26
+
27
+ /**
28
+ * Search for all @friggframework/api-module-* packages
29
+ * @param {Object} options - Search options
30
+ * @param {boolean} options.includePrerelease - Include prerelease versions
31
+ * @param {boolean} options.forceRefresh - Force cache refresh
32
+ * @returns {Promise<Array>} Array of package information
33
+ */
34
+ async searchApiModules(options = {}) {
35
+ const cacheKey = `api-modules-${JSON.stringify(options)}`;
36
+
37
+ // Check cache first unless force refresh is requested
38
+ if (!options.forceRefresh) {
39
+ const cached = this.cache.get(cacheKey);
40
+ if (cached) {
41
+ return cached;
42
+ }
43
+ }
44
+
45
+ try {
46
+ // Search for packages matching our pattern
47
+ const searchQuery = `${this.packageScope}/${this.modulePrefix}`;
48
+ const response = await axios.get(this.searchUrl, {
49
+ params: {
50
+ text: searchQuery,
51
+ size: 250, // Get up to 250 results
52
+ quality: 0.65,
53
+ popularity: 0.98,
54
+ maintenance: 0.5
55
+ },
56
+ timeout: 10000
57
+ });
58
+
59
+ const packages = response.data.objects
60
+ .filter(obj => obj.package.name.startsWith(`${this.packageScope}/${this.modulePrefix}`))
61
+ .map(obj => this.formatPackageInfo(obj.package));
62
+
63
+ // Filter out prereleases if requested
64
+ const filtered = options.includePrerelease
65
+ ? packages
66
+ : packages.filter(pkg => !semver.prerelease(pkg.version));
67
+
68
+ // Cache the results
69
+ this.cache.set(cacheKey, filtered);
70
+
71
+ return filtered;
72
+ } catch (error) {
73
+ console.error('Error searching NPM registry:', error.message);
74
+ // Return empty array on error to allow offline usage
75
+ return [];
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Extract integration name from package name
81
+ * @private
82
+ */
83
+ extractIntegrationName(packageName) {
84
+ return packageName
85
+ .replace(`${this.packageScope}/${this.modulePrefix}`, '')
86
+ .replace(/-/g, ' ')
87
+ .replace(/\b\w/g, l => l.toUpperCase());
88
+ }
89
+
90
+ /**
91
+ * Format package information for API response
92
+ * @private
93
+ */
94
+ formatPackageInfo(pkg) {
95
+ return {
96
+ name: pkg.name,
97
+ version: pkg.version,
98
+ description: pkg.description,
99
+ keywords: pkg.keywords || [],
100
+ author: pkg.author,
101
+ publisher: pkg.publisher,
102
+ date: pkg.date,
103
+ links: pkg.links,
104
+ integrationName: this.extractIntegrationName(pkg.name),
105
+ category: this.categorizeModule(pkg)
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Categorize module based on keywords and name
111
+ * @private
112
+ */
113
+ categorizeModule(module) {
114
+ const name = module.name?.toLowerCase() || '';
115
+ const keywords = module.keywords?.map(k => k.toLowerCase()) || [];
116
+ const allTerms = [...keywords, name];
117
+
118
+ // Categories based on common integration types - ordered by specificity
119
+ const categories = {
120
+ 'Marketing': ['marketing', 'mailchimp', 'campaign', 'automation', 'klaviyo', 'activecampaign'],
121
+ 'CRM': ['crm', 'customer', 'salesforce', 'hubspot', 'pipedrive', 'zoho'],
122
+ 'E-commerce': ['ecommerce', 'shop', 'store', 'payment', 'stripe', 'paypal', 'shopify', 'woocommerce'],
123
+ 'Analytics': ['analytics', 'tracking', 'google-analytics', 'mixpanel', 'segment', 'amplitude'],
124
+ 'Social Media': ['social', 'facebook', 'twitter', 'instagram', 'linkedin', 'youtube'],
125
+ 'Project Management': ['project', 'task', 'jira', 'trello', 'asana', 'monday', 'notion'],
126
+ 'Storage': ['storage', 'file', 'dropbox', 'google-drive', 's3', 'box', 'onedrive'],
127
+ 'Productivity': ['spreadsheet', 'google-sheets', 'airtable', 'calendar', 'todo'],
128
+ 'Development': ['github', 'gitlab', 'bitbucket', 'git', 'ci', 'cd', 'jenkins'],
129
+ 'Support': ['support', 'zendesk', 'freshdesk', 'intercom', 'helpdesk'],
130
+ 'Finance': ['accounting', 'quickbooks', 'xero', 'sage', 'invoice', 'billing'],
131
+ 'Communication': ['email', 'sms', 'chat', 'messaging', 'slack', 'discord', 'twilio', 'sendgrid'],
132
+ 'Other': []
133
+ };
134
+
135
+ for (const [category, terms] of Object.entries(categories)) {
136
+ if (category === 'Other') continue;
137
+
138
+ if (terms.some(term => allTerms.some(t => t.includes(term)))) {
139
+ return category;
140
+ }
141
+ }
142
+
143
+ return 'Other';
144
+ }
145
+
146
+ /**
147
+ * Get grouped modules by integration type
148
+ * @returns {Promise<Object>} Modules grouped by type
149
+ */
150
+ async getModulesByType() {
151
+ const modules = await this.searchApiModules();
152
+
153
+ const grouped = modules.reduce((acc, module) => {
154
+ const type = module.category;
155
+ if (!acc[type]) {
156
+ acc[type] = [];
157
+ }
158
+ acc[type].push(module);
159
+ return acc;
160
+ }, {});
161
+
162
+ return grouped;
163
+ }
164
+ }
165
+
166
+ // Export singleton instance
167
+ module.exports = new NPMRegistryService();
@@ -0,0 +1,199 @@
1
+ const chalk = require('chalk');
2
+ const { spawn } = require('child_process');
3
+ const readline = require('readline');
4
+
5
+ class ProcessManager {
6
+ constructor() {
7
+ this.processes = new Map();
8
+ this.isShuttingDown = false;
9
+ this.outputBuffer = new Map();
10
+ this.setupShutdownHandlers();
11
+ }
12
+
13
+ setupShutdownHandlers() {
14
+ const shutdown = async () => {
15
+ if (this.isShuttingDown) return;
16
+ this.isShuttingDown = true;
17
+
18
+ console.log('\n' + chalk.yellow('⏹ Shutting down...'));
19
+
20
+ const shutdownPromises = [];
21
+ for (const [name, proc] of this.processes) {
22
+ shutdownPromises.push(this.killProcess(name, proc));
23
+ }
24
+
25
+ await Promise.all(shutdownPromises);
26
+
27
+ console.log(chalk.green('✓ All processes stopped cleanly'));
28
+ process.exit(0);
29
+ };
30
+
31
+ process.on('SIGINT', shutdown);
32
+ process.on('SIGTERM', shutdown);
33
+ process.on('exit', () => {
34
+ for (const [, proc] of this.processes) {
35
+ try {
36
+ proc.kill('SIGKILL');
37
+ } catch (e) {
38
+ // Process already dead
39
+ }
40
+ }
41
+ });
42
+ }
43
+
44
+ async killProcess(name, proc) {
45
+ return new Promise((resolve) => {
46
+ if (!proc || proc.killed) {
47
+ resolve();
48
+ return;
49
+ }
50
+
51
+ const timeout = setTimeout(() => {
52
+ try {
53
+ proc.kill('SIGKILL');
54
+ } catch (e) {
55
+ // Process already dead
56
+ }
57
+ resolve();
58
+ }, 5000);
59
+
60
+ proc.once('exit', () => {
61
+ clearTimeout(timeout);
62
+ this.processes.delete(name);
63
+ resolve();
64
+ });
65
+
66
+ try {
67
+ proc.kill('SIGTERM');
68
+ } catch (e) {
69
+ clearTimeout(timeout);
70
+ resolve();
71
+ }
72
+ });
73
+ }
74
+
75
+ spawnProcess(name, command, args, options = {}) {
76
+ const proc = spawn(command, args, {
77
+ ...options,
78
+ stdio: ['inherit', 'pipe', 'pipe'],
79
+ shell: true
80
+ });
81
+
82
+ this.processes.set(name, proc);
83
+ this.outputBuffer.set(name, []);
84
+
85
+ // Create readline interfaces for better line handling
86
+ const stdoutReader = readline.createInterface({
87
+ input: proc.stdout,
88
+ crlfDelay: Infinity
89
+ });
90
+
91
+ const stderrReader = readline.createInterface({
92
+ input: proc.stderr,
93
+ crlfDelay: Infinity
94
+ });
95
+
96
+ stdoutReader.on('line', (line) => {
97
+ if (!this.isShuttingDown) {
98
+ this.handleOutput(name, line, 'stdout');
99
+ }
100
+ });
101
+
102
+ stderrReader.on('line', (line) => {
103
+ if (!this.isShuttingDown) {
104
+ this.handleOutput(name, line, 'stderr');
105
+ }
106
+ });
107
+
108
+ proc.on('error', (error) => {
109
+ if (!this.isShuttingDown) {
110
+ console.error(chalk.red(`[${name}] Process error:`), error.message);
111
+ }
112
+ });
113
+
114
+ proc.on('exit', (code, signal) => {
115
+ this.processes.delete(name);
116
+ if (!this.isShuttingDown && code !== 0 && code !== null) {
117
+ console.error(chalk.red(`[${name}] Process exited with code ${code}`));
118
+ }
119
+ });
120
+
121
+ return proc;
122
+ }
123
+
124
+ handleOutput(processName, line, stream) {
125
+ // Filter out noisy/redundant messages
126
+ const filters = [
127
+ /VITE v\d+\.\d+\.\d+/,
128
+ /ready in \d+ ms/,
129
+ /Local:/,
130
+ /Network:/,
131
+ /press h \+ enter to show help/,
132
+ /\[nodemon\]/,
133
+ /watching for file changes/,
134
+ /restarting due to changes/,
135
+ /starting/,
136
+ /clean exit/,
137
+ /waiting for changes before restart/,
138
+ /^$/ // empty lines
139
+ ];
140
+
141
+ if (filters.some(filter => filter.test(line))) {
142
+ return;
143
+ }
144
+
145
+ // Format output based on process
146
+ const prefix = this.getProcessPrefix(processName);
147
+ const coloredLine = this.colorizeOutput(line, stream);
148
+
149
+ console.log(`${prefix} ${coloredLine}`);
150
+ }
151
+
152
+ getProcessPrefix(processName) {
153
+ const prefixes = {
154
+ 'frontend': chalk.blue('[Frontend]'),
155
+ 'backend': chalk.green('[Backend]'),
156
+ 'vite': chalk.blue('[Vite]'),
157
+ 'server': chalk.green('[Server]')
158
+ };
159
+
160
+ return prefixes[processName.toLowerCase()] || chalk.gray(`[${processName}]`);
161
+ }
162
+
163
+ colorizeOutput(line, stream) {
164
+ // Error detection
165
+ if (stream === 'stderr' || /error|fail|exception/i.test(line)) {
166
+ return chalk.red(line);
167
+ }
168
+
169
+ // Warning detection
170
+ if (/warn|warning/i.test(line)) {
171
+ return chalk.yellow(line);
172
+ }
173
+
174
+ // Success detection
175
+ if (/success|ready|started|listening|compiled/i.test(line)) {
176
+ return chalk.green(line);
177
+ }
178
+
179
+ // Info detection
180
+ if (/info|starting/i.test(line)) {
181
+ return chalk.blue(line);
182
+ }
183
+
184
+ return chalk.gray(line);
185
+ }
186
+
187
+ printStatus(frontendUrl, backendUrl, repoName) {
188
+ console.log('\n' + chalk.bold.green('✨ Frigg Management UI is ready!'));
189
+ console.log('');
190
+ console.log(chalk.cyan(' Frontend: ') + chalk.white(frontendUrl));
191
+ console.log(chalk.cyan(' Backend: ') + chalk.white(backendUrl));
192
+ console.log(chalk.cyan(' Repository:') + chalk.white(` ${repoName}`));
193
+ console.log('');
194
+ console.log(chalk.gray(' Press ' + chalk.bold('Ctrl+C') + ' to stop all servers'));
195
+ console.log('');
196
+ }
197
+ }
198
+
199
+ module.exports = ProcessManager;