@tamyla/clodo-framework 4.3.2 β 4.3.4
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 +15 -0
- package/README.md +38 -3
- package/dist/api/frameworkCapabilities.js +44 -0
- package/dist/api/index.js +7 -0
- package/dist/api/versionCompatibility.js +78 -0
- package/dist/errors/index.js +5 -0
- package/dist/errors/integrationErrors.js +70 -0
- package/dist/index.js +9 -0
- package/dist/programmatic/deployService.js +5 -0
- package/dist/programmatic/index.js +8 -0
- package/dist/programmatic/validateService.js +5 -0
- package/dist/testing/index.js +6 -0
- package/dist/testing/mockFramework.js +236 -0
- package/dist/validation/index.js +6 -0
- package/dist/validation/payloadValidation.js +49 -8
- package/docs/00_START_HERE.md +524 -0
- package/docs/HOWTO_CONSUME_CLODO_FRAMEWORK.md +400 -0
- package/docs/MIGRATION.md +458 -0
- package/docs/README.md +131 -21
- package/docs/SIMPLE_API_GUIDE.md +230 -0
- package/docs/api/PROGRAMMATIC_API.md +270 -0
- package/docs/api/README.md +526 -0
- package/docs/api/parameter_reference.md +296 -0
- package/docs/errors.md +367 -0
- package/package.json +12 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [4.3.4](https://github.com/tamylaa/clodo-framework/compare/v4.3.3...v4.3.4) (2026-02-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* include middleware migration doc in packaged artifact ([a6e7c9e](https://github.com/tamylaa/clodo-framework/commit/a6e7c9e8d57f0bf3c11516e418ebe71a8b4e3c0e))
|
|
7
|
+
* trigger semantic-release for test fixes ([04f6f90](https://github.com/tamylaa/clodo-framework/commit/04f6f90fede7fab4ca1060fc6f490d1848a2ad55))
|
|
8
|
+
|
|
9
|
+
## [4.3.3](https://github.com/tamylaa/clodo-framework/compare/v4.3.2...v4.3.3) (2026-02-02)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **x:** strip CRLF from POST_MESSAGE lines before comparison and message extraction ([d9db8e0](https://github.com/tamylaa/clodo-framework/commit/d9db8e0eb87081c5e9506191b21a32970a7745f4))
|
|
15
|
+
|
|
1
16
|
## [4.3.2](https://github.com/tamylaa/clodo-framework/compare/v4.3.1...v4.3.2) (2026-02-02)
|
|
2
17
|
|
|
3
18
|
|
package/README.md
CHANGED
|
@@ -11,9 +11,44 @@ A comprehensive framework for building enterprise-grade software architecture on
|
|
|
11
11
|
|
|
12
12
|
> **β
VALIDATED PROMISE**: Through comprehensive testing and validation, the Clodo Framework has been proven to deliver on its core promise of automated Cloudflare service creation. See [Framework Evolution Narrative](docs/FRAMEWORK_EVOLUTION_NARRATIVE.md) for the complete development story.
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
## π Documentation
|
|
15
|
+
|
|
16
|
+
### π **Quick Start** (5 minutes)
|
|
17
|
+
- **[Developer Quick Start](docs/00_START_HERE.md)** - Get running immediately
|
|
18
|
+
- **[Simple API Guide](docs/SIMPLE_API_GUIDE.md)** - Quick examples and usage
|
|
19
|
+
|
|
20
|
+
### π§ **API Reference**
|
|
21
|
+
- **[Programmatic API](docs/api/PROGRAMMATIC_API.md)** - Complete programmatic usage
|
|
22
|
+
- **[Parameter Reference](docs/api/parameter_reference.md)** - All parameters and validation
|
|
23
|
+
- **[Error Reference](docs/errors.md)** - Error codes and troubleshooting
|
|
24
|
+
|
|
25
|
+
### π **Guides & Migration**
|
|
26
|
+
- **[Getting Started](docs/HOWTO_CONSUME_CLODO_FRAMEWORK.md)** - Step-by-step tutorial
|
|
27
|
+
- **[Migration Guide](docs/MIGRATION.md)** - CLI to programmatic APIs
|
|
28
|
+
- **[Framework Overview](docs/overview.md)** - Philosophy and concepts
|
|
29
|
+
|
|
30
|
+
### ποΈ **Architecture & Security**
|
|
31
|
+
- **[Security](docs/SECURITY.md)** - Security considerations
|
|
32
|
+
- **[Framework Evolution](docs/FRAMEWORK_EVOLUTION_NARRATIVE.md)** - Development history
|
|
33
|
+
|
|
34
|
+
### π **Documentation Structure**
|
|
35
|
+
```
|
|
36
|
+
βββ docs/ # π Public documentation (npm package)
|
|
37
|
+
β βββ 00_START_HERE.md # π Quick start guide
|
|
38
|
+
β βββ README.md # π Documentation index
|
|
39
|
+
β βββ overview.md # ποΈ Framework philosophy
|
|
40
|
+
β βββ api/ # π§ API documentation
|
|
41
|
+
β βββ integration/ # π Integration guides
|
|
42
|
+
β βββ architecture/ # ποΈ Technical architecture
|
|
43
|
+
βββ i-docs/ # π Internal documentation (private)
|
|
44
|
+
βββ commercialization/ # πΌ Business strategy
|
|
45
|
+
βββ roadmap/ # πΊοΈ Development planning
|
|
46
|
+
βββ analysis/ # π Technical analysis
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### π·οΈ **Document Types**
|
|
50
|
+
- **π Public** (`docs/`) - Developer usage, API reference, examples
|
|
51
|
+
- **π Internal** (`i-docs/`) - Business strategy, implementation details, planning
|
|
17
52
|
|
|
18
53
|
## π― Key Achievements
|
|
19
54
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Capabilities API
|
|
3
|
+
* Provides programmatic access to framework capabilities and supported features
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { FrameworkInfo } from '../version/FrameworkInfo.js';
|
|
7
|
+
import { getConfig } from '../config/service-schema-config.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Framework Capabilities Interface
|
|
11
|
+
* @typedef {Object} FrameworkCapabilities
|
|
12
|
+
* @property {string} version - Current framework version
|
|
13
|
+
* @property {boolean} supportsProgrammaticCreation - Whether programmatic service creation is supported
|
|
14
|
+
* @property {string[]} supportedServiceTypes - Array of supported service types
|
|
15
|
+
* @property {string[]} supportedFeatures - Array of supported features
|
|
16
|
+
* @property {boolean} hasParameterDiscovery - Whether parameter discovery API is available
|
|
17
|
+
* @property {boolean} hasUnifiedValidation - Whether unified payload validation is available
|
|
18
|
+
* @property {boolean} supportsPassthrough - Whether clodo passthrough data is supported
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get framework capabilities
|
|
23
|
+
* @returns {FrameworkCapabilities} Framework capabilities object
|
|
24
|
+
*/
|
|
25
|
+
export function getFrameworkCapabilities() {
|
|
26
|
+
const config = getConfig();
|
|
27
|
+
return {
|
|
28
|
+
version: FrameworkInfo.getVersion(),
|
|
29
|
+
supportsProgrammaticCreation: true,
|
|
30
|
+
supportedServiceTypes: [...config.serviceTypes],
|
|
31
|
+
supportedFeatures: [...config.features],
|
|
32
|
+
hasParameterDiscovery: true,
|
|
33
|
+
hasUnifiedValidation: true,
|
|
34
|
+
supportsPassthrough: true
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get framework version
|
|
40
|
+
* @returns {string} Framework version string
|
|
41
|
+
*/
|
|
42
|
+
export function getFrameworkVersion() {
|
|
43
|
+
return FrameworkInfo.getVersion();
|
|
44
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clodo Framework - API Module
|
|
3
|
+
* Framework capabilities and introspection APIs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { getFrameworkCapabilities, getFrameworkVersion } from './frameworkCapabilities.js';
|
|
7
|
+
export { checkApplicationCompatibility, getSupportedApplicationVersions } from './versionCompatibility.js';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version Compatibility API
|
|
3
|
+
* Provides version checking and compatibility validation for programmatic integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { FrameworkInfo } from '../version/FrameworkInfo.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Compatibility Result Interface
|
|
10
|
+
* @typedef {Object} CompatibilityResult
|
|
11
|
+
* @property {boolean} compatible - Whether the application version is compatible
|
|
12
|
+
* @property {string} frameworkVersion - Current framework version
|
|
13
|
+
* @property {string} [minimumApplicationVersion] - Minimum required application version
|
|
14
|
+
* @property {string[]} [breakingChanges] - List of breaking changes if incompatible
|
|
15
|
+
* @property {string[]} [recommendations] - Recommended actions or updates
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Check application compatibility with current framework version
|
|
20
|
+
* @param {string} applicationVersion - Version of the consuming application
|
|
21
|
+
* @returns {CompatibilityResult} Compatibility assessment
|
|
22
|
+
*/
|
|
23
|
+
export function checkApplicationCompatibility(applicationVersion) {
|
|
24
|
+
const frameworkVersion = FrameworkInfo.getVersion();
|
|
25
|
+
const result = {
|
|
26
|
+
compatible: true,
|
|
27
|
+
frameworkVersion,
|
|
28
|
+
minimumApplicationVersion: '0.1.0',
|
|
29
|
+
breakingChanges: [],
|
|
30
|
+
recommendations: []
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Parse versions for comparison
|
|
34
|
+
const parseVersion = v => v.split('.').map(n => parseInt(n, 10));
|
|
35
|
+
const [appMajor, appMinor, appPatch] = parseVersion(applicationVersion);
|
|
36
|
+
const [fwMajor, fwMinor, fwPatch] = parseVersion(frameworkVersion);
|
|
37
|
+
|
|
38
|
+
// Version compatibility logic
|
|
39
|
+
if (appMajor < 0 || appMajor === 0 && appMinor < 1) {
|
|
40
|
+
result.compatible = false;
|
|
41
|
+
result.breakingChanges.push('Application version must be 0.1.0 or higher for programmatic API support');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Framework version specific checks
|
|
45
|
+
if (fwMajor >= 5) {
|
|
46
|
+
if (appMajor < 1) {
|
|
47
|
+
result.recommendations.push('Consider upgrading to application version 1.x for full feature support with framework 5.x');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Known compatibility issues
|
|
52
|
+
const knownIncompatibilities = {
|
|
53
|
+
'0.0.1': ['Programmatic API not supported'],
|
|
54
|
+
'0.0.2': ['Limited parameter validation'],
|
|
55
|
+
'0.0.3': ['Missing error handling for passthrough data']
|
|
56
|
+
};
|
|
57
|
+
if (knownIncompatibilities[applicationVersion]) {
|
|
58
|
+
result.compatible = false;
|
|
59
|
+
result.breakingChanges.push(...knownIncompatibilities[applicationVersion]);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get supported application versions
|
|
66
|
+
* @returns {string[]} Array of supported application version strings
|
|
67
|
+
*/
|
|
68
|
+
export function getSupportedApplicationVersions() {
|
|
69
|
+
return ['0.1.0', '0.2.0', '0.3.0', '1.0.0', '1.1.0'];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get framework version (convenience function)
|
|
74
|
+
* @returns {string} Framework version string
|
|
75
|
+
*/
|
|
76
|
+
export function getFrameworkVersion() {
|
|
77
|
+
return FrameworkInfo.getVersion();
|
|
78
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration-specific Error Classes
|
|
3
|
+
* Provides structured error handling for programmatic API integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base class for integration-related errors
|
|
8
|
+
*/
|
|
9
|
+
export class IntegrationError extends Error {
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} message - Error message
|
|
12
|
+
* @param {string} code - Error code for programmatic handling
|
|
13
|
+
* @param {Object} details - Additional error details
|
|
14
|
+
*/
|
|
15
|
+
constructor(message, code, details = {}) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'IntegrationError';
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.details = details;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Error thrown when service payload validation fails
|
|
25
|
+
*/
|
|
26
|
+
export class PayloadValidationError extends IntegrationError {
|
|
27
|
+
/**
|
|
28
|
+
* @param {Object} validationResult - Result from validateServicePayload
|
|
29
|
+
*/
|
|
30
|
+
constructor(validationResult) {
|
|
31
|
+
super(`Service payload validation failed: ${validationResult.errors.length} errors`, 'PAYLOAD_VALIDATION_FAILED', {
|
|
32
|
+
validationResult
|
|
33
|
+
});
|
|
34
|
+
this.name = 'PayloadValidationError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when a parameter is not supported in the current framework version
|
|
40
|
+
*/
|
|
41
|
+
export class ParameterNotSupportedError extends IntegrationError {
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} parameterName - Name of the unsupported parameter
|
|
44
|
+
* @param {string} frameworkVersion - Current framework version
|
|
45
|
+
*/
|
|
46
|
+
constructor(parameterName, frameworkVersion) {
|
|
47
|
+
super(`Parameter '${parameterName}' not supported in framework version ${frameworkVersion}`, 'PARAMETER_NOT_SUPPORTED', {
|
|
48
|
+
parameterName,
|
|
49
|
+
frameworkVersion
|
|
50
|
+
});
|
|
51
|
+
this.name = 'ParameterNotSupportedError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Error thrown when application version is incompatible with framework version
|
|
57
|
+
*/
|
|
58
|
+
export class VersionCompatibilityError extends IntegrationError {
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} applicationVersion - Application version
|
|
61
|
+
* @param {string} frameworkVersion - Framework version
|
|
62
|
+
*/
|
|
63
|
+
constructor(applicationVersion, frameworkVersion) {
|
|
64
|
+
super(`Application version ${applicationVersion} not compatible with framework version ${frameworkVersion}`, 'VERSION_INCOMPATIBILITY', {
|
|
65
|
+
applicationVersion,
|
|
66
|
+
frameworkVersion
|
|
67
|
+
});
|
|
68
|
+
this.name = 'VersionCompatibilityError';
|
|
69
|
+
}
|
|
70
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,15 @@ export { ServiceCreator } from './service-management/ServiceCreator.js';
|
|
|
40
40
|
export { ServiceOrchestrator } from './service-management/ServiceOrchestrator.js';
|
|
41
41
|
export { InputCollector } from './service-management/InputCollector.js';
|
|
42
42
|
|
|
43
|
+
// Programmatic APIs
|
|
44
|
+
export { createServiceProgrammatic } from './programmatic/createService.js';
|
|
45
|
+
export { deployServiceProgrammatic } from './programmatic/deployService.js';
|
|
46
|
+
export { validateServiceProgrammatic } from './programmatic/validateService.js';
|
|
47
|
+
export { getFrameworkCapabilities, getFrameworkVersion } from './api/frameworkCapabilities.js';
|
|
48
|
+
export { getAcceptedParameters, validateServicePayload } from './validation/payloadValidation.js';
|
|
49
|
+
export { IntegrationError, PayloadValidationError, ParameterNotSupportedError, VersionCompatibilityError } from './errors/integrationErrors.js';
|
|
50
|
+
export { MockServiceOrchestrator, createMockFramework } from './testing/mockFramework.js';
|
|
51
|
+
|
|
43
52
|
// CLI utilities (for framework CLI commands)
|
|
44
53
|
export { StandardOptions } from './lib/shared/utils/cli-options.js';
|
|
45
54
|
export { ConfigLoader } from './lib/shared/utils/config-loader.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { MultiDomainOrchestrator } from '../orchestration/multi-domain-orchestrator.js';
|
|
2
|
+
export async function deployServiceProgrammatic(options = {}) {
|
|
3
|
+
return await MultiDomainOrchestrator.deploy(options);
|
|
4
|
+
}
|
|
5
|
+
export const deployService = deployServiceProgrammatic; // Backwards-compatible alias
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clodo Framework - Programmatic APIs
|
|
3
|
+
* Programmatic service creation and management
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { createServiceProgrammatic } from './createService.js';
|
|
7
|
+
export { deployServiceProgrammatic } from './deployService.js';
|
|
8
|
+
export { validateServiceProgrammatic } from './validateService.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ServiceOrchestrator } from '../service-management/ServiceOrchestrator.js';
|
|
2
|
+
export async function validateServiceProgrammatic(servicePath = '.', options = {}) {
|
|
3
|
+
return await ServiceOrchestrator.validate(servicePath, options);
|
|
4
|
+
}
|
|
5
|
+
export const validateService = validateServiceProgrammatic; // Backwards-compatible alias
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Framework for Integration Testing
|
|
3
|
+
* Provides mock implementations for testing programmatic API consumers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getConfig } from '../config/service-schema-config.js';
|
|
7
|
+
import { validateServicePayload } from '../validation/payloadValidation.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Mock Service Orchestrator for testing
|
|
11
|
+
* Provides predictable behavior without file system operations
|
|
12
|
+
*/
|
|
13
|
+
export class MockServiceOrchestrator {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.createdServices = [];
|
|
16
|
+
this.reset();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Mock service creation - validates payload and stores for testing
|
|
21
|
+
* @param {Object} payload - Service payload to create
|
|
22
|
+
* @param {Object} options - Creation options
|
|
23
|
+
* @returns {Promise<Object>} Creation result
|
|
24
|
+
*/
|
|
25
|
+
async createService(payload, options = {}) {
|
|
26
|
+
// Validate payload using real validation logic
|
|
27
|
+
const validation = validateServicePayload(payload);
|
|
28
|
+
if (!validation.valid) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
errors: validation.errors.map(e => e.message),
|
|
32
|
+
warnings: validation.warnings.map(w => w.message)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Store for testing purposes
|
|
37
|
+
const serviceId = `mock-${payload.serviceName}-${Date.now()}`;
|
|
38
|
+
const servicePath = `/mock/path/${payload.serviceName}`;
|
|
39
|
+
const serviceRecord = {
|
|
40
|
+
...payload,
|
|
41
|
+
serviceId,
|
|
42
|
+
servicePath,
|
|
43
|
+
createdAt: new Date().toISOString(),
|
|
44
|
+
options
|
|
45
|
+
};
|
|
46
|
+
this.createdServices.push(serviceRecord);
|
|
47
|
+
return {
|
|
48
|
+
success: true,
|
|
49
|
+
serviceId,
|
|
50
|
+
servicePath,
|
|
51
|
+
warnings: validation.warnings.map(w => w.message)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get all services created during testing
|
|
57
|
+
* @returns {Array} Array of created service records
|
|
58
|
+
*/
|
|
59
|
+
getCreatedServices() {
|
|
60
|
+
return [...this.createdServices];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Find a service by name
|
|
65
|
+
* @param {string} serviceName - Name of the service to find
|
|
66
|
+
* @returns {Object|null} Service record or null if not found
|
|
67
|
+
*/
|
|
68
|
+
findService(serviceName) {
|
|
69
|
+
return this.createdServices.find(s => s.serviceName === serviceName) || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Reset the mock state
|
|
74
|
+
*/
|
|
75
|
+
reset() {
|
|
76
|
+
this.createdServices = [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get creation statistics
|
|
81
|
+
* @returns {Object} Statistics about mock operations
|
|
82
|
+
*/
|
|
83
|
+
getStats() {
|
|
84
|
+
return {
|
|
85
|
+
totalCreated: this.createdServices.length,
|
|
86
|
+
serviceTypes: [...new Set(this.createdServices.map(s => s.serviceType))],
|
|
87
|
+
features: [...new Set(this.createdServices.flatMap(s => s.features || []))]
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a complete mock framework for testing
|
|
94
|
+
* @returns {Object} Mock framework with all necessary APIs
|
|
95
|
+
*/
|
|
96
|
+
export function createMockFramework() {
|
|
97
|
+
const mockOrchestrator = new MockServiceOrchestrator();
|
|
98
|
+
return {
|
|
99
|
+
// Mock ServiceOrchestrator
|
|
100
|
+
ServiceOrchestrator: MockServiceOrchestrator,
|
|
101
|
+
// Mock programmatic creation function
|
|
102
|
+
createService: (payload, options) => mockOrchestrator.createService(payload, options),
|
|
103
|
+
// Mock parameter discovery (returns real parameter definitions)
|
|
104
|
+
getAcceptedParameters: () => {
|
|
105
|
+
const config = getConfig();
|
|
106
|
+
return {
|
|
107
|
+
serviceName: {
|
|
108
|
+
name: 'serviceName',
|
|
109
|
+
type: 'string',
|
|
110
|
+
required: true,
|
|
111
|
+
description: 'Unique identifier for the service',
|
|
112
|
+
validationRules: [{
|
|
113
|
+
rule: 'pattern',
|
|
114
|
+
value: '^[a-z0-9-]+$',
|
|
115
|
+
message: 'Lowercase letters, numbers and hyphens only'
|
|
116
|
+
}, {
|
|
117
|
+
rule: 'minLength',
|
|
118
|
+
value: 3,
|
|
119
|
+
message: 'At least 3 characters'
|
|
120
|
+
}, {
|
|
121
|
+
rule: 'maxLength',
|
|
122
|
+
value: 50,
|
|
123
|
+
message: 'At most 50 characters'
|
|
124
|
+
}]
|
|
125
|
+
},
|
|
126
|
+
serviceType: {
|
|
127
|
+
name: 'serviceType',
|
|
128
|
+
type: 'string',
|
|
129
|
+
required: true,
|
|
130
|
+
description: 'Type of service to create',
|
|
131
|
+
enum: config.serviceTypes
|
|
132
|
+
},
|
|
133
|
+
domain: {
|
|
134
|
+
name: 'domain',
|
|
135
|
+
type: 'string',
|
|
136
|
+
required: true,
|
|
137
|
+
description: 'Domain for the service',
|
|
138
|
+
validationRules: [{
|
|
139
|
+
rule: 'pattern',
|
|
140
|
+
value: '^([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,}$',
|
|
141
|
+
message: 'Must be a valid domain'
|
|
142
|
+
}]
|
|
143
|
+
},
|
|
144
|
+
features: {
|
|
145
|
+
name: 'features',
|
|
146
|
+
type: 'array',
|
|
147
|
+
required: false,
|
|
148
|
+
description: 'Features to enable',
|
|
149
|
+
enum: config.features
|
|
150
|
+
},
|
|
151
|
+
clodo: {
|
|
152
|
+
name: 'clodo',
|
|
153
|
+
type: 'object',
|
|
154
|
+
required: false,
|
|
155
|
+
description: 'Passthrough data for clodo-application specific configuration'
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
// Mock framework capabilities
|
|
160
|
+
getFrameworkCapabilities: () => {
|
|
161
|
+
const config = getConfig();
|
|
162
|
+
return {
|
|
163
|
+
version: '4.3.2-mock',
|
|
164
|
+
supportsProgrammaticCreation: true,
|
|
165
|
+
supportedServiceTypes: [...config.serviceTypes],
|
|
166
|
+
supportedFeatures: [...config.features],
|
|
167
|
+
hasParameterDiscovery: true,
|
|
168
|
+
hasUnifiedValidation: true,
|
|
169
|
+
supportsPassthrough: true
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
// Mock framework version
|
|
173
|
+
getFrameworkVersion: () => '4.3.2-mock',
|
|
174
|
+
// Access to the underlying mock orchestrator for advanced testing
|
|
175
|
+
_mockOrchestrator: mockOrchestrator
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Helper function to create a mock service payload for testing
|
|
181
|
+
* @param {Object} overrides - Properties to override in the default payload
|
|
182
|
+
* @returns {Object} Complete service payload
|
|
183
|
+
*/
|
|
184
|
+
export function createMockServicePayload(overrides = {}) {
|
|
185
|
+
return {
|
|
186
|
+
serviceName: 'test-service',
|
|
187
|
+
serviceType: 'api-service',
|
|
188
|
+
domain: 'test.example.com',
|
|
189
|
+
description: 'Test service description',
|
|
190
|
+
features: ['d1', 'metrics'],
|
|
191
|
+
...overrides
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Helper function to assert service creation results
|
|
197
|
+
* @param {Object} result - Result from createService
|
|
198
|
+
* @param {Object} expected - Expected properties
|
|
199
|
+
*/
|
|
200
|
+
export function assertServiceCreationResult(result, expected = {}) {
|
|
201
|
+
const defaults = {
|
|
202
|
+
success: true,
|
|
203
|
+
hasServiceId: true,
|
|
204
|
+
hasServicePath: true,
|
|
205
|
+
errorCount: 0,
|
|
206
|
+
warningCount: 0
|
|
207
|
+
};
|
|
208
|
+
const checks = {
|
|
209
|
+
...defaults,
|
|
210
|
+
...expected
|
|
211
|
+
};
|
|
212
|
+
if (checks.success) {
|
|
213
|
+
expect(result.success).toBe(true);
|
|
214
|
+
if (checks.hasServiceId) {
|
|
215
|
+
expect(result.serviceId).toBeDefined();
|
|
216
|
+
expect(typeof result.serviceId).toBe('string');
|
|
217
|
+
}
|
|
218
|
+
if (checks.hasServicePath) {
|
|
219
|
+
expect(result.servicePath).toBeDefined();
|
|
220
|
+
expect(typeof result.servicePath).toBe('string');
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
expect(result.success).toBe(false);
|
|
224
|
+
}
|
|
225
|
+
if (checks.errorCount > 0) {
|
|
226
|
+
expect(result.errors).toBeDefined();
|
|
227
|
+
expect(Array.isArray(result.errors)).toBe(true);
|
|
228
|
+
expect(result.errors).toHaveLength(checks.errorCount);
|
|
229
|
+
}
|
|
230
|
+
if (checks.warningCount >= 0) {
|
|
231
|
+
if (result.warnings) {
|
|
232
|
+
expect(Array.isArray(result.warnings)).toBe(true);
|
|
233
|
+
expect(result.warnings).toHaveLength(checks.warningCount);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -20,7 +20,7 @@ export const ServicePayloadSchema = z.object({
|
|
|
20
20
|
bindings: z.array(z.string()).optional(),
|
|
21
21
|
resources: z.record(z.any()).optional(),
|
|
22
22
|
specs: z.record(z.any()).optional(),
|
|
23
|
-
clodo: z.
|
|
23
|
+
clodo: z.any().optional()
|
|
24
24
|
});
|
|
25
25
|
export function validateServicePayload(payload) {
|
|
26
26
|
const result = {
|
|
@@ -59,11 +59,19 @@ export function validateServicePayload(payload) {
|
|
|
59
59
|
// Handle Zod-like errors with an errors array
|
|
60
60
|
if (err && err.errors && Array.isArray(err.errors)) {
|
|
61
61
|
for (const e of err.errors) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
if (e && typeof e === 'object') {
|
|
63
|
+
result.errors.push({
|
|
64
|
+
field: (e.path || []).join('.'),
|
|
65
|
+
code: 'SCHEMA_VALIDATION',
|
|
66
|
+
message: e.message
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
result.errors.push({
|
|
70
|
+
field: 'unknown',
|
|
71
|
+
code: 'SCHEMA_VALIDATION',
|
|
72
|
+
message: `Unknown validation error: ${JSON.stringify(e)}`
|
|
73
|
+
});
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
// Some environments stringify Zod errors into err.message (JSON array) - try to parse
|
|
@@ -142,12 +150,42 @@ export function getParameterDefinitions() {
|
|
|
142
150
|
message: 'Must be a valid domain'
|
|
143
151
|
}]
|
|
144
152
|
},
|
|
153
|
+
description: {
|
|
154
|
+
name: 'description',
|
|
155
|
+
type: 'string',
|
|
156
|
+
required: false,
|
|
157
|
+
description: 'Optional description of the service'
|
|
158
|
+
},
|
|
159
|
+
template: {
|
|
160
|
+
name: 'template',
|
|
161
|
+
type: 'string',
|
|
162
|
+
required: false,
|
|
163
|
+
description: 'Template to use for service creation'
|
|
164
|
+
},
|
|
145
165
|
features: {
|
|
146
166
|
name: 'features',
|
|
147
167
|
type: 'array',
|
|
148
168
|
required: false,
|
|
149
169
|
description: 'Features to enable',
|
|
150
|
-
enum: VALID_FEATURES
|
|
170
|
+
enum: VALID_FEATURES()
|
|
171
|
+
},
|
|
172
|
+
bindings: {
|
|
173
|
+
name: 'bindings',
|
|
174
|
+
type: 'array',
|
|
175
|
+
required: false,
|
|
176
|
+
description: 'Service bindings configuration'
|
|
177
|
+
},
|
|
178
|
+
resources: {
|
|
179
|
+
name: 'resources',
|
|
180
|
+
type: 'object',
|
|
181
|
+
required: false,
|
|
182
|
+
description: 'Resource specifications'
|
|
183
|
+
},
|
|
184
|
+
specs: {
|
|
185
|
+
name: 'specs',
|
|
186
|
+
type: 'object',
|
|
187
|
+
required: false,
|
|
188
|
+
description: 'Additional specifications'
|
|
151
189
|
},
|
|
152
190
|
clodo: {
|
|
153
191
|
name: 'clodo',
|
|
@@ -156,4 +194,7 @@ export function getParameterDefinitions() {
|
|
|
156
194
|
description: 'Passthrough data for clodo-application specific configuration'
|
|
157
195
|
}
|
|
158
196
|
};
|
|
159
|
-
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Alias for backward compatibility and API consistency
|
|
200
|
+
export const getAcceptedParameters = getParameterDefinitions;
|