Class: Browsable::Sources::Importmap

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

Overview

Resolves importmap pins to their source and makes that source available to the JavaScript analyzer.

Rails importmap apps keep no node_modules: vendored JS is referenced by CDN URL in config/importmap.rb. This source reads those pins and downloads each remote file into a tmpdir so eslint can be pointed at real files.

config/importmap.rb is *parsed as text*, never evaluated — running an arbitrary project file just to read string literals is not worth the risk.

Defined Under Namespace

Classes: Pin

Constant Summary collapse

PIN_PATTERN =

‘pin “name”, to: “url”, …` — captures the name and an optional `to:`.

/^\s*pin\s+["']([^"']+)["'](?:[^\n]*?\bto:\s*["']([^"']+)["'])?/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root:) ⇒ Importmap

Returns a new instance of Importmap.



29
30
31
# File 'lib/browsable/sources/importmap.rb', line 29

def initialize(root:)
  @root = File.expand_path(root)
end

Instance Attribute Details

#rootObject (readonly)

Returns the value of attribute root.



27
28
29
# File 'lib/browsable/sources/importmap.rb', line 27

def root
  @root
end

Instance Method Details

#fetch(dir: Dir.mktmpdir("browsable-importmap")) ⇒ Object

Download every remote pin into ‘dir` and return the local file paths.

Remote fetches are skipped entirely when BROWSABLE_OFFLINE=1 — useful in CI, in air-gapped environments, or when a fast offline audit is wanted.



57
58
59
60
61
62
63
# File 'lib/browsable/sources/importmap.rb', line 57

def fetch(dir: Dir.mktmpdir("browsable-importmap"))
  return [] if ENV["BROWSABLE_OFFLINE"] == "1"

  pins.select(&:remote?).filter_map do |pin|
    download(pin, dir)
  end
end

#importmap_pathObject



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

def importmap_path
  File.join(root, "config/importmap.rb")
end

#pinsObject

All pins declared in config/importmap.rb.



42
43
44
45
46
47
48
49
50
51
# File 'lib/browsable/sources/importmap.rb', line 42

def pins
  return [] unless present?

  File.read(importmap_path).each_line.filter_map do |line|
    next if line.strip.start_with?("#")

    m = line.match(PIN_PATTERN)
    m && Pin.new(name: m[1], url: m[2])
  end
end

#present?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/browsable/sources/importmap.rb', line 37

def present?
  File.file?(importmap_path)
end