module Sprockets::URIUtils

def build_asset_uri(path, params = {})

Returns String URI.

params - Hash of optional parameters
path - String file path

# => "file:///tmp/js/application.coffee?type=application/javascript"
build("/tmp/js/application.coffee", type: "application/javascript")

Examples

Internal: Build Asset URI.
def build_asset_uri(path, params = {})
  join_file_uri("file", nil, path, encode_uri_query_params(params))
end

def build_file_digest_uri(path)

Returns String URI.

path - String file path

# => "file-digest:/tmp/js/application.js"
build("/tmp/js/application.js")

Examples

Internal: Build file-digest dependency URI.
def build_file_digest_uri(path)
  join_file_uri('file-digest'.freeze, nil, path, nil)
end

def encode_uri_query_params(params)

Returns String query or nil if empty.

params - Hash of params to serialize

Internal: Serialize hash of params into query string.
def encode_uri_query_params(params)
  query = []
  params.each do |key, value|
    case value
    when Integer
      query << "#{key}=#{value}"
    when String, Symbol
      query << "#{key}=#{URI::Generic::DEFAULT_PARSER.escape(value.to_s)}"
    when TrueClass
      query << "#{key}"
    when FalseClass, NilClass
    else
      raise TypeError, "unexpected type: #{value.class}"
    end
  end
  "#{query.join('&')}" if query.any?
end

def join_file_uri(scheme, host, path, query)

Returns String.

Internal: Join file: URI component parts into String.
def join_file_uri(scheme, host, path, query)
  str = "#{scheme}://"
  str << host if host
  path = "/#{path}" unless path.start_with?("/")
  str << URI::Generic::DEFAULT_PARSER.escape(path)
  str << "?#{query}" if query
  str
end

def join_uri(scheme, userinfo, host, port, registry, path, opaque, query, fragment)

Returns String.

Internal: Join URI component parts into String.
def join_uri(scheme, userinfo, host, port, registry, path, opaque, query, fragment)
  URI::Generic.new(scheme, userinfo, host, port, registry, path, opaque, query, fragment).to_s
end

def parse_asset_uri(uri)

Returns String path and Hash of symbolized parameters.

uri - String asset URI

# => "/tmp/js/application.coffee", {type: "application/javascript"}
parse("file:///tmp/js/application.coffee?type=application/javascript")

Examples

Internal: Parse Asset URI.
def parse_asset_uri(uri)
  scheme, _, path, query = split_file_uri(uri)
  unless scheme == 'file'
    raise URI::InvalidURIError, "expected file:// scheme: #{uri}"
  end
  return path, parse_uri_query_params(query)
end

def parse_file_digest_uri(uri)

Returns String path.

uri - String file-digest URI

# => "/tmp/js/application.js"
parse("file-digest:/tmp/js/application.js")

Examples

Internal: Parse file-digest dependency URI.
def parse_file_digest_uri(uri)
  scheme, _, path, _ = split_file_uri(uri)
  unless scheme == 'file-digest'.freeze
    raise URI::InvalidURIError, "expected file-digest scheme: #{uri}"
  end
  path
end

def parse_uri_query_params(query)

Return Hash of params.

query - String query string

Internal: Parse query string into hash of params
def parse_uri_query_params(query)
  query.to_s.split('&').reduce({}) do |h, p|
    k, v = p.split('=', 2)
    v = URI::Generic::DEFAULT_PARSER.unescape(v) if v
    h[k.to_sym] = v || true
    h
  end
end

def split_file_uri(uri)

Returns [scheme, host, path, query].

uri - String uri

Internal: Parse file: URI into component parts.
def split_file_uri(uri)
  scheme, _, host, _, _, path, _, query, _ = URI.split(uri)
  path = URI::Generic::DEFAULT_PARSER.unescape(path)
  path.force_encoding(Encoding::UTF_8)
  # Hack for parsing Windows "file:///C:/Users/IEUser" paths
  path.gsub!(/^\/([a-zA-Z]:)/, '\1'.freeze)
  [scheme, host, path, query]
end

def split_uri(uri)

Returns Array of components.

uri - String uri

Internal: Parse URI into component parts.
def split_uri(uri)
  URI.split(uri)
end

def valid_asset_uri?(str)

Returns true or false.

str - Possible String asset URI.

Internal: Check if String is a valid Asset URI.
def valid_asset_uri?(str)
  # Quick prefix check before attempting a full parse
  str.start_with?("file://") && parse_asset_uri(str) ? true : false
rescue URI::InvalidURIError
  false
end