@tamyla/clodo-framework 3.2.2 → 3.2.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 CHANGED
@@ -1,3 +1,18 @@
1
+ ## [3.2.4](https://github.com/tamylaa/clodo-framework/compare/v3.2.3...v3.2.4) (2025-12-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * expose CLI utilities in public API to fix import issues ([5d995ab](https://github.com/tamylaa/clodo-framework/commit/5d995abb2f6cb718acc0a03beef75f1025204200))
7
+
8
+ ## [3.2.3](https://github.com/tamylaa/clodo-framework/compare/v3.2.2...v3.2.3) (2025-12-06)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * clean up debug logging in fix-dist-imports.js ([374318e](https://github.com/tamylaa/clodo-framework/commit/374318efc9b73cf304306f3dd249eb88f8b06c98))
14
+ * resolve all test suite failures for production readiness ([519df7c](https://github.com/tamylaa/clodo-framework/commit/519df7c755bd1a93bb5e9717c2aaf21bdf02e636))
15
+
1
16
  ## [3.2.2](https://github.com/tamylaa/clodo-framework/compare/v3.2.1...v3.2.2) (2025-12-05)
2
17
 
3
18
 
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 auth login
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 auth login
1321
+ npx wrangler login
1322
1322
  ```
1323
1323
 
1324
1324
  #### **"D1 database discovery requires additional permissions"**
@@ -5,9 +5,7 @@
5
5
 
6
6
  import chalk from 'chalk';
7
7
  import path from 'path';
8
- import { ServiceOrchestrator } from '@tamyla/clodo-framework';
9
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
10
- import { ServiceConfigManager } from '../../lib/shared/utils/service-config-manager.js';
8
+ import { ServiceOrchestrator, StandardOptions, ServiceConfigManager } from '@tamyla/clodo-framework';
11
9
  export function registerAssessCommand(program) {
12
10
  const command = program.command('assess [service-path]').description('Run intelligent capability assessment (requires @tamyla/clodo-orchestration)').option('--export <file>', 'Export assessment results to JSON file').option('--domain <domain>', 'Domain name for assessment').option('--service-type <type>', 'Service type for assessment').option('--token <token>', 'Cloudflare API token').option('--show-config-sources', 'Display all configuration sources and merged result');
13
11
 
@@ -6,9 +6,7 @@
6
6
  */
7
7
 
8
8
  import chalk from 'chalk';
9
- import { Clodo } from '@tamyla/clodo-framework';
10
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
11
- import { ConfigLoader } from '../../lib/shared/utils/config-loader.js';
9
+ import { Clodo, StandardOptions, ConfigLoader } from '@tamyla/clodo-framework';
12
10
  export function registerCreateCommand(program) {
13
11
  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('--force', 'Skip confirmation prompts').option('--validate', 'Validate service after creation');
14
12
 
@@ -1,17 +1,14 @@
1
1
  import chalk from 'chalk';
2
- import { Clodo } from '@tamyla/clodo-framework';
3
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
4
- import { ConfigLoader } from '../../lib/shared/utils/config-loader.js';
5
- import { InteractiveDeploymentCoordinator } from '../../lib/shared/deployment/workflows/interactive-deployment-coordinator.js';
2
+ import { Clodo, StandardOptions, ConfigLoader, InteractiveDeploymentCoordinator, OutputFormatter } from '@tamyla/clodo-framework';
6
3
  export function registerDeployCommand(program) {
7
4
  const command = program.command('deploy').description('Deploy a Clodo service with interactive configuration and validation')
8
5
  // 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');
6
+ .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
7
 
11
8
  // Add standard options (--verbose, --quiet, --json, --no-color, --config-file)
12
9
  StandardOptions.define(command).action(async options => {
13
10
  try {
14
- const output = new (await import('../../lib/shared/utils/output-formatter.js')).OutputFormatter(options);
11
+ const output = new OutputFormatter(options);
15
12
  const configLoader = new ConfigLoader({
16
13
  verbose: options.verbose,
17
14
  quiet: options.quiet,
@@ -51,6 +48,7 @@ export function registerDeployCommand(program) {
51
48
  servicePath: mergedOptions.servicePath || '.',
52
49
  environment: mergedOptions.environment || 'production',
53
50
  domain: mergedOptions.domain,
51
+ serviceName: mergedOptions.serviceName,
54
52
  dryRun: mergedOptions.dryRun || false,
55
53
  credentials: {
56
54
  token: mergedOptions.token,
@@ -80,6 +78,7 @@ export function registerDeployCommand(program) {
80
78
  servicePath: mergedOptions.servicePath || '.',
81
79
  environment: mergedOptions.environment || 'production',
82
80
  domain: mergedOptions.domain,
81
+ serviceName: mergedOptions.serviceName,
83
82
  dryRun: mergedOptions.dryRun || false,
84
83
  credentials: {
85
84
  token: mergedOptions.token,
@@ -98,7 +97,7 @@ export function registerDeployCommand(program) {
98
97
  }
99
98
  }
100
99
  } catch (error) {
101
- const output = new (await import('../../lib/shared/utils/output-formatter.js')).OutputFormatter(options || {});
100
+ const output = new OutputFormatter(options || {});
102
101
  output.error(`Deployment failed: ${error.message}`);
103
102
  process.exit(1);
104
103
  }
@@ -1,8 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import path from 'path';
3
- import { ServiceOrchestrator } from '@tamyla/clodo-framework';
4
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
5
- import { ServiceConfigManager } from '../../lib/shared/utils/service-config-manager.js';
3
+ import { ServiceOrchestrator, StandardOptions, ServiceConfigManager } from '@tamyla/clodo-framework';
6
4
  export function registerDiagnoseCommand(program) {
7
5
  const command = program.command('diagnose [service-path]').description('Diagnose and report issues with an existing service').option('--deep-scan', 'Perform deep analysis including dependencies and deployment readiness').option('--export-report <file>', 'Export diagnostic report to file').option('--fix-suggestions', 'Include suggested fixes for issues').option('--show-config-sources', 'Display all configuration sources and merged result');
8
6
 
@@ -3,7 +3,7 @@
3
3
  * Provides UI-specific deployment verification by delegating to shared infrastructure
4
4
  */
5
5
 
6
- import { verifyWorkerDeployment, healthCheckWithBackoff, checkHealth } from '../../../lib/shared/monitoring/health-checker.js';
6
+ import { verifyWorkerDeployment, healthCheckWithBackoff, checkHealth } from '@tamyla/clodo-framework';
7
7
  import chalk from 'chalk';
8
8
  import readline from 'readline';
9
9
 
@@ -3,7 +3,7 @@
3
3
  * Provides interactive error recovery by delegating to shared error classification
4
4
  */
5
5
 
6
- import { classifyError, getRecoverySuggestions } from '../../../lib/shared/error-handling/error-classifier.js';
6
+ import { classifyError, getRecoverySuggestions } from '@tamyla/clodo-framework';
7
7
  import chalk from 'chalk';
8
8
  import readline from 'readline';
9
9
 
@@ -4,9 +4,7 @@
4
4
 
5
5
  import chalk from 'chalk';
6
6
  import path from 'path';
7
- import { ServiceOrchestrator } from '@tamyla/clodo-framework';
8
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
9
- import { ServiceConfigManager } from '../../lib/shared/utils/service-config-manager.js';
7
+ import { ServiceOrchestrator, StandardOptions, ServiceConfigManager } from '@tamyla/clodo-framework';
10
8
  export function registerUpdateCommand(program) {
11
9
  const command = program.command('update [service-path]').description('Update an existing service configuration').option('-i, --interactive', 'Run in interactive mode to select what to update').option('--domain-name <domain>', 'Update domain name').option('--cloudflare-token <token>', 'Update Cloudflare API token').option('--cloudflare-account-id <id>', 'Update Cloudflare account ID').option('--cloudflare-zone-id <id>', 'Update Cloudflare zone ID').option('--environment <env>', 'Update target environment: development, staging, production').option('--add-feature <feature>', 'Add a feature flag').option('--remove-feature <feature>', 'Remove a feature flag').option('--regenerate-configs', 'Regenerate all configuration files').option('--fix-errors', 'Attempt to fix common configuration errors').option('--preview', 'Show what would be changed without applying').option('--show-config-sources', 'Display all configuration sources and merged result').option('--force', 'Skip confirmation prompts');
12
10
 
@@ -1,6 +1,5 @@
1
1
  import chalk from 'chalk';
2
- import { Clodo } from '@tamyla/clodo-framework';
3
- import { StandardOptions } from '../../lib/shared/utils/cli-options.js';
2
+ import { Clodo, StandardOptions } from '@tamyla/clodo-framework';
4
3
  export function registerValidateCommand(program) {
5
4
  const command = program.command('validate <service-path>').description('Validate an existing service configuration').option('--export-report <file>', 'Export validation report to JSON file');
6
5
 
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "cloudflare": {
14
14
  "whoami": "npx wrangler whoami",
15
- "auth_login": "npx wrangler auth login",
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",
@@ -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 auth login', 'Or set CLOUDFLARE_API_TOKEN environment variable']
490
+ suggestions: ['Run: wrangler login', 'Or set CLOUDFLARE_API_TOKEN environment variable']
491
491
  };
492
492
  }
493
493
 
package/dist/index.js CHANGED
@@ -37,6 +37,15 @@ export { ServiceCreator } from './service-management/ServiceCreator.js';
37
37
  export { ServiceOrchestrator } from './service-management/ServiceOrchestrator.js';
38
38
  export { InputCollector } from './service-management/InputCollector.js';
39
39
 
40
+ // CLI utilities (for framework CLI commands)
41
+ export { StandardOptions } from '../lib/shared/utils/cli-options.js';
42
+ export { ConfigLoader } from '../lib/shared/utils/config-loader.js';
43
+ export { ServiceConfigManager } from '../lib/shared/utils/service-config-manager.js';
44
+ export { InteractiveDeploymentCoordinator } from '../lib/shared/deployment/workflows/interactive-deployment-coordinator.js';
45
+ export { OutputFormatter } from '../lib/shared/utils/output-formatter.js';
46
+ export { verifyWorkerDeployment, healthCheckWithBackoff, checkHealth } from '../lib/shared/monitoring/health-checker.js';
47
+ export { classifyError, getRecoverySuggestions } from '../lib/shared/error-handling/error-classifier.js';
48
+
40
49
  // Framework version info
41
50
  export const FRAMEWORK_VERSION = '1.0.0';
42
51
  export const FRAMEWORK_NAME = 'Clodo Framework';
@@ -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, CrossDomainCoordinator } from '../../shared/deployment/index.js';
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
- this.coordinator = new CrossDomainCoordinator({
47
- portfolioName: this.config.portfolioName || 'interactive-portfolio',
48
- enableContinuousMonitoring: true,
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 auth login for initial authentication
124
- await execAsync('npx wrangler auth login', {
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 auth login',
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 { InteractiveValidation } from './interactive-validation.js';
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 InteractiveValidation({
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 InteractiveValidation {
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 auth login');
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 auth login');
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 auth login');
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 auth login', 'Check API token permissions include D1 access', 'Verify correct Cloudflare account is selected'];
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 auth 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'],
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 auth login');
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 || 'worker'; // Service name for custom domain
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 '../../lib/shared/deployment/credential-collector.js';
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
- // Handle test environment where import.meta might be transformed
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 test environment
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
- const possiblePaths = ['./validation-config.json', '../validation-config.json', '../../validation-config.json', join(process.cwd(), 'validation-config.json'), join(__dirname, '..', '..', 'validation-config.json')];
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
- // Note: This is expected behavior - services don't need their own config
59
+ // This is expected behavior - services don't need their own config
49
60
  return null;
50
61
  }
51
62
 
@@ -29,6 +29,9 @@ export const createLogger = (prefix = 'ClodoFramework') => {
29
29
  };
30
30
  };
31
31
 
32
+ // Validation utilities
33
+ export * from './validation.js';
34
+
32
35
  // Health checking utilities
33
36
  export * from './health-checker.js';
34
37
 
@@ -1,13 +1,13 @@
1
1
  import { getDomainFromEnv, createEnvironmentConfig } from '../config/domains.js';
2
2
 
3
- // Export COMMON_FEATURES constant (simplified from ConfigurationManager)
4
- export const COMMON_FEATURES = ['authentication', 'logging', 'caching', 'rate-limiting', 'monitoring'];
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: featureManager.getEnabledFeatures(),
53
+ features: Object.keys(domainConfig.features || {}).filter(feature => domainConfig.features[feature] === true),
54
54
  config: envConfig,
55
55
  env,
56
56
  isProduction: environment === 'production',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamyla/clodo-framework",
3
- "version": "3.2.2",
3
+ "version": "3.2.4",
4
4
  "description": "Reusable framework for Clodo-style software architecture on Cloudflare Workers + D1",
5
5
  "type": "module",
6
6
  "sideEffects": [