# frozen_string_literal: true require 'base64' require 'sewing_kit/webpack/manifest' module SewingKit module Webpack module Helper class UnknownAssetError < StandardError end Asset = Struct.new(:path, :integrity) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def sewing_kit_assets(entrypoint_name, extension: 'js') return '' unless entrypoint_name.present? assets = SewingKit::Webpack::Manifest.asset_dependencies(entrypoint_name, request.user_agent) raise UnknownAssetError, "#{entrypoint_name} was not found in manifest." if raise_unknown_error?(assets) return [] unless assets && assets[extension] dependencies = assets[extension] dependencies.unshift(dll_asset) if serve_development_assets? && extension == 'js' dependencies.map do |raw_asset| Asset.new(raw_asset['path'], raw_asset['integrity']) end end # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def sewing_kit_link_tag(*assets) options = assets.extract_options! tags = assets.uniq.map do |asset| next '' if asset.path == '' create_asset_tag(:link, asset, options) end safe_join(tags, "\n") end def sewing_kit_script_tag(*assets) options = assets.extract_options! tags = assets.map do |asset| next '' if asset.path == '' create_asset_tag(:script, asset, options) end safe_join(tags, "\n") end def sewing_kit_assets_bundle_name SewingKit::Webpack::Manifest.asset_bundle_name(request.user_agent) end private def create_asset_tag(tag_type, asset, tag_options) raise ArgumentError, "Invalid tag type: #{tag_type}" unless [:script, :link].include?(tag_type) options = tag_options.clone if tag_options[:integrity] && asset.integrity options[:integrity] = asset.integrity else options.delete(:integrity) end case tag_type when :script content_tag(:script, '', options.reverse_merge(src: asset.path)) when :link tag(:link, options.reverse_merge(href: asset.path, rel: 'stylesheet')) end end def serve_development_assets? return false if ENV['SK_SIMULATE_PRODUCTION'] == '1' Rails.env.development? end def raise_unknown_error?(assets) assets.nil? && serve_development_assets? end def dll_asset Asset.new('/webpack/assets/dll/vendor.js') end end end end