@tamyla/clodo-framework 4.1.0 → 4.2.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [4.2.0](https://github.com/tamylaa/clodo-framework/compare/v4.1.0...v4.2.0) (2026-01-31)
2
+
3
+
4
+ ### Features
5
+
6
+ * **validation:** integrate ConfigurationValidator into ValidationHandler; add post-generation validation in ServiceOrchestrator; tests ([#5](https://github.com/tamylaa/clodo-framework/issues/5)) ([2889864](https://github.com/tamylaa/clodo-framework/commit/28898641bac4c2d6d206e12dbba8216e1de386a3))
7
+
1
8
  # [4.1.0](https://github.com/tamylaa/clodo-framework/compare/v4.0.15...v4.1.0) (2026-01-31)
2
9
 
3
10
 
@@ -131,15 +131,52 @@ export class ServiceOrchestrator {
131
131
  outputPath: options.outputDir || this.outputPath,
132
132
  middlewareStrategy: this.middlewareStrategy
133
133
  });
134
- return {
135
- success: true,
136
- serviceId: generationResult.serviceId || null,
137
- servicePath: generationResult.servicePath || null,
138
- serviceName: generationResult.serviceName || coreInputs.serviceName,
139
- fileCount: generationResult.fileCount || (generationResult.generatedFiles || []).length,
140
- generatedFiles: generationResult.generatedFiles || [],
141
- warnings: validation.warnings || []
142
- };
134
+
135
+ // Post-generation validation using ValidationHandler
136
+ const validationHandler = options.customConfig ? new ValidationHandler({
137
+ customConfig: options.customConfig
138
+ }) : this.validationHandler;
139
+ try {
140
+ const postValidation = await validationHandler.validateService(generationResult.servicePath);
141
+ if (!postValidation.valid && !options.force) {
142
+ return {
143
+ success: false,
144
+ errors: postValidation.issues || [],
145
+ warnings: validation.warnings || [],
146
+ validationReport: postValidation
147
+ };
148
+ }
149
+ return {
150
+ success: true,
151
+ serviceId: generationResult.serviceId || null,
152
+ servicePath: generationResult.servicePath || null,
153
+ serviceName: generationResult.serviceName || coreInputs.serviceName,
154
+ fileCount: generationResult.fileCount || (generationResult.generatedFiles || []).length,
155
+ generatedFiles: generationResult.generatedFiles || [],
156
+ warnings: validation.warnings || [],
157
+ validationReport: postValidation
158
+ };
159
+ } catch (valErr) {
160
+ // If validation step throws, surface error unless forced
161
+ if (!options.force) {
162
+ return {
163
+ success: false,
164
+ errors: [valErr.message]
165
+ };
166
+ }
167
+ return {
168
+ success: true,
169
+ serviceId: generationResult.serviceId || null,
170
+ servicePath: generationResult.servicePath || null,
171
+ serviceName: generationResult.serviceName || coreInputs.serviceName,
172
+ fileCount: generationResult.fileCount || (generationResult.generatedFiles || []).length,
173
+ generatedFiles: generationResult.generatedFiles || [],
174
+ warnings: validation.warnings || [],
175
+ validationReport: {
176
+ error: valErr.message
177
+ }
178
+ };
179
+ }
143
180
  } catch (error) {
144
181
  return {
145
182
  success: false,
@@ -6,8 +6,7 @@
6
6
  import fs from 'fs/promises';
7
7
  import path from 'path';
8
8
  import { FrameworkConfig } from '../../utils/framework-config.js';
9
- // import { ConfigurationValidator } from '../../lib/shared/utils/configuration-validator.js';
10
-
9
+ import { ConfigurationValidator } from '../../security/ConfigurationValidator.js';
11
10
  export class ValidationHandler {
12
11
  constructor(options = {}) {
13
12
  this.strict = options.strict || false;
@@ -94,17 +93,33 @@ export class ValidationHandler {
94
93
  issues.push(...wranglerValidation.issues);
95
94
 
96
95
  // Run comprehensive configuration validation using ConfigurationValidator
97
- // Temporarily disabled due to import issues
98
- // try {
99
- // const configValidation = await ConfigurationValidator.validateServiceConfig(servicePath);
100
- // if (!configValidation.isValid) {
101
- // issues.push(...configValidation.errors);
102
- // issues.push(...configValidation.warnings.map(w => `Warning: ${w}`));
103
- // }
104
- // } catch (error) {
105
- // issues.push(`Configuration validation failed: ${error.message}`);
106
- // }
107
-
96
+ try {
97
+ // Determine manifest path candidates and select first that exists
98
+ const manifestCandidates = ['clodo-service-manifest.json', 'service-manifest.json', 'manifest.json'];
99
+ let manifestPath = null;
100
+ for (const candidate of manifestCandidates) {
101
+ const candidatePath = path.join(servicePath, candidate);
102
+ try {
103
+ await fs.access(candidatePath);
104
+ manifestPath = candidatePath;
105
+ break;
106
+ } catch {
107
+ // Not found, continue
108
+ }
109
+ }
110
+ const wranglerPath = path.join(servicePath, 'wrangler.toml');
111
+ if (manifestPath) {
112
+ const configValidation = ConfigurationValidator.validateServiceConfig(manifestPath, wranglerPath);
113
+ if (!configValidation.valid) {
114
+ issues.push(...(configValidation.issues || []).map(i => `Configuration mismatch: ${i.message || JSON.stringify(i)}`));
115
+ }
116
+ } else {
117
+ // No manifest found — warn but do not block validation
118
+ issues.push('Warning: No service manifest found (clodo-service-manifest.json) — skipping manifest↔wrangler validation');
119
+ }
120
+ } catch (error) {
121
+ issues.push(`Configuration validation step failed: ${error.message}`);
122
+ }
108
123
  return {
109
124
  valid: issues.length === 0,
110
125
  issues,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamyla/clodo-framework",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Reusable framework for Clodo-style software architecture on Cloudflare Workers + D1",
5
5
  "type": "module",
6
6
  "sideEffects": [