UNPKG

@starship-ci/generator

Version:

Kubernetes manifest generator for Starship deployments

344 lines (343 loc) 11.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyDefaults = exports.DefaultsManager = exports.deepMerge = void 0; const fs = __importStar(require("fs")); const yaml = __importStar(require("js-yaml")); const path = __importStar(require("path")); /** * Deep merge utility for nested objects */ function deepMerge(target, source) { const result = { ...target }; Object.keys(source).forEach((key) => { if (source[key] !== undefined) { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { result[key] = deepMerge(result[key] || {}, source[key]); } else { result[key] = source[key]; } } }); return result; } exports.deepMerge = deepMerge; class DefaultsManager { defaultsData; defaultsPath; config; constructor(defaultsPath) { // Default to the configs/defaults.yaml in the generator package this.defaultsPath = defaultsPath || path.join(__dirname, '../configs/defaults.yaml'); this.loadDefaults(); } /** * Load defaults from the YAML file */ loadDefaults() { try { if (fs.existsSync(this.defaultsPath)) { const yamlContent = fs.readFileSync(this.defaultsPath, 'utf8'); this.defaultsData = yaml.load(yamlContent); } else { console.warn(`Defaults file not found at ${this.defaultsPath}, using empty defaults`); this.defaultsData = { defaultChains: {}, defaultFaucet: {}, defaultRelayers: {}, defaultScripts: {}, defaultCometmock: { image: 'ghcr.io/informalsystems/cometmock:v0.37.x' } }; } } catch (error) { console.error('Failed to load defaults.yaml:', error); this.defaultsData = { defaultChains: {}, defaultFaucet: {}, defaultRelayers: {}, defaultScripts: {}, defaultCometmock: { image: 'ghcr.io/informalsystems/cometmock:v0.37.x' } }; } } /** * Get chain defaults for a specific chain name */ getChainDefaults(chainName) { return this.defaultsData.defaultChains?.[chainName]; } /** * Get faucet defaults for a specific faucet type */ getFaucetDefaults(faucetType) { return this.defaultsData.defaultFaucet?.[faucetType]; } /** * Get default scripts */ getDefaultScripts() { return this.defaultsData.defaultScripts || {}; } /** * Get default relayers */ getDefaultRelayers() { return this.defaultsData.defaultRelayers || {}; } /** * Get default relayer configuration for a specific type */ getRelayerDefaults(relayerType) { return this.defaultsData.defaultRelayers?.[relayerType] || {}; } /** * Get default cometmock configuration */ getDefaultCometmock() { return this.defaultsData.defaultCometmock || {}; } /** * Process explorer configuration by merging with defaults */ processExplorer(explorerConfig) { if (!explorerConfig) return undefined; const defaultExplorer = this.defaultsData.explorer || {}; return deepMerge(defaultExplorer, explorerConfig); } /** * Process registry configuration by merging with defaults */ processRegistry(registryConfig) { if (!registryConfig) return undefined; const defaultRegistry = this.defaultsData.registry || {}; return deepMerge(defaultRegistry, registryConfig); } /** * Process faucet configuration by merging with defaults */ processFaucet(faucetConfig) { if (!faucetConfig) return undefined; const defaultFaucet = this.defaultsData.faucet || {}; return deepMerge(defaultFaucet, faucetConfig); } /** * Process monitoring configuration by merging with defaults */ processMonitoring(monitoringConfig) { if (!monitoringConfig) return undefined; const defaultMonitoring = this.defaultsData.monitoring || {}; return deepMerge(defaultMonitoring, monitoringConfig); } /** * Process ingress configuration by merging with defaults */ processIngress(ingressConfig) { if (!ingressConfig) return undefined; const defaultIngress = this.defaultsData.ingress || {}; return deepMerge(defaultIngress, ingressConfig); } /** * Process exposer configuration by merging with defaults */ processExposer(exposerConfig) { if (!exposerConfig) return undefined; const defaultExposer = this.defaultsData.exposer || {}; return deepMerge(defaultExposer, exposerConfig); } /** * Process images configuration by merging with defaults */ processImages(imagesConfig) { if (!imagesConfig) return undefined; const defaultImages = this.defaultsData.images || {}; return deepMerge(defaultImages, imagesConfig); } /** * Process resources configuration by merging with defaults */ processResources(resourcesConfig) { if (!resourcesConfig) return undefined; const defaultResources = this.defaultsData.resources || {}; return deepMerge(defaultResources, resourcesConfig); } /** * Process timeouts configuration by merging with defaults */ processTimeouts(timeoutsConfig) { if (!timeoutsConfig) return undefined; const defaultTimeouts = this.defaultsData.timeouts || {}; return deepMerge(defaultTimeouts, timeoutsConfig); } /** * Process a relayer configuration by merging with defaults * This handles partial overrides properly using deep merge */ processRelayer(relayerConfig) { // Get default relayer configuration for this type const defaultRelayer = this.getRelayerDefaults(relayerConfig.type); // Deep merge the configurations (relayer config takes precedence) const mergedRelayer = deepMerge(defaultRelayer, relayerConfig); return mergedRelayer; } /** * Process a chain configuration by merging with defaults * This replaces the complex _chains.tpl logic */ processChain(chainConfig) { // Get default chain configuration const defaultChain = this.getChainDefaults(chainConfig.name); // Merge configurations (chain config takes precedence) const mergedChain = { ...defaultChain, ...chainConfig }; // Process faucet configuration const defaultFaucet = this.getFaucetDefaults('starship'); const faucetConfig = { enabled: true, type: 'starship', ...defaultFaucet, ...mergedChain.faucet }; // Process cometmock configuration const cometmockConfig = { enabled: false, ...this.getDefaultCometmock(), ...mergedChain.cometmock }; // Process upgrade/build settings const upgradeConfig = mergedChain.upgrade || { enabled: false }; const buildConfig = mergedChain.build || { enabled: false }; // Set image based on build requirements let image = mergedChain.image; if (mergedChain.build?.enabled || mergedChain.upgrade?.enabled) { image = 'ghcr.io/cosmology-tech/starship/runner:latest'; } // Process scripts - merge default scripts with chain-specific scripts const defaultScripts = this.getDefaultScripts(); const chainDefaultScripts = defaultChain?.scripts || {}; const scripts = { ...defaultScripts, ...chainDefaultScripts, ...mergedChain.scripts }; return { ...mergedChain, image, faucet: faucetConfig, cometmock: cometmockConfig, upgrade: upgradeConfig, build: buildConfig, scripts }; } /** * Get all available chain types from defaults */ getAvailableChainTypes() { return Object.keys(this.defaultsData.defaultChains || {}); } /** * Check if a chain type is supported */ isChainTypeSupported(chainName) { return chainName in (this.defaultsData.defaultChains || {}); } /** * Get all defaults data (for debugging or advanced usage) */ getAllDefaults() { return this.defaultsData; } } exports.DefaultsManager = DefaultsManager; /** * Apply defaults to a StarshipConfig * This is a standalone function that processes all chains, relayers, and global configs */ function applyDefaults(config) { const defaultsManager = new DefaultsManager(); // Process chains with defaults const processedChains = config.chains?.map((chain) => defaultsManager.processChain(chain)); // Process relayers with defaults let processedRelayers; if (config.relayers && config.relayers?.length > 0) { processedRelayers = config.relayers.map((relayer) => defaultsManager.processRelayer(relayer)); } // Process global configurations individually to maintain type safety const processedConfig = { ...config, chains: processedChains, relayers: processedRelayers, ...(config.explorer && { explorer: defaultsManager.processExplorer(config.explorer) }), ...(config.registry && { registry: defaultsManager.processRegistry(config.registry) }), ...(config.faucet && { faucet: defaultsManager.processFaucet(config.faucet) }), ...(config.monitoring && { monitoring: defaultsManager.processMonitoring(config.monitoring) }), ...(config.ingress && { ingress: defaultsManager.processIngress(config.ingress) }), ...(config.exposer && { exposer: defaultsManager.processExposer(config.exposer) }), ...(config.images && { images: defaultsManager.processImages(config.images) }), ...(config.resources && { resources: defaultsManager.processResources(config.resources) }), ...(config.timeouts && { timeouts: defaultsManager.processTimeouts(config.timeouts) }) }; return processedConfig; } exports.applyDefaults = applyDefaults;