class Importmap::Packager

Constants

Error
HTTPError
ServiceError

Attributes

endpoint[RW]
vendor_path[R]

Public Class Methods

new(importmap_path = "config/importmap.rb", vendor_path: "vendor/javascript") click to toggle source
# File lib/importmap/packager.rb, line 15
def initialize(importmap_path = "config/importmap.rb", vendor_path: "vendor/javascript")
  @importmap_path = Pathname.new(importmap_path)
  @vendor_path    = Pathname.new(vendor_path)
end

Public Instance Methods

download(package, url) click to toggle source
# File lib/importmap/packager.rb, line 54
def download(package, url)
  ensure_vendor_directory_exists
  remove_existing_package_file(package)
  download_package_file(package, url)
end
import(*packages, env: "production", from: "jspm") click to toggle source
# File lib/importmap/packager.rb, line 20
def import(*packages, env: "production", from: "jspm")
  response = post_json({
    "install"      => Array(packages), 
    "flattenScope" => true,
    "env"          => [ "browser", "module", env ],
    "provider"     => from.to_s,
  })

  case response.code
  when "200"        then extract_parsed_imports(response)
  when "404", "401" then nil
  else                   handle_failure_response(response)
  end
end
packaged?(package) click to toggle source
# File lib/importmap/packager.rb, line 50
def packaged?(package)
  importmap.match(/^pin "#{package}".*$/)
end
pin_for(package, url) click to toggle source
# File lib/importmap/packager.rb, line 35
def pin_for(package, url)
  %(pin "#{package}", to: "#{url}")
end
remove(package) click to toggle source
# File lib/importmap/packager.rb, line 60
def remove(package)
  remove_existing_package_file(package)
  remove_package_from_importmap(package)
end
vendored_pin_for(package, url) click to toggle source
# File lib/importmap/packager.rb, line 39
def vendored_pin_for(package, url)
  filename = package_filename(package)
  version  = extract_package_version_from(url)

  if "#{package}.js" == filename
    %(pin "#{package}" # #{version})
  else
    %(pin "#{package}", to: "#{filename}" # #{version})
  end
end

Private Instance Methods

download_package_file(package, url) click to toggle source
# File lib/importmap/packager.rb, line 112
def download_package_file(package, url)
  response = Net::HTTP.get_response(URI(url))

  if response.code == "200"
    save_vendored_package(package, response.body)
  else
    handle_failure_response(response)
  end
end
ensure_vendor_directory_exists() click to toggle source
# File lib/importmap/packager.rb, line 95
def ensure_vendor_directory_exists
  FileUtils.mkdir_p @vendor_path
end
extract_package_version_from(url) click to toggle source
# File lib/importmap/packager.rb, line 140
def extract_package_version_from(url)
  url.match(/@\d+\.\d+\.\d+/)&.to_a&.first
end
extract_parsed_imports(response) click to toggle source
# File lib/importmap/packager.rb, line 72
def extract_parsed_imports(response)
  JSON.parse(response.body).dig("map", "imports")
end
handle_failure_response(response) click to toggle source
# File lib/importmap/packager.rb, line 76
def handle_failure_response(response)
  if error_message = parse_service_error(response)
    raise ServiceError, error_message
  else
    raise HTTPError, "Unexpected response code (#{response.code})"
  end
end
importmap() click to toggle source
# File lib/importmap/packager.rb, line 90
def importmap
  @importmap ||= File.read(@importmap_path)
end
package_filename(package) click to toggle source
# File lib/importmap/packager.rb, line 136
def package_filename(package)
  package.gsub("/", "--") + ".js"
end
parse_service_error(response) click to toggle source
# File lib/importmap/packager.rb, line 84
def parse_service_error(response)
  JSON.parse(response.body.to_s)["error"]
rescue JSON::ParserError
  nil
end
post_json(body) click to toggle source
# File lib/importmap/packager.rb, line 66
def post_json(body)
  Net::HTTP.post(self.class.endpoint, body.to_json, "Content-Type" => "application/json")
rescue => error
  raise HTTPError, "Unexpected transport error (#{error.class}: #{error.message})"
end
remove_existing_package_file(package) click to toggle source
# File lib/importmap/packager.rb, line 99
def remove_existing_package_file(package)
  FileUtils.rm_rf vendored_package_path(package)
end
remove_package_from_importmap(package) click to toggle source
# File lib/importmap/packager.rb, line 103
def remove_package_from_importmap(package)
  all_lines = File.readlines(@importmap_path)
  with_lines_removed = all_lines.select { |line| line !~ /pin "#{package}"/ }

  File.open(@importmap_path, "w") do |file|
    with_lines_removed.each { |line| file.write(line) }
  end
end
remove_sourcemap_comment_from(source) click to toggle source
# File lib/importmap/packager.rb, line 128
def remove_sourcemap_comment_from(source)
  source.gsub(/^\/\/# sourceMappingURL=.*/, "")
end
save_vendored_package(package, source) click to toggle source
# File lib/importmap/packager.rb, line 122
def save_vendored_package(package, source)
  File.open(vendored_package_path(package), "w+") do |vendored_package|
    vendored_package.write remove_sourcemap_comment_from(source).force_encoding("UTF-8")
  end
end
vendored_package_path(package) click to toggle source
# File lib/importmap/packager.rb, line 132
def vendored_package_path(package)
  @vendor_path.join(package_filename(package))
end