@tamyla/clodo-framework 3.1.4 → 3.1.8
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 +29 -0
- package/bin/clodo-service.js +29 -989
- package/bin/database/enterprise-db-manager.js +7 -5
- package/bin/security/security-cli.js +0 -0
- package/bin/service-management/create-service.js +0 -0
- package/bin/service-management/init-service.js +0 -0
- package/bin/shared/cloudflare/domain-discovery.js +11 -10
- package/bin/shared/cloudflare/ops.js +1 -1
- package/bin/shared/config/ConfigurationManager.js +539 -0
- package/bin/shared/config/index.js +13 -1
- package/bin/shared/database/connection-manager.js +2 -2
- package/bin/shared/database/orchestrator.js +5 -4
- package/bin/shared/deployment/auditor.js +9 -8
- package/bin/shared/logging/Logger.js +214 -0
- package/bin/shared/monitoring/production-monitor.js +21 -9
- package/bin/shared/utils/ErrorHandler.js +675 -0
- package/bin/shared/utils/error-recovery.js +33 -13
- package/bin/shared/utils/file-manager.js +162 -0
- package/bin/shared/utils/formatters.js +247 -0
- package/bin/shared/utils/index.js +14 -4
- package/bin/shared/validation/ValidationRegistry.js +143 -0
- package/dist/deployment/auditor.js +23 -8
- package/dist/deployment/orchestration/BaseDeploymentOrchestrator.js +426 -0
- package/dist/deployment/orchestration/EnterpriseOrchestrator.js +401 -0
- package/dist/deployment/orchestration/PortfolioOrchestrator.js +273 -0
- package/dist/deployment/orchestration/SingleServiceOrchestrator.js +231 -0
- package/dist/deployment/orchestration/UnifiedDeploymentOrchestrator.js +662 -0
- package/dist/deployment/orchestration/index.js +17 -0
- package/dist/index.js +12 -0
- package/dist/orchestration/modules/DomainResolver.js +8 -6
- package/dist/orchestration/multi-domain-orchestrator.js +13 -1
- package/dist/security/index.js +2 -2
- package/dist/service-management/ConfirmationEngine.js +8 -7
- package/dist/service-management/ErrorTracker.js +7 -2
- package/dist/service-management/InputCollector.js +31 -16
- package/dist/service-management/ServiceCreator.js +22 -7
- package/dist/service-management/ServiceInitializer.js +12 -18
- package/dist/shared/cloudflare/domain-discovery.js +11 -10
- package/dist/shared/cloudflare/ops.js +1 -1
- package/dist/shared/config/ConfigurationManager.js +519 -0
- package/dist/shared/config/index.js +5 -1
- package/dist/shared/database/connection-manager.js +2 -2
- package/dist/shared/database/orchestrator.js +13 -4
- package/dist/shared/deployment/auditor.js +23 -8
- package/dist/shared/logging/Logger.js +209 -0
- package/dist/shared/monitoring/production-monitor.js +24 -8
- package/dist/{utils → shared/utils}/ErrorHandler.js +306 -28
- package/dist/shared/utils/error-recovery.js +33 -13
- package/dist/shared/utils/file-manager.js +155 -0
- package/dist/shared/utils/formatters.js +215 -0
- package/dist/shared/utils/index.js +14 -4
- package/dist/shared/validation/ValidationRegistry.js +126 -0
- package/dist/utils/config/unified-config-manager.js +14 -12
- package/dist/utils/deployment/config-cache.js +3 -1
- package/dist/utils/deployment/secret-generator.js +32 -29
- package/dist/utils/framework-config.js +6 -3
- package/dist/utils/ui-structures-loader.js +3 -0
- package/dist/worker/integration.js +11 -1
- package/package.json +31 -3
- package/dist/config/FeatureManager.js +0 -426
- package/dist/config/features.js +0 -230
- package/dist/utils/error-recovery.js +0 -240
|
@@ -11,12 +11,18 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { randomBytes, createHash } from 'crypto';
|
|
14
|
-
import {
|
|
14
|
+
import { readdirSync, statSync } from 'fs';
|
|
15
15
|
import { join, dirname } from 'path';
|
|
16
16
|
import { execSync } from 'child_process';
|
|
17
17
|
import { fileURLToPath } from 'url';
|
|
18
|
+
import { FileManager } from '../../../bin/shared/utils/file-manager.js';
|
|
18
19
|
let __filename, __dirname;
|
|
19
20
|
|
|
21
|
+
// Module-level FileManager for standalone functions
|
|
22
|
+
const moduleFileManager = new FileManager({
|
|
23
|
+
enableCache: true
|
|
24
|
+
});
|
|
25
|
+
|
|
20
26
|
// Handle test environment where import.meta might be transformed
|
|
21
27
|
try {
|
|
22
28
|
__filename = fileURLToPath(import.meta.url);
|
|
@@ -85,6 +91,9 @@ const SECRET_CONFIGS = {
|
|
|
85
91
|
*/
|
|
86
92
|
export class EnhancedSecretManager {
|
|
87
93
|
constructor(options = {}) {
|
|
94
|
+
this.fileManager = new FileManager({
|
|
95
|
+
enableCache: true
|
|
96
|
+
});
|
|
88
97
|
this.projectRoot = options.projectRoot || join(__dirname, '..', '..');
|
|
89
98
|
this.dryRun = options.dryRun || false;
|
|
90
99
|
this.retryAttempts = options.retryAttempts || 3;
|
|
@@ -535,7 +544,7 @@ export class EnhancedSecretManager {
|
|
|
535
544
|
default:
|
|
536
545
|
throw new Error(`Unsupported format: ${format}`);
|
|
537
546
|
}
|
|
538
|
-
|
|
547
|
+
this.fileManager.writeFile(filepath, content);
|
|
539
548
|
return {
|
|
540
549
|
format,
|
|
541
550
|
filename,
|
|
@@ -635,7 +644,7 @@ ${Object.entries(SECRET_CONFIGS).map(([key, config]) => `- **${key}**: ${config.
|
|
|
635
644
|
`;
|
|
636
645
|
const readmeFile = join(domain, environment, 'README.md');
|
|
637
646
|
const readmePath = join(this.secretPaths.distribution, readmeFile);
|
|
638
|
-
|
|
647
|
+
this.fileManager.writeFile(readmePath, readmeContent);
|
|
639
648
|
return {
|
|
640
649
|
filename: 'README.md',
|
|
641
650
|
filepath: readmePath,
|
|
@@ -655,11 +664,11 @@ ${Object.entries(SECRET_CONFIGS).map(([key, config]) => `- **${key}**: ${config.
|
|
|
655
664
|
}
|
|
656
665
|
async loadDomainSecrets(domain, environment) {
|
|
657
666
|
const filename = join(this.secretPaths.root, `${domain}-${environment}-secrets.json`);
|
|
658
|
-
if (!
|
|
667
|
+
if (!this.fileManager.exists(filename)) {
|
|
659
668
|
return null;
|
|
660
669
|
}
|
|
661
670
|
try {
|
|
662
|
-
const data = JSON.parse(
|
|
671
|
+
const data = JSON.parse(this.fileManager.readFile(filename, 'utf8'));
|
|
663
672
|
const {
|
|
664
673
|
domain: d,
|
|
665
674
|
environment: e,
|
|
@@ -693,15 +702,13 @@ ${Object.entries(SECRET_CONFIGS).map(([key, config]) => `- **${key}**: ${config.
|
|
|
693
702
|
console.log(` 🔍 DRY RUN: Would save secrets to ${filename}`);
|
|
694
703
|
return filename;
|
|
695
704
|
}
|
|
696
|
-
|
|
705
|
+
this.fileManager.writeFile(filename, JSON.stringify(secretData, null, 2));
|
|
697
706
|
console.log(` 💾 Secrets saved: ${filename}`);
|
|
698
707
|
return filename;
|
|
699
708
|
}
|
|
700
709
|
ensureDirectory(path) {
|
|
701
|
-
if (!
|
|
702
|
-
|
|
703
|
-
recursive: true
|
|
704
|
-
});
|
|
710
|
+
if (!this.fileManager.exists(path)) {
|
|
711
|
+
this.fileManager.ensureDir(path);
|
|
705
712
|
}
|
|
706
713
|
}
|
|
707
714
|
logSecretEvent(event, domain, details = {}) {
|
|
@@ -719,10 +726,10 @@ ${Object.entries(SECRET_CONFIGS).map(([key, config]) => `- **${key}**: ${config.
|
|
|
719
726
|
};
|
|
720
727
|
try {
|
|
721
728
|
const logLine = JSON.stringify(logEntry) + '\n';
|
|
722
|
-
if (
|
|
723
|
-
|
|
729
|
+
if (this.fileManager.exists(this.secretPaths.audit)) {
|
|
730
|
+
this.fileManager.appendFile(this.secretPaths.audit, logLine);
|
|
724
731
|
} else {
|
|
725
|
-
|
|
732
|
+
this.fileManager.writeFile(this.secretPaths.audit, logLine);
|
|
726
733
|
}
|
|
727
734
|
} catch (error) {
|
|
728
735
|
console.warn(`⚠️ Failed to log secret event: ${error.message}`);
|
|
@@ -747,10 +754,8 @@ export function generateSingleSecret(length = 32) {
|
|
|
747
754
|
}
|
|
748
755
|
export function saveSecrets(domain, environment, secrets, additionalData = {}) {
|
|
749
756
|
const secretsDir = 'secrets';
|
|
750
|
-
if (!
|
|
751
|
-
|
|
752
|
-
recursive: true
|
|
753
|
-
});
|
|
757
|
+
if (!moduleFileManager.exists(secretsDir)) {
|
|
758
|
+
moduleFileManager.ensureDir(secretsDir);
|
|
754
759
|
}
|
|
755
760
|
const data = {
|
|
756
761
|
domain,
|
|
@@ -761,16 +766,16 @@ export function saveSecrets(domain, environment, secrets, additionalData = {}) {
|
|
|
761
766
|
...secrets
|
|
762
767
|
};
|
|
763
768
|
const filename = join(secretsDir, `${domain}-secrets.json`);
|
|
764
|
-
|
|
769
|
+
moduleFileManager.writeFile(filename, JSON.stringify(data, null, 2));
|
|
765
770
|
return filename;
|
|
766
771
|
}
|
|
767
772
|
export function loadSecrets(domain) {
|
|
768
773
|
const filename = join('secrets', `${domain}-secrets.json`);
|
|
769
|
-
if (!
|
|
774
|
+
if (!moduleFileManager.exists(filename)) {
|
|
770
775
|
return null;
|
|
771
776
|
}
|
|
772
777
|
try {
|
|
773
|
-
const data = JSON.parse(
|
|
778
|
+
const data = JSON.parse(moduleFileManager.readFile(filename, 'utf8'));
|
|
774
779
|
const {
|
|
775
780
|
domain: d,
|
|
776
781
|
environment,
|
|
@@ -794,32 +799,30 @@ export function loadSecrets(domain) {
|
|
|
794
799
|
}
|
|
795
800
|
export function distributeSecrets(domain, secrets) {
|
|
796
801
|
const distDir = join('secrets', 'distribution', domain);
|
|
797
|
-
|
|
798
|
-
recursive: true
|
|
799
|
-
});
|
|
802
|
+
moduleFileManager.ensureDir(distDir);
|
|
800
803
|
const files = {};
|
|
801
804
|
|
|
802
805
|
// .env format
|
|
803
806
|
const envContent = Object.entries(secrets).map(([key, value]) => `${key}=${value}`).join('\n');
|
|
804
807
|
const envFile = join(distDir, '.env');
|
|
805
|
-
|
|
808
|
+
moduleFileManager.writeFile(envFile, envContent);
|
|
806
809
|
files.env = envFile;
|
|
807
810
|
|
|
808
811
|
// JSON format
|
|
809
812
|
const jsonFile = join(distDir, 'secrets.json');
|
|
810
|
-
|
|
813
|
+
moduleFileManager.writeFile(jsonFile, JSON.stringify(secrets, null, 2));
|
|
811
814
|
files.json = jsonFile;
|
|
812
815
|
|
|
813
816
|
// Shell script format (cross-platform)
|
|
814
817
|
const shellContent = Object.entries(secrets).map(([key, value]) => `echo "${value}" | npx wrangler secret put ${key} --env production`).join('\n');
|
|
815
818
|
const shellFile = join(distDir, 'deploy-secrets.sh');
|
|
816
|
-
|
|
819
|
+
moduleFileManager.writeFile(shellFile, shellContent);
|
|
817
820
|
files.shell = shellFile;
|
|
818
821
|
|
|
819
822
|
// PowerShell script format
|
|
820
823
|
const psContent = Object.entries(secrets).map(([key, value]) => `"${value}" | npx wrangler secret put ${key} --env production`).join('\n');
|
|
821
824
|
const psFile = join(distDir, 'deploy-secrets.ps1');
|
|
822
|
-
|
|
825
|
+
moduleFileManager.writeFile(psFile, psContent);
|
|
823
826
|
files.powershell = psFile;
|
|
824
827
|
|
|
825
828
|
// README
|
|
@@ -857,7 +860,7 @@ chmod +x deploy-secrets.sh
|
|
|
857
860
|
- Distribute via secure channels only
|
|
858
861
|
`;
|
|
859
862
|
const readmeFile = join(distDir, 'README.md');
|
|
860
|
-
|
|
863
|
+
moduleFileManager.writeFile(readmeFile, readme);
|
|
861
864
|
files.readme = readmeFile;
|
|
862
865
|
return {
|
|
863
866
|
directory: distDir,
|
|
@@ -882,7 +885,7 @@ export function validateSecrets(secrets) {
|
|
|
882
885
|
}
|
|
883
886
|
export function listSecretsFiles() {
|
|
884
887
|
const secretsDir = 'secrets';
|
|
885
|
-
if (!
|
|
888
|
+
if (!moduleFileManager.exists(secretsDir)) {
|
|
886
889
|
return [];
|
|
887
890
|
}
|
|
888
891
|
try {
|
|
@@ -6,11 +6,14 @@
|
|
|
6
6
|
* from validation-config.json and environment variables
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { readFileSync, existsSync } from 'fs';
|
|
10
9
|
import { join, dirname } from 'path';
|
|
11
10
|
import { fileURLToPath } from 'url';
|
|
11
|
+
import { FileManager } from '../../bin/shared/utils/file-manager.js';
|
|
12
12
|
export class FrameworkConfig {
|
|
13
13
|
constructor(configPath = null) {
|
|
14
|
+
this.fileManager = new FileManager({
|
|
15
|
+
enableCache: true
|
|
16
|
+
});
|
|
14
17
|
this.configPath = configPath || this.findConfigFile();
|
|
15
18
|
this.config = this.loadConfig();
|
|
16
19
|
this.environment = process.env.ENVIRONMENT || 'development';
|
|
@@ -36,7 +39,7 @@ export class FrameworkConfig {
|
|
|
36
39
|
}
|
|
37
40
|
const possiblePaths = ['./validation-config.json', '../validation-config.json', '../../validation-config.json', join(process.cwd(), 'validation-config.json'), join(__dirname, '..', '..', 'validation-config.json')];
|
|
38
41
|
for (const path of possiblePaths) {
|
|
39
|
-
if (
|
|
42
|
+
if (this.fileManager.exists(path)) {
|
|
40
43
|
return path;
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -56,7 +59,7 @@ export class FrameworkConfig {
|
|
|
56
59
|
return this.getDefaultConfig();
|
|
57
60
|
}
|
|
58
61
|
try {
|
|
59
|
-
const configContent =
|
|
62
|
+
const configContent = this.fileManager.readFile(this.configPath, 'utf8');
|
|
60
63
|
const config = JSON.parse(configContent);
|
|
61
64
|
console.log(`📋 Loaded configuration from: ${this.configPath}`);
|
|
62
65
|
return config;
|
|
@@ -38,14 +38,17 @@ class UIStructuresLoader {
|
|
|
38
38
|
|
|
39
39
|
// Load reference templates
|
|
40
40
|
const referenceDir = path.join(uiStructuresDir, 'reference');
|
|
41
|
+
console.log('🔍 Reference dir:', referenceDir, 'exists:', fs.existsSync(referenceDir));
|
|
41
42
|
if (fs.existsSync(referenceDir)) {
|
|
42
43
|
const referenceFiles = fs.readdirSync(referenceDir).filter(f => f.endsWith('.json'));
|
|
44
|
+
console.log('🔍 Reference files:', referenceFiles);
|
|
43
45
|
for (const file of referenceFiles) {
|
|
44
46
|
const filePath = path.join(referenceDir, file);
|
|
45
47
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
46
48
|
const template = JSON.parse(content);
|
|
47
49
|
// Use template.name if available, otherwise filename
|
|
48
50
|
const name = template.template?.name || path.basename(file, '.json');
|
|
51
|
+
console.log('🔍 Loaded template:', name);
|
|
49
52
|
this.templates.set(name, template);
|
|
50
53
|
}
|
|
51
54
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { COMMON_FEATURES, ConfigurationManager } from '../../bin/shared/config/ConfigurationManager.js';
|
|
2
2
|
import { getDomainFromEnv, createEnvironmentConfig } from '../config/domains.js';
|
|
3
3
|
|
|
4
|
+
// Create a singleton instance of ConfigurationManager for use in integration
|
|
5
|
+
export const configManager = new ConfigurationManager({});
|
|
6
|
+
|
|
7
|
+
// Legacy featureManager compatibility interface using ConfigurationManager
|
|
8
|
+
const featureManager = {
|
|
9
|
+
setDomain: domainConfig => configManager.setDomain(domainConfig),
|
|
10
|
+
getEnabledFeatures: () => configManager.getEnabledFeatures(),
|
|
11
|
+
isEnabled: featureName => configManager.isFeatureEnabled(featureName)
|
|
12
|
+
};
|
|
13
|
+
|
|
4
14
|
// Simple inline logger to avoid circular dependency with index.js
|
|
5
15
|
const logger = {
|
|
6
16
|
info: (message, ...args) => console.log(`[WorkerIntegration] ${message}`, ...args),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamyla/clodo-framework",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"description": "Reusable framework for Clodo-style software architecture on Cloudflare Workers + D1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -70,19 +70,40 @@
|
|
|
70
70
|
],
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "npm run prebuild && babel src/ --out-dir dist/ && babel bin/shared/ --out-dir dist/shared/ && babel bin/shared/production-tester/ --out-dir dist/deployment/testers/ && babel bin/shared/deployment/ --out-dir dist/deployment/ && node -e \"const fs=require('fs'); fs.cpSync('ui-structures', 'dist/ui-structures', {recursive: true});\" && npm run postbuild",
|
|
73
|
+
"build:ci": "npm run prebuild:ci && babel src/ --out-dir dist/ && babel bin/shared/ --out-dir dist/shared/ && babel bin/shared/production-tester/ --out-dir dist/deployment/testers/ && babel bin/shared/deployment/ --out-dir dist/deployment/ && node -e \"const fs=require('fs'); fs.cpSync('ui-structures', 'dist/ui-structures', {recursive: true});\" && npm run postbuild",
|
|
73
74
|
"prebuild": "npm run clean && npm run type-check",
|
|
75
|
+
"prebuild:ci": "npm run clean && npm run type-check",
|
|
74
76
|
"postbuild": "npm run check:bundle",
|
|
75
77
|
"clean": "rimraf dist",
|
|
76
78
|
"clean:generated": "rimraf generated",
|
|
77
79
|
"clean:all": "npm run clean && npm run clean:generated",
|
|
78
80
|
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests",
|
|
81
|
+
"test:ci": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests --testPathIgnorePatterns=\"test/cli-integration|backups/|i-docs/|generated/\"",
|
|
82
|
+
"test:unit": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests",
|
|
79
83
|
"test:watch": "jest --watch",
|
|
80
84
|
"test:coverage": "jest --coverage",
|
|
85
|
+
"test:cli": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/ --verbose",
|
|
81
86
|
"test:cli-integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --config test/cli-integration/jest.config.js",
|
|
82
87
|
"test:cli-create": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/clodo-create-service.test.js",
|
|
83
88
|
"test:cli-init": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/clodo-init-service.test.js",
|
|
84
89
|
"test:cli-security": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/clodo-security.test.js",
|
|
85
90
|
"test:cli-e2e": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/e2e-workflows.test.js",
|
|
91
|
+
"test:deployment": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/deployment/ test/deployment-security.spec.js --verbose",
|
|
92
|
+
"test:services": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/service-management/ test/services/ --verbose",
|
|
93
|
+
"test:services:create": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/service-orchestrator.test.js test/service-orchestrator-unit.test.js test/multi-domain-orchestrator-unit.test.js test/database-orchestrator-unit.test.js test/generic-data-service.test.js --verbose",
|
|
94
|
+
"test:generation": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/generation-engine.test.js test/generation-engine-unit.test.js --verbose",
|
|
95
|
+
"test:routing": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/routing/ --verbose",
|
|
96
|
+
"test:security": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/deployment-security.spec.js test/security-validation.test.js test/validation.test.js --verbose",
|
|
97
|
+
"test:handlers": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/handlers/ --verbose",
|
|
98
|
+
"test:utils": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/utils/ test/shared/ test/input-collector.test.js test/interactive-utils.test.js test/import-cleanup.test.js test/ui-structures.test.js --verbose",
|
|
99
|
+
"test:config": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/config/ --verbose",
|
|
100
|
+
"test:schema": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/schema/ --verbose",
|
|
101
|
+
"test:worker": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/worker/ --verbose",
|
|
102
|
+
"test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/integration/ --verbose",
|
|
103
|
+
"test:comprehensive": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/comprehensive-suite.spec.js --verbose",
|
|
104
|
+
"test:coverage:cli": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/cli-integration/ --coverage",
|
|
105
|
+
"test:coverage:deployment": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/deployment/ test/deployment-security.spec.js --coverage",
|
|
106
|
+
"test:coverage:services": "cross-env NODE_OPTIONS=--experimental-vm-modules jest test/service-management/ test/services/ --coverage",
|
|
86
107
|
"lint": "eslint --config ./eslint.config.js src",
|
|
87
108
|
"lint:fix": "eslint --config ./eslint.config.js src --fix",
|
|
88
109
|
"type-check": "tsc --noEmit",
|
|
@@ -92,7 +113,7 @@
|
|
|
92
113
|
"analyze:bundle": "echo 'Bundle analysis not implemented yet'",
|
|
93
114
|
"docs": "echo 'JSDoc documentation generation not configured yet'",
|
|
94
115
|
"validate": "npm run check:all",
|
|
95
|
-
"prepublishOnly": "npm run
|
|
116
|
+
"prepublishOnly": "npm run build:ci",
|
|
96
117
|
"postpublish": "echo 'Published successfully to npm registry!'",
|
|
97
118
|
"publish:beta": "npm publish --tag beta",
|
|
98
119
|
"publish:latest": "npm publish --tag latest",
|
|
@@ -103,7 +124,14 @@
|
|
|
103
124
|
"validate-service": "node bin/clodo-service.js validate",
|
|
104
125
|
"customer-config": "node bin/shared/config/customer-cli.js",
|
|
105
126
|
"push:safe": "powershell -ExecutionPolicy Bypass -File ./scripts/utilities/safe-push.ps1",
|
|
106
|
-
"sync": "git fetch && git rebase origin/master"
|
|
127
|
+
"sync": "git fetch && git rebase origin/master",
|
|
128
|
+
"test:automated": "node scripts/automated-testing-suite.js",
|
|
129
|
+
"test:automated:cli": "node scripts/automated-testing-suite.js cli",
|
|
130
|
+
"test:automated:deployment": "node scripts/automated-testing-suite.js deployment",
|
|
131
|
+
"test:automated:lifecycle": "node scripts/automated-testing-suite.js lifecycle",
|
|
132
|
+
"test:automated:integration": "node scripts/automated-testing-suite.js integration",
|
|
133
|
+
"test:automated:performance": "node scripts/automated-testing-suite.js performance",
|
|
134
|
+
"test:automated:regression": "node scripts/automated-testing-suite.js regression"
|
|
107
135
|
},
|
|
108
136
|
"keywords": [
|
|
109
137
|
"cloudflare",
|