@tamyla/clodo-framework 4.0.12 → 4.0.14

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +708 -426
  2. package/README.md +7 -0
  3. package/dist/cli/commands/create.js +2 -1
  4. package/dist/deployment/wrangler-deployer.js +1 -1
  5. package/dist/middleware/Composer.js +38 -0
  6. package/dist/middleware/Registry.js +14 -0
  7. package/dist/middleware/index.js +3 -0
  8. package/dist/middleware/shared/basicAuth.js +21 -0
  9. package/dist/middleware/shared/cors.js +28 -0
  10. package/dist/middleware/shared/index.js +3 -0
  11. package/dist/middleware/shared/logging.js +14 -0
  12. package/dist/service-management/GenerationEngine.js +13 -2
  13. package/dist/service-management/ServiceOrchestrator.js +6 -2
  14. package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +156 -10
  15. package/dist/service-management/generators/code/WorkerIndexGenerator.js +75 -9
  16. package/dist/service-management/generators/config/WranglerTomlGenerator.js +1 -1
  17. package/dist/simple-api.js +32 -1
  18. package/docs/MIDDLEWARE_MIGRATION_SUMMARY.md +121 -0
  19. package/package.json +7 -2
  20. package/scripts/DEPLOY_COMMAND_NEW.js +128 -0
  21. package/scripts/README-automated-testing-suite.md +356 -0
  22. package/scripts/README-test-clodo-deployment.md +157 -0
  23. package/scripts/README.md +50 -0
  24. package/scripts/analyze-imports.ps1 +104 -0
  25. package/scripts/analyze-mixed-code.js +163 -0
  26. package/scripts/analyze-mixed-rationale.js +149 -0
  27. package/scripts/automated-testing-suite.js +776 -0
  28. package/scripts/deployment/README.md +31 -0
  29. package/scripts/deployment/deploy-domain.ps1 +449 -0
  30. package/scripts/deployment/deploy-staging.js +120 -0
  31. package/scripts/deployment/validate-staging.js +166 -0
  32. package/scripts/diagnose-imports.js +362 -0
  33. package/scripts/framework-diagnostic.js +368 -0
  34. package/scripts/migration/migrate-middleware-legacy-to-contract.js +47 -0
  35. package/scripts/post-publish-test.js +663 -0
  36. package/scripts/scan-worker-issues.js +52 -0
  37. package/scripts/service-management/README.md +27 -0
  38. package/scripts/service-management/setup-interactive.ps1 +693 -0
  39. package/scripts/test-clodo-deployment.js +588 -0
  40. package/scripts/test-downstream-install.js +237 -0
  41. package/scripts/test-local-package.ps1 +126 -0
  42. package/scripts/test-local-package.sh +166 -0
  43. package/scripts/test-package.js +339 -0
  44. package/scripts/testing/README.md +49 -0
  45. package/scripts/testing/test-first.ps1 +0 -0
  46. package/scripts/testing/test-first50.ps1 +0 -0
  47. package/scripts/testing/test.ps1 +0 -0
  48. package/scripts/utilities/README.md +61 -0
  49. package/scripts/utilities/check-bin.js +8 -0
  50. package/scripts/utilities/check-bundle.js +23 -0
  51. package/scripts/utilities/check-dist-imports.js +65 -0
  52. package/scripts/utilities/check-import-paths.js +191 -0
  53. package/scripts/utilities/cleanup-cli.js +159 -0
  54. package/scripts/utilities/deployment-helpers.ps1 +199 -0
  55. package/scripts/utilities/fix-dist-imports.js +135 -0
  56. package/scripts/utilities/generate-secrets.js +159 -0
  57. package/scripts/utilities/safe-push.ps1 +51 -0
  58. package/scripts/utilities/setup-helpers.ps1 +206 -0
  59. package/scripts/utilities/test-packaged-artifact.js +92 -0
  60. package/scripts/utilities/validate-dist-imports.js +189 -0
  61. package/scripts/utilities/validate-schema.js +102 -0
  62. package/scripts/verify-exports.js +193 -0
  63. package/scripts/verify-worker-safety.js +73 -0
  64. package/types/middleware.d.ts +1 -0
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Check Import Paths Validator
5
+ *
6
+ * Validates that all re-export wrappers AND dynamic imports have correct paths that work
7
+ * when compiled to dist/. This prevents module resolution errors in published packages.
8
+ *
9
+ * Purpose: Catch path issues BEFORE publication to npm
10
+ *
11
+ * Checks:
12
+ * 1. Static imports in re-export wrappers (src/utils/)
13
+ * 2. Dynamic imports in bin/ files (must NOT reference dist/)
14
+ * 3. Compiled dist/ structure integrity
15
+ */
16
+
17
+ import fs from 'fs';
18
+ import path from 'path';
19
+ import { fileURLToPath } from 'url';
20
+
21
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
+ const projectRoot = path.join(__dirname, '../../');
23
+
24
+ const RULES = {
25
+ // Re-export wrappers in src/utils/ compile to dist/utils/ and need paths that work in npm packages
26
+ // When installed via npm, only dist/ exists at package root level
27
+ // So paths must resolve correctly: dist/utils/X.js -> ../lib/ (one level up to dist, then lib)
28
+
29
+ // Files at src/utils/X.js compile to dist/utils/X.js (2 levels deep) use '../lib/...'
30
+ 'src/utils/file-manager.js': {
31
+ pattern: /from\s+['"]([^'"]+)['"]/,
32
+ shouldContain: '../lib/shared/utils/file-manager.js',
33
+ description: 'file-manager re-export wrapper (compiles with depth adjustment for npm)'
34
+ },
35
+ 'src/utils/formatters.js': {
36
+ pattern: /from\s+['"]([^'"]+)['"]/,
37
+ shouldContain: '../lib/shared/utils/formatters.js',
38
+ description: 'formatters re-export wrapper (compiles with depth adjustment for npm)'
39
+ },
40
+ 'src/utils/logger.js': {
41
+ pattern: /from\s+['"]([^'"]+)['"]/,
42
+ shouldContain: '../lib/shared/logging/Logger.js',
43
+ description: 'logger re-export wrapper (compiles with depth adjustment for npm)'
44
+ },
45
+
46
+ // Files at src/utils/cloudflare/X.js compile to dist/utils/cloudflare/X.js (3 levels deep) use '../../lib/...'
47
+ 'src/utils/cloudflare/ops.js': {
48
+ pattern: /from\s+['"]([^'"]+)['"]/,
49
+ shouldContain: '../../lib/shared/cloudflare/ops.js',
50
+ description: 'cloudflare ops re-export wrapper (3 levels, compiles with depth adjustment)'
51
+ }
52
+ };
53
+
54
+ // Check for problematic dynamic imports that reference dist/ from bin/
55
+ const DYNAMIC_IMPORT_CHECKS = {
56
+ 'lib/shared/cloudflare/ops.js': {
57
+ pattern: /import\(['"]([^'"]*dist[^'"]*)['"]\)/g,
58
+ shouldNotContain: 'dist/',
59
+ description: 'Dynamic imports in lib/ must not reference dist/ (causes dist/dist/ bug)'
60
+ }
61
+ };
62
+
63
+ let passCount = 0;
64
+ let failCount = 0;
65
+ const failures = [];
66
+
67
+ console.log('\n🔍 Checking import paths in re-export wrappers...\n');
68
+
69
+ for (const [filePath, rule] of Object.entries(RULES)) {
70
+ const fullPath = path.join(projectRoot, filePath);
71
+
72
+ if (!fs.existsSync(fullPath)) {
73
+ console.log(`❌ MISSING: ${filePath}`);
74
+ failCount++;
75
+ failures.push(`File not found: ${filePath}`);
76
+ continue;
77
+ }
78
+
79
+ const content = fs.readFileSync(fullPath, 'utf8');
80
+ const match = content.match(rule.pattern);
81
+
82
+ if (!match || match[1] !== rule.shouldContain) {
83
+ const actual = match ? match[1] : 'NOT FOUND';
84
+ console.log(`❌ INCORRECT PATH: ${filePath}`);
85
+ console.log(` Expected: ${rule.shouldContain}`);
86
+ console.log(` Actual: ${actual}`);
87
+ console.log(` (${rule.description})\n`);
88
+ failCount++;
89
+ failures.push(`${filePath}: expected "${rule.shouldContain}", got "${actual}"`);
90
+ } else {
91
+ console.log(`✅ CORRECT: ${filePath}`);
92
+ console.log(` → ${rule.shouldContain}\n`);
93
+ passCount++;
94
+ }
95
+ }
96
+
97
+ // Check for problematic dynamic imports
98
+ console.log('\n🔍 Checking dynamic imports in bin/ files...\n');
99
+
100
+ for (const [filePath, rule] of Object.entries(DYNAMIC_IMPORT_CHECKS)) {
101
+ const fullPath = path.join(projectRoot, filePath);
102
+
103
+ if (!fs.existsSync(fullPath)) {
104
+ console.log(`⚠️ SKIPPED: ${filePath} (file not found)`);
105
+ continue;
106
+ }
107
+
108
+ const content = fs.readFileSync(fullPath, 'utf8');
109
+ const matches = [...content.matchAll(rule.pattern)];
110
+
111
+ if (matches.length > 0) {
112
+ console.log(`❌ PROBLEMATIC IMPORTS: ${filePath}`);
113
+ matches.forEach(match => {
114
+ console.log(` → ${match[1]}`);
115
+ });
116
+ console.log(` Issue: ${rule.description}\n`);
117
+ failCount += matches.length;
118
+ failures.push(`${filePath}: contains ${matches.length} dynamic import(s) referencing dist/`);
119
+ } else {
120
+ console.log(`✅ NO DIST/ IMPORTS: ${filePath}\n`);
121
+ passCount++;
122
+ }
123
+ }
124
+
125
+ // Check compiled dist paths
126
+ console.log('\n📦 Verifying compiled dist/ structure...\n');
127
+
128
+ const distFiles = [
129
+ 'dist/utils/file-manager.js',
130
+ 'dist/utils/formatters.js',
131
+ 'dist/utils/logger.js',
132
+ 'dist/utils/cloudflare/ops.js'
133
+ ];
134
+
135
+ for (const file of distFiles) {
136
+ const fullPath = path.join(projectRoot, file);
137
+
138
+ if (!fs.existsSync(fullPath)) {
139
+ console.log(`❌ MISSING: ${file}`);
140
+ failCount++;
141
+ failures.push(`Compiled file not found: ${file}`);
142
+ } else {
143
+ console.log(`✅ EXISTS: ${file}`);
144
+ passCount++;
145
+ }
146
+ }
147
+
148
+ // Check dist/cli/ and dist/lib/ exist
149
+ console.log('\n📂 Verifying cli/ and lib/ were compiled to dist/...\n');
150
+
151
+ const cliPath = path.join(projectRoot, 'dist/cli');
152
+ const libPath = path.join(projectRoot, 'dist/lib');
153
+
154
+ if (!fs.existsSync(cliPath)) {
155
+ console.log(`❌ MISSING: dist/cli/ directory`);
156
+ failCount++;
157
+ failures.push('dist/cli/ directory not found - cli/ not compiled');
158
+ } else {
159
+ console.log(`✅ EXISTS: dist/cli/ directory`);
160
+ passCount++;
161
+ }
162
+
163
+ if (!fs.existsSync(libPath)) {
164
+ console.log(`❌ MISSING: dist/lib/ directory`);
165
+ failCount++;
166
+ failures.push('dist/lib/ directory not found - lib/ not compiled');
167
+ } else {
168
+ console.log(`✅ EXISTS: dist/lib/ directory\n`);
169
+ passCount++;
170
+ }
171
+
172
+ // Summary
173
+ console.log(`\n${'='.repeat(60)}`);
174
+ console.log(`Validation Results: ${passCount} passed, ${failCount} failed`);
175
+ console.log(`${'='.repeat(60)}\n`);
176
+
177
+ if (failCount > 0) {
178
+ console.log('❌ PATH VALIDATION FAILED\n');
179
+ console.log('Issues found:');
180
+ failures.forEach(f => console.log(` • ${f}`));
181
+ console.log('\nRecommendations:');
182
+ console.log('1. Ensure all src/utils/*.js re-export wrappers use "../../bin/shared/..." paths');
183
+ console.log('2. These paths must work AFTER Babel compilation to dist/');
184
+ console.log('3. Run: npm run build && npm run check:imports\n');
185
+ process.exit(1);
186
+ } else {
187
+ console.log('✅ ALL PATHS VALID\n');
188
+ console.log('The re-export wrappers are correctly configured for the npm package.');
189
+ console.log('Users should not encounter ERR_MODULE_NOT_FOUND errors.\n');
190
+ process.exit(0);
191
+ }
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Data Cleanup CLI Tool
5
+ * Provides command-line access to data cleanup operations
6
+ */
7
+
8
+ import { initD1Client } from '../../src/shared/clients/d1/index.js';
9
+ import { readFileSync, writeFileSync } from 'fs';
10
+ import { join } from 'path';
11
+
12
+ // Load environment variables
13
+ const env = {
14
+ NODE_ENV: process.env.NODE_ENV || 'development',
15
+ ...process.env
16
+ };
17
+
18
+ // Initialize D1 client
19
+ let d1Client;
20
+ try {
21
+ // For local development, we need to handle the database binding
22
+ if (env.NODE_ENV === 'development') {
23
+ // Create a mock database binding for development
24
+ env.DB = {}; // This will trigger in-memory database creation
25
+ }
26
+
27
+ d1Client = await initD1Client(env);
28
+
29
+ // Wait for the client to be fully initialized
30
+ await new Promise((resolve) => {
31
+ const checkInit = () => {
32
+ if (d1Client._isInitialized || d1Client.db) {
33
+ resolve();
34
+ } else {
35
+ setTimeout(checkInit, 10);
36
+ }
37
+ };
38
+ checkInit();
39
+ });
40
+
41
+ } catch (error) {
42
+ console.error('Failed to initialize D1 client:', error.message);
43
+ process.exit(1);
44
+ }
45
+
46
+ const command = process.argv[2];
47
+ const args = process.argv.slice(3);
48
+
49
+ async function main() {
50
+ try {
51
+ switch (command) {
52
+ case 'stats': {
53
+ console.log('📊 Getting database statistics...');
54
+ const stats = await d1Client.getDatabaseStats();
55
+ console.log(JSON.stringify(stats, null, 2));
56
+ break;
57
+ }
58
+
59
+ case 'backup': {
60
+ console.log('💾 Creating database backup...');
61
+ const backup = await d1Client.createBackup({ reason: args[0] || 'CLI backup' });
62
+
63
+ const filename = `backup_${backup.id}.sql`;
64
+ writeFileSync(filename, backup.content);
65
+ console.log(`✅ Backup saved to: ${filename}`);
66
+ console.log(`📊 Records backed up: ${backup.totalRecords}`);
67
+ break;
68
+ }
69
+
70
+ case 'clear-old': {
71
+ const days = parseInt(args[0]);
72
+ if (!days || days < 1) {
73
+ console.error('❌ Please specify number of days (e.g., clear-old 90)');
74
+ process.exit(1);
75
+ }
76
+
77
+ console.log(`🗑️ Clearing data older than ${days} days...`);
78
+ const oldResult = await d1Client.safeCleanup('CLEAR_OLD', { daysOld: days });
79
+ console.log('✅ Old data cleared:', JSON.stringify(oldResult, null, 2));
80
+ break;
81
+ }
82
+
83
+ case 'clear-user': {
84
+ const userId = args[0];
85
+ if (!userId) {
86
+ console.error('❌ Please specify user ID (e.g., clear-user user123)');
87
+ process.exit(1);
88
+ }
89
+
90
+ console.log(`🗑️ Clearing data for user: ${userId}`);
91
+ const userResult = await d1Client.safeCleanup('CLEAR_USER', { userId });
92
+ console.log('✅ User data cleared:', JSON.stringify(userResult, null, 2));
93
+ break;
94
+ }
95
+
96
+ case 'clear-all': {
97
+ if (env.NODE_ENV === 'production') {
98
+ console.error('❌ CLEAR ALL operation blocked in production environment');
99
+ console.log('💡 Use selective cleanup operations instead');
100
+ process.exit(1);
101
+ }
102
+
103
+ console.log('🗑️ Clearing ALL data (this will delete everything!)...');
104
+ const confirm = args.includes('--confirm');
105
+ if (!confirm) {
106
+ console.log('⚠️ This operation will delete ALL data permanently');
107
+ console.log('💡 Add --confirm flag to proceed');
108
+ process.exit(1);
109
+ }
110
+
111
+ const allResult = await d1Client.safeCleanup('CLEAR_ALL');
112
+ console.log('✅ All data cleared:', JSON.stringify(allResult, null, 2));
113
+ break;
114
+ }
115
+
116
+ case 'validate': {
117
+ const operation = args[0];
118
+ const params = {};
119
+
120
+ if (operation === 'CLEAR_OLD') params.daysOld = parseInt(args[1]);
121
+ if (operation === 'CLEAR_USER') params.userId = args[1];
122
+
123
+ console.log(`🔍 Validating operation: ${operation}`);
124
+ const validation = await d1Client.validateCleanupOperation(operation, params);
125
+ console.log(JSON.stringify(validation, null, 2));
126
+ break;
127
+ }
128
+
129
+ default:
130
+ console.log('🧹 Data Cleanup CLI Tool');
131
+ console.log('');
132
+ console.log('Usage: node scripts/cleanup-cli.js <command> [args...]');
133
+ console.log('');
134
+ console.log('Commands:');
135
+ console.log(' stats Show database statistics');
136
+ console.log(' backup [reason] Create database backup');
137
+ console.log(' clear-old <days> Clear data older than X days');
138
+ console.log(' clear-user <userId> Clear all data for a user');
139
+ console.log(' clear-all --confirm Clear ALL data (dangerous!)');
140
+ console.log(' validate <op> [params] Validate if operation is safe');
141
+ console.log('');
142
+ console.log('Examples:');
143
+ console.log(' node scripts/cleanup-cli.js stats');
144
+ console.log(' node scripts/cleanup-cli.js backup "Pre-deployment backup"');
145
+ console.log(' node scripts/cleanup-cli.js clear-old 90');
146
+ console.log(' node scripts/cleanup-cli.js clear-user user123');
147
+ console.log(' node scripts/cleanup-cli.js validate CLEAR_OLD 90');
148
+ break;
149
+ }
150
+ } catch (error) {
151
+ console.error('❌ Error:', error.message);
152
+ process.exit(1);
153
+ }
154
+ }
155
+
156
+ main().catch(error => {
157
+ console.error('❌ Unexpected error:', error);
158
+ process.exit(1);
159
+ });
@@ -0,0 +1,199 @@
1
+ # PowerShell Deployment Helper Functions
2
+ # Common utilities for Clodo Framework deployment scripts
3
+
4
+ function Write-DeploymentLog {
5
+ param(
6
+ [Parameter(Mandatory=$true)]
7
+ [string]$Message,
8
+
9
+ [Parameter(Mandatory=$false)]
10
+ [ValidateSet("Info", "Warning", "Error", "Success")]
11
+ [string]$Level = "Info"
12
+ )
13
+
14
+ $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
15
+ $color = switch ($Level) {
16
+ "Info" { "White" }
17
+ "Warning" { "Yellow" }
18
+ "Error" { "Red" }
19
+ "Success" { "Green" }
20
+ default { "White" }
21
+ }
22
+
23
+ Write-Host "[$timestamp] $Level`: $Message" -ForegroundColor $color
24
+ }
25
+
26
+ function Test-Prerequisites {
27
+ param(
28
+ [Parameter(Mandatory=$false)]
29
+ [string[]]$RequiredCommands = @("node", "npm", "wrangler")
30
+ )
31
+
32
+ Write-DeploymentLog "Checking prerequisites..." "Info"
33
+
34
+ $allPresent = $true
35
+ foreach ($cmd in $RequiredCommands) {
36
+ try {
37
+ $null = Get-Command $cmd -ErrorAction Stop
38
+ Write-DeploymentLog "✓ $cmd is available" "Success"
39
+ }
40
+ catch {
41
+ Write-DeploymentLog "✗ $cmd is not available" "Error"
42
+ $allPresent = $false
43
+ }
44
+ }
45
+
46
+ return $allPresent
47
+ }
48
+
49
+ function Test-EnvironmentVariables {
50
+ param(
51
+ [Parameter(Mandatory=$true)]
52
+ [string[]]$RequiredVars
53
+ )
54
+
55
+ Write-DeploymentLog "Checking environment variables..." "Info"
56
+
57
+ $allPresent = $true
58
+ foreach ($var in $RequiredVars) {
59
+ $value = [System.Environment]::GetEnvironmentVariable($var)
60
+ if ([string]::IsNullOrEmpty($value)) {
61
+ Write-DeploymentLog "✗ Environment variable $var is not set" "Error"
62
+ $allPresent = $false
63
+ } else {
64
+ Write-DeploymentLog "✓ $var is set" "Success"
65
+ }
66
+ }
67
+
68
+ return $allPresent
69
+ }
70
+
71
+ function Invoke-SafeCommand {
72
+ param(
73
+ [Parameter(Mandatory=$true)]
74
+ [string]$Command,
75
+
76
+ [Parameter(Mandatory=$false)]
77
+ [string]$WorkingDirectory = $PWD,
78
+
79
+ [Parameter(Mandatory=$false)]
80
+ [switch]$DryRun
81
+ )
82
+
83
+ if ($DryRun) {
84
+ Write-DeploymentLog "[DRY RUN] Would execute: $Command" "Warning"
85
+ return @{
86
+ Success = $true
87
+ Output = "[DRY RUN] Command not executed"
88
+ }
89
+ }
90
+
91
+ try {
92
+ Write-DeploymentLog "Executing: $Command" "Info"
93
+ $output = Invoke-Expression $Command -ErrorAction Stop
94
+ Write-DeploymentLog "Command completed successfully" "Success"
95
+
96
+ return @{
97
+ Success = $true
98
+ Output = $output
99
+ }
100
+ }
101
+ catch {
102
+ Write-DeploymentLog "Command failed: $($_.Exception.Message)" "Error"
103
+
104
+ return @{
105
+ Success = $false
106
+ Error = $_.Exception.Message
107
+ }
108
+ }
109
+ }
110
+
111
+ function Test-FileExists {
112
+ param(
113
+ [Parameter(Mandatory=$true)]
114
+ [string]$FilePath,
115
+
116
+ [Parameter(Mandatory=$false)]
117
+ [string]$Description = "file"
118
+ )
119
+
120
+ if (Test-Path $FilePath) {
121
+ Write-DeploymentLog "✓ $Description exists: $FilePath" "Success"
122
+ return $true
123
+ } else {
124
+ Write-DeploymentLog "✗ $Description not found: $FilePath" "Error"
125
+ return $false
126
+ }
127
+ }
128
+
129
+ function Get-ServiceConfiguration {
130
+ param(
131
+ [Parameter(Mandatory=$true)]
132
+ [string]$ConfigPath
133
+ )
134
+
135
+ Write-DeploymentLog "Loading service configuration from: $ConfigPath" "Info"
136
+
137
+ try {
138
+ if (Test-Path $ConfigPath) {
139
+ $content = Get-Content $ConfigPath -Raw
140
+ Write-DeploymentLog "Configuration loaded successfully" "Success"
141
+ return $content
142
+ } else {
143
+ throw "Configuration file not found: $ConfigPath"
144
+ }
145
+ }
146
+ catch {
147
+ Write-DeploymentLog "Failed to load configuration: $($_.Exception.Message)" "Error"
148
+ throw
149
+ }
150
+ }
151
+
152
+ function Start-DeploymentProcess {
153
+ param(
154
+ [Parameter(Mandatory=$true)]
155
+ [string]$ServiceName,
156
+
157
+ [Parameter(Mandatory=$true)]
158
+ [string]$Environment,
159
+
160
+ [Parameter(Mandatory=$false)]
161
+ [switch]$DryRun
162
+ )
163
+
164
+ $startTime = Get-Date
165
+ Write-DeploymentLog "Starting deployment for $ServiceName ($Environment)" "Info"
166
+ Write-DeploymentLog "Deployment started at: $startTime" "Info"
167
+
168
+ return @{
169
+ ServiceName = $ServiceName
170
+ Environment = $Environment
171
+ StartTime = $startTime
172
+ DryRun = $DryRun.IsPresent
173
+ }
174
+ }
175
+
176
+ function Complete-DeploymentProcess {
177
+ param(
178
+ [Parameter(Mandatory=$true)]
179
+ [hashtable]$DeploymentInfo,
180
+
181
+ [Parameter(Mandatory=$true)]
182
+ [bool]$Success
183
+ )
184
+
185
+ $endTime = Get-Date
186
+ $duration = $endTime - $DeploymentInfo.StartTime
187
+
188
+ if ($Success) {
189
+ Write-DeploymentLog "✅ Deployment completed successfully" "Success"
190
+ } else {
191
+ Write-DeploymentLog "❌ Deployment failed" "Error"
192
+ }
193
+
194
+ Write-DeploymentLog "Deployment duration: $($duration.ToString('hh\:mm\:ss'))" "Info"
195
+ Write-DeploymentLog "Deployment ended at: $endTime" "Info"
196
+ }
197
+
198
+ # Export functions for use by other scripts
199
+ Export-ModuleMember -Function *
@@ -0,0 +1,135 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const projectRoot = path.join(__dirname, '../..');
7
+
8
+ /**
9
+ * Minimal import path fix for dist/ after Babel compilation
10
+ *
11
+ * NOTE: This script should do MINIMAL changes. Babel preserves relative imports
12
+ * from source files, so most imports are already correct.
13
+ *
14
+ * Fix:
15
+ * 1. CLI commands that reference ../lib/ instead of ../../lib/ (depth mismatch)
16
+ * 2. CLI commands that reference ../config/ instead of ../../config/
17
+ * 3. CLI commands that reference ../service-management/ instead of ../../service-management/
18
+ * 4. Files importing ../../../dist/utils/ should be ../../../utils/
19
+ * 5. Files in dist/utils/ importing ../../../lib/shared/ should be ../../lib/shared/
20
+ * 6. Files in dist/lib/shared/ importing ../../../src/utils/ should be ../../utils/
21
+ *
22
+ * DO NOT apply aggressive global replacements - they break things!
23
+ */
24
+ function fixDistImports(dir) {
25
+ const fullDir = path.join(projectRoot, dir);
26
+ if (!fs.existsSync(fullDir)) return;
27
+
28
+ const files = fs.readdirSync(fullDir, { recursive: true });
29
+ files.forEach(file => {
30
+ const filePath = path.join(fullDir, file);
31
+ if (fs.statSync(filePath).isFile() && filePath.endsWith('.js')) {
32
+ let content = fs.readFileSync(filePath, 'utf8');
33
+ const original = content;
34
+ const relPath = path.relative(projectRoot, filePath);
35
+
36
+ // Only fix CLI command imports
37
+ // Files in dist/cli/commands/ are 2 levels deep and need ../../ to reach dist root
38
+ if (relPath.startsWith('dist/cli/commands/')) {
39
+ // Fix imports that incorrectly have ../lib/ instead of ../../lib/
40
+ content = content.replace(/from\s+['"]\.\.\/lib\//g, "from '../../lib/");
41
+ // Fix imports that incorrectly have ../config/ instead of ../../config/
42
+ content = content.replace(/from\s+['"]\.\.\/config\//g, "from '../../config/");
43
+ // Fix imports that incorrectly have ../service-management/ instead of ../../service-management/
44
+ content = content.replace(/from\s+['"]\.\.\/service-management\//g, "from '../../service-management/");
45
+
46
+ // Also fix dynamic imports with import()
47
+ content = content.replace(/import\(['"]\.\.\/lib\//g, "import('../../lib/");
48
+ content = content.replace(/import\(['"]\.\.\/config\//g, "import('../../config/");
49
+ content = content.replace(/import\(['"]\.\.\/service-management\//g, "import('../../service-management/");
50
+ }
51
+
52
+ // Fix imports in all dist/ files
53
+ if (relPath.startsWith('dist')) {
54
+ // Fix ../../../src/utils/ to ../../utils/ for files in dist/lib/shared/
55
+ if (relPath.includes('dist/lib/shared/') || relPath.includes('dist\\lib\\shared\\')) {
56
+ content = content.replace(/\.\.\/\.\.\/\.\.\/src\/utils\//g, "../../utils/");
57
+ }
58
+
59
+ const normalizedRelPath = relPath.replace(/\\/g, '/');
60
+ const pathDepth = normalizedRelPath.split('/').length;
61
+
62
+ // Fix ../../lib/shared/ to ../lib/shared/ for files at depth 2: dist/<dir>/<file>.js
63
+ // Example: dist/database/database-orchestrator.js importing ../../lib/shared/utils/framework-config.js
64
+ // Should become: ../lib/shared/utils/framework-config.js
65
+ if (pathDepth === 3 && normalizedRelPath.match(/^dist\/[^\/]+\/[^\/]+\.js$/)) {
66
+ // File is at depth 2: dist/<dir>/<file>.js
67
+ // Fix specific shared lib imports
68
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/lib\/shared\//g, "from $1../lib/shared/");
69
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/lib\/shared\//g, "import($1../lib/shared/");
70
+ // Fix generic lib imports (e.g. ../../lib/database/.. -> ../lib/database/...)
71
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/lib\//g, "from $1../lib/");
72
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/lib\//g, "import($1../lib/");
73
+ }
74
+
75
+ // Fix ../../../lib/shared/ to ../../lib/shared/ for files at depth 3: dist/<dir>/<subdir>/<file>.js
76
+ // Example: dist/deployment/orchestration/BaseDeploymentOrchestrator.js importing ../../../lib/shared/utils/ErrorHandler.js
77
+ // Should become: ../../lib/shared/utils/ErrorHandler.js
78
+ if (pathDepth === 4 && normalizedRelPath.match(/^dist\/[^\/]+\/[^\/]+\/[^\/]+\.js$/)) {
79
+ // File is at depth 3: dist/<dir>/<subdir>/<file>.js
80
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "from $1../../lib/shared/");
81
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "import($1../../lib/shared/");
82
+ }
83
+
84
+ // Fix ../../../lib/shared/ to ../../lib/shared/ for files in dist/utils/ subdirectories
85
+ // Example: dist/utils/deployment/config-cache.js importing ../../../lib/shared/utils/framework-config.js
86
+ // Should become: ../../lib/shared/utils/framework-config.js
87
+ if (normalizedRelPath.match(/^dist\/utils\/[^\/]+\/[^\/]+\.js$/)) {
88
+ // File is at depth 3: dist/utils/<subdir>/<file>.js
89
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "from $1../../lib/shared/");
90
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "import($1../../lib/shared/");
91
+ }
92
+
93
+ // Fix ../../../lib/shared/ to ../../lib/shared/ for files in dist/service-management/ subdirectories
94
+ if (normalizedRelPath.match(/^dist\/service-management\/[^\/]+\/[^\/]+\.js$/)) {
95
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "from $1../../lib/shared/");
96
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "import($1../../lib/shared/");
97
+ }
98
+ // Fix ../../../../lib/ to ../../../lib/ for deeper nested files in dist/service-management (e.g. generators/config/...)
99
+ if (normalizedRelPath.startsWith('dist/service-management/')) {
100
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "from $1../../../lib/shared/");
101
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\//g, "from $1../../../lib/");
102
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "import($1../../../lib/shared/");
103
+ content = content.replace(/import\s*\(\s*(['"])\.\.\/\.\.\/\.\.\/lib\//g, "import($1../../../lib/");
104
+ }
105
+
106
+ // Specific fix for generators/config files that had one extra ../ and still resolve outside dist
107
+ if (normalizedRelPath.match(/^dist\/service-management\/generators\/config\/.+\.js$/)) {
108
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\/utils\//g, "from $1../../../lib/shared/utils/");
109
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/shared\//g, "from $1../../../lib/shared/");
110
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\/utils\//g, "from $1../../../lib/utils/");
111
+ content = content.replace(/from\s+(['"])\.\.\/\.\.\/\.\.\/lib\//g, "from $1../../../lib/");
112
+ }
113
+
114
+ // General fix: convert four-level '../../../../lib/' imports to '../../../lib/' across dist/
115
+ // This handles deeply nested files that mistakenly reference project root lib/ (outside dist)
116
+ content = content.replace(/(\.\.\/){4}lib\//g, "../../../lib/");
117
+ content = content.replace(/import\s*\(\s*(['"])(?:\.\.\/){4}lib\//g, "import($1../../../lib/");
118
+
119
+ // Fix ../lib/ to ./lib/ for files directly in dist/ root (like index.js)
120
+ if (normalizedRelPath.startsWith('dist/') && pathDepth === 2 && normalizedRelPath.endsWith('.js')) {
121
+ content = content.replace(/\.\.\/lib\//g, "./lib/");
122
+ }
123
+ }
124
+
125
+ if (content !== original) {
126
+ fs.writeFileSync(filePath, content);
127
+ console.log('✅ Fixed dist import:', relPath);
128
+ }
129
+ }
130
+ });
131
+ }
132
+
133
+ // Process all dist/ where the fixes are needed
134
+ fixDistImports('dist');
135
+ console.log('✅ Dist import path fixes completed');