@friggframework/devtools 2.0.0-next.44 → 2.0.0-next.46

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 (212) hide show
  1. package/infrastructure/ARCHITECTURE.md +487 -0
  2. package/infrastructure/HEALTH.md +468 -0
  3. package/infrastructure/README.md +51 -0
  4. package/infrastructure/__tests__/postgres-config.test.js +914 -0
  5. package/infrastructure/__tests__/template-generation.test.js +687 -0
  6. package/infrastructure/create-frigg-infrastructure.js +1 -1
  7. package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
  8. package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
  9. package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
  10. package/infrastructure/domains/database/aurora-builder.js +809 -0
  11. package/infrastructure/domains/database/aurora-builder.test.js +950 -0
  12. package/infrastructure/domains/database/aurora-discovery.js +87 -0
  13. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  14. package/infrastructure/domains/database/aurora-resolver.js +210 -0
  15. package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
  16. package/infrastructure/domains/database/migration-builder.js +633 -0
  17. package/infrastructure/domains/database/migration-builder.test.js +294 -0
  18. package/infrastructure/domains/database/migration-resolver.js +163 -0
  19. package/infrastructure/domains/database/migration-resolver.test.js +337 -0
  20. package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
  21. package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
  22. package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
  23. package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
  24. package/infrastructure/domains/health/application/ports/index.js +26 -0
  25. package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
  26. package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
  27. package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
  28. package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
  29. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
  30. package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
  31. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
  32. package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
  33. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
  34. package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
  35. package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
  36. package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
  37. package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
  38. package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
  39. package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
  40. package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
  41. package/infrastructure/domains/health/domain/entities/issue.js +299 -0
  42. package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
  43. package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
  44. package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
  45. package/infrastructure/domains/health/domain/entities/resource.js +159 -0
  46. package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
  47. package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
  48. package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
  49. package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
  50. package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
  51. package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
  52. package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
  53. package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
  54. package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
  55. package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
  56. package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
  57. package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
  58. package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
  59. package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
  60. package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
  61. package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
  62. package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
  63. package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
  64. package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
  65. package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
  66. package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
  67. package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
  68. package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
  69. package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
  70. package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
  71. package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
  72. package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
  73. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
  74. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
  75. package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
  76. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
  77. package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
  78. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
  79. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
  80. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
  81. package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
  82. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
  83. package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
  84. package/infrastructure/domains/integration/integration-builder.js +397 -0
  85. package/infrastructure/domains/integration/integration-builder.test.js +593 -0
  86. package/infrastructure/domains/integration/integration-resolver.js +170 -0
  87. package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
  88. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  89. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  90. package/infrastructure/domains/networking/vpc-builder.js +1829 -0
  91. package/infrastructure/domains/networking/vpc-builder.test.js +1262 -0
  92. package/infrastructure/domains/networking/vpc-discovery.js +177 -0
  93. package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
  94. package/infrastructure/domains/networking/vpc-resolver.js +324 -0
  95. package/infrastructure/domains/networking/vpc-resolver.test.js +501 -0
  96. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  97. package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
  98. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  99. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  100. package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
  101. package/infrastructure/domains/security/kms-builder.js +366 -0
  102. package/infrastructure/domains/security/kms-builder.test.js +374 -0
  103. package/infrastructure/domains/security/kms-discovery.js +80 -0
  104. package/infrastructure/domains/security/kms-discovery.test.js +177 -0
  105. package/infrastructure/domains/security/kms-resolver.js +96 -0
  106. package/infrastructure/domains/security/kms-resolver.test.js +216 -0
  107. package/infrastructure/domains/shared/base-builder.js +112 -0
  108. package/infrastructure/domains/shared/base-resolver.js +186 -0
  109. package/infrastructure/domains/shared/base-resolver.test.js +305 -0
  110. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  111. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  112. package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
  113. package/infrastructure/domains/shared/cloudformation-discovery.js +375 -0
  114. package/infrastructure/domains/shared/cloudformation-discovery.test.js +590 -0
  115. package/infrastructure/domains/shared/environment-builder.js +119 -0
  116. package/infrastructure/domains/shared/environment-builder.test.js +247 -0
  117. package/infrastructure/domains/shared/providers/aws-provider-adapter.js +544 -0
  118. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +377 -0
  119. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  120. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  121. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  122. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  123. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  124. package/infrastructure/domains/shared/resource-discovery.js +192 -0
  125. package/infrastructure/domains/shared/resource-discovery.test.js +552 -0
  126. package/infrastructure/domains/shared/types/app-definition.js +205 -0
  127. package/infrastructure/domains/shared/types/discovery-result.js +106 -0
  128. package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
  129. package/infrastructure/domains/shared/types/index.js +46 -0
  130. package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
  131. package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
  132. package/infrastructure/domains/shared/utilities/base-definition-factory.js +380 -0
  133. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  134. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
  135. package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
  136. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
  137. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
  138. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +138 -0
  139. package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +2 -1
  140. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  141. package/infrastructure/esbuild.config.js +53 -0
  142. package/infrastructure/infrastructure-composer.js +87 -0
  143. package/infrastructure/{serverless-template.test.js → infrastructure-composer.test.js} +115 -24
  144. package/infrastructure/scripts/build-prisma-layer.js +553 -0
  145. package/infrastructure/scripts/build-prisma-layer.test.js +102 -0
  146. package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +80 -48
  147. package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
  148. package/layers/prisma/nodejs/package.json +8 -0
  149. package/management-ui/server/utils/cliIntegration.js +1 -1
  150. package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
  151. package/package.json +11 -11
  152. package/frigg-cli/.eslintrc.js +0 -141
  153. package/frigg-cli/__tests__/unit/commands/build.test.js +0 -251
  154. package/frigg-cli/__tests__/unit/commands/db-setup.test.js +0 -548
  155. package/frigg-cli/__tests__/unit/commands/install.test.js +0 -400
  156. package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -346
  157. package/frigg-cli/__tests__/unit/utils/database-validator.test.js +0 -366
  158. package/frigg-cli/__tests__/unit/utils/error-messages.test.js +0 -304
  159. package/frigg-cli/__tests__/unit/utils/prisma-runner.test.js +0 -486
  160. package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
  161. package/frigg-cli/__tests__/utils/prisma-mock.js +0 -194
  162. package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
  163. package/frigg-cli/__tests__/utils/test-setup.js +0 -287
  164. package/frigg-cli/build-command/index.js +0 -65
  165. package/frigg-cli/db-setup-command/index.js +0 -193
  166. package/frigg-cli/deploy-command/index.js +0 -175
  167. package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -301
  168. package/frigg-cli/generate-command/azure-generator.js +0 -43
  169. package/frigg-cli/generate-command/gcp-generator.js +0 -47
  170. package/frigg-cli/generate-command/index.js +0 -332
  171. package/frigg-cli/generate-command/terraform-generator.js +0 -555
  172. package/frigg-cli/generate-iam-command.js +0 -118
  173. package/frigg-cli/index.js +0 -75
  174. package/frigg-cli/index.test.js +0 -158
  175. package/frigg-cli/init-command/backend-first-handler.js +0 -756
  176. package/frigg-cli/init-command/index.js +0 -93
  177. package/frigg-cli/init-command/template-handler.js +0 -143
  178. package/frigg-cli/install-command/backend-js.js +0 -33
  179. package/frigg-cli/install-command/commit-changes.js +0 -16
  180. package/frigg-cli/install-command/environment-variables.js +0 -127
  181. package/frigg-cli/install-command/environment-variables.test.js +0 -136
  182. package/frigg-cli/install-command/index.js +0 -54
  183. package/frigg-cli/install-command/install-package.js +0 -13
  184. package/frigg-cli/install-command/integration-file.js +0 -30
  185. package/frigg-cli/install-command/logger.js +0 -12
  186. package/frigg-cli/install-command/template.js +0 -90
  187. package/frigg-cli/install-command/validate-package.js +0 -75
  188. package/frigg-cli/jest.config.js +0 -124
  189. package/frigg-cli/package.json +0 -54
  190. package/frigg-cli/start-command/index.js +0 -149
  191. package/frigg-cli/start-command/start-command.test.js +0 -297
  192. package/frigg-cli/test/init-command.test.js +0 -180
  193. package/frigg-cli/test/npm-registry.test.js +0 -319
  194. package/frigg-cli/ui-command/index.js +0 -154
  195. package/frigg-cli/utils/app-resolver.js +0 -319
  196. package/frigg-cli/utils/backend-path.js +0 -25
  197. package/frigg-cli/utils/database-validator.js +0 -161
  198. package/frigg-cli/utils/error-messages.js +0 -257
  199. package/frigg-cli/utils/npm-registry.js +0 -167
  200. package/frigg-cli/utils/prisma-runner.js +0 -280
  201. package/frigg-cli/utils/process-manager.js +0 -199
  202. package/frigg-cli/utils/repo-detection.js +0 -405
  203. package/infrastructure/aws-discovery.js +0 -1176
  204. package/infrastructure/aws-discovery.test.js +0 -1220
  205. package/infrastructure/serverless-template.js +0 -2074
  206. /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
  207. /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
  208. /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
  209. /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
  210. /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
  211. /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
  212. /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
