@friggframework/devtools 2.0.0--canary.545.ae2019f.0 → 2.0.0--canary.549.a579cca.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 (127) 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/networking/vpc-builder.test.js +4 -2
  30. package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
  31. package/infrastructure/domains/shared/resource-discovery.js +5 -5
  32. package/infrastructure/domains/shared/types/app-definition.js +0 -21
  33. package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
  34. package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -10
  35. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
  36. package/infrastructure/infrastructure-composer.js +0 -2
  37. package/infrastructure/infrastructure-composer.test.js +2 -2
  38. package/management-ui/README.md +109 -245
  39. package/package.json +7 -8
  40. package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
  41. package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
  42. package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
  43. package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
  44. package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
  45. package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
  46. package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
  47. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
  48. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
  49. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -383
  50. package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
  51. package/frigg-cli/__tests__/unit/commands/provider-dispatch.test.js +0 -383
  52. package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
  53. package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
  54. package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
  55. package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
  56. package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
  57. package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
  58. package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
  59. package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
  60. package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
  61. package/frigg-cli/container.js +0 -172
  62. package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
  63. package/frigg-cli/domain/entities/ApiModule.js +0 -272
  64. package/frigg-cli/domain/entities/AppDefinition.js +0 -227
  65. package/frigg-cli/domain/entities/Integration.js +0 -198
  66. package/frigg-cli/domain/exceptions/DomainException.js +0 -24
  67. package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
  68. package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
  69. package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
  70. package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
  71. package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
  72. package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
  73. package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
  74. package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
  75. package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
  76. package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
  77. package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
  78. package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
  79. package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
  80. package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
  81. package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
  82. package/frigg-cli/package-lock.json +0 -16226
  83. package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
  84. package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
  85. package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
  86. package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
  87. package/frigg-cli/templates/backend/.env.example +0 -62
  88. package/frigg-cli/templates/backend/.eslintrc.json +0 -12
  89. package/frigg-cli/templates/backend/.prettierrc +0 -6
  90. package/frigg-cli/templates/backend/docker-compose.yml +0 -22
  91. package/frigg-cli/templates/backend/index.js +0 -96
  92. package/frigg-cli/templates/backend/infrastructure.js +0 -12
  93. package/frigg-cli/templates/backend/jest.config.js +0 -17
  94. package/frigg-cli/templates/backend/package.json +0 -50
  95. package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
  96. package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
  97. package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
  98. package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
  99. package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
  100. package/frigg-cli/templates/backend/test/setup.js +0 -30
  101. package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
  102. package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
  103. package/frigg-cli/utils/__tests__/provider-helper.test.js +0 -55
  104. package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
  105. package/frigg-cli/utils/output.js +0 -382
  106. package/frigg-cli/utils/provider-helper.js +0 -75
  107. package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
  108. package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
  109. package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
  110. package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
  111. package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
  112. package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
  113. package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
  114. package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
  115. package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
  116. package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
  117. package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
  118. package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
  119. package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
  120. package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
  121. package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
  122. package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -128
  123. package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
  124. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  125. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  126. package/infrastructure/domains/admin-scripts/index.js +0 -5
  127. 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 };