tdpw
Version:
CLI tool for uploading Playwright test reports to TestDino platform with Azure storage support
257 lines • 9.85 kB
JavaScript
;
/**
* Configuration management with environment detection and validation
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnvironmentUtils = exports.EnvironmentDetector = exports.configLoader = exports.ConfigLoader = void 0;
const tslib_1 = require("tslib");
const dotenv = tslib_1.__importStar(require("dotenv-expand"));
const zod_1 = require("zod");
const types_1 = require("../types");
const env_1 = require("../utils/env");
Object.defineProperty(exports, "EnvironmentUtils", { enumerable: true, get: function () { return env_1.EnvironmentUtils; } });
const validation_1 = require("../utils/validation");
// Load environment variables with proper typing
dotenv.expand({ parsed: process.env });
/**
* Default configuration values
*/
const DEFAULT_CONFIG = {
// API URLs by environment
API_URLS: {
[env_1.EnvironmentType.PRODUCTION]: 'https://api.testdino.com',
[env_1.EnvironmentType.STAGING]: 'https://staging-api.testdino.com',
[env_1.EnvironmentType.DEVELOPMENT]: 'http://localhost:3000',
[env_1.EnvironmentType.TEST]: 'http://localhost:3000',
},
// Default options
UPLOAD_IMAGES: false,
UPLOAD_VIDEOS: false,
UPLOAD_HTML: false,
UPLOAD_TRACES: false,
VERBOSE: false,
DRY_RUN: false,
// Performance settings
TIMEOUT_MS: 60000, // 60 seconds
RETRY_COUNT: 3,
MAX_FILE_SIZE_MB: 100,
};
/**
* Environment detection utilities
*/
class EnvironmentDetectorClass {
/**
* Determine current environment type
*/
getEnvironmentType() {
return env_1.EnvironmentUtils.detectEnvironmentType();
}
/**
* Determine if we're in development mode
*/
isDevelopment() {
return env_1.EnvironmentUtils.isDevelopment();
}
/**
* Determine if we're in production mode
*/
isProduction() {
return env_1.EnvironmentUtils.isProduction();
}
/**
* Determine if we're in test mode
*/
isTest() {
return env_1.EnvironmentUtils.isTest();
}
/**
* Check if running in CI environment
*/
isCI() {
return env_1.EnvironmentUtils.isCI();
}
/**
* Get CI provider information
*/
getCIProvider() {
return env_1.EnvironmentUtils.detectCIProvider();
}
/**
* Get the appropriate API URL based on environment
*/
getApiUrl() {
const envType = this.getEnvironmentType();
// Check for explicit override (always allow override)
const override = env_1.EnvironmentUtils.getStringEnv('TESTDINO_API_URL');
if (override) {
return override;
}
// Use environment-specific default
return DEFAULT_CONFIG.API_URLS[envType];
}
/**
* Get environment summary for debugging
*/
getEnvironmentInfo() {
return {
...env_1.EnvironmentUtils.getEnvironmentSummary(),
apiUrl: this.getApiUrl(),
isCI: this.isCI(),
ciProvider: this.getCIProvider(),
};
}
}
/**
* Enhanced configuration loader and validator
*/
class ConfigLoader {
/**
* Validate API token format and environment compatibility
*/
validateToken(token) {
validation_1.ValidationUtils.validateApiToken(token);
// Extract environment from token
const tokenEnv = token.split('_')[1];
exports.EnvironmentDetector.getEnvironmentType();
// Warn about environment mismatches in development
if (exports.EnvironmentDetector.isDevelopment() && tokenEnv !== 'development') {
console.warn(`⚠️ Using ${tokenEnv} token in development environment. ` +
'Consider using a development token for local testing.');
}
}
/**
* Resolve configuration values with proper precedence
*/
resolveConfigValue(cliValue, envKey, defaultValue, converter) {
// CLI option has highest precedence
if (cliValue !== undefined) {
return cliValue;
}
// Environment variable is second
const envValue = env_1.EnvironmentUtils.getStringEnv(envKey);
if (envValue !== undefined) {
if (converter) {
return converter(envValue);
}
// For boolean values
if (typeof defaultValue === 'boolean') {
return (0, types_1.stringToBoolean)(envValue);
}
return envValue;
}
// Default value is last
return defaultValue;
}
/**
* Create configuration from CLI options with environment fallbacks
*/
createConfig(options) {
// Token resolution: CLI > ENV > error
const token = this.resolveConfigValue(options.token, 'TESTDINO_TOKEN', '');
if (!token) {
throw new types_1.ConfigurationError('API token is required. Provide via --token flag or TESTDINO_TOKEN environment variable.');
}
// Validate token format
this.validateToken(token);
// Build configuration with precedence handling
const config = {
apiUrl: exports.EnvironmentDetector.getApiUrl(),
token,
uploadImages: this.resolveConfigValue(options.uploadImages, 'TESTDINO_UPLOAD_IMAGES', DEFAULT_CONFIG.UPLOAD_IMAGES),
uploadVideos: this.resolveConfigValue(options.uploadVideos, 'TESTDINO_UPLOAD_VIDEOS', DEFAULT_CONFIG.UPLOAD_VIDEOS),
uploadHtml: this.resolveConfigValue(options.uploadHtml, 'TESTDINO_UPLOAD_HTML', DEFAULT_CONFIG.UPLOAD_HTML),
uploadTraces: this.resolveConfigValue(options.uploadTraces, 'TESTDINO_UPLOAD_TRACES', DEFAULT_CONFIG.UPLOAD_TRACES),
verbose: this.resolveConfigValue(options.verbose, 'TESTDINO_VERBOSE', DEFAULT_CONFIG.VERBOSE),
dryRun: options.dryRun || DEFAULT_CONFIG.DRY_RUN,
};
// Validate the final configuration
try {
const validatedConfig = types_1.ConfigSchema.parse(config);
// Log configuration summary in verbose mode
if (validatedConfig.verbose) {
this.logConfigurationSummary(validatedConfig, options);
}
return validatedConfig;
}
catch (error) {
if (error instanceof zod_1.z.ZodError) {
const issues = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
throw new types_1.ConfigurationError(`Invalid configuration: ${issues.join(', ')}`, error);
}
throw new types_1.ConfigurationError('Configuration validation failed', error);
}
}
/**
* Log configuration summary for debugging
*/
logConfigurationSummary(config, options) {
const envInfo = exports.EnvironmentDetector.getEnvironmentInfo();
console.log('🔧 Configuration Summary:');
console.log(` Environment: ${envInfo.type}`);
console.log(` CI/CD: ${envInfo.isCI ? `Yes (${envInfo.ciProvider})` : 'No'}`);
console.log(` API URL: ${config.apiUrl}`);
console.log(` Report Directory: ${options.reportDirectory}`);
console.log(` Upload Images: ${config.uploadImages ? 'Yes' : 'No'}`);
console.log(` Upload Videos: ${config.uploadVideos ? 'Yes' : 'No'}`);
console.log(` Upload HTML: ${config.uploadHtml ? 'Yes' : 'No'}`);
console.log(` Upload Traces: ${config.uploadTraces ? 'Yes' : 'No'}`);
console.log(` Dry Run: ${config.dryRun ? 'Yes' : 'No'}`);
if (options.jsonReport) {
console.log(` Custom JSON Report: ${options.jsonReport}`);
}
if (options.htmlReport) {
console.log(` Custom HTML Report: ${options.htmlReport}`);
}
if (options.traceDir) {
console.log(` Custom Trace Dir: ${options.traceDir}`);
}
}
/**
* Get runtime configuration with validation
*/
getRuntimeConfig() {
const timeout = env_1.EnvironmentUtils.getNumberEnv('TESTDINO_TIMEOUT', DEFAULT_CONFIG.TIMEOUT_MS);
const retryCount = env_1.EnvironmentUtils.getNumberEnv('TESTDINO_RETRY_COUNT', DEFAULT_CONFIG.RETRY_COUNT);
const maxFileSizeMB = env_1.EnvironmentUtils.getNumberEnv('TESTDINO_MAX_FILE_SIZE', DEFAULT_CONFIG.MAX_FILE_SIZE_MB);
const logLevel = env_1.EnvironmentUtils.getStringEnv('LOG_LEVEL', 'info') || 'info';
// Validate runtime values
validation_1.ValidationUtils.validateTimeout(timeout);
validation_1.ValidationUtils.validateRetryCount(retryCount);
return {
timeout,
retryCount,
maxFileSize: maxFileSizeMB * 1024 * 1024, // Convert MB to bytes
logLevel,
};
}
/**
* Validate environment for CLI operation
*/
validateEnvironment() {
try {
// Validate environment variables
env_1.EnvironmentUtils.getEnvironment();
// Check Node.js version
validation_1.ValidationUtils.validateNodeVersion('18.0.0');
// Validate API URL if present
const apiUrl = exports.EnvironmentDetector.getApiUrl();
validation_1.ValidationUtils.validateUrl(apiUrl, 'API');
}
catch (error) {
if (error instanceof types_1.ConfigurationError || error instanceof types_1.ValidationError) {
throw error;
}
throw new types_1.ConfigurationError('Environment validation failed', error);
}
}
}
exports.ConfigLoader = ConfigLoader;
/**
* Global configuration instance
*/
exports.configLoader = new ConfigLoader();
/**
* Create a singleton instance of EnvironmentDetector
*/
exports.EnvironmentDetector = new EnvironmentDetectorClass();
//# sourceMappingURL=index.js.map