@tamyla/clodo-framework 3.2.2 → 3.2.3
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 +8 -0
- package/README.md +2 -2
- package/dist/cli/commands/deploy.js +3 -1
- package/dist/config/validation-config.json +1 -1
- package/dist/deployment/index.js +4 -1
- package/dist/deployment/wrangler-deployer.js +1 -1
- package/dist/lib/deployment/modules/EnvironmentManager.js +4 -7
- package/dist/lib/shared/cloudflare/ops.js +2 -2
- package/dist/lib/shared/config/command-config-manager.js +1 -1
- package/dist/lib/shared/deployment/index.js +1 -1
- package/dist/lib/shared/deployment/workflows/index.js +2 -2
- package/dist/lib/shared/deployment/workflows/interactive-deployment-coordinator.js +4 -2
- package/dist/lib/shared/deployment/workflows/interactive-validation.js +1 -1
- package/dist/lib/shared/utils/ErrorHandler.js +6 -6
- package/dist/orchestration/multi-domain-orchestrator.js +8 -2
- package/dist/utils/deployment/index.js +1 -1
- package/dist/utils/framework-config.js +16 -5
- package/dist/utils/index.js +3 -0
- package/dist/worker/integration.js +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [3.2.3](https://github.com/tamylaa/clodo-framework/compare/v3.2.2...v3.2.3) (2025-12-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* clean up debug logging in fix-dist-imports.js ([374318e](https://github.com/tamylaa/clodo-framework/commit/374318efc9b73cf304306f3dd249eb88f8b06c98))
|
|
7
|
+
* resolve all test suite failures for production readiness ([519df7c](https://github.com/tamylaa/clodo-framework/commit/519df7c755bd1a93bb5e9717c2aaf21bdf02e636))
|
|
8
|
+
|
|
1
9
|
## [3.2.2](https://github.com/tamylaa/clodo-framework/compare/v3.2.1...v3.2.2) (2025-12-05)
|
|
2
10
|
|
|
3
11
|
|
package/README.md
CHANGED
|
@@ -748,7 +748,7 @@ npx wrangler --version
|
|
|
748
748
|
### **2. Cloudflare Authentication**
|
|
749
749
|
```bash
|
|
750
750
|
# Login to Cloudflare (first time only)
|
|
751
|
-
npx wrangler
|
|
751
|
+
npx wrangler login
|
|
752
752
|
|
|
753
753
|
# Or set API token directly (will be prompted automatically)
|
|
754
754
|
# The system will securely store your token with encryption
|
|
@@ -1318,7 +1318,7 @@ node bin/deployment/enterprise-deploy.js list
|
|
|
1318
1318
|
# Problem: No Cloudflare authentication
|
|
1319
1319
|
# Solution: The system will automatically prompt for API token
|
|
1320
1320
|
# Or manually set up wrangler auth:
|
|
1321
|
-
npx wrangler
|
|
1321
|
+
npx wrangler login
|
|
1322
1322
|
```
|
|
1323
1323
|
|
|
1324
1324
|
#### **"D1 database discovery requires additional permissions"**
|
|
@@ -6,7 +6,7 @@ import { InteractiveDeploymentCoordinator } from '../../lib/shared/deployment/wo
|
|
|
6
6
|
export function registerDeployCommand(program) {
|
|
7
7
|
const command = program.command('deploy').description('Deploy a Clodo service with interactive configuration and validation')
|
|
8
8
|
// Cloudflare-specific options
|
|
9
|
-
.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('--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');
|
|
9
|
+
.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');
|
|
10
10
|
|
|
11
11
|
// Add standard options (--verbose, --quiet, --json, --no-color, --config-file)
|
|
12
12
|
StandardOptions.define(command).action(async options => {
|
|
@@ -51,6 +51,7 @@ export function registerDeployCommand(program) {
|
|
|
51
51
|
servicePath: mergedOptions.servicePath || '.',
|
|
52
52
|
environment: mergedOptions.environment || 'production',
|
|
53
53
|
domain: mergedOptions.domain,
|
|
54
|
+
serviceName: mergedOptions.serviceName,
|
|
54
55
|
dryRun: mergedOptions.dryRun || false,
|
|
55
56
|
credentials: {
|
|
56
57
|
token: mergedOptions.token,
|
|
@@ -80,6 +81,7 @@ export function registerDeployCommand(program) {
|
|
|
80
81
|
servicePath: mergedOptions.servicePath || '.',
|
|
81
82
|
environment: mergedOptions.environment || 'production',
|
|
82
83
|
domain: mergedOptions.domain,
|
|
84
|
+
serviceName: mergedOptions.serviceName,
|
|
83
85
|
dryRun: mergedOptions.dryRun || false,
|
|
84
86
|
credentials: {
|
|
85
87
|
token: mergedOptions.token,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"cloudflare": {
|
|
14
14
|
"whoami": "npx wrangler whoami",
|
|
15
|
-
"auth_login": "npx wrangler
|
|
15
|
+
"auth_login": "npx wrangler login",
|
|
16
16
|
"deployments_list": "npx wrangler deployments list",
|
|
17
17
|
"list_workers": "npx wrangler dev --help",
|
|
18
18
|
"deploy": "npx wrangler deploy",
|
package/dist/deployment/index.js
CHANGED
|
@@ -8,4 +8,7 @@
|
|
|
8
8
|
export { BaseDeploymentOrchestrator } from './orchestration/BaseDeploymentOrchestrator.js';
|
|
9
9
|
export { SingleServiceOrchestrator } from './orchestration/SingleServiceOrchestrator.js';
|
|
10
10
|
export { PortfolioOrchestrator } from './orchestration/PortfolioOrchestrator.js';
|
|
11
|
-
export { UnifiedDeploymentOrchestrator } from './orchestration/UnifiedDeploymentOrchestrator.js';
|
|
11
|
+
export { UnifiedDeploymentOrchestrator } from './orchestration/UnifiedDeploymentOrchestrator.js';
|
|
12
|
+
|
|
13
|
+
// Rollback Management
|
|
14
|
+
export { RollbackManager } from './rollback-manager.js';
|
|
@@ -487,7 +487,7 @@ export class WranglerDeployer {
|
|
|
487
487
|
valid: false,
|
|
488
488
|
error: 'Wrangler authentication failed',
|
|
489
489
|
details: 'You need to login to Cloudflare',
|
|
490
|
-
suggestions: ['Run: wrangler
|
|
490
|
+
suggestions: ['Run: wrangler login', 'Or set CLOUDFLARE_API_TOKEN environment variable']
|
|
491
491
|
};
|
|
492
492
|
}
|
|
493
493
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles environment configuration, domain mapping, deployment mode selection, and cross-domain coordination
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { MultiDomainOrchestrator
|
|
6
|
+
import { MultiDomainOrchestrator } from '../../shared/deployment/index.js';
|
|
7
7
|
import { DomainDiscovery } from '../../shared/cloudflare/domain-discovery.js';
|
|
8
8
|
import { askChoice, askUser, askYesNo, DeploymentInteractiveUtils } from '../../shared/utils/interactive-utils.js';
|
|
9
9
|
export class EnvironmentManager {
|
|
@@ -43,12 +43,9 @@ export class EnvironmentManager {
|
|
|
43
43
|
|
|
44
44
|
// Initialize cross-domain coordinator for portfolio mode
|
|
45
45
|
if (this.config.deploymentMode === 'portfolio') {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
crossDomainCoordination: this.config.secrets?.crossDomainSharing || false
|
|
50
|
-
});
|
|
51
|
-
console.log(' ✅ Cross-domain coordinator initialized');
|
|
46
|
+
// CrossDomainCoordinator is not available in current build
|
|
47
|
+
console.log(' ⚠️ Cross-domain coordinator not available in current build');
|
|
48
|
+
console.log(' ℹ️ Portfolio mode will use basic multi-domain coordination');
|
|
52
49
|
}
|
|
53
50
|
|
|
54
51
|
// Initialize domain discovery
|
|
@@ -120,8 +120,8 @@ export async function checkAuth() {
|
|
|
120
120
|
}
|
|
121
121
|
export async function authenticate() {
|
|
122
122
|
try {
|
|
123
|
-
// Use wrangler
|
|
124
|
-
await execAsync('npx wrangler
|
|
123
|
+
// Use wrangler login for authentication (Wrangler 3.x+)
|
|
124
|
+
await execAsync('npx wrangler login', {
|
|
125
125
|
stdio: 'inherit'
|
|
126
126
|
});
|
|
127
127
|
|
|
@@ -58,7 +58,7 @@ export class CommandConfigManager {
|
|
|
58
58
|
},
|
|
59
59
|
cloudflareCommands: {
|
|
60
60
|
whoami: 'npx wrangler whoami',
|
|
61
|
-
auth_login: 'npx wrangler
|
|
61
|
+
auth_login: 'npx wrangler login',
|
|
62
62
|
deployments_list: 'npx wrangler deployments list',
|
|
63
63
|
list_workers: 'npx wrangler dev --help',
|
|
64
64
|
deploy: 'npx wrangler deploy',
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
export { DeploymentValidator } from './validator.js';
|
|
7
7
|
export { MultiDomainOrchestrator } from '@tamyla/clodo-framework/orchestration';
|
|
8
|
-
export { CrossDomainCoordinator } from '@tamyla/clodo-framework/orchestration';
|
|
8
|
+
// export { CrossDomainCoordinator } from '@tamyla/clodo-framework/orchestration'; // Not available in src/
|
|
9
9
|
export { DeploymentAuditor } from './auditor.js';
|
|
10
10
|
export { RollbackManager } from './rollback-manager.js';
|
|
11
11
|
export { DeploymentCredentialCollector } from './credential-collector.js';
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
export { InteractiveDeploymentCoordinator } from './interactive-deployment-coordinator.js';
|
|
7
|
-
export { InteractiveConfirmationWorkflow } from './interactive-confirmation.js';
|
|
7
|
+
export { InteractiveConfirmation as InteractiveConfirmationWorkflow } from './interactive-confirmation.js';
|
|
8
8
|
export { InteractiveDatabaseWorkflow } from './interactive-database-workflow.js';
|
|
9
9
|
export { InteractiveDomainInfoGatherer } from './interactive-domain-info-gatherer.js';
|
|
10
10
|
export { InteractiveSecretWorkflow } from './interactive-secret-workflow.js';
|
|
11
11
|
export { InteractiveTestingWorkflow } from './interactive-testing-workflow.js';
|
|
12
12
|
export { InteractiveValidationWorkflow } from './interactive-validation.js';
|
|
13
|
-
export { DeploymentSummaryWorkflow } from './deployment-summary.js';
|
|
13
|
+
export { DeploymentSummary as DeploymentSummaryWorkflow } from './deployment-summary.js';
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { InteractiveDomainInfoGatherer } from './interactive-domain-info-gatherer.js';
|
|
19
19
|
import { InteractiveDatabaseWorkflow } from './interactive-database-workflow.js';
|
|
20
20
|
import { InteractiveSecretWorkflow } from './interactive-secret-workflow.js';
|
|
21
|
-
import {
|
|
21
|
+
import { InteractiveValidationWorkflow } from './interactive-validation.js';
|
|
22
22
|
import { InteractiveConfirmation } from './interactive-confirmation.js';
|
|
23
23
|
import { InteractiveTestingWorkflow } from './interactive-testing-workflow.js';
|
|
24
24
|
import { Clodo } from '@tamyla/clodo-framework';
|
|
@@ -35,6 +35,7 @@ export class InteractiveDeploymentCoordinator {
|
|
|
35
35
|
* @param {string} options.servicePath - Path to service directory
|
|
36
36
|
* @param {string} options.environment - Target environment
|
|
37
37
|
* @param {string} options.domain - Specific domain (optional)
|
|
38
|
+
* @param {string} options.serviceName - Service name for URL generation
|
|
38
39
|
* @param {boolean} options.dryRun - Dry run mode
|
|
39
40
|
* @param {Object} options.credentials - Cloudflare credentials
|
|
40
41
|
* @param {boolean} options.checkPrereqs - Check prerequisites
|
|
@@ -72,7 +73,7 @@ export class InteractiveDeploymentCoordinator {
|
|
|
72
73
|
secretWorkflow: new InteractiveSecretWorkflow({
|
|
73
74
|
interactive: true
|
|
74
75
|
}),
|
|
75
|
-
validation: new
|
|
76
|
+
validation: new InteractiveValidationWorkflow({
|
|
76
77
|
interactive: true
|
|
77
78
|
}),
|
|
78
79
|
confirmation: InteractiveConfirmation,
|
|
@@ -206,6 +207,7 @@ export class InteractiveDeploymentCoordinator {
|
|
|
206
207
|
servicePath: this.deploymentState.config.servicePath,
|
|
207
208
|
environment: this.deploymentState.config.environment,
|
|
208
209
|
domain: this.deploymentState.config.domain,
|
|
210
|
+
serviceName: this.options.serviceName,
|
|
209
211
|
dryRun: this.deploymentState.config.dryRun,
|
|
210
212
|
credentials: this.deploymentState.config.credentials
|
|
211
213
|
});
|
|
@@ -14,7 +14,7 @@ import { validatePrerequisites, checkAuth, authenticate, workerExists } from '..
|
|
|
14
14
|
* Interactive Validation Workflow
|
|
15
15
|
* Handles pre-deployment checks and comprehensive validation
|
|
16
16
|
*/
|
|
17
|
-
export class
|
|
17
|
+
export class InteractiveValidationWorkflow {
|
|
18
18
|
/**
|
|
19
19
|
* @param {Object} options - Configuration options
|
|
20
20
|
*/
|
|
@@ -273,9 +273,9 @@ export class ErrorHandler {
|
|
|
273
273
|
console.error(' - Verify service is running and responding');
|
|
274
274
|
}
|
|
275
275
|
if (errorMsg.includes('authentication')) {
|
|
276
|
-
suggestions.push('Re-authenticate with Cloudflare: wrangler
|
|
276
|
+
suggestions.push('Re-authenticate with Cloudflare: wrangler login');
|
|
277
277
|
suggestions.push('Check API token validity');
|
|
278
|
-
console.error(' - Re-authenticate with Cloudflare: wrangler
|
|
278
|
+
console.error(' - Re-authenticate with Cloudflare: wrangler login');
|
|
279
279
|
console.error(' - Check API token validity');
|
|
280
280
|
}
|
|
281
281
|
if (errorMsg.includes('timeout')) {
|
|
@@ -377,7 +377,7 @@ export class ErrorHandler {
|
|
|
377
377
|
console.error(' - Verify Cloudflare API token has D1 permissions');
|
|
378
378
|
console.error(' - Check if you have access to the specified database');
|
|
379
379
|
console.error(' - Ensure you\'re authenticated to the correct account');
|
|
380
|
-
console.error(' - Re-authenticate: wrangler
|
|
380
|
+
console.error(' - Re-authenticate: wrangler login');
|
|
381
381
|
} else if (errorMessage.includes('migration')) {
|
|
382
382
|
console.error('\n🔄 D1 Migration Error:');
|
|
383
383
|
console.error(' - Check migration files for syntax errors');
|
|
@@ -455,7 +455,7 @@ export class ErrorHandler {
|
|
|
455
455
|
analysis.severity = 'high';
|
|
456
456
|
analysis.autoFixable = false;
|
|
457
457
|
analysis.canRecover = false;
|
|
458
|
-
analysis.suggestions = ['Re-authenticate with Cloudflare: wrangler
|
|
458
|
+
analysis.suggestions = ['Re-authenticate with Cloudflare: wrangler login', 'Check API token permissions include D1 access', 'Verify correct Cloudflare account is selected'];
|
|
459
459
|
} else if (errorMessage.includes('migration')) {
|
|
460
460
|
analysis.category = 'migration';
|
|
461
461
|
analysis.severity = 'medium';
|
|
@@ -475,7 +475,7 @@ export class ErrorHandler {
|
|
|
475
475
|
const guides = {
|
|
476
476
|
database_not_found: ['1. List available databases: wrangler d1 list', '2. Check if database name in wrangler.toml matches an existing database', '3. If database doesn\'t exist, create it: wrangler d1 create <database-name>', '4. Copy the database ID from the creation output', '5. Update database_id in wrangler.toml [[d1_databases]] section', '6. Retry deployment: npm run deploy'],
|
|
477
477
|
binding_configuration: ['1. Open wrangler.toml and locate [[d1_databases]] section', '2. Verify binding name matches what your code expects (usually "DB")', '3. Check database_name is correct (no typos)', '4. Verify database_id is a valid UUID format', '5. Test configuration: wrangler deploy --dry-run', '6. If issues persist, validate with: wrangler d1 info <database-name>'],
|
|
478
|
-
authentication: ['1. Log out of current session: wrangler logout', '2. Re-authenticate: wrangler
|
|
478
|
+
authentication: ['1. Log out of current session: wrangler logout', '2. Re-authenticate: wrangler login', '3. Verify correct account: wrangler whoami', '4. Check API token permissions if using token authentication', '5. Ensure token has D1:Edit permissions in Cloudflare dashboard', '6. Retry the operation after successful authentication'],
|
|
479
479
|
migration: ['1. Check migration files in migrations/ directory', '2. Validate SQL syntax in migration files', '3. List current migration status: wrangler d1 migrations list <database>', '4. Apply pending migrations: wrangler d1 migrations apply <database>', '5. If errors occur, check migration file format and naming', '6. Consider rolling back problematic migrations if needed'],
|
|
480
480
|
general: ['1. Check Cloudflare account has D1 enabled and available', '2. Update wrangler to latest version: npm install -g wrangler', '3. Verify wrangler.toml file exists and has correct format', '4. Test authentication: wrangler whoami', '5. List available D1 databases: wrangler d1 list', '6. Check Cloudflare Dashboard for any service issues']
|
|
481
481
|
};
|
|
@@ -549,7 +549,7 @@ export class ErrorHandler {
|
|
|
549
549
|
suggestions.push('Check network connectivity and firewall rules');
|
|
550
550
|
}
|
|
551
551
|
if (errorMessage.includes('auth') || errorMessage.includes('token')) {
|
|
552
|
-
suggestions.push('Re-authenticate with Cloudflare: wrangler
|
|
552
|
+
suggestions.push('Re-authenticate with Cloudflare: wrangler login');
|
|
553
553
|
suggestions.push('Check API token validity and permissions');
|
|
554
554
|
}
|
|
555
555
|
if (errorMessage.includes('timeout')) {
|
|
@@ -35,7 +35,7 @@ export class MultiDomainOrchestrator {
|
|
|
35
35
|
this.skipTests = options.skipTests || false;
|
|
36
36
|
this.parallelDeployments = options.parallelDeployments || 3;
|
|
37
37
|
this.servicePath = options.servicePath || process.cwd();
|
|
38
|
-
this.serviceName = options.serviceName || '
|
|
38
|
+
this.serviceName = options.serviceName || 'data-service'; // Service name for custom domain (e.g., 'data-service', 'auth-service')
|
|
39
39
|
|
|
40
40
|
// Wrangler config path - allows using customer-specific wrangler.toml files
|
|
41
41
|
// If not specified, wrangler uses the default wrangler.toml in servicePath
|
|
@@ -767,7 +767,8 @@ export class MultiDomainOrchestrator {
|
|
|
767
767
|
* @param {Object} options - Simple deployment options
|
|
768
768
|
* @param {string} options.servicePath - Path to service directory
|
|
769
769
|
* @param {string} options.environment - Target environment
|
|
770
|
-
* @param {string} options.domain - Specific domain to deploy to
|
|
770
|
+
* @param {string} options.domain - Specific domain to deploy to (used as zone name and domain suffix)
|
|
771
|
+
* @param {string} options.serviceName - Service name for URL generation (e.g., 'data-service', 'auth-service')
|
|
771
772
|
* @param {boolean} options.dryRun - Simulate deployment
|
|
772
773
|
* @param {Object} options.credentials - Cloudflare credentials
|
|
773
774
|
* @returns {Promise<Object>} Deployment result
|
|
@@ -777,6 +778,7 @@ export class MultiDomainOrchestrator {
|
|
|
777
778
|
servicePath = '.',
|
|
778
779
|
environment = 'production',
|
|
779
780
|
domain,
|
|
781
|
+
serviceName,
|
|
780
782
|
dryRun = false,
|
|
781
783
|
credentials = {}
|
|
782
784
|
} = options;
|
|
@@ -786,9 +788,13 @@ export class MultiDomainOrchestrator {
|
|
|
786
788
|
environment,
|
|
787
789
|
dryRun,
|
|
788
790
|
servicePath,
|
|
791
|
+
serviceName,
|
|
792
|
+
// Pass through serviceName if provided
|
|
789
793
|
cloudflareToken: credentials.token,
|
|
790
794
|
cloudflareAccountId: credentials.accountId,
|
|
791
795
|
cloudflareZoneId: credentials.zoneId,
|
|
796
|
+
cloudflareZoneName: domain,
|
|
797
|
+
// Use domain as zone name for customer config
|
|
792
798
|
domains: domain ? [domain] : []
|
|
793
799
|
});
|
|
794
800
|
try {
|
|
@@ -5,4 +5,4 @@ export { ConfigurationCacheManager } from './config-cache.js';
|
|
|
5
5
|
export { EnhancedSecretManager } from './secret-generator.js';
|
|
6
6
|
export { UnifiedConfigManager, unifiedConfigManager } from '../config/unified-config-manager.js';
|
|
7
7
|
export { askUser, askYesNo, askChoice, closePrompts } from '../interactive-prompts.js';
|
|
8
|
-
export { DeploymentCredentialCollector } from '
|
|
8
|
+
export { DeploymentCredentialCollector } from '../../../lib/shared/deployment/credential-collector.js';
|
|
@@ -24,20 +24,31 @@ export class FrameworkConfig {
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Find the configuration file in standard locations
|
|
27
|
+
*
|
|
28
|
+
* For a packaged framework, we should only look within the framework's own directory
|
|
29
|
+
* to maintain self-containment. Users can explicitly pass config paths if needed.
|
|
27
30
|
*/
|
|
28
31
|
findConfigFile() {
|
|
29
32
|
let __filename, __dirname;
|
|
30
33
|
|
|
31
|
-
//
|
|
34
|
+
// Get the framework's directory (works in both source and packaged environments)
|
|
32
35
|
try {
|
|
33
36
|
__filename = fileURLToPath(import.meta.url);
|
|
34
37
|
__dirname = dirname(__filename);
|
|
35
38
|
} catch (error) {
|
|
36
|
-
// Fallback for
|
|
39
|
+
// Fallback for environments where import.meta is not available
|
|
40
|
+
// This should not happen in modern Node.js environments
|
|
41
|
+
console.warn('⚠️ Unable to determine framework directory, using current directory');
|
|
37
42
|
__dirname = process.cwd();
|
|
38
|
-
__filename = join(__dirname, 'src', 'utils', 'framework-config.js');
|
|
39
43
|
}
|
|
40
|
-
|
|
44
|
+
|
|
45
|
+
// Only look for config files within the framework's package directory
|
|
46
|
+
// This ensures the framework is self-contained and doesn't depend on user project files
|
|
47
|
+
const frameworkRoot = join(__dirname, '..', '..');
|
|
48
|
+
const possiblePaths = [join(frameworkRoot, 'validation-config.json'), join(frameworkRoot, 'config', 'validation-config.json'),
|
|
49
|
+
// Allow explicit config path via environment variable (for advanced users)
|
|
50
|
+
process.env.CLODO_FRAMEWORK_CONFIG && join(process.cwd(), process.env.CLODO_FRAMEWORK_CONFIG)].filter(Boolean); // Remove falsy values
|
|
51
|
+
|
|
41
52
|
for (const path of possiblePaths) {
|
|
42
53
|
if (this.fileManager.exists(path)) {
|
|
43
54
|
return path;
|
|
@@ -45,7 +56,7 @@ export class FrameworkConfig {
|
|
|
45
56
|
}
|
|
46
57
|
|
|
47
58
|
// Return null instead of throwing - will use default config
|
|
48
|
-
//
|
|
59
|
+
// This is expected behavior - services don't need their own config
|
|
49
60
|
return null;
|
|
50
61
|
}
|
|
51
62
|
|
package/dist/utils/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getDomainFromEnv, createEnvironmentConfig } from '../config/domains.js';
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
|
|
3
|
+
// Import COMMON_FEATURES from ConfigurationManager
|
|
4
|
+
import { COMMON_FEATURES } from '../../lib/shared/config/ConfigurationManager.js';
|
|
5
5
|
|
|
6
6
|
// Simple feature manager interface (replaces ConfigurationManager dependency)
|
|
7
7
|
export const configManager = {
|
|
8
8
|
setDomain: () => {},
|
|
9
|
-
getEnabledFeatures: () => COMMON_FEATURES,
|
|
10
|
-
isFeatureEnabled: feature => COMMON_FEATURES.includes(feature)
|
|
9
|
+
getEnabledFeatures: () => Object.values(COMMON_FEATURES),
|
|
10
|
+
isFeatureEnabled: feature => Object.values(COMMON_FEATURES).includes(feature)
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
// Legacy featureManager compatibility interface
|
|
@@ -50,7 +50,7 @@ export const initializeService = (env, domainConfigs = {}) => {
|
|
|
50
50
|
const serviceContext = {
|
|
51
51
|
domain: domainConfig.name,
|
|
52
52
|
environment,
|
|
53
|
-
features:
|
|
53
|
+
features: Object.keys(domainConfig.features || {}).filter(feature => domainConfig.features[feature] === true),
|
|
54
54
|
config: envConfig,
|
|
55
55
|
env,
|
|
56
56
|
isProduction: environment === 'production',
|