class SvelteOnRails::Configuration
def self.instance
def self.instance @instance ||= new end
def client_dist_folder(app_root = nil)
def client_dist_folder(app_root = nil) if Rails.env.development? rails_root(app_root).join('public', 'vite') else rails_root(app_root).join('public', 'vite') end end
def components_folder
def components_folder Pathname.new(@configs[:components_folder].to_s) end
def components_folder_full
def components_folder_full Pathname.new(frontend_folder_full).join(components_folder.to_s) end
def frontend_folder
def frontend_folder Pathname.new(@configs[:frontend_folder].to_s) end
def frontend_folder_full
def frontend_folder_full rails_root.join(@configs[:frontend_folder].to_s) end
def initialize
def initialize @configs = redis_cache_store_configs return unless defined?(Rails.root) config_path = Rails.root.join("config", "svelte_on_rails.yml") return unless File.exist?(config_path) environments = Dir[Rails.root.join('config', 'environments', '*.rb')] .map { |file| File.basename(file, '.rb') } configs_base = YAML.load_file(config_path) @configs = @configs.deep_merge(configs_base.reject { |k, _| environments.include?(k) }) @configs = @configs.deep_merge(configs_base[Rails.env] || {}) @configs = @configs.symbolize_keys if @configs[:redis_cache_store] if @configs[:redis_cache_store]['expires_in'].is_a?(String) @configs[:redis_cache_store]['expires_in'] = parse_duration( @configs[:redis_cache_store]['expires_in'] ) end end if defined? Redis @redis_instance = Redis.new(url: redis_cache_store[:url]) end end
def node_bin_path
def node_bin_path @node_bin_path ||= begin n = ENV['SVELTE_ON_RAILS_NODE_BIN'] || 'node' if n == 'node' nvm_installed = false nvm_dir = ENV['NVM_DIR'] || File.expand_path('~/.nvm') nvm_installed ||= File.exist?("#{nvm_dir}/nvm.sh") if nvm_installed # Check for .nvmrc in the project root project_root = rails_root || Dir.pwd nvmrc_path = File.join(project_root, '.nvmrc') use_nvmrc = File.exist?(nvmrc_path) if use_nvmrc # Read the version from .nvmrc node_version = File.read(nvmrc_path).strip # Ensure NVM is sourced and use the version from .nvmrc command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm use #{node_version} > /dev/null 2>&1 && nvm which #{node_version}" else # Fallback to current NVM version command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm which current" end node_path, status = Open3.capture2("bash -lc '#{command}'") # Only update n if the command succeeded and output is non-empty n = node_path.strip if status.success? && !node_path.strip.empty? end end # Validate node_bin unless n && !n.empty? && system("#{n} --version > /dev/null 2>&1") raise "Node.js not found at '#{n || 'unknown'}'. Please configure SVELTE_ON_RAILS_NODE_BIN (e.g., to ~/.nvm/versions/node/vX.Y.Z/bin/node) or ensure 'node' is in the PATH. If using NVM, run `nvm alias default <version>` to set a default version or ensure a valid .nvmrc file is present." end n rescue StandardError => e raise "Failed to detect Node.js binary: «#{e.message}». Ensure Node.js is installed and accessible, or set SVELTE_ON_RAILS_NODE_BIN. If using .nvmrc, ensure the specified version is installed via NVM." end end
def non_ssr_request_header
def non_ssr_request_header rss = @configs[:non_ssr_request_header] if rss.present? rss else 'X-Turbo-Request-ID' end end
def parse_duration(string)
def parse_duration(string) # Extract number and unit match = string.match(/^(\d+)\.(\w+)$/) raise ArgumentError, "Invalid duration format: #{string}" unless match number, unit = match[1].to_i, match[2] # Ensure the unit is a valid ActiveSupport duration method valid_units = %w[seconds minutes hours days weeks months years] raise ArgumentError, "Invalid unit: #{unit} (valid: #{valid_units})" unless valid_units.include?(unit) ActiveSupport::Duration.build(number.send(unit)) end
def rails_root(root_url = nil)
def rails_root(root_url = nil) root_url || Rails.root end
def redis_cache_store
def redis_cache_store (@configs[:redis_cache_store] || {}).transform_keys(&:to_sym) end
def redis_cache_store_configs
def redis_cache_store_configs if defined?(Rails.application) && Rails.application.config.cache_store.is_a?(Array) && Rails.application.config.cache_store.first == :redis_cache_store { 'redis_cache_store' => Rails.application.config.cache_store.second.stringify_keys } else {} end end
def redis_instance
def redis_instance @redis_instance end
def ssr
def ssr rss = @configs[:ssr] if rss == false || rss == :auto rss else true end end
def ssr_dist_folder(app_root = nil)
def ssr_dist_folder(app_root = nil) rails_root(app_root).join('public', 'vite-ssr') end
def ssr_manifest
def ssr_manifest file = rails_root.join('public', 'vite-ssr', 'manifest.json') if watch_changes? begin JSON.parse(File.read(file)) rescue raise "ERROR: Could not read public/vite-ssr/manifest.json." end else @manifest ||= JSON.parse(File.read(file)) end end
def system_type
def system_type :vite_rails end
def watch_changes?
def watch_changes? @configs[:watch_changes] == true end