@tamyla/clodo-framework 3.0.2 → 3.0.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,17 @@
1
+ ## [3.0.4](https://github.com/tamylaa/clodo-framework/compare/v3.0.3...v3.0.4) (2025-10-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * resolve deployment configuration and database binding issues ([f9d7036](https://github.com/tamylaa/clodo-framework/commit/f9d7036e18b49ba9082cad8f8e181f5abc1c2c2d))
7
+
8
+ ## [3.0.3](https://github.com/tamylaa/clodo-framework/compare/v3.0.2...v3.0.3) (2025-10-14)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * resolve database creation redundancy in deployments ([4a54f2c](https://github.com/tamylaa/clodo-framework/commit/4a54f2ce4bd1bb17d49c4d911171a01179fbd519))
14
+
1
15
  ## [3.0.2](https://github.com/tamylaa/clodo-framework/compare/v3.0.1...v3.0.2) (2025-10-14)
2
16
 
3
17
 
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * Clodo Framework - Unified Three-Tier Service Management CLI
@@ -436,7 +436,9 @@ program
436
436
  console.log(chalk.white('Using Three-Tier Input Architecture\n'));
437
437
 
438
438
  const isInteractive = options.interactive && !options.nonInteractive;
439
- const configManager = new UnifiedConfigManager();
439
+ const configManager = new UnifiedConfigManager({
440
+ configDir: join(process.cwd(), 'config', 'customers')
441
+ });
440
442
  const inputCollector = new InputCollector({ interactive: isInteractive });
441
443
  const confirmationHandler = new ConfirmationHandler({ interactive: isInteractive });
442
444
 
@@ -398,7 +398,7 @@ export class DatabaseOrchestrator {
398
398
  // Use BINDING name (not database name) for wrangler command
399
399
  const command = this.buildMigrationCommand(bindingName, environment, isRemote);
400
400
  console.log(` 📋 Migration command: ${command}`);
401
- const output = await this.executeWithRetry(command, 120000); // 2 minute timeout
401
+ const output = await this.executeWithRetry(command, 120000, this.projectRoot); // 2 minute timeout
402
402
 
403
403
  // Parse migration output
404
404
  const migrationsApplied = this.parseMigrationOutput(output);
@@ -504,7 +504,7 @@ export class DatabaseOrchestrator {
504
504
  try {
505
505
  const isRemote = this.environments[environment].isRemote;
506
506
  const command = this.buildBackupCommand(databaseName, environment, backupFile, isRemote);
507
- await this.executeWithRetry(command, 300000); // 5 minute timeout for backups
507
+ await this.executeWithRetry(command, 300000, this.projectRoot); // 5 minute timeout for backups
508
508
 
509
509
  if (existsSync(backupFile)) {
510
510
  const stats = await stat(backupFile);
@@ -629,7 +629,7 @@ export class DatabaseOrchestrator {
629
629
  try {
630
630
  for (const command of commands) {
631
631
  const fullCommand = this.buildDatabaseCommand(command, databaseName, environment);
632
- await this.executeWithRetry(fullCommand, 60000);
632
+ await this.executeWithRetry(fullCommand, 60000, this.projectRoot);
633
633
  executedCommands++;
634
634
  }
635
635
  console.log(` ✅ Cleanup completed: ${executedCommands} operations`);
@@ -683,10 +683,11 @@ export class DatabaseOrchestrator {
683
683
  const matches = output.match(/Applied (\d+) migration/);
684
684
  return matches ? parseInt(matches[1]) : 0;
685
685
  }
686
- async executeWithRetry(command, timeout = null) {
686
+ async executeWithRetry(command, timeout = null, workingDir = null) {
687
687
  const actualTimeout = timeout || (this.config ? this.config.executionTimeout : 30000);
688
688
  const maxAttempts = this.config ? this.config.retryAttempts : 3;
689
689
  const retryDelay = this.config ? this.config.retryDelay : 1000;
690
+ const cwd = workingDir || this.projectRoot;
690
691
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
691
692
  try {
692
693
  const {
@@ -694,7 +695,8 @@ export class DatabaseOrchestrator {
694
695
  } = await execAsync(command, {
695
696
  encoding: 'utf8',
696
697
  timeout: actualTimeout,
697
- stdio: 'pipe'
698
+ stdio: 'pipe',
699
+ cwd: cwd
698
700
  });
699
701
  return stdout;
700
702
  } catch (error) {
@@ -17,7 +17,7 @@ import { ConfigurationValidator } from '../security/ConfigurationValidator.js';
17
17
  import { exec } from 'child_process';
18
18
  import { promisify } from 'util';
19
19
  import { join } from 'path';
20
- import { createDatabase } from '../utils/cloudflare/index.js';
20
+ import { createDatabase, databaseExists, getDatabaseId } from '../utils/cloudflare/index.js';
21
21
  const execAsync = promisify(exec);
22
22
 
23
23
  /**
@@ -267,10 +267,23 @@ export class MultiDomainOrchestrator {
267
267
  try {
268
268
  // Create D1 database using Cloudflare ops
269
269
  const databaseName = `${domain.replace(/\./g, '-')}-${this.environment}-db`;
270
- console.log(` 📦 Creating database: ${databaseName}`);
271
- const databaseId = await createDatabase(databaseName);
272
- console.log(` Database created: ${databaseName}`);
273
- console.log(` 📊 Database ID: ${databaseId}`);
270
+
271
+ // Check if database already exists
272
+ console.log(` Checking if database exists: ${databaseName}`);
273
+ const exists = await databaseExists(databaseName);
274
+ let databaseId;
275
+ let created = false;
276
+ if (exists) {
277
+ console.log(` ✅ Database already exists: ${databaseName}`);
278
+ databaseId = await getDatabaseId(databaseName);
279
+ console.log(` 📊 Existing Database ID: ${databaseId}`);
280
+ } else {
281
+ console.log(` 📦 Creating database: ${databaseName}`);
282
+ databaseId = await createDatabase(databaseName);
283
+ console.log(` ✅ Database created: ${databaseName}`);
284
+ console.log(` 📊 Database ID: ${databaseId}`);
285
+ created = true;
286
+ }
274
287
 
275
288
  // Store database info in domain state
276
289
  const domainState = this.portfolioState.domainStates.get(domain);
@@ -313,17 +326,18 @@ export class MultiDomainOrchestrator {
313
326
  }
314
327
 
315
328
  // Log comprehensive audit event
316
- this.stateManager.logAuditEvent('DATABASE_CREATED', domain, {
329
+ this.stateManager.logAuditEvent(created ? 'DATABASE_CREATED' : 'DATABASE_FOUND', domain, {
317
330
  databaseName,
318
331
  databaseId,
319
332
  environment: this.environment,
320
333
  migrationsApplied: true,
321
- isRemote: this.environment !== 'development'
334
+ isRemote: this.environment !== 'development',
335
+ created
322
336
  });
323
337
  return {
324
338
  databaseName,
325
339
  databaseId,
326
- created: true,
340
+ created,
327
341
  migrationsApplied: true
328
342
  };
329
343
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamyla/clodo-framework",
3
- "version": "3.0.2",
3
+ "version": "3.0.4",
4
4
  "description": "Reusable framework for Clodo-style software architecture on Cloudflare Workers + D1",
5
5
  "type": "module",
6
6
  "sideEffects": [