@tamyla/clodo-framework 4.5.1 → 4.6.1
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 +28 -0
- package/README.md +157 -13
- package/dist/cli/clodo-service.js +13 -0
- package/dist/cli/commands/config-schema.js +144 -0
- package/dist/cli/commands/create.js +18 -1
- package/dist/cli/commands/deploy.js +61 -2
- package/dist/cli/commands/doctor.js +124 -0
- package/dist/cli/commands/secrets.js +258 -0
- package/dist/cli/security-cli.js +1 -1
- package/dist/index.js +4 -1
- package/dist/security/SecretsManager.js +398 -0
- package/dist/security/index.js +2 -0
- package/dist/service-management/handlers/ValidationHandler.js +696 -0
- package/dist/validation/ConfigSchemaValidator.js +503 -0
- package/dist/validation/configSchemas.js +236 -0
- package/dist/validation/index.js +6 -2
- package/docs/00_START_HERE.md +26 -338
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [4.6.1](https://github.com/tamylaa/clodo-framework/compare/v4.6.0...v4.6.1) (2026-02-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **security:** export SecretsManager from main index ([2884b9d](https://github.com/tamylaa/clodo-framework/commit/2884b9d880f75cc924803d6070e3603bf46929d9))
|
|
7
|
+
|
|
8
|
+
# [4.6.0](https://github.com/tamylaa/clodo-framework/compare/v4.5.1...v4.6.0) (2026-02-18)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **config:** add Zod schema validation for CLI config files ([3c25c88](https://github.com/tamylaa/clodo-framework/commit/3c25c88626fa5e4bc48c874a25ff89b8f75fb236))
|
|
14
|
+
* **secrets:** integrate secret scanning CLI with existing SecretGenerator infrastructure ([f72f70f](https://github.com/tamylaa/clodo-framework/commit/f72f70f8fd3a0dd8da552c15e8b34bc459584870))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **doctor:** implement clodo doctor command with token scope validation, secrets baseline scanning, and comprehensive test stabilization ([9b1fe00](https://github.com/tamylaa/clodo-framework/commit/9b1fe00f77bd7167cb8c836637caae68b9e8cd1c))
|
|
20
|
+
|
|
1
21
|
## [4.5.1](https://github.com/tamylaa/clodo-framework/compare/v4.5.0...v4.5.1) (2026-02-11)
|
|
2
22
|
|
|
3
23
|
|
|
@@ -5,6 +25,14 @@
|
|
|
5
25
|
|
|
6
26
|
* resolve e2e test failures for validate and deploy commands ([97fd564](https://github.com/tamylaa/clodo-framework/commit/97fd5648211d13f46004b9e69c9b6face546d86d))
|
|
7
27
|
|
|
28
|
+
### Features (post-4.5.1)
|
|
29
|
+
|
|
30
|
+
* **doctor**: add `clodo-service doctor` preflight command — automated environment, dependency, and connectivity checks before deployment. Integrates with deploy via `--skip-doctor` / `--doctor-strict` flags. ([f72f70f](https://github.com/tamylaa/clodo-framework/commit/f72f70f))
|
|
31
|
+
|
|
32
|
+
* **secrets**: add `clodo-service secrets` command — source code secret scanning with 15+ built-in patterns (AWS, Stripe, GitHub, JWT, etc.), baseline management (`baseline show`/`baseline update`), and `SecretsManager` programmatic API. 42 unit + 19 E2E tests. ([f72f70f](https://github.com/tamylaa/clodo-framework/commit/f72f70f))
|
|
33
|
+
|
|
34
|
+
* **config**: add `clodo-service config-schema` command — Zod-powered schema validation for all CLI config files (create, deploy, validate, update). Includes `show`, `validate`, `types` subcommands, semantic warnings (env var placeholders, duplicate features, production without security). `ConfigSchemaValidator` programmatic API. 77 unit + 21 E2E tests. ([3c25c88](https://github.com/tamylaa/clodo-framework/commit/3c25c88))
|
|
35
|
+
|
|
8
36
|
# [4.5.0](https://github.com/tamylaa/clodo-framework/compare/v4.4.1...v4.5.0) (2026-02-11)
|
|
9
37
|
|
|
10
38
|
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
**Framework Status: ✅ VALIDATED & PRODUCTION-READY**
|
|
8
8
|
**Validation: 10/10 Phases Passed**
|
|
9
9
|
**Service Generation: 28+ Files Per Service**
|
|
10
|
-
**Test Coverage:** (Latest CI run 2026-02-
|
|
10
|
+
**Test Coverage:** (Latest CI run 2026-02-18) — **124 test suites passed; 1 skipped; 2328 passed, 2352 total**
|
|
11
11
|
|
|
12
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.
|
|
13
13
|
|
|
@@ -234,11 +234,23 @@ const zones = await api.listZones();
|
|
|
234
234
|
Run framework commands in your terminal:
|
|
235
235
|
|
|
236
236
|
```bash
|
|
237
|
+
# Create a new service
|
|
238
|
+
clodo-service create
|
|
239
|
+
|
|
237
240
|
# Deploy your service
|
|
238
241
|
clodo-service deploy
|
|
239
242
|
|
|
240
|
-
#
|
|
241
|
-
clodo-
|
|
243
|
+
# Validate service configuration
|
|
244
|
+
clodo-service validate
|
|
245
|
+
|
|
246
|
+
# Preflight health checks before deployment
|
|
247
|
+
clodo-service doctor
|
|
248
|
+
|
|
249
|
+
# Scan for leaked secrets
|
|
250
|
+
clodo-service secrets scan
|
|
251
|
+
|
|
252
|
+
# Validate config files against schemas
|
|
253
|
+
clodo-service config-schema validate clodo-deploy.json
|
|
242
254
|
|
|
243
255
|
# Security auditing
|
|
244
256
|
clodo-security audit
|
|
@@ -293,7 +305,7 @@ clodo-framework/
|
|
|
293
305
|
│ ├── analysis/ # Technical analysis
|
|
294
306
|
│ └── licensing/ # License information
|
|
295
307
|
├── src/ # 💻 Source code
|
|
296
|
-
├── test/ # ✅ Test suites (Latest CI:
|
|
308
|
+
├── test/ # ✅ Test suites (Latest CI: 124 suites; 2328 tests passed, 24 skipped)
|
|
297
309
|
├── cli/ # 🔧 CLI tools & commands
|
|
298
310
|
├── examples/ # 📚 Usage examples & demos
|
|
299
311
|
├── config/ # ⚙️ Configuration files & examples
|
|
@@ -311,7 +323,7 @@ clodo-framework/
|
|
|
311
323
|
```
|
|
312
324
|
|
|
313
325
|
**Quality Metrics:**
|
|
314
|
-
- ✅ **Latest CI (2026-02-
|
|
326
|
+
- ✅ **Latest CI (2026-02-18): 124 test suites passed; 1 skipped; 2328/2352 tests passed**
|
|
315
327
|
- ✅ **CLI tests:** passing (all CLI-specific tests passed in the latest run)
|
|
316
328
|
- ✅ **Clean architecture** (organized file structure, no clutter in root)
|
|
317
329
|
- ✅ **Configuration-based** (no hard-coded values in source)
|
|
@@ -369,6 +381,15 @@ npx @tamyla/clodo-framework security generate-key api content-skimmer
|
|
|
369
381
|
# Validate configuration security
|
|
370
382
|
npx @tamyla/clodo-framework security validate customer production
|
|
371
383
|
|
|
384
|
+
# Scan source code for leaked secrets
|
|
385
|
+
clodo-service secrets scan
|
|
386
|
+
|
|
387
|
+
# Validate secrets against baseline
|
|
388
|
+
clodo-service secrets validate
|
|
389
|
+
|
|
390
|
+
# Run preflight security checks
|
|
391
|
+
clodo-service doctor
|
|
392
|
+
|
|
372
393
|
# Deploy with automatic security validation
|
|
373
394
|
npx @tamyla/clodo-framework security deploy customer production
|
|
374
395
|
```
|
|
@@ -388,6 +409,9 @@ npx @tamyla/clodo-framework security deploy customer production
|
|
|
388
409
|
- ✅ **🔒 Security Validation Framework**: Automated security validation and deployment blocking
|
|
389
410
|
- ✅ **🛡️ Cryptographic Key Generation**: Secure API key and JWT secret generation
|
|
390
411
|
- ✅ **🚫 Deployment Security**: Pre-deployment validation that blocks insecure configurations
|
|
412
|
+
- ✅ **🩺 Doctor / Preflight Checks**: Automated environment, dependency, and connectivity validation before deploy
|
|
413
|
+
- ✅ **🔍 Secret Scanning & Baseline**: Detect leaked secrets in source code with baseline management
|
|
414
|
+
- ✅ **📋 Config Schema Validation**: Zod-powered schema validation for all CLI config files (create, deploy, validate, update)
|
|
391
415
|
- ✅ **👥 Customer Configuration Management**: Multi-environment, multi-customer configuration system
|
|
392
416
|
- ✅ **🏗️ Template-Based Customer Onboarding**: Automated customer setup from reusable templates
|
|
393
417
|
- ✅ **🔗 Framework Integration**: Customer configs integrate with domain and feature flag systems
|
|
@@ -404,6 +428,9 @@ npx @tamyla/clodo-framework security deploy customer production
|
|
|
404
428
|
- **🔒 Security-by-Default**: Automatic detection and prevention of insecure configurations
|
|
405
429
|
- **🛡️ Production Security**: Environment-specific security requirements and validation
|
|
406
430
|
- **🔐 Cryptographic Utilities**: Secure key generation and secret management
|
|
431
|
+
- **🩺 Doctor / Preflight**: Automated pre-deployment environment checks with `--skip-doctor` / `--doctor-strict` flags
|
|
432
|
+
- **🔍 Secret Scanning**: Source code secret detection, pattern matching, and baseline management
|
|
433
|
+
- **📋 Config Schema Validation**: Zod schemas for all config file types with semantic warnings
|
|
407
434
|
- **Production Testing**: Health checks, authentication flows, performance monitoring
|
|
408
435
|
- **Audit & Compliance**: Detailed deployment logging and reporting
|
|
409
436
|
- **👥 Customer Configuration Management**: Multi-environment customer isolation and management
|
|
@@ -413,10 +440,84 @@ npx @tamyla/clodo-framework security deploy customer production
|
|
|
413
440
|
- **⚡ Performance Optimized**: Intelligent caching system for schemas, SQL queries, and validation results
|
|
414
441
|
- **🔄 Advanced Data Operations**: Enhanced CRUD with relationships, advanced pagination, and query optimization
|
|
415
442
|
|
|
416
|
-
## 🎉 What's New in
|
|
443
|
+
## 🎉 What's New in v4.5.x
|
|
444
|
+
|
|
445
|
+
### 🩺 Doctor / Preflight Command (v4.5.x)
|
|
446
|
+
Run comprehensive pre-deployment health checks to catch issues before they reach production:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
# Run all preflight checks
|
|
450
|
+
clodo-service doctor
|
|
451
|
+
|
|
452
|
+
# Skip doctor during deploy
|
|
453
|
+
clodo-service deploy --skip-doctor
|
|
454
|
+
|
|
455
|
+
# Fail deploy on doctor warnings
|
|
456
|
+
clodo-service deploy --doctor-strict
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Checks performed:**
|
|
460
|
+
- ✅ Node.js version compatibility
|
|
461
|
+
- ✅ Required dependencies installed (wrangler, etc.)
|
|
462
|
+
- ✅ Environment variables set
|
|
463
|
+
- ✅ Cloudflare API connectivity
|
|
464
|
+
- ✅ Config file schema validation
|
|
465
|
+
- ✅ Secret baseline compliance
|
|
466
|
+
|
|
467
|
+
### 🔍 Secret Scanning & Baseline Management (v4.5.x)
|
|
468
|
+
Detect leaked secrets in your codebase before they reach version control:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# Scan for secrets in source code
|
|
472
|
+
clodo-service secrets scan [directory]
|
|
473
|
+
|
|
474
|
+
# Validate against a known baseline
|
|
475
|
+
clodo-service secrets validate
|
|
476
|
+
|
|
477
|
+
# Show current baseline
|
|
478
|
+
clodo-service secrets baseline show
|
|
479
|
+
|
|
480
|
+
# Update baseline after review
|
|
481
|
+
clodo-service secrets baseline update
|
|
482
|
+
|
|
483
|
+
# List known secret patterns
|
|
484
|
+
clodo-service secrets patterns
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**Features:**
|
|
488
|
+
- 15+ built-in secret patterns (AWS, Stripe, GitHub, JWT, etc.)
|
|
489
|
+
- Baseline management for known/accepted findings
|
|
490
|
+
- Integration with doctor preflight checks
|
|
491
|
+
- Programmatic API via `SecretsManager`
|
|
492
|
+
|
|
493
|
+
### 📋 Config Schema Validation (v4.5.x)
|
|
494
|
+
Validate your CLI config files against Zod schemas with semantic warnings:
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
# Validate a config file
|
|
498
|
+
clodo-service config-schema validate clodo-deploy.json
|
|
499
|
+
|
|
500
|
+
# Strict mode (exit code 1 on any error)
|
|
501
|
+
clodo-service config-schema validate clodo-create.json --strict
|
|
502
|
+
|
|
503
|
+
# Show schema for a config type
|
|
504
|
+
clodo-service config-schema show deploy
|
|
505
|
+
|
|
506
|
+
# List all supported config types
|
|
507
|
+
clodo-service config-schema types
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Supported config types:** `create`, `deploy`, `validate`, `update`
|
|
511
|
+
|
|
512
|
+
**Semantic warnings detect:**
|
|
513
|
+
- Environment variable placeholders left in values
|
|
514
|
+
- Duplicate features
|
|
515
|
+
- Production configs without security features
|
|
516
|
+
- Missing backup strategy with migrations enabled
|
|
517
|
+
- Name mismatches between config fields
|
|
417
518
|
|
|
418
519
|
### 🔧 Enhanced Customer Configuration System
|
|
419
|
-
The customer configuration CLI
|
|
520
|
+
The customer configuration CLI **reads directly from your wrangler.toml** file, providing a single source of truth for deployment configuration:
|
|
420
521
|
|
|
421
522
|
```bash
|
|
422
523
|
# List all customers with complete deployment metadata
|
|
@@ -1200,15 +1301,58 @@ npx clodo-db sync --portfolio
|
|
|
1200
1301
|
npx clodo-db backup my-domain
|
|
1201
1302
|
```
|
|
1202
1303
|
|
|
1203
|
-
#### `clodo-secrets` - Secret
|
|
1204
|
-
|
|
1304
|
+
#### `clodo-secrets` - Secret Scanning & Baseline Management
|
|
1305
|
+
Detect leaked secrets in source code and manage baselines for known findings.
|
|
1205
1306
|
|
|
1206
1307
|
```bash
|
|
1207
|
-
#
|
|
1208
|
-
|
|
1308
|
+
# Scan current directory for secrets
|
|
1309
|
+
clodo-service secrets scan
|
|
1310
|
+
|
|
1311
|
+
# Scan a specific directory
|
|
1312
|
+
clodo-service secrets scan ./src
|
|
1313
|
+
|
|
1314
|
+
# Validate against baseline
|
|
1315
|
+
clodo-service secrets validate
|
|
1316
|
+
|
|
1317
|
+
# Show current baseline
|
|
1318
|
+
clodo-service secrets baseline show
|
|
1319
|
+
|
|
1320
|
+
# Update baseline after review
|
|
1321
|
+
clodo-service secrets baseline update
|
|
1322
|
+
|
|
1323
|
+
# List known secret patterns
|
|
1324
|
+
clodo-service secrets patterns
|
|
1325
|
+
```
|
|
1326
|
+
|
|
1327
|
+
#### `clodo doctor` - Preflight Health Checks
|
|
1328
|
+
Run comprehensive environment and configuration checks before deployment.
|
|
1329
|
+
|
|
1330
|
+
```bash
|
|
1331
|
+
# Run all checks
|
|
1332
|
+
clodo-service doctor
|
|
1333
|
+
|
|
1334
|
+
# Skip during deploy
|
|
1335
|
+
clodo-service deploy --skip-doctor
|
|
1336
|
+
|
|
1337
|
+
# Strict mode (fail on warnings)
|
|
1338
|
+
clodo-service deploy --doctor-strict
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
#### `clodo config-schema` - Config File Validation
|
|
1342
|
+
Validate CLI config files against Zod schemas with semantic analysis.
|
|
1343
|
+
|
|
1344
|
+
```bash
|
|
1345
|
+
# Validate a config file
|
|
1346
|
+
clodo-service config-schema validate clodo-deploy.json
|
|
1347
|
+
|
|
1348
|
+
# Show schema for a config type
|
|
1349
|
+
clodo-service config-schema show create
|
|
1350
|
+
|
|
1351
|
+
# List all supported config types
|
|
1352
|
+
clodo-service config-schema types
|
|
1209
1353
|
|
|
1210
|
-
#
|
|
1211
|
-
|
|
1354
|
+
# Strict mode
|
|
1355
|
+
clodo-service config-schema validate config.json --strict
|
|
1212
1356
|
```
|
|
1213
1357
|
|
|
1214
1358
|
## Quick Start
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - diagnose Diagnose and report issues with an existing service
|
|
15
15
|
* - assess Run intelligent capability assessment
|
|
16
16
|
* - list-types List available service types and their features
|
|
17
|
+
* - secrets Secret scanning and baseline management for leak prevention
|
|
17
18
|
*/
|
|
18
19
|
import { Command } from 'commander';
|
|
19
20
|
import { join, dirname } from 'path';
|
|
@@ -51,6 +52,10 @@ async function registerAvailableCommands() {
|
|
|
51
52
|
name: 'diagnose',
|
|
52
53
|
path: pathToFileURL(join(commandsDir, 'diagnose.js')).href,
|
|
53
54
|
register: 'registerDiagnoseCommand'
|
|
55
|
+
}, {
|
|
56
|
+
name: 'doctor',
|
|
57
|
+
path: pathToFileURL(join(commandsDir, 'doctor.js')).href,
|
|
58
|
+
register: 'registerDoctorCommand'
|
|
54
59
|
}, {
|
|
55
60
|
name: 'assess',
|
|
56
61
|
path: pathToFileURL(join(commandsDir, 'assess.js')).href,
|
|
@@ -59,6 +64,14 @@ async function registerAvailableCommands() {
|
|
|
59
64
|
name: 'init-config',
|
|
60
65
|
path: pathToFileURL(join(commandsDir, 'init-config.js')).href,
|
|
61
66
|
register: 'registerInitConfigCommand'
|
|
67
|
+
}, {
|
|
68
|
+
name: 'secrets',
|
|
69
|
+
path: pathToFileURL(join(commandsDir, 'secrets.js')).href,
|
|
70
|
+
register: 'registerSecretsCommand'
|
|
71
|
+
}, {
|
|
72
|
+
name: 'config-schema',
|
|
73
|
+
path: pathToFileURL(join(commandsDir, 'config-schema.js')).href,
|
|
74
|
+
register: 'registerConfigSchemaCommand'
|
|
62
75
|
}];
|
|
63
76
|
for (const cmd of commands) {
|
|
64
77
|
try {
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Schema CLI Command
|
|
3
|
+
* Provides schema inspection, validation, and documentation for config files
|
|
4
|
+
*
|
|
5
|
+
* Subcommands:
|
|
6
|
+
* clodo config-schema show <type> - Show schema for a command type
|
|
7
|
+
* clodo config-schema validate <file> - Validate a config file
|
|
8
|
+
* clodo config-schema types - List all config types
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
import { ConfigSchemaValidator } from '../../src/validation/ConfigSchemaValidator.js';
|
|
14
|
+
export function registerConfigSchemaCommand(program) {
|
|
15
|
+
const cmd = program.command('config-schema').description('Inspect and validate configuration file schemas');
|
|
16
|
+
|
|
17
|
+
// ─── show ──────────────────────────────────────────────────────────────
|
|
18
|
+
cmd.command('show <type>').description('Show the schema definition for a config type (create, deploy, validate, update)').option('--json', 'Output as JSON').action((type, options) => {
|
|
19
|
+
const validator = new ConfigSchemaValidator();
|
|
20
|
+
const definition = validator.getSchemaDefinition(type);
|
|
21
|
+
if (!definition) {
|
|
22
|
+
console.error(chalk.red(`Unknown config type: '${type}'`));
|
|
23
|
+
console.log(`Valid types: ${validator.getRegisteredTypes().join(', ')}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
if (options.json) {
|
|
27
|
+
console.log(JSON.stringify(definition, null, 2));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(chalk.cyan(`\n📋 Config Schema: ${type}`));
|
|
31
|
+
console.log(chalk.gray('═'.repeat(60)));
|
|
32
|
+
console.log(chalk.white(definition.description));
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(chalk.bold('Fields:'));
|
|
35
|
+
for (const [name, field] of Object.entries(definition.fields)) {
|
|
36
|
+
const required = field.required ? chalk.red('*') : ' ';
|
|
37
|
+
const type = chalk.gray(`(${field.type})`);
|
|
38
|
+
console.log(` ${required} ${chalk.white(name)} ${type}`);
|
|
39
|
+
if (field.description) {
|
|
40
|
+
console.log(` ${chalk.gray(field.description)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log(chalk.bold('Valid Service Types:'));
|
|
45
|
+
console.log(` ${definition.validServiceTypes.join(', ')}`);
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log(chalk.bold('Valid Features:'));
|
|
48
|
+
console.log(` ${definition.validFeatures.join(', ')}`);
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(chalk.gray(`Total fields: ${definition.fieldCount}`));
|
|
51
|
+
console.log(chalk.gray(`Usage: npx clodo-service ${type} --config-file your-config.json`));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ─── validate ──────────────────────────────────────────────────────────
|
|
55
|
+
cmd.command('validate <file>').description('Validate a config file against its schema').option('--type <type>', 'Config type (auto-detected if not specified)').option('--strict', 'Exit with error code on validation failures').option('--json', 'Output as JSON').action((file, options) => {
|
|
56
|
+
const validator = new ConfigSchemaValidator();
|
|
57
|
+
|
|
58
|
+
// Determine command type
|
|
59
|
+
let commandType = options.type;
|
|
60
|
+
if (!commandType) {
|
|
61
|
+
// Try to auto-detect from filename or content
|
|
62
|
+
const filenameLower = file.toLowerCase();
|
|
63
|
+
if (filenameLower.includes('create')) commandType = 'create';else if (filenameLower.includes('deploy')) commandType = 'deploy';else if (filenameLower.includes('validate')) commandType = 'validate';else if (filenameLower.includes('update')) commandType = 'update';else {
|
|
64
|
+
// Try content-based detection
|
|
65
|
+
try {
|
|
66
|
+
const content = JSON.parse(readFileSync(file, 'utf8'));
|
|
67
|
+
const detection = validator.detectConfigType(content);
|
|
68
|
+
if (detection.detected) {
|
|
69
|
+
commandType = detection.commandType;
|
|
70
|
+
if (!options.json) {
|
|
71
|
+
console.log(chalk.gray(`Auto-detected config type: ${commandType} (confidence: ${Math.round(detection.confidence * 100)}%)`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
// Fall through
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!commandType) {
|
|
79
|
+
console.error(chalk.red('Could not detect config type. Use --type to specify.'));
|
|
80
|
+
console.log(`Valid types: ${validator.getRegisteredTypes().join(', ')}`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const result = validator.validateConfigFile(file, commandType);
|
|
85
|
+
if (options.json) {
|
|
86
|
+
console.log(JSON.stringify(result, null, 2));
|
|
87
|
+
} else {
|
|
88
|
+
console.log(chalk.cyan(`\n🔍 Config Validation: ${file}`));
|
|
89
|
+
console.log(chalk.gray(`Type: ${commandType}`));
|
|
90
|
+
console.log(chalk.gray('═'.repeat(60)));
|
|
91
|
+
if (result.valid) {
|
|
92
|
+
console.log(chalk.green(`✅ Valid configuration (${result.fieldCount} fields)`));
|
|
93
|
+
} else {
|
|
94
|
+
console.log(chalk.red(`❌ Invalid configuration — ${result.errors.length} error(s)`));
|
|
95
|
+
}
|
|
96
|
+
if (result.errors.length > 0) {
|
|
97
|
+
console.log('');
|
|
98
|
+
console.log(chalk.bold('Errors:'));
|
|
99
|
+
for (const err of result.errors) {
|
|
100
|
+
console.log(chalk.red(` ✗ ${err.field}: ${err.message}`));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (result.warnings.length > 0) {
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(chalk.bold('Warnings:'));
|
|
106
|
+
for (const warn of result.warnings) {
|
|
107
|
+
console.log(chalk.yellow(` ⚠ ${warn.field}: ${warn.message}`));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Exit with error code for file-level errors (always) or validation errors (when --strict)
|
|
113
|
+
if (!result.valid) {
|
|
114
|
+
const hasFileError = result.errors.some(e => e.code === 'FILE_NOT_FOUND' || e.code === 'INVALID_JSON');
|
|
115
|
+
if (hasFileError || options.strict) {
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// ─── types ─────────────────────────────────────────────────────────────
|
|
122
|
+
cmd.command('types').description('List all available config types').option('--json', 'Output as JSON').action(options => {
|
|
123
|
+
const validator = new ConfigSchemaValidator();
|
|
124
|
+
const types = validator.getRegisteredTypes();
|
|
125
|
+
if (options.json) {
|
|
126
|
+
const details = {};
|
|
127
|
+
for (const type of types) {
|
|
128
|
+
details[type] = validator.getSchemaDefinition(type);
|
|
129
|
+
}
|
|
130
|
+
console.log(JSON.stringify(details, null, 2));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
console.log(chalk.cyan('\n📋 Available Config Types'));
|
|
134
|
+
console.log(chalk.gray('═'.repeat(60)));
|
|
135
|
+
for (const type of types) {
|
|
136
|
+
const def = validator.getSchemaDefinition(type);
|
|
137
|
+
console.log(` ${chalk.white(type)} — ${def.fieldCount} fields`);
|
|
138
|
+
console.log(chalk.gray(` Example: config/clodo-${type}.example.json`));
|
|
139
|
+
console.log(chalk.gray(` Usage: npx clodo-service ${type} --config-file config.json`));
|
|
140
|
+
}
|
|
141
|
+
console.log('');
|
|
142
|
+
console.log(chalk.gray('Run `clodo config-schema show <type>` for detailed field info'));
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { Clodo, ConfigLoader } from '@tamyla/clodo-framework';
|
|
10
10
|
import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
|
|
11
|
+
import { ConfigSchemaValidator } from '../../src/validation/ConfigSchemaValidator.js';
|
|
11
12
|
export function registerCreateCommand(program) {
|
|
12
13
|
const command = program.command('create').description('Create a new Clodo service with conversational setup').option('-n, --non-interactive', 'Run in non-interactive mode with all required parameters').option('--service-name <name>', 'Service name (required in non-interactive mode)').option('--service-type <type>', 'Service type: data-service, auth-service, content-service, api-gateway, generic', 'generic').option('--domain-name <domain>', 'Domain name (required in non-interactive mode)').option('--cloudflare-token <token>', 'Cloudflare API token (required in non-interactive mode)').option('--cloudflare-account-id <id>', 'Cloudflare account ID (required in non-interactive mode)').option('--cloudflare-zone-id <id>', 'Cloudflare zone ID (required in non-interactive mode)').option('--environment <env>', 'Target environment: development, staging, production', 'development').option('--output-path <path>', 'Output directory for generated service', '.').option('--template-path <path>', 'Path to service templates', './templates').option('--middleware-strategy <strategy>', 'Middleware generation strategy: contract|legacy', 'contract').option('--force', 'Skip confirmation prompts').option('--validate', 'Validate service after creation');
|
|
13
14
|
|
|
@@ -21,10 +22,26 @@ export function registerCreateCommand(program) {
|
|
|
21
22
|
json: options.json
|
|
22
23
|
});
|
|
23
24
|
|
|
24
|
-
// Load config from file if specified
|
|
25
|
+
// Load config from file if specified (with schema validation)
|
|
25
26
|
let configFileData = {};
|
|
26
27
|
if (options.configFile) {
|
|
27
28
|
configFileData = configLoader.loadSafe(options.configFile, {});
|
|
29
|
+
// Validate against create schema
|
|
30
|
+
const schemaValidator = new ConfigSchemaValidator({
|
|
31
|
+
verbose: options.verbose
|
|
32
|
+
});
|
|
33
|
+
const validation = schemaValidator.validateConfig(configFileData, 'create');
|
|
34
|
+
if (!validation.valid && options.verbose) {
|
|
35
|
+
output.warning(`Config file has ${validation.errors.length} schema validation issue(s):`);
|
|
36
|
+
for (const err of validation.errors) {
|
|
37
|
+
output.warning(` ${err.field}: ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (validation.warnings.length > 0 && options.verbose) {
|
|
41
|
+
for (const warn of validation.warnings) {
|
|
42
|
+
output.info(` ⚠ ${warn.field}: ${warn.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
28
45
|
if (options.verbose && !options.quiet) {
|
|
29
46
|
output.info(`Loaded configuration from: ${options.configFile}`);
|
|
30
47
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { Clodo, ConfigLoader, InteractiveDeploymentCoordinator, OutputFormatter } from '@tamyla/clodo-framework';
|
|
3
3
|
import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
|
|
4
|
+
import { ConfigSchemaValidator } from '../../src/validation/ConfigSchemaValidator.js';
|
|
4
5
|
export function registerDeployCommand(program) {
|
|
5
6
|
const command = program.command('deploy').description('Deploy a Clodo service with interactive configuration and validation')
|
|
6
7
|
// Cloudflare-specific options
|
|
7
|
-
.option('--token <token>', 'Cloudflare API token (or set CLOUDFLARE_API_TOKEN env var)').option('--account-id <id>', 'Cloudflare account ID (or set CLOUDFLARE_ACCOUNT_ID env var)').option('--zone-id <id>', 'Cloudflare zone ID (or set CLOUDFLARE_ZONE_ID env var)').option('--domain <domain>', 'Specific domain to deploy to').option('--service-name <name>', 'Service name for URL generation (e.g., data-service, auth-service)', 'data-service').option('--environment <env>', 'Target environment (development, staging, production)', 'production').option('--development', 'Deploy to development environment (shorthand for --environment development)').option('--staging', 'Deploy to staging environment (shorthand for --environment staging)').option('--production', 'Deploy to production environment (shorthand for --environment production)').option('--dry-run', 'Simulate deployment without making changes').option('-y, --yes', 'Skip confirmation prompts (for CI/CD)').option('--service-path <path>', 'Path to service directory', '.').option('--check-prereqs', 'Check deployment prerequisites before starting').option('--check-auth', 'Check Wrangler authentication status').option('--check-network', 'Check network connectivity to Cloudflare');
|
|
8
|
+
.option('--token <token>', 'Cloudflare API token (or set CLOUDFLARE_API_TOKEN env var)').option('--account-id <id>', 'Cloudflare account ID (or set CLOUDFLARE_ACCOUNT_ID env var)').option('--zone-id <id>', 'Cloudflare zone ID (or set CLOUDFLARE_ZONE_ID env var)').option('--domain <domain>', 'Specific domain to deploy to').option('--service-name <name>', 'Service name for URL generation (e.g., data-service, auth-service)', 'data-service').option('--environment <env>', 'Target environment (development, staging, production)', 'production').option('--development', 'Deploy to development environment (shorthand for --environment development)').option('--staging', 'Deploy to staging environment (shorthand for --environment staging)').option('--production', 'Deploy to production environment (shorthand for --environment production)').option('--dry-run', 'Simulate deployment without making changes').option('-y, --yes', 'Skip confirmation prompts (for CI/CD)').option('--service-path <path>', 'Path to service directory', '.').option('--check-prereqs', 'Check deployment prerequisites before starting').option('--check-auth', 'Check Wrangler authentication status').option('--check-network', 'Check network connectivity to Cloudflare').option('--skip-doctor', 'Skip preflight doctor checks').option('--doctor-strict', 'Fail deployment if doctor finds warnings (default: fail only on errors)');
|
|
8
9
|
|
|
9
10
|
// Add standard options (--verbose, --quiet, --json, --no-color, --config-file)
|
|
10
11
|
StandardOptions.define(command).action(async options => {
|
|
@@ -25,10 +26,26 @@ export function registerDeployCommand(program) {
|
|
|
25
26
|
options.environment = 'production';
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
// Load config from file if specified
|
|
29
|
+
// Load config from file if specified (with schema validation)
|
|
29
30
|
let configFileData = {};
|
|
30
31
|
if (options.configFile) {
|
|
31
32
|
configFileData = configLoader.loadSafe(options.configFile, {});
|
|
33
|
+
// Validate against deploy schema
|
|
34
|
+
const schemaValidator = new ConfigSchemaValidator({
|
|
35
|
+
verbose: options.verbose
|
|
36
|
+
});
|
|
37
|
+
const validation = schemaValidator.validateConfig(configFileData, 'deploy');
|
|
38
|
+
if (!validation.valid && options.verbose) {
|
|
39
|
+
output.warning(`Config file has ${validation.errors.length} schema validation issue(s):`);
|
|
40
|
+
for (const err of validation.errors) {
|
|
41
|
+
output.warning(` ${err.field}: ${err.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (validation.warnings.length > 0 && options.verbose) {
|
|
45
|
+
for (const warn of validation.warnings) {
|
|
46
|
+
output.info(` ⚠ ${warn.field}: ${warn.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
32
49
|
if (options.verbose && !options.quiet) {
|
|
33
50
|
output.info(`Loaded configuration from: ${options.configFile}`);
|
|
34
51
|
}
|
|
@@ -37,6 +54,48 @@ export function registerDeployCommand(program) {
|
|
|
37
54
|
// Merge config file defaults with CLI options (CLI takes precedence)
|
|
38
55
|
const mergedOptions = configLoader.merge(configFileData, options);
|
|
39
56
|
|
|
57
|
+
// Run doctor preflight checks (unless skipped)
|
|
58
|
+
if (!mergedOptions.skipDoctor) {
|
|
59
|
+
const {
|
|
60
|
+
ValidationHandler
|
|
61
|
+
} = await import('../../src/service-management/handlers/ValidationHandler.js');
|
|
62
|
+
const doctor = new ValidationHandler();
|
|
63
|
+
if (!mergedOptions.quiet) {
|
|
64
|
+
output.info('🔍 Running preflight doctor checks...');
|
|
65
|
+
}
|
|
66
|
+
const doctorResults = await doctor.runDoctor({
|
|
67
|
+
servicePath: mergedOptions.servicePath || '.',
|
|
68
|
+
strict: mergedOptions.doctorStrict || false,
|
|
69
|
+
json: false // Always use human-readable for deploy context
|
|
70
|
+
});
|
|
71
|
+
if (doctorResults.exitCode !== 0) {
|
|
72
|
+
output.error('❌ Preflight checks failed!');
|
|
73
|
+
output.error(`Found ${doctorResults.summary.errors} errors and ${doctorResults.summary.warnings} warnings`);
|
|
74
|
+
|
|
75
|
+
// Show details of failed checks
|
|
76
|
+
doctorResults.checks.forEach(check => {
|
|
77
|
+
if (check.status !== 'passed') {
|
|
78
|
+
const color = check.severity === 'error' ? 'red' : check.severity === 'warning' ? 'yellow' : 'gray';
|
|
79
|
+
console.log(chalk[color](` ${check.name}: ${check.message}`));
|
|
80
|
+
check.details.forEach(detail => {
|
|
81
|
+
console.log(chalk.gray(` ${detail}`));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
if (doctorResults.fixSuggestions.length > 0) {
|
|
86
|
+
output.info('\n💡 Fix suggestions:');
|
|
87
|
+
doctorResults.fixSuggestions.forEach(suggestion => {
|
|
88
|
+
output.log(chalk.blue(` • ${suggestion}`));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
output.info('\nTo skip these checks, use --skip-doctor');
|
|
92
|
+
output.info('To run checks manually, use: clodo doctor');
|
|
93
|
+
process.exit(1);
|
|
94
|
+
} else if (!mergedOptions.quiet) {
|
|
95
|
+
output.success(`✅ Preflight checks passed (${doctorResults.summary.passed}/${doctorResults.summary.total})`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
40
99
|
// Determine if interactive mode should be enabled
|
|
41
100
|
const interactive = !mergedOptions.nonInteractive && !mergedOptions.yes;
|
|
42
101
|
if (interactive) {
|