# 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) 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.map do |raw_asset| Asset.new(raw_asset["path"], raw_asset["integrity"]) end end 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 end end end