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