@tamyla/clodo-framework 4.3.3 β 4.3.5
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 +69 -10
- 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 +19 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [4.3.5](https://github.com/tamylaa/clodo-framework/compare/v4.3.4...v4.3.5) (2026-02-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **funding:** use string value for open_collective in FUNDING.yml ([680cb5f](https://github.com/tamylaa/clodo-framework/commit/680cb5fa28499f2297b39a556ee2c60c0573ab4a))
|
|
7
|
+
|
|
8
|
+
## [4.3.4](https://github.com/tamylaa/clodo-framework/compare/v4.3.3...v4.3.4) (2026-02-04)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* include middleware migration doc in packaged artifact ([a6e7c9e](https://github.com/tamylaa/clodo-framework/commit/a6e7c9e8d57f0bf3c11516e418ebe71a8b4e3c0e))
|
|
14
|
+
* trigger semantic-release for test fixes ([04f6f90](https://github.com/tamylaa/clodo-framework/commit/04f6f90fede7fab4ca1060fc6f490d1848a2ad55))
|
|
15
|
+
|
|
1
16
|
## [4.3.3](https://github.com/tamylaa/clodo-framework/compare/v4.3.2...v4.3.3) (2026-02-02)
|
|
2
17
|
|
|
3
18
|
|
package/README.md
CHANGED
|
@@ -1,19 +1,69 @@
|
|
|
1
1
|
# Clodo Framework
|
|
2
2
|
|
|
3
|
+
[](https://github.com/tamylaa/clodo-framework/actions/workflows/validate-on-pr.yml) [](https://github.com/tamylaa/clodo-framework/actions/workflows/full-tests-nightly.yml) [](https://www.npmjs.com/package/@tamyla/clodo-framework) [](https://www.npmjs.com/package/@tamyla/clodo-framework) [](https://github.com/tamylaa/clodo-framework/blob/main/LICENSE) [](https://github.com/sponsors/tamylaa) [](SUPPORT.md)
|
|
4
|
+
|
|
3
5
|
## π Production-Ready: Promise Delivered
|
|
4
6
|
|
|
5
7
|
**Framework Status: β
VALIDATED & PRODUCTION-READY**
|
|
6
8
|
**Validation: 10/10 Phases Passed**
|
|
7
9
|
**Service Generation: 28+ Files Per Service**
|
|
8
|
-
**Test Coverage
|
|
10
|
+
**Test Coverage:** (Latest CI run 2026-02-04) β **115 test suites passed; 4 tests skipped; 2113 passed, 2117 total**
|
|
9
11
|
|
|
10
12
|
A comprehensive framework for building enterprise-grade software architecture on Cloudflare Workers + D1. This framework enables rapid development of autonomous, domain-specific services while maintaining consistency and reusability across your entire ecosystem.
|
|
11
13
|
|
|
12
14
|
> **β
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
15
|
|
|
14
|
-
##
|
|
16
|
+
## π Documentation
|
|
17
|
+
|
|
18
|
+
### π **Quick Start** (5 minutes)
|
|
19
|
+
- **[Developer Quick Start](docs/00_START_HERE.md)** - Get running immediately
|
|
20
|
+
- **[Simple API Guide](docs/SIMPLE_API_GUIDE.md)** - Quick examples and usage
|
|
21
|
+
|
|
22
|
+
### π§ **API Reference**
|
|
23
|
+
- **[Programmatic API](docs/api/PROGRAMMATIC_API.md)** - Complete programmatic usage
|
|
24
|
+
- **[Parameter Reference](docs/api/parameter_reference.md)** - All parameters and validation
|
|
25
|
+
- **[Error Reference](docs/errors.md)** - Error codes and troubleshooting
|
|
26
|
+
|
|
27
|
+
### π **Guides & Migration**
|
|
28
|
+
- **[Getting Started](docs/HOWTO_CONSUME_CLODO_FRAMEWORK.md)** - Step-by-step tutorial
|
|
29
|
+
- **[Migration Guide](docs/MIGRATION.md)** - CLI to programmatic APIs
|
|
30
|
+
- **[Framework Overview](docs/overview.md)** - Philosophy and concepts
|
|
31
|
+
|
|
32
|
+
### ποΈ **Architecture & Security**
|
|
33
|
+
- **[Security](docs/SECURITY.md)** - Security considerations
|
|
34
|
+
- **[Framework Evolution](docs/FRAMEWORK_EVOLUTION_NARRATIVE.md)** - Development history
|
|
15
35
|
|
|
16
|
-
|
|
36
|
+
## π§βπ€βπ§ Community & Support
|
|
37
|
+
- **Email:** `product@clodo.dev` β product support, feedback, and security reports
|
|
38
|
+
- **Twitter:** [@clodoframework](https://twitter.com/clodoframework) β follow for updates and announcements
|
|
39
|
+
- **Quick ways to help:**
|
|
40
|
+
- β Star the repository on GitHub
|
|
41
|
+
- π Open issues for bugs or feature ideas
|
|
42
|
+
- π Submit PRs or reviews (even small documentation fixes are welcome)
|
|
43
|
+
- π£οΈ Share your experience on Twitter and tag **@clodoframework**
|
|
44
|
+
|
|
45
|
+
Your feedback helps prioritize improvements and signals others that this project is useful.
|
|
46
|
+
|
|
47
|
+
- **Support & SLAs:** See [SUPPORT.md](SUPPORT.md) for response times and escalation procedures.
|
|
48
|
+
|
|
49
|
+
### π **Documentation Structure**
|
|
50
|
+
```
|
|
51
|
+
βββ docs/ # π Public documentation (npm package)
|
|
52
|
+
β βββ 00_START_HERE.md # π Quick start guide
|
|
53
|
+
β βββ README.md # π Documentation index
|
|
54
|
+
β βββ overview.md # ποΈ Framework philosophy
|
|
55
|
+
β βββ api/ # π§ API documentation
|
|
56
|
+
β βββ integration/ # π Integration guides
|
|
57
|
+
β βββ architecture/ # ποΈ Technical architecture
|
|
58
|
+
βββ i-docs/ # π Internal documentation (private)
|
|
59
|
+
βββ commercialization/ # πΌ Business strategy
|
|
60
|
+
βββ roadmap/ # πΊοΈ Development planning
|
|
61
|
+
βββ analysis/ # π Technical analysis
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### π·οΈ **Document Types**
|
|
65
|
+
- **π Public** (`docs/`) - Developer usage, API reference, examples
|
|
66
|
+
- **π Internal** (`i-docs/`) - Business strategy, implementation details, planning
|
|
17
67
|
|
|
18
68
|
## π― Key Achievements
|
|
19
69
|
|
|
@@ -225,7 +275,7 @@ clodo-framework/
|
|
|
225
275
|
β βββ analysis/ # Technical analysis
|
|
226
276
|
β βββ licensing/ # License information
|
|
227
277
|
βββ src/ # π» Source code
|
|
228
|
-
βββ test/ # β
Test suites (
|
|
278
|
+
βββ test/ # β
Test suites (Latest CI: 115 suites; 2113 tests passed, 4 skipped)
|
|
229
279
|
βββ bin/ # π§ CLI executables
|
|
230
280
|
βββ dist/ # π¦ Built distribution
|
|
231
281
|
βββ templates/ # π Service templates
|
|
@@ -233,8 +283,8 @@ clodo-framework/
|
|
|
233
283
|
```
|
|
234
284
|
|
|
235
285
|
**Quality Metrics:**
|
|
236
|
-
- β
**
|
|
237
|
-
- β
**
|
|
286
|
+
- β
**Latest CI (2026-02-04): 115 test suites passed; 4 tests skipped; 2113/2117 tests passed**
|
|
287
|
+
- β
**CLI tests:** passing (all CLI-specific tests passed in the latest run)
|
|
238
288
|
- β
**Clean architecture** (no temporary or duplicate files)
|
|
239
289
|
- β
**Configuration-based** (no hard-coded values in source)
|
|
240
290
|
|
|
@@ -1336,13 +1386,22 @@ npx wrangler login
|
|
|
1336
1386
|
# - Cloudflare D1:Edit permissions
|
|
1337
1387
|
```
|
|
1338
1388
|
|
|
1339
|
-
#### **
|
|
1389
|
+
#### **Integration tests & DNS: how CI avoids ENOTFOUND**
|
|
1390
|
+
- Integration tests mock network calls when `TEST_URL` is not provided to avoid DNS resolution failures (ENOTFOUND) in CI and developer environments.
|
|
1391
|
+
- To run integration tests against an actual deployment set `TEST_URL` to your deployment URL, for example:
|
|
1392
|
+
|
|
1393
|
+
```bash
|
|
1394
|
+
TEST_URL='https://your-service.workers.dev' npm run test:integration
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
- Database integration tests are disabled by default for CI. Enable them by setting `RUN_DB_TESTS=true` (or `RUN_DB_TESTS=1`) when you have a configured database and credentials available:
|
|
1398
|
+
|
|
1340
1399
|
```bash
|
|
1341
|
-
|
|
1342
|
-
# The system waits 10 seconds but some domains may need longer
|
|
1343
|
-
# Tests failures don't prevent deployment success
|
|
1400
|
+
TEST_URL='https://your-service.workers.dev' RUN_DB_TESTS=true npm run test:integration
|
|
1344
1401
|
```
|
|
1345
1402
|
|
|
1403
|
+
This prevents flaky CI failures while still allowing full end-to-end verification when desired.
|
|
1404
|
+
|
|
1346
1405
|
#### **"npx command not found" on Windows**
|
|
1347
1406
|
```bash
|
|
1348
1407
|
# Problem: Command configuration for cross-platform compatibility
|
|
@@ -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
|
+
}
|