Class: Utopia::ImportMap
- Inherits:
-
Object
- Object
- Utopia::ImportMap
- Defined in:
- lib/utopia/import_map.rb
Overview
Represents an import map for JavaScript modules with support for URI and relative path resolution. Import maps allow you to control how JavaScript imports are resolved, supporting both absolute URLs and relative paths with proper context-aware resolution.
The builder pattern supports nested base URIs that are properly resolved relative to parent bases.
All URL resolution follows RFC 3986 via the protocol-url gem.
Defined Under Namespace
Classes: Builder
Instance Attribute Summary collapse
-
#base ⇒ Object
readonly
Returns the value of attribute base.
-
#imports ⇒ Object
readonly
Returns the value of attribute imports.
-
#integrity ⇒ Object
readonly
Returns the value of attribute integrity.
- #Scoped import mappings.(importmappings.) ⇒ Object readonly
-
#scopes ⇒ Object
readonly
Returns the value of attribute scopes.
- #Subresource integrity hashes for imports.(integrityhashes) ⇒ Object readonly
- #The imports mapping.(importsmapping.) ⇒ Object readonly
- #The parsed base URL for efficient resolution.(parsedbaseURL) ⇒ Object readonly
Class Method Summary collapse
-
.build(base: nil, &block) ⇒ Object
Create an import map using a builder pattern.
-
.load_manifest(root) ⇒ Object
Load the import mappings from a Web Packages static projection manifest.
Instance Method Summary collapse
-
#as_json ⇒ Object
Build the import map as a Hash with resolved paths.
-
#import(specifier, value, integrity: nil) ⇒ Object
Add an import mapping.
-
#initialize(imports = {}, integrity = {}, scopes = {}, base: nil) ⇒ ImportMap
constructor
Initialize a new import map.
-
#relative_to(path) ⇒ Object
Create a new import map with paths relative to the given page path.
-
#scope(scope_prefix, imports) ⇒ Object
Add a scope mapping.
-
#to_html ⇒ Object
Generate the import map as an XRB fragment suitable for embedding in HTML.
-
#to_json ⇒ Object
Convert the import map to JSON.
-
#to_s ⇒ Object
Convenience method for rendering the import map as an HTML string.
Constructor Details
#initialize(imports = {}, integrity = {}, scopes = {}, base: nil) ⇒ ImportMap
Initialize a new import map.
Typically you should use build instead of calling this directly.
225 226 227 228 229 230 |
# File 'lib/utopia/import_map.rb', line 225 def initialize(imports = {}, integrity = {}, scopes = {}, base: nil) @imports = imports @integrity = integrity @scopes = scopes @base = Protocol::URL[base] end |
Instance Attribute Details
#base ⇒ Object (readonly)
Returns the value of attribute base.
242 243 244 |
# File 'lib/utopia/import_map.rb', line 242 def base @base end |
#imports ⇒ Object (readonly)
Returns the value of attribute imports.
233 234 235 |
# File 'lib/utopia/import_map.rb', line 233 def imports @imports end |
#integrity ⇒ Object (readonly)
Returns the value of attribute integrity.
236 237 238 |
# File 'lib/utopia/import_map.rb', line 236 def integrity @integrity end |
#Scoped import mappings.(importmappings.) ⇒ Object (readonly)
239 |
# File 'lib/utopia/import_map.rb', line 239 attr :scopes |
#scopes ⇒ Object (readonly)
Returns the value of attribute scopes.
239 240 241 |
# File 'lib/utopia/import_map.rb', line 239 def scopes @scopes end |
#Subresource integrity hashes for imports.(integrityhashes) ⇒ Object (readonly)
236 |
# File 'lib/utopia/import_map.rb', line 236 attr :integrity |
#The imports mapping.(importsmapping.) ⇒ Object (readonly)
233 |
# File 'lib/utopia/import_map.rb', line 233 attr :imports |
#The parsed base URL for efficient resolution.(parsedbaseURL) ⇒ Object (readonly)
242 |
# File 'lib/utopia/import_map.rb', line 242 attr :base |
Class Method Details
.build(base: nil, &block) ⇒ Object
Create an import map using a builder pattern.
The builder supports both block parameter and instance_eval styles. The returned import map is frozen to prevent accidental mutation.
209 210 211 212 213 214 215 |
# File 'lib/utopia/import_map.rb', line 209 def self.build(base: nil, &block) instance = self.new(base: base) builder = Builder.build(instance, &block) return instance.freeze end |
.load_manifest(root) ⇒ Object
Load the import mappings from a Web Packages static projection manifest.
62 63 64 65 66 67 68 69 70 |
# File 'lib/utopia/import_map.rb', line 62 def self.load_manifest(root) manifest = Web::Packages::Manifest.load(root) base = Protocol::URL[manifest.data.fetch("base")] imports = manifest.import_map.fetch("imports").transform_values do |value| Protocol::URL[value].relative_to(base).to_s end return self.new(imports, base: base).freeze end |
Instance Method Details
#as_json ⇒ Object
Build the import map as a Hash with resolved paths.
All relative paths are resolved against the base URL if present.
Absolute URLs and protocol-relative URLs are preserved as-is.
This method is compatible with the JSON gem's as_json convention.
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/utopia/import_map.rb', line 329 def as_json(...) result = {} # Add imports if @imports.any? result["imports"] = resolve_imports(@imports, @base) end # Add scopes if @scopes.any? result["scopes"] = {} @scopes.each do |scope_prefix, scope_imports| # Resolve the scope prefix itself with base scope_url = Protocol::URL[scope_prefix] resolved_prefix = if @base && !scope_url.is_a?(Protocol::URL::Absolute) (@base + scope_url).to_s else scope_prefix end result["scopes"][resolved_prefix] = resolve_imports(scope_imports, @base) end end # Add integrity if @integrity.any? result["integrity"] = @integrity.dup end return result end |
#import(specifier, value, integrity: nil) ⇒ Object
Add an import mapping.
250 251 252 253 254 255 |
# File 'lib/utopia/import_map.rb', line 250 def import(specifier, value, integrity: nil) @imports[specifier] = value @integrity[specifier] = integrity if integrity self end |
#relative_to(path) ⇒ Object
Create a new import map with paths relative to the given page path. This is useful for creating page-specific import maps from a global one.
284 285 286 287 288 289 290 |
# File 'lib/utopia/import_map.rb', line 284 def relative_to(path) resolved_base = @base&.relative_to(path) instance = self.class.new(@imports.dup, @integrity.dup, @scopes.dup, base: resolved_base) return instance.freeze end |
#scope(scope_prefix, imports) ⇒ Object
Add a scope mapping.
Scopes allow different import resolutions based on the referrer URL. See https://github.com/WICG/import-maps#scoping-examples for details.
265 266 267 268 269 |
# File 'lib/utopia/import_map.rb', line 265 def scope(scope_prefix, imports) @scopes[scope_prefix] = imports self end |
#to_html ⇒ Object
Generate the import map as an XRB fragment suitable for embedding in HTML.
Creates a <script type="importmap"> tag containing the JSON representation.
373 374 375 376 377 378 379 380 381 |
# File 'lib/utopia/import_map.rb', line 373 def to_html json_data = to_json XRB::Builder.fragment do |builder| builder.inline("script", type: "importmap") do builder.raw(json_data) end end end |
#to_json ⇒ Object
Convert the import map to JSON.
364 365 366 |
# File 'lib/utopia/import_map.rb', line 364 def to_json(...) as_json.to_json(...) end |
#to_s ⇒ Object
Convenience method for rendering the import map as an HTML string.
Equivalent to to_html.to_s.
388 389 390 |
# File 'lib/utopia/import_map.rb', line 388 def to_s to_html.to_s end |