class CKEditor5::Rails::VersionDetector
def clear_cache!
def clear_cache! @monitor.synchronize { @cache.clear } end
def fetch_all_versions
def fetch_all_versions uri = URI("https://registry.npmjs.org/#{NPM_PACKAGE}") response = fetch_with_timeout(uri) if response.is_a?(Net::HTTPSuccess) data = JSON.parse(response.body) data['versions'].keys else warn 'Failed to fetch CKEditor versions' [] end rescue StandardError => e warn "Error fetching versions: #{e.message}" [] end
def fetch_with_timeout(uri)
def fetch_with_timeout(uri) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.scheme == 'https') http.open_timeout = 1 http.read_timeout = 1 http.get(uri.request_uri) end
def find_latest_safe_version(current_version)
def find_latest_safe_version(current_version) versions = fetch_all_versions return nil if versions.empty? current_semver = Semver.new(current_version) versions .reject { |v| v.include?('nightly') || v.include?('dev') } .select { |v| v.match?(Semver::SEMVER_PATTERN) } .sort_by { |v| Semver.new(v) } .reverse .find { |v| current_semver.safe_update?(v) } end
def initialize
def initialize @cache = {} @monitor = Monitor.new end
def latest_safe_version(current_version)
def latest_safe_version(current_version) @monitor.synchronize do cache_key = "#{current_version}_latest" return @cache[cache_key][:version] if valid_cache_entry?(cache_key) version = find_latest_safe_version(current_version) @cache[cache_key] = { version: version, timestamp: Time.now.to_i } version end end
def valid_cache_entry?(key)
def valid_cache_entry?(key) entry = @cache[key] entry && (Time.now.to_i - entry[:timestamp] < CACHE_DURATION) end