@@ -1,319 +0,0 @@
1
- const axios = require('axios');
2
-
3
- // Mock dependencies
4
- jest.mock('axios');
5
- jest.mock('node-cache');
6
-
7
- describe('NPMRegistryService', () => {
8
- let npmRegistry;
9
- let mockCache;
10
- let NodeCache;
11
-
12
- beforeEach(() => {
13
- jest.clearAllMocks();
14
-
15
- // Mock cache methods
16
- mockCache = {
17
- get: jest.fn(),
18
- set: jest.fn(),
19
- del: jest.fn()
20
- };
21
-
22
- // Re-require NodeCache and set up mock
23
- NodeCache = require('node-cache');
24
- NodeCache.mockImplementation(() => mockCache);
25
-
26
- // Create new instance for each test
27
- jest.isolateModules(() => {
28
- npmRegistry = require('../utils/npm-registry');
29
- // Access the cache directly to ensure our mock is used
30
- npmRegistry.cache = mockCache;
31
- });
32
- });
33
-
34
- describe('searchApiModules', () => {
35
- const mockApiResponse = {
36
- data: {
37
- objects: [
38
- {
39
- package: {
40
- name: '@friggframework/api-module-slack',
41
- version: '2.0.0',
42
- description: 'Slack integration for Frigg',
43
- keywords: ['frigg', 'slack', 'integration'],
44
- author: { name: 'Frigg Team' },
45
- date: '2024-01-01'
46
- }
47
- },
48
- {
49
- package: {
50
- name: '@friggframework/api-module-hubspot',
51
- version: '2.1.0',
52
- description: 'HubSpot CRM integration',
53
- keywords: ['frigg', 'hubspot', 'crm'],
54
- author: { name: 'Frigg Team' },
55
- date: '2024-01-02'
56
- }
57
- },
58
- {
59
- package: {
60
- name: '@friggframework/not-api-module',
61
- version: '1.0.0',
62
- description: 'Should be filtered out'
63
- }
64
- }
65
- ]
66
- }
67
- };
68
-
69
- it('should fetch and format API modules from npm registry', async () => {
70
- mockCache.get.mockReturnValue(null);
71
- axios.get.mockResolvedValue(mockApiResponse);
72
-
73
- const result = await npmRegistry.searchApiModules();
74
-
75
- expect(axios.get).toHaveBeenCalledWith(
76
- 'https://registry.npmjs.org/-/v1/search',
77
- expect.objectContaining({
78
- params: expect.objectContaining({
79
- text: '@friggframework/api-module-',
80
- size: 250
81
- }),
82
- timeout: 10000
83
- })
84
- );
85
-
86
- expect(result).toHaveLength(2);
87
- expect(result[0]).toMatchObject({
88
- name: '@friggframework/api-module-slack',
89
- version: '2.0.0',
90
- integrationName: 'Slack',
91
- category: 'Communication'
92
- });
93
- expect(result[1]).toMatchObject({
94
- name: '@friggframework/api-module-hubspot',
95
- integrationName: 'Hubspot',
96
- category: 'CRM'
97
- });
98
- });
99
-
100
- it('should use cached results when available', async () => {
101
- const cachedData = [{ name: 'cached-module' }];
102
- mockCache.get.mockReturnValue(cachedData);
103
-
104
- const result = await npmRegistry.searchApiModules();
105
-
106
- expect(axios.get).not.toHaveBeenCalled();
107
- expect(result).toEqual(cachedData);
108
- });
109
-
110
- it('should force refresh when requested', async () => {
111
- const cachedData = [{ name: 'cached-module' }];
112
- mockCache.get.mockReturnValue(cachedData);
113
- axios.get.mockResolvedValue(mockApiResponse);
114
-
115
- const result = await npmRegistry.searchApiModules({ forceRefresh: true });
116
-
117
- expect(axios.get).toHaveBeenCalled();
118
- expect(result).toHaveLength(2);
119
- });
120
-
121
- it('should filter out prerelease versions by default', async () => {
122
- const responseWithPrerelease = {
123
- data: {
124
- objects: [
125
- {
126
- package: {
127
- name: '@friggframework/api-module-test',
128
- version: '2.0.0-beta.1',
129
- description: 'Prerelease version'
130
- }
131
- },
132
- {
133
- package: {
134
- name: '@friggframework/api-module-stable',
135
- version: '1.0.0',
136
- description: 'Stable version'
137
- }
138
- }
139
- ]
140
- }
141
- };
142
-
143
- mockCache.get.mockReturnValue(null);
144
- axios.get.mockResolvedValue(responseWithPrerelease);
145
-
146
- const result = await npmRegistry.searchApiModules();
147
-
148
- expect(result).toHaveLength(1);
149
- expect(result[0].name).toBe('@friggframework/api-module-stable');
150
- });
151
-
152
- it('should include prerelease versions when requested', async () => {
153
- const responseWithPrerelease = {
154
- data: {
155
- objects: [
156
- {
157
- package: {
158
- name: '@friggframework/api-module-test',
159
- version: '2.0.0-beta.1'
160
- }
161
- }
162
- ]
163
- }
164
- };
165
-
166
- mockCache.get.mockReturnValue(null);
167
- axios.get.mockResolvedValue(responseWithPrerelease);
168
-
169
- const result = await npmRegistry.searchApiModules({ includePrerelease: true });
170
-
171
- expect(result).toHaveLength(1);
172
- expect(result[0].version).toBe('2.0.0-beta.1');
173
- });
174
-
175
- it('should handle network errors gracefully', async () => {
176
- mockCache.get.mockReturnValue(null);
177
- axios.get.mockRejectedValue(new Error('Network error'));
178
-
179
- const result = await npmRegistry.searchApiModules();
180
-
181
- expect(result).toEqual([]);
182
- });
183
-
184
- it('should cache results after successful fetch', async () => {
185
- mockCache.get.mockReturnValue(null);
186
- axios.get.mockResolvedValue(mockApiResponse);
187
-
188
- await npmRegistry.searchApiModules();
189
-
190
- expect(mockCache.set).toHaveBeenCalledWith(
191
- expect.any(String),
192
- expect.arrayContaining([
193
- expect.objectContaining({ name: '@friggframework/api-module-slack' })
194
- ])
195
- );
196
- });
197
- });
198
-
199
- describe('categorizeModule', () => {
200
- it('should categorize modules based on keywords and name', async () => {
201
- const testCases = [
202
- { name: '@friggframework/api-module-salesforce', keywords: ['crm'], expected: 'CRM' },
203
- { name: '@friggframework/api-module-slack', keywords: ['chat'], expected: 'Communication' },
204
- { name: '@friggframework/api-module-stripe', keywords: ['payment'], expected: 'E-commerce' },
205
- { name: '@friggframework/api-module-google-analytics', keywords: [], expected: 'Analytics' },
206
- { name: '@friggframework/api-module-mailchimp', keywords: ['email', 'marketing'], expected: 'Marketing' },
207
- { name: '@friggframework/api-module-facebook', keywords: [], expected: 'Social Media' },
208
- { name: '@friggframework/api-module-jira', keywords: ['project'], expected: 'Project Management' },
209
- { name: '@friggframework/api-module-dropbox', keywords: ['storage'], expected: 'Storage' },
210
- { name: '@friggframework/api-module-airtable', keywords: [], expected: 'Productivity' },
211
- { name: '@friggframework/api-module-github', keywords: ['git'], expected: 'Development' },
212
- { name: '@friggframework/api-module-zendesk', keywords: ['support'], expected: 'Support' },
213
- { name: '@friggframework/api-module-quickbooks', keywords: ['accounting'], expected: 'Finance' },
214
- { name: '@friggframework/api-module-unknown', keywords: [], expected: 'Other' }
215
- ];
216
-
217
- mockCache.get.mockReturnValue(null);
218
- axios.get.mockResolvedValue({
219
- data: {
220
- objects: testCases.map(tc => ({
221
- package: {
222
- name: tc.name,
223
- version: '1.0.0',
224
- keywords: tc.keywords
225
- }
226
- }))
227
- }
228
- });
229
-
230
- const results = await npmRegistry.searchApiModules();
231
-
232
- testCases.forEach((testCase, index) => {
233
- expect(results[index].category).toBe(testCase.expected);
234
- });
235
- });
236
- });
237
-
238
- describe('getModulesByType', () => {
239
- it('should group modules by category', async () => {
240
- mockCache.get.mockReturnValue(null);
241
- axios.get.mockResolvedValue({
242
- data: {
243
- objects: [
244
- {
245
- package: {
246
- name: '@friggframework/api-module-slack',
247
- version: '1.0.0',
248
- keywords: ['chat', 'communication']
249
- }
250
- },
251
- {
252
- package: {
253
- name: '@friggframework/api-module-discord',
254
- version: '1.0.0',
255
- keywords: ['chat', 'communication']
256
- }
257
- },
258
- {
259
- package: {
260
- name: '@friggframework/api-module-salesforce',
261
- version: '1.0.0',
262
- keywords: ['crm']
263
- }
264
- }
265
- ]
266
- }
267
- });
268
-
269
- const grouped = await npmRegistry.getModulesByType();
270
-
271
- expect(grouped).toMatchObject({
272
- 'Communication': expect.arrayContaining([
273
- expect.objectContaining({ name: '@friggframework/api-module-slack' }),
274
- expect.objectContaining({ name: '@friggframework/api-module-discord' })
275
- ]),
276
- 'CRM': expect.arrayContaining([
277
- expect.objectContaining({ name: '@friggframework/api-module-salesforce' })
278
- ])
279
- });
280
-
281
- expect(grouped['Communication']).toHaveLength(2);
282
- expect(grouped['CRM']).toHaveLength(1);
283
- });
284
-
285
- it('should handle empty results', async () => {
286
- mockCache.get.mockReturnValue(null);
287
- axios.get.mockResolvedValue({ data: { objects: [] } });
288
-
289
- const grouped = await npmRegistry.getModulesByType();
290
-
291
- expect(grouped).toEqual({});
292
- });
293
- });
294
-
295
- describe('extractIntegrationName', () => {
296
- it('should extract and format integration names correctly', async () => {
297
- const testCases = [
298
- { input: '@friggframework/api-module-slack', expected: 'Slack' },
299
- { input: '@friggframework/api-module-google-sheets', expected: 'Google Sheets' },
300
- { input: '@friggframework/api-module-hubspot-crm', expected: 'Hubspot Crm' }
301
- ];
302
-
303
- mockCache.get.mockReturnValue(null);
304
- axios.get.mockResolvedValue({
305
- data: {
306
- objects: testCases.map(tc => ({
307
- package: { name: tc.input, version: '1.0.0' }
308
- }))
309
- }
310
- });
311
-
312
- const results = await npmRegistry.searchApiModules();
313
-
314
- testCases.forEach((testCase, index) => {
315
- expect(results[index].integrationName).toBe(testCase.expected);
316
- });
317
- });
318
- });
319
- });
@@ -1,154 +0,0 @@
1
- const open = require('open');
2
- const chalk = require('chalk');
3
- const path = require('path');
4
- const ProcessManager = require('../utils/process-manager');
5
- const {
6
- getCurrentRepositoryInfo,
7
- discoverFriggRepositories,
8
- promptRepositorySelection,
9
- formatRepositoryInfo
10
- } = require('../utils/repo-detection');
11
-
12
- async function uiCommand(options) {
13
- const { port = 3001, open: shouldOpen = true, repo: specifiedRepo, dev = false } = options;
14
-
15
- let targetRepo = null;
16
- let workingDirectory = process.cwd();
17
-
18
- // If a specific repo path is provided, use it
19
- if (specifiedRepo) {
20
- const repoPath = path.resolve(specifiedRepo);
21
- console.log(chalk.blue(`Using specified repository: ${repoPath}`));
22
- workingDirectory = repoPath;
23
- targetRepo = { path: repoPath, name: path.basename(repoPath) };
24
- } else {
25
- // Check if we're already in a Frigg repository
26
- console.log(chalk.blue('Detecting Frigg repository...'));
27
- const currentRepo = await getCurrentRepositoryInfo();
28
-
29
- if (currentRepo) {
30
- console.log(chalk.green(`✓ Found Frigg repository: ${formatRepositoryInfo(currentRepo)}`));
31
- if (currentRepo.currentSubPath) {
32
- console.log(chalk.gray(` Currently in subdirectory: ${currentRepo.currentSubPath}`));
33
- }
34
- targetRepo = currentRepo;
35
- workingDirectory = currentRepo.path;
36
- } else {
37
- // Discover Frigg repositories
38
- console.log(chalk.yellow('Current directory is not a Frigg repository.'));
39
- console.log(chalk.blue('Searching for Frigg repositories...'));
40
-
41
- const discoveredRepos = await discoverFriggRepositories();
42
-
43
- if (discoveredRepos.length === 0) {
44
- console.log(chalk.red('No Frigg repositories found. Please create one first.'));
45
- process.exit(1);
46
- }
47
-
48
- // For UI command, we'll let the UI handle repository selection
49
- // Set a placeholder and pass the discovered repos via environment
50
- targetRepo = {
51
- name: 'Multiple Repositories Available',
52
- path: process.cwd(),
53
- isMultiRepo: true,
54
- availableRepos: discoveredRepos
55
- };
56
- workingDirectory = process.cwd();
57
-
58
- console.log(chalk.blue(`Found ${discoveredRepos.length} Frigg repositories. You'll be able to select one in the UI.`));
59
- }
60
- }
61
-
62
- console.log(chalk.blue('🚀 Starting Frigg Management UI...'));
63
-
64
- const processManager = new ProcessManager();
65
-
66
- try {
67
- const managementUiPath = path.join(__dirname, '../../management-ui');
68
-
69
- // Check if we're in development mode
70
- // For CLI usage, we prefer development mode unless explicitly set to production
71
- const fs = require('fs');
72
- const isDevelopment = dev || process.env.NODE_ENV !== 'production';
73
-
74
- if (isDevelopment) {
75
- const env = {
76
- ...process.env,
77
- VITE_API_URL: `http://localhost:${port}`,
78
- PORT: port,
79
- PROJECT_ROOT: workingDirectory,
80
- REPOSITORY_INFO: JSON.stringify(targetRepo),
81
- AVAILABLE_REPOSITORIES: targetRepo.isMultiRepo ? JSON.stringify(targetRepo.availableRepos) : null
82
- };
83
-
84
- // Start backend server
85
- processManager.spawnProcess(
86
- 'backend',
87
- 'npm',
88
- ['run', 'server'],
89
- { cwd: managementUiPath, env }
90
- );
91
-
92
- // Start frontend dev server
93
- processManager.spawnProcess(
94
- 'frontend',
95
- 'npm',
96
- ['run', 'dev'],
97
- { cwd: managementUiPath, env }
98
- );
99
-
100
- // Wait for servers to start
101
- await new Promise(resolve => setTimeout(resolve, 2000));
102
-
103
- // Display clean status
104
- processManager.printStatus(
105
- 'http://localhost:5173',
106
- `http://localhost:${port}`,
107
- targetRepo.name
108
- );
109
-
110
- // Open browser if requested
111
- if (shouldOpen) {
112
- setTimeout(() => {
113
- open('http://localhost:5173');
114
- }, 1000);
115
- }
116
-
117
- } else {
118
- // Production mode - just start the backend server
119
- const { FriggManagementServer } = await import('../../management-ui/server/index.js');
120
-
121
- const server = new FriggManagementServer({
122
- port,
123
- projectRoot: workingDirectory,
124
- repositoryInfo: targetRepo,
125
- availableRepositories: targetRepo.isMultiRepo ? targetRepo.availableRepos : null
126
- });
127
- await server.start();
128
-
129
- processManager.printStatus(
130
- `http://localhost:${port}`,
131
- `http://localhost:${port}/api`,
132
- targetRepo.name
133
- );
134
-
135
- if (shouldOpen) {
136
- setTimeout(() => {
137
- open(`http://localhost:${port}`);
138
- }, 1000);
139
- }
140
- }
141
-
142
- // Keep the process running
143
- process.stdin.resume();
144
-
145
- } catch (error) {
146
- console.error(chalk.red('Failed to start Management UI:'), error.message);
147
- if (error.code === 'EADDRINUSE') {
148
- console.log(chalk.yellow(`Port ${port} is already in use. Try using a different port with --port <number>`));
149
- }
150
- process.exit(1);
151
- }
152
- }
153
-
154
- module.exports = { uiCommand };