Class: Browsable::AssetResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/browsable/asset_resolver.rb

Overview

Translates an asset URL discovered in an HTML response into an on-disk file path under the Rails app. Runtime mode hands every <link> / <script src> through here so the end-of-suite analyzers can read those files directly.

The resolver is intentionally conservative: it returns ‘nil` rather than guessing when a URL clearly belongs to a third-party CDN, when the digested filename does not map back to a real source on disk, or when the host Rails app cannot be introspected. The TestReport surfaces those misses as skipped entries — never as fabricated findings.

Defined Under Namespace

Classes: Result

Constant Summary collapse

DIGEST_PATTERN =
/-[0-9a-f]{7,64}(?=\.\w+\z)/.freeze
DEFAULT_ROOTS =
%w[
  app/assets/stylesheets
  app/assets/javascripts
  app/javascript
  app/assets/builds
  vendor/assets/stylesheets
  vendor/assets/javascripts
  public
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rails_app: nil, root: nil, search_roots: nil) ⇒ AssetResolver

Returns a new instance of AssetResolver.



35
36
37
38
39
# File 'lib/browsable/asset_resolver.rb', line 35

def initialize(rails_app: nil, root: nil, search_roots: nil)
  @rails_app = rails_app || (defined?(Rails) ? Rails.application : nil)
  @root = root && File.expand_path(root)
  @search_roots = search_roots
end

Instance Attribute Details

#rails_appObject (readonly)

Returns the value of attribute rails_app.



33
34
35
# File 'lib/browsable/asset_resolver.rb', line 33

def rails_app
  @rails_app
end

Instance Method Details

#detailed_resolve(url) ⇒ Object

Same as #resolve, but returns a Result carrying which strategy matched —useful for the benchmark script and for skipped-entry diagnostics.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/browsable/asset_resolver.rb', line 49

def detailed_resolve(url)
  return Result.new(path: nil, strategy: :empty) if url.nil? || url.empty?

  path = path_component(url)
  return Result.new(path: nil, strategy: :external) if path.nil?

  undigested = strip_digest(path)

  if (hit = resolve_via_propshaft(undigested))
    return Result.new(path: hit, strategy: :propshaft)
  end

  if (hit = resolve_via_sprockets(undigested))
    return Result.new(path: hit, strategy: :sprockets)
  end

  if (hit = resolve_via_filesystem(undigested))
    return Result.new(path: hit, strategy: :filesystem)
  end

  if (hit = resolve_via_public(undigested))
    return Result.new(path: hit, strategy: :public)
  end

  Result.new(path: nil, strategy: :unresolved)
end

#resolve(url) ⇒ Object

Resolve a URL to an absolute on-disk path. Returns nil for URLs we cannot honestly attribute to a file in the host application.



43
44
45
# File 'lib/browsable/asset_resolver.rb', line 43

def resolve(url)
  detailed_resolve(url).path
end