@friggframework/devtools 2.0.0--canary.545.e256e95.0 → 2.0.0--canary.553.dc5f898.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/frigg-cli/README.md +1 -1
  2. package/frigg-cli/__tests__/unit/commands/build.test.js +1 -1
  3. package/frigg-cli/__tests__/unit/commands/doctor.test.js +2 -0
  4. package/frigg-cli/__tests__/unit/commands/install.test.js +19 -23
  5. package/frigg-cli/__tests__/unit/dependencies.test.js +2 -2
  6. package/frigg-cli/build-command/index.js +11 -123
  7. package/frigg-cli/deploy-command/index.js +1 -83
  8. package/frigg-cli/doctor-command/index.js +16 -37
  9. package/frigg-cli/generate-iam-command.js +1 -21
  10. package/frigg-cli/index.js +6 -21
  11. package/frigg-cli/index.test.js +2 -7
  12. package/frigg-cli/init-command/backend-first-handler.js +42 -124
  13. package/frigg-cli/init-command/index.js +1 -2
  14. package/frigg-cli/init-command/template-handler.js +3 -13
  15. package/frigg-cli/install-command/backend-js.js +3 -3
  16. package/frigg-cli/install-command/environment-variables.js +19 -16
  17. package/frigg-cli/install-command/environment-variables.test.js +13 -12
  18. package/frigg-cli/install-command/index.js +9 -14
  19. package/frigg-cli/install-command/integration-file.js +3 -3
  20. package/frigg-cli/install-command/logger.js +12 -0
  21. package/frigg-cli/install-command/validate-package.js +9 -5
  22. package/frigg-cli/jest.config.js +1 -4
  23. package/frigg-cli/repair-command/index.js +128 -121
  24. package/frigg-cli/start-command/index.js +2 -324
  25. package/frigg-cli/ui-command/index.js +36 -58
  26. package/frigg-cli/utils/repo-detection.js +37 -85
  27. package/infrastructure/create-frigg-infrastructure.js +0 -93
  28. package/infrastructure/docs/iam-policy-templates.md +1 -1
  29. package/infrastructure/domains/integration/integration-builder.js +3 -2
  30. package/infrastructure/domains/integration/integration-builder.test.js +54 -2
  31. package/infrastructure/domains/networking/vpc-builder.test.js +4 -2
  32. package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
  33. package/infrastructure/domains/shared/resource-discovery.js +5 -5
  34. package/infrastructure/domains/shared/types/app-definition.js +0 -35
  35. package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
  36. package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -10
  37. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
  38. package/infrastructure/infrastructure-composer.js +0 -2
  39. package/infrastructure/infrastructure-composer.test.js +6 -5
  40. package/management-ui/README.md +109 -245
  41. package/package.json +7 -8
  42. package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
  43. package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
  44. package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
  45. package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
  46. package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
  47. package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
  48. package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
  49. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
  50. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
  51. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -383
  52. package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
  53. package/frigg-cli/__tests__/unit/commands/provider-dispatch.test.js +0 -383
  54. package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
  55. package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
  56. package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
  57. package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
  58. package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
  59. package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
  60. package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
  61. package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
  62. package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
  63. package/frigg-cli/container.js +0 -172
  64. package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
  65. package/frigg-cli/domain/entities/ApiModule.js +0 -272
  66. package/frigg-cli/domain/entities/AppDefinition.js +0 -227
  67. package/frigg-cli/domain/entities/Integration.js +0 -198
  68. package/frigg-cli/domain/exceptions/DomainException.js +0 -24
  69. package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
  70. package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
  71. package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
  72. package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
  73. package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
  74. package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
  75. package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
  76. package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
  77. package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
  78. package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
  79. package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
  80. package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
  81. package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
  82. package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
  83. package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
  84. package/frigg-cli/package-lock.json +0 -16226
  85. package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
  86. package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
  87. package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
  88. package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
  89. package/frigg-cli/templates/backend/.env.example +0 -62
  90. package/frigg-cli/templates/backend/.eslintrc.json +0 -12
  91. package/frigg-cli/templates/backend/.prettierrc +0 -6
  92. package/frigg-cli/templates/backend/docker-compose.yml +0 -22
  93. package/frigg-cli/templates/backend/index.js +0 -96
  94. package/frigg-cli/templates/backend/infrastructure.js +0 -12
  95. package/frigg-cli/templates/backend/jest.config.js +0 -17
  96. package/frigg-cli/templates/backend/package.json +0 -50
  97. package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
  98. package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
  99. package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
  100. package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
  101. package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
  102. package/frigg-cli/templates/backend/test/setup.js +0 -30
  103. package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
  104. package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
  105. package/frigg-cli/utils/__tests__/provider-helper.test.js +0 -55
  106. package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
  107. package/frigg-cli/utils/output.js +0 -382
  108. package/frigg-cli/utils/provider-helper.js +0 -75
  109. package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
  110. package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
  111. package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
  112. package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
  113. package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
  114. package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
  115. package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
  116. package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
  117. package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
  118. package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
  119. package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
  120. package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
  121. package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
  122. package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
  123. package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
  124. package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -145
  125. package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
  126. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  127. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  128. package/infrastructure/domains/admin-scripts/index.js +0 -5
  129. package/infrastructure/jest.config.js +0 -16
@@ -1,155 +0,0 @@
1
- /**
2
- * Template Validation Tests
3
- *
4
- * Validates that the frigg init templates produce valid configurations
5
- * when run through the validator.
6
- */
7
-
8
- const path = require('path');
9
- const { AppDefinitionValidator } = require('../../infrastructure/validators/app-definition-validator');
10
- const { IntegrationClassValidator } = require('../../infrastructure/validators/integration-class-validator');
11
- const { ApiModuleValidator } = require('../../infrastructure/validators/api-module-validator');
12
-
13
- // Resolve template paths relative to frigg-cli package root
14
- const FRIGG_CLI_ROOT = path.resolve(__dirname, '../../..');
15
- const TEMPLATES_DIR = path.join(FRIGG_CLI_ROOT, 'templates');
16
-
17
- describe('Template Validation', () => {
18
- let appDefinitionValidator;
19
- let integrationClassValidator;
20
- let apiModuleValidator;
21
-
22
- beforeEach(() => {
23
- appDefinitionValidator = new AppDefinitionValidator();
24
- integrationClassValidator = new IntegrationClassValidator();
25
- apiModuleValidator = new ApiModuleValidator();
26
- });
27
-
28
- describe('backend/index.js template', () => {
29
- // Load the actual template
30
- const templatePath = path.join(TEMPLATES_DIR, 'backend/index.js');
31
- let templateModule;
32
-
33
- beforeAll(() => {
34
- // Clear require cache to ensure fresh load
35
- delete require.cache[require.resolve(templatePath)];
36
- templateModule = require(templatePath);
37
- });
38
-
39
- it('exports a Definition property', () => {
40
- expect(templateModule.Definition).toBeDefined();
41
- expect(typeof templateModule.Definition).toBe('object');
42
- });
43
-
44
- it('has valid app definition structure', () => {
45
- const result = appDefinitionValidator.validate(templateModule.Definition);
46
-
47
- // Log errors for debugging
48
- if (!result.isValid()) {
49
- console.log('App Definition Errors:', result.getErrors().map(e => `${e.path}: ${e.message}`));
50
- }
51
-
52
- expect(result.isValid()).toBe(true);
53
- });
54
-
55
- it('has required integrations array', () => {
56
- expect(templateModule.Definition.integrations).toBeDefined();
57
- expect(Array.isArray(templateModule.Definition.integrations)).toBe(true);
58
- });
59
-
60
- it('has valid user configuration', () => {
61
- const userConfig = templateModule.Definition.user;
62
- expect(userConfig).toBeDefined();
63
- expect(typeof userConfig.usePassword).toBe('boolean');
64
- expect(['individual', 'organization']).toContain(userConfig.primary);
65
- });
66
-
67
- it('has valid database configuration', () => {
68
- const dbConfig = templateModule.Definition.database;
69
- expect(dbConfig).toBeDefined();
70
- // Should have at least one database type configured
71
- expect(dbConfig.postgres || dbConfig.mongoDB || dbConfig.documentDB).toBeDefined();
72
- });
73
-
74
- it('has valid vpc configuration', () => {
75
- const vpcConfig = templateModule.Definition.vpc;
76
- expect(vpcConfig).toBeDefined();
77
- expect(typeof vpcConfig.enable).toBe('boolean');
78
- });
79
-
80
- it('has valid encryption configuration', () => {
81
- const encConfig = templateModule.Definition.encryption;
82
- expect(encConfig).toBeDefined();
83
- expect(['kms', 'aes', 'none']).toContain(encConfig.fieldLevelEncryptionMethod);
84
- });
85
- });
86
-
87
- describe('ExampleIntegration template', () => {
88
- const templatePath = path.join(TEMPLATES_DIR, 'backend/src/integrations/ExampleIntegration.js');
89
- let ExampleIntegration;
90
-
91
- beforeAll(() => {
92
- // Mock @friggframework/core since it may not be installed in CLI package
93
- jest.mock('@friggframework/core', () => ({
94
- Integration: class Integration {
95
- static Config = {};
96
- }
97
- }), { virtual: true });
98
-
99
- delete require.cache[require.resolve(templatePath)];
100
- ExampleIntegration = require(templatePath);
101
- });
102
-
103
- afterAll(() => {
104
- jest.unmock('@friggframework/core');
105
- });
106
-
107
- it('is a class/function', () => {
108
- expect(typeof ExampleIntegration).toBe('function');
109
- });
110
-
111
- it('has static Definition property', () => {
112
- expect(ExampleIntegration.Definition).toBeDefined();
113
- });
114
-
115
- it('Definition has required properties', () => {
116
- const definition = ExampleIntegration.Definition;
117
- expect(definition.name).toBeDefined();
118
- expect(definition.version).toBeDefined();
119
- });
120
-
121
- it('Definition matches pattern used in core integrations', () => {
122
- // ExampleIntegration uses static Definition (not Config)
123
- // to match the pattern expected by IntegrationClassValidator
124
- expect(ExampleIntegration.Definition).toBeDefined();
125
- expect(typeof ExampleIntegration.Definition.name).toBe('string');
126
- expect(typeof ExampleIntegration.Definition.version).toBe('string');
127
- });
128
- });
129
-
130
- describe('Template schema compliance', () => {
131
- it('template app definition does not use unknown properties', () => {
132
- const templatePath = path.join(TEMPLATES_DIR, 'backend/index.js');
133
- delete require.cache[require.resolve(templatePath)];
134
- const { Definition } = require(templatePath);
135
-
136
- const result = appDefinitionValidator.validate(Definition);
137
- const errors = result.getErrors();
138
-
139
- // Check for "additional property" errors which indicate unknown fields
140
- const additionalPropErrors = errors.filter(e =>
141
- e.message.includes('additional properties') ||
142
- e.code === 'ADDITIONALPROPERTIES'
143
- );
144
-
145
- if (additionalPropErrors.length > 0) {
146
- console.log('Unknown properties in template:',
147
- additionalPropErrors.map(e => e.message));
148
- }
149
-
150
- // For now, document what additional properties exist
151
- // These may need to be added to the schema or removed from template
152
- expect(additionalPropErrors).toEqual([]);
153
- });
154
- });
155
- });
@@ -1,199 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const { ValidateAppUseCase } = require('../../application/use-cases/validate-app-use-case');
4
- const { AppDefinitionValidator } = require('../../infrastructure/validators/app-definition-validator');
5
- const { IntegrationClassValidator } = require('../../infrastructure/validators/integration-class-validator');
6
- const { ApiModuleValidator } = require('../../infrastructure/validators/api-module-validator');
7
-
8
- function createValidateCommand(program) {
9
- program
10
- .command('validate [path]')
11
- .description('Validate a Frigg application configuration (auto-detects local app if no path given)')
12
- .option('-f, --format <format>', 'Output format (console, json)', 'console')
13
- .option('-v, --verbose', 'Show detailed output including fix suggestions', false)
14
- .action(async (appPath, options) => {
15
- const output = require('../../../utils/output');
16
- await validateCommand(appPath, options, { output });
17
- });
18
- }
19
-
20
- function autoDetectFriggApp(startDir = process.cwd()) {
21
- let currentDir = startDir;
22
- const root = path.parse(currentDir).root;
23
-
24
- while (currentDir !== root) {
25
- const backendPath = findBackendPathInDir(currentDir);
26
- if (backendPath) {
27
- return { appRoot: currentDir, backendPath };
28
- }
29
- currentDir = path.dirname(currentDir);
30
- }
31
-
32
- return null;
33
- }
34
-
35
- function findBackendPathInDir(dir) {
36
- const backendDir = path.join(dir, 'backend');
37
- if (fs.existsSync(path.join(backendDir, 'index.js'))) {
38
- return backendDir;
39
- }
40
-
41
- if (fs.existsSync(path.join(dir, 'index.js'))) {
42
- const content = fs.readFileSync(path.join(dir, 'index.js'), 'utf-8');
43
- if (content.includes('integrations') || content.includes('Definition')) {
44
- return dir;
45
- }
46
- }
47
-
48
- return null;
49
- }
50
-
51
- function findBackendPath(startPath) {
52
- const absolutePath = path.isAbsolute(startPath) ? startPath : path.resolve(process.cwd(), startPath);
53
-
54
- const backendDir = path.join(absolutePath, 'backend');
55
- if (fs.existsSync(path.join(backendDir, 'package.json')) || fs.existsSync(path.join(backendDir, 'index.js'))) {
56
- return backendDir;
57
- }
58
-
59
- if (fs.existsSync(path.join(absolutePath, 'package.json')) || fs.existsSync(path.join(absolutePath, 'index.js'))) {
60
- return absolutePath;
61
- }
62
-
63
- return null;
64
- }
65
-
66
- function loadAppDefinition(backendPath) {
67
- const indexPath = path.join(backendPath, 'index.js');
68
- if (!fs.existsSync(indexPath)) {
69
- throw new Error(`No index.js found at ${backendPath}`);
70
- }
71
-
72
- const originalCwd = process.cwd();
73
- try {
74
- process.chdir(backendPath);
75
- delete require.cache[require.resolve(indexPath)];
76
- const exported = require(indexPath);
77
- return exported.Definition || exported.default || exported;
78
- } finally {
79
- process.chdir(originalCwd);
80
- }
81
- }
82
-
83
- async function validateCommand(appPath, options, { output }) {
84
- try {
85
- let backendPath;
86
- let definition;
87
-
88
- if (!appPath) {
89
- const detected = autoDetectFriggApp();
90
- if (!detected) {
91
- output.error('No Frigg app found. Run from within a Frigg app directory or specify a path.');
92
- return;
93
- }
94
- backendPath = detected.backendPath;
95
- output.info(`Auto-detected Frigg app at: ${detected.appRoot}`);
96
- } else {
97
- backendPath = findBackendPath(appPath);
98
- if (!backendPath) {
99
- output.error(`Could not find backend directory in ${appPath}`);
100
- return;
101
- }
102
- output.info(`Validating Frigg app at: ${appPath}`);
103
- }
104
-
105
- try {
106
- definition = loadAppDefinition(backendPath);
107
- } catch (err) {
108
- output.error(`Could not load app definition: ${err.message}`);
109
- return;
110
- }
111
-
112
- const appDefinitionValidator = new AppDefinitionValidator();
113
- const integrationClassValidator = new IntegrationClassValidator();
114
- const apiModuleValidator = new ApiModuleValidator();
115
- const useCase = new ValidateAppUseCase({
116
- appDefinitionValidator,
117
- integrationClassValidator,
118
- apiModuleValidator
119
- });
120
-
121
- const result = await useCase.execute({ definition, appPath: backendPath });
122
-
123
- if (options.format === 'json') {
124
- output.log(JSON.stringify(result.toJSON(), null, 2));
125
- return;
126
- }
127
-
128
- formatConsoleOutput(result, options, output);
129
- } catch (err) {
130
- output.error(`Validation failed: ${err.message}`);
131
- if (options.verbose) {
132
- output.error(err.stack);
133
- }
134
- }
135
- }
136
-
137
- function formatConsoleOutput(result, options, output) {
138
- const summary = result.getSummary();
139
-
140
- output.log('');
141
- output.log('═'.repeat(60));
142
- output.log(' FRIGG VALIDATE - App Configuration Report');
143
- output.log('═'.repeat(60));
144
- output.log('');
145
-
146
- if (result.isValid()) {
147
- output.success('App configuration is valid');
148
- } else {
149
- output.error(`App configuration has ${summary.errorCount} error(s)`);
150
- }
151
-
152
- if (summary.warningCount > 0) {
153
- output.warn(`${summary.warningCount} warning(s) found`);
154
- }
155
-
156
- output.log('');
157
-
158
- if (result.getErrors().length > 0) {
159
- output.log('─'.repeat(60));
160
- output.log('ERRORS:');
161
- output.log('');
162
- result.getErrors().forEach((error, idx) => {
163
- output.log(` ${idx + 1}. [${error.path}] ${error.message}`);
164
- if (options.verbose && error.fix) {
165
- output.log(` Fix: ${error.fix.description}`);
166
- if (error.fix.template) {
167
- output.log(` Template: ${JSON.stringify(error.fix.template)}`);
168
- }
169
- }
170
- });
171
- output.log('');
172
- }
173
-
174
- if (result.getWarnings().length > 0) {
175
- output.log('─'.repeat(60));
176
- output.log('WARNINGS:');
177
- output.log('');
178
- result.getWarnings().forEach((warning, idx) => {
179
- output.log(` ${idx + 1}. [${warning.path}] ${warning.message}`);
180
- if (options.verbose && warning.fix) {
181
- output.log(` Fix: ${warning.fix.description}`);
182
- }
183
- });
184
- output.log('');
185
- }
186
-
187
- output.log('═'.repeat(60));
188
- output.log('');
189
- }
190
-
191
- module.exports = {
192
- validateCommand,
193
- createValidateCommand,
194
- formatConsoleOutput,
195
- autoDetectFriggApp,
196
- findBackendPathInDir,
197
- findBackendPath,
198
- loadAppDefinition
199
- };
@@ -1,35 +0,0 @@
1
- const { ValidationResult } = require('../../domain/entities/validation-result');
2
-
3
- class ValidateAppUseCase {
4
- constructor({ appDefinitionValidator, integrationClassValidator, apiModuleValidator }) {
5
- this.appDefinitionValidator = appDefinitionValidator;
6
- this.integrationClassValidator = integrationClassValidator;
7
- this.apiModuleValidator = apiModuleValidator;
8
- }
9
-
10
- async execute({ definition, appPath }) {
11
- let result = ValidationResult.create({
12
- context: { appPath }
13
- });
14
-
15
- const appResult = this.appDefinitionValidator.validate(definition);
16
- result = result.merge(appResult);
17
-
18
- if (definition.integrations && Array.isArray(definition.integrations)) {
19
- definition.integrations.forEach((integration, index) => {
20
- const integrationResult = this.integrationClassValidator.validate(integration, index);
21
- result = result.merge(integrationResult);
22
-
23
- // Validate API modules within the integration
24
- if (this.apiModuleValidator && integration.Definition) {
25
- const moduleResult = this.apiModuleValidator.validate(integration.Definition, index);
26
- result = result.merge(moduleResult);
27
- }
28
- });
29
- }
30
-
31
- return result;
32
- }
33
- }
34
-
35
- module.exports = { ValidateAppUseCase };
@@ -1,74 +0,0 @@
1
- class ValidationResult {
2
- constructor({ errors, context }) {
3
- this.errors = errors || [];
4
- this.context = context || {};
5
- }
6
-
7
- static create(props = {}) {
8
- return new ValidationResult(props);
9
- }
10
-
11
- isValid() {
12
- return !this.errors.some(e => e.isError());
13
- }
14
-
15
- getErrors() {
16
- return this.errors.filter(e => e.isError());
17
- }
18
-
19
- getWarnings() {
20
- return this.errors.filter(e => e.isWarning());
21
- }
22
-
23
- getInfos() {
24
- return this.errors.filter(e => e.isInfo());
25
- }
26
-
27
- addError(error) {
28
- this.errors.push(error);
29
- return this;
30
- }
31
-
32
- merge(other) {
33
- return ValidationResult.create({
34
- errors: [...this.errors, ...other.errors],
35
- context: { ...this.context, ...other.context }
36
- });
37
- }
38
-
39
- getContext() {
40
- return this.context;
41
- }
42
-
43
- filterByPath(pathPrefix) {
44
- return ValidationResult.create({
45
- errors: this.errors.filter(e => e.path.startsWith(pathPrefix)),
46
- context: this.context
47
- });
48
- }
49
-
50
- getBySeverity(severity) {
51
- return this.errors.filter(e => e.severity === severity);
52
- }
53
-
54
- getSummary() {
55
- return {
56
- isValid: this.isValid(),
57
- errorCount: this.getErrors().length,
58
- warningCount: this.getWarnings().length,
59
- infoCount: this.getInfos().length,
60
- totalCount: this.errors.length
61
- };
62
- }
63
-
64
- toJSON() {
65
- return {
66
- valid: this.isValid(),
67
- errors: this.errors.map(e => e.toJSON()),
68
- summary: this.getSummary(),
69
- context: this.context
70
- };
71
- }
72
- }
73
-
74
- module.exports = { ValidationResult };
@@ -1,74 +0,0 @@
1
- const VALID_ACTIONS = ['add', 'remove', 'replace', 'rename', 'update'];
2
-
3
- class FixSuggestion {
4
- constructor({ action, description, template, codeSnippet, targetPath, targetFile }) {
5
- if (!action) {
6
- throw new Error('action is required');
7
- }
8
- if (!description) {
9
- throw new Error('description is required');
10
- }
11
- if (!VALID_ACTIONS.includes(action)) {
12
- throw new Error(`Invalid action: ${action}. Must be one of: ${VALID_ACTIONS.join(', ')}`);
13
- }
14
-
15
- this.action = action;
16
- this.description = description;
17
- this.template = template || null;
18
- this.codeSnippet = codeSnippet || null;
19
- this.targetPath = targetPath || null;
20
- this.targetFile = targetFile || null;
21
- }
22
-
23
- static create(props) {
24
- return new FixSuggestion(props);
25
- }
26
-
27
- isAdd() {
28
- return this.action === 'add';
29
- }
30
-
31
- isRemove() {
32
- return this.action === 'remove';
33
- }
34
-
35
- isReplace() {
36
- return this.action === 'replace';
37
- }
38
-
39
- isRename() {
40
- return this.action === 'rename';
41
- }
42
-
43
- isUpdate() {
44
- return this.action === 'update';
45
- }
46
-
47
- isAutoApplicable() {
48
- return this.template !== null || this.codeSnippet !== null;
49
- }
50
-
51
- toJSON() {
52
- return {
53
- action: this.action,
54
- description: this.description,
55
- template: this.template,
56
- codeSnippet: this.codeSnippet,
57
- targetPath: this.targetPath,
58
- targetFile: this.targetFile
59
- };
60
- }
61
-
62
- format() {
63
- let output = `[${this.action}] ${this.description}`;
64
- if (this.template) {
65
- output += `\n Template: ${JSON.stringify(this.template)}`;
66
- }
67
- if (this.codeSnippet) {
68
- output += `\n Code: ${this.codeSnippet}`;
69
- }
70
- return output;
71
- }
72
- }
73
-
74
- module.exports = { FixSuggestion };
@@ -1,68 +0,0 @@
1
- const VALID_SEVERITIES = ['error', 'warning', 'info'];
2
-
3
- class ValidationError {
4
- constructor({ path, message, severity, code, fix }) {
5
- if (!path) {
6
- throw new Error('path is required');
7
- }
8
- if (!message) {
9
- throw new Error('message is required');
10
- }
11
- if (severity && !VALID_SEVERITIES.includes(severity)) {
12
- throw new Error(`Invalid severity: ${severity}. Must be one of: ${VALID_SEVERITIES.join(', ')}`);
13
- }
14
-
15
- this.path = path;
16
- this.message = message;
17
- this.severity = severity || 'error';
18
- this.code = code || null;
19
- this.fix = fix || null;
20
- }
21
-
22
- static create(props) {
23
- return new ValidationError(props);
24
- }
25
-
26
- getPathSegments() {
27
- return this.path
28
- .replace(/\[(\d+)\]/g, '.$1')
29
- .split('.')
30
- .filter(Boolean);
31
- }
32
-
33
- getRootPath() {
34
- return this.getPathSegments()[0];
35
- }
36
-
37
- isError() {
38
- return this.severity === 'error';
39
- }
40
-
41
- isWarning() {
42
- return this.severity === 'warning';
43
- }
44
-
45
- isInfo() {
46
- return this.severity === 'info';
47
- }
48
-
49
- hasFix() {
50
- return this.fix !== null;
51
- }
52
-
53
- equals(other) {
54
- return this.path === other.path && this.message === other.message;
55
- }
56
-
57
- toJSON() {
58
- return {
59
- path: this.path,
60
- message: this.message,
61
- severity: this.severity,
62
- code: this.code,
63
- fix: this.fix ? this.fix.toJSON() : null
64
- };
65
- }
66
- }
67
-
68
- module.exports = { ValidationError };