Module: Alap

Defined in:
lib/alap/deep_freeze.rb,
lib/alap.rb,
lib/alap/deep_clone.rb,
lib/alap/ssrf_guard.rb,
lib/alap/sanitize_url.rb,
lib/alap/validate_regex.rb,
lib/alap/link_provenance.rb,
lib/alap/validate_config.rb,
lib/alap/sanitize_by_tier.rb,
lib/alap/expression_parser.rb

Overview

Copyright 2026 Daniel Smith Licensed under the Apache License, Version 2.0 See www.apache.org/licenses/LICENSE-2.0

Defined Under Namespace

Modules: DeepClone, DeepFreeze, LinkProvenance, SanitizeByTier, SanitizeUrl, SsrfGuard, ValidateConfig, ValidateRegex Classes: ConfigMigrationError, ExpressionParser

Class Method Summary collapse

Class Method Details

Resolve an expression and return { “allLinks” => { id => link, … } }.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/alap.rb', line 33

def self.cherry_pick_links(config, expression)
  parser = ExpressionParser.new(config)
  ids = parser.query(expression)
  all_links = config["allLinks"] || {}

  result = {}
  ids.each do |item_id|
    link = all_links[item_id]
    result[item_id] = sanitize_link(link) if link.is_a?(Hash)
  end
  result
end

.merge_configs(*configs) ⇒ Object

Shallow-merge multiple Alap configs. Later configs win on collision.



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

def self.merge_configs(*configs)
  blocked = Set.new(%w[__proto__ constructor prototype])
  settings = {}
  macros = {}
  all_links = {}
  search_patterns = {}
  protocols = {}

  configs.each do |cfg|
    next unless cfg.is_a?(Hash)

    (cfg["settings"] || {}).each { |k, v| settings[k] = v unless blocked.include?(k) }
    (cfg["macros"] || {}).each { |k, v| macros[k] = v unless blocked.include?(k) }
    (cfg["allLinks"] || {}).each { |k, v| all_links[k] = v unless blocked.include?(k) }
    (cfg["searchPatterns"] || {}).each { |k, v| search_patterns[k] = v unless blocked.include?(k) }
    (cfg["protocols"] || {}).each { |k, v| protocols[k] = v unless blocked.include?(k) }
  end

  result = { "allLinks" => all_links }
  result["settings"] = settings unless settings.empty?
  result["macros"] = macros unless macros.empty?
  result["searchPatterns"] = search_patterns unless search_patterns.empty?
  result["protocols"] = protocols unless protocols.empty?
  result
end

.resolve_expression(config, expression, anchor_id: nil) ⇒ Object

Resolve an expression against a config and return matching link hashes with IDs.



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/alap.rb', line 19

def self.resolve_expression(config, expression, anchor_id: nil)
  parser = ExpressionParser.new(config)
  ids = parser.query(expression, anchor_id: anchor_id)
  all_links = config["allLinks"] || {}

  ids.each_with_object([]) do |item_id, results|
    link = all_links[item_id]
    next unless link.is_a?(Hash)

    results << { "id" => item_id }.merge(sanitize_link(link))
  end
end