Class: Philiprehberger::UriKit::Url

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/uri_kit.rb

Overview

Parsed URL wrapper with mutation methods

Instance Method Summary collapse

Constructor Details

#initialize(url_string) ⇒ Url

Returns a new instance of Url.

Parameters:

  • url_string (String)

    the URL to parse



13
14
15
16
17
# File 'lib/philiprehberger/uri_kit.rb', line 13

def initialize(url_string)
  @uri = ::URI.parse(url_string.to_s.strip)
rescue ::URI::InvalidURIError => e
  raise Error, "Invalid URL: #{e.message}"
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Value equality based on string representation

Parameters:

  • other (Object)

    object to compare

Returns:

  • (Boolean)


184
185
186
# File 'lib/philiprehberger/uri_kit.rb', line 184

def ==(other)
  other.is_a?(self.class) && to_s == other.to_s
end

#add_param(key, val) ⇒ Url

Add a query parameter

Parameters:

  • key (String)

    parameter name

  • val (String)

    parameter value

Returns:

  • (Url)

    self for chaining



24
25
26
27
28
29
# File 'lib/philiprehberger/uri_kit.rb', line 24

def add_param(key, val)
  current = params
  current[key.to_s] = val.to_s
  @uri.query = encode_params(current)
  self
end

#add_params(hash) ⇒ Url

Add multiple query parameters at once

Parameters:

  • hash (Hash)

    parameters to add

Returns:

  • (Url)

    a new Url with the added parameters



122
123
124
125
126
127
# File 'lib/philiprehberger/uri_kit.rb', line 122

def add_params(hash)
  merged = params.merge(hash.transform_keys(&:to_s).transform_values(&:to_s))
  new_url = build_with(query: nil)
  new_url.instance_variable_get(:@uri).query = encode_params(merged) unless merged.empty?
  new_url
end

#append_path(segment) ⇒ Url

Append a path segment, handling leading/trailing slashes correctly

Parameters:

  • segment (String)

    the path segment to append

Returns:

  • (Url)

    a new Url with the appended path



95
96
97
98
99
100
# File 'lib/philiprehberger/uri_kit.rb', line 95

def append_path(segment)
  current = @uri.path.chomp('/')
  clean_segment = segment.to_s.sub(%r{^/}, '')
  new_path = "#{current}/#{clean_segment}"
  build_with(path: new_path)
end

#base_urlString

Get the base URL (scheme + host + port only)

Returns:

  • (String)

    the base URL string



139
140
141
142
143
# File 'lib/philiprehberger/uri_kit.rb', line 139

def base_url
  base = "#{@uri.scheme}://#{@uri.host}"
  base += ":#{@uri.port}" if @uri.port && !default_port?
  base
end

#clear_paramsUrl

Remove all query parameters

Returns:

  • (Url)

    a new Url with no query parameters



132
133
134
# File 'lib/philiprehberger/uri_kit.rb', line 132

def clear_params
  build_with(query: nil)
end

#domainString?

Get the registered domain (host without subdomain)

Returns:

  • (String, nil)

    the domain



70
71
72
73
74
75
76
77
# File 'lib/philiprehberger/uri_kit.rb', line 70

def domain
  return nil unless @uri.host

  parts = @uri.host.split('.')
  return @uri.host if parts.length <= 2

  parts.last(2).join('.')
end

#fragmentString?

Returns the fragment.

Returns:

  • (String, nil)

    the fragment



171
172
173
# File 'lib/philiprehberger/uri_kit.rb', line 171

def fragment
  @uri.fragment
end

#hashInteger

Returns hash code consistent with eql?.

Returns:

  • (Integer)

    hash code consistent with eql?



191
192
193
# File 'lib/philiprehberger/uri_kit.rb', line 191

def hash
  to_s.hash
end

#hostString?

Returns the hostname.

Returns:

  • (String, nil)

    the hostname



151
152
153
# File 'lib/philiprehberger/uri_kit.rb', line 151

def host
  @uri.host
end

#normalizeUrl

Normalize the URL (lowercase scheme/host, remove default ports, sort params)

Returns:

  • (Url)

    self for chaining



57
58
59
60
61
62
63
64
65
# File 'lib/philiprehberger/uri_kit.rb', line 57

def normalize
  @uri.scheme = @uri.scheme&.downcase
  @uri.host = @uri.host&.downcase
  remove_default_port
  sort_params
  @uri.path = '/' if @uri.path.empty? && @uri.host
  @uri.fragment = nil if @uri.fragment && @uri.fragment.empty?
  self
end

#paramsHash<String, String>

Get all query parameters as a hash

Returns:

  • (Hash<String, String>)

    parameter key-value pairs



45
46
47
48
49
50
51
52
# File 'lib/philiprehberger/uri_kit.rb', line 45

def params
  return {} if @uri.query.nil? || @uri.query.empty?

  @uri.query.split('&').each_with_object({}) do |pair, hash|
    key, value = pair.split('=', 2)
    hash[::URI.decode_www_form_component(key)] = ::URI.decode_www_form_component(value || '')
  end
end

#pathString

Returns the path component.

Returns:

  • (String)

    the path component



161
162
163
# File 'lib/philiprehberger/uri_kit.rb', line 161

def path
  @uri.path
end

#path_segmentsArray<String>

Get path segments as an array

Returns:

  • (Array<String>)

    non-empty path segments



105
106
107
# File 'lib/philiprehberger/uri_kit.rb', line 105

def path_segments
  @uri.path.split('/').reject(&:empty?)
end

#portInteger?

Returns the port number.

Returns:

  • (Integer, nil)

    the port number



156
157
158
# File 'lib/philiprehberger/uri_kit.rb', line 156

def port
  @uri.port
end

#queryString?

Returns the raw query string.

Returns:

  • (String, nil)

    the raw query string



166
167
168
# File 'lib/philiprehberger/uri_kit.rb', line 166

def query
  @uri.query
end

#remove_param(key) ⇒ Url

Remove a query parameter

Parameters:

  • key (String)

    parameter name to remove

Returns:

  • (Url)

    self for chaining



35
36
37
38
39
40
# File 'lib/philiprehberger/uri_kit.rb', line 35

def remove_param(key)
  current = params
  current.delete(key.to_s)
  @uri.query = current.empty? ? nil : encode_params(current)
  self
end

#replace_path(new_path) ⇒ Url

Replace the entire path

Parameters:

  • new_path (String)

    the new path

Returns:

  • (Url)

    a new Url with the replaced path



113
114
115
116
# File 'lib/philiprehberger/uri_kit.rb', line 113

def replace_path(new_path)
  normalized = new_path.to_s.start_with?('/') ? new_path.to_s : "/#{new_path}"
  build_with(path: normalized)
end

#schemeString?

Returns the URL scheme (e.g. “https”).

Returns:

  • (String, nil)

    the URL scheme (e.g. “https”)



146
147
148
# File 'lib/philiprehberger/uri_kit.rb', line 146

def scheme
  @uri.scheme
end

#subdomainString?

Get the subdomain portion

Returns:

  • (String, nil)

    the subdomain



82
83
84
85
86
87
88
89
# File 'lib/philiprehberger/uri_kit.rb', line 82

def subdomain
  return nil unless @uri.host

  parts = @uri.host.split('.')
  return nil if parts.length <= 2

  parts[0...-2].join('.')
end

#to_sString

Returns the full URL string.

Returns:

  • (String)

    the full URL string



176
177
178
# File 'lib/philiprehberger/uri_kit.rb', line 176

def to_s
  @uri.to_s
end