Class: Jets::Router::Route

Inherits:
Object
  • Object
show all
Includes:
Authorizer, Util
Defined in:
lib/jets/router/route.rb,
lib/jets/router/route/authorizer.rb

Defined Under Namespace

Modules: Authorizer

Constant Summary collapse

CAPTURE_REGEX =

as string

"([^/]*)"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Authorizer

#api_key_required, #authorization_scopes, #authorization_type, #authorizer, #authorizer_id, #authorizer_metadata

Methods included from Authorizer::ModuleMethods

#logical_id, #metadata

Methods included from Util

#get_controller_action, #handle_on!, #join, #underscore

Constructor Details

#initialize(options, scope = Scope.new) ⇒ Route

Returns a new instance of Route.



14
15
16
17
18
19
# File 'lib/jets/router/route.rb', line 14

def initialize(options, scope=Scope.new)
  @options, @scope = options, scope
  @path = compute_path
  @to = compute_to
  @as = compute_as
end

Instance Attribute Details

#asObject (readonly)

Returns the value of attribute as.



13
14
15
# File 'lib/jets/router/route.rb', line 13

def as
  @as
end

#toObject (readonly)

Returns the value of attribute to.



13
14
15
# File 'lib/jets/router/route.rb', line 13

def to
  @to
end

Instance Method Details

#account_on(prefix) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/jets/router/route.rb', line 49

def (prefix)
  # Tricky @scope.from == :resources since the account_scope already has accounted for it
  if @options[:on] == :collection && @scope.from == :resources
    prefix = prefix.split('/')[0..-2].join('/')
  end
  prefix == '' ? nil : prefix
end

#account_scope(prefix) ⇒ Object



38
39
40
41
42
43
44
45
46
47
# File 'lib/jets/router/route.rb', line 38

def (prefix)
  return unless prefix
  return prefix unless @options[:from_scope]

  if @options[:singular_resource]
    prefix.split('/')[0..-2].join('/')
  else
    prefix.split('/')[0..-3].join('/')
  end
end

#action_nameObject

IE: index



112
113
114
# File 'lib/jets/router/route.rb', line 112

def action_name
  to.sub(/.*#/,'')
end

#compute_asObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/jets/router/route.rb', line 64

def compute_as
  return nil if @options[:as] == :disabled
  return unless @options[:method] == :get || @options[:root]

  controller, action = get_controller_action(@options)
  klass = if @options[:root]
    Jets::Router::MethodCreator::Root
  elsif %w[index edit show new].include?(action.to_s)
    class_name = "Jets::Router::MethodCreator::#{action.camelize}"
    class_name.constantize # Index, Show, Edit, New
  else
    Jets::Router::MethodCreator::Generic
  end

  klass.new(@options, @scope, controller).full_meth_name(nil)
end

#compute_pathObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/jets/router/route.rb', line 21

def compute_path
  # Note: The @options[:prefix] is missing prefix and is not support via direct create_route.
  # This is because it can be added directly to the path. IE:
  #
  #     get "myprefix/posts", to: "posts#index"
  #
  # Also, this helps to keep the method creator logic more simple.
  #
  prefix = @scope.full_prefix
  prefix = (prefix)
  prefix = (prefix)

  path = [prefix, @options[:path]].compact.join('/')
  path = path[1..-1] if path.starts_with?('/') # be more forgiving if / accidentally included
  path
end

#compute_toObject



57
58
59
60
61
62
# File 'lib/jets/router/route.rb', line 57

def compute_to
  controller, action = get_controller_action(@options)
  mod = @options[:module] || @scope.full_module
  controller = [mod, controller].compact.join('/') # add module
  "#{controller}##{action}"
end

#controller_nameObject

IE: PostsController



107
108
109
# File 'lib/jets/router/route.rb', line 107

def controller_name
  to.sub(/#.*/,'').camelize + "Controller"
end

#extract_parameters(actual_path) ⇒ Object

Extracts the path parameters from the actual path Only supports extracting 1 parameter. So:

actual_path: posts/tung/edit
route.path: posts/:id/edit

Returns:

{ id: "tung" }


135
136
137
138
139
140
141
142
143
144
# File 'lib/jets/router/route.rb', line 135

def extract_parameters(actual_path)
  if path.include?(':')
    extract_parameters_capture(actual_path)
  elsif path.include?('*')
    extract_parameters_proxy(actual_path)
  else
    # Lambda AWS_PROXY sets null to the input request when there are no path parmeters
    nil
  end
end

#extract_parameters_capture(actual_path) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/jets/router/route.rb', line 168

def extract_parameters_capture(actual_path)
  # changes path to a string used for a regexp
  # posts/:id/edit => posts\/(.*)\/edit
  labels = []
  regexp_string = path.split('/').map do |s|
                    if s.start_with?(':')
                      labels << s.delete_prefix(':')
                      CAPTURE_REGEX
                    else
                      s
                    end
                  end.join('\/')
  # make sure beginning and end of the string matches
  regexp_string = "^#{regexp_string}$"
  regexp = Regexp.new(regexp_string)

  values = regexp.match(actual_path).captures
  labels.map do |next_label|
    [next_label, values.delete_at(0)]
  end.to_h
end

#extract_parameters_proxy(actual_path) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/jets/router/route.rb', line 146

def extract_parameters_proxy(actual_path)
  # changes path to a string used for a regexp
  # others/*proxy => others\/(.*)
  # nested/others/*proxy => nested/others\/(.*)
  if path.include?('/')
    leading_path = path.split('/')[0..-2].join('/') # drop last segment
    # leading_path: nested/others
    # capture everything after the leading_path as the value
    regexp = Regexp.new("#{leading_path}/(.*)")
    value = actual_path.match(regexp)[1]
  else
    value = actual_path
  end

  # the last segment without the '*' is the key
  proxy_segment = path.split('/').last # last segment is the proxy segment
  # proxy_segment: *proxy
  key = proxy_segment.sub('*','')

  { key => value }
end

#homepage?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/jets/router/route.rb', line 102

def homepage?
  path == ''
end

#internal?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/jets/router/route.rb', line 98

def internal?
  !!@options[:internal]
end

#methodObject



94
95
96
# File 'lib/jets/router/route.rb', line 94

def method
  @options[:method].to_s.upcase
end

#mount_classObject



190
191
192
# File 'lib/jets/router/route.rb', line 190

def mount_class
  @options[:mount_class]
end

#path(format = :jets) ⇒ Object

IE: standard: posts/:id/edit

api_gateway: posts/{id}/edit


83
84
85
86
87
88
89
90
91
92
# File 'lib/jets/router/route.rb', line 83

def path(format=:jets)
  case format
  when :api_gateway
    api_gateway_format(@path)
  when :raw
    @path
  else # jets format
    ensure_jets_format(@path)
  end
end

#to_hObject



194
195
196
# File 'lib/jets/router/route.rb', line 194

def to_h
  JSON.load(to_json)
end

#valid?Boolean

Checks to see if the corresponding controller exists. Useful to validate routes before deploying to CloudFormation and then rolling back.

Returns:

  • (Boolean)


118
119
120
121
122
123
124
125
# File 'lib/jets/router/route.rb', line 118

def valid?
  controller_class = begin
    controller_name.constantize
  rescue NameError
    return false
  end
  controller_class.lambda_functions.include?(action_name.to_sym)
end