rackr 0.0.64 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/rackr.rb CHANGED
@@ -1,28 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'rackr/utils'
3
4
  require_relative 'rackr/action'
4
5
  require_relative 'rackr/callback'
5
- require_relative 'rackr/router/errors/dev_html'
6
6
  require_relative 'rackr/router'
7
7
 
8
+ # Rackr is a simple router for Rack.
8
9
  class Rackr
9
10
  class NotFound < StandardError; end
10
11
 
12
+ # Dump is a special error that is used to dump the content of a request.
13
+ class Dump < StandardError
14
+ attr_reader :content
15
+
16
+ def initialize(content)
17
+ @content = content
18
+
19
+ super
20
+ end
21
+ end
22
+
11
23
  HTTP_METHODS = %w[GET POST DELETE PUT TRACE OPTIONS PATCH].freeze
12
24
 
13
- include Action
25
+ include Callback
26
+ include Utils
14
27
 
15
28
  def initialize(config = {}, before: [], after: [])
16
29
  @router = Router.new(config, before: before, after: after)
17
30
  end
18
31
 
19
- def call(&block)
20
- instance_eval(&block)
21
- puts "\n= Routes =============="
22
- routes.each_pair { |v| p v }
23
- puts "\n= Config =============="
24
- puts config
25
- puts "\n"
32
+ def call(&)
33
+ instance_eval(&)
26
34
 
27
35
  @router
28
36
  end
@@ -40,7 +48,15 @@ class Rackr
40
48
  end
41
49
 
42
50
  def db
43
- @router.config.dig(:deps, :db)
51
+ @router.config&.dig(:deps, :db)
52
+ end
53
+
54
+ def log
55
+ @router.config&.dig(:deps, :log)
56
+ end
57
+
58
+ def cache
59
+ @router.config&.dig(:deps, :cache)
44
60
  end
45
61
 
46
62
  def scope(name = '', before: [], after: [], &block)
@@ -62,50 +78,105 @@ class Rackr
62
78
  end
63
79
  end
64
80
 
65
- def error(endpoint = -> {}, &block)
81
+ def error(error_class_or_endpoint = nil, endpoint = nil, &block)
66
82
  if block_given?
67
- @router.add_error(block)
83
+ if error_class_or_endpoint
84
+ @router.add_error(block, error_class_or_endpoint)
85
+ else
86
+ @router.add_error(block)
87
+ end
88
+ elsif endpoint
89
+ @router.add_error(endpoint, error_class_or_endpoint)
68
90
  else
69
- @router.add_error(endpoint)
91
+ @router.add_error(error_class_or_endpoint)
70
92
  end
71
93
  end
72
94
 
73
- def resources(name, id: :id, before: [], after: [], &block)
74
- @resource_namespace = (@resource_namespace || []).push([name.to_s.capitalize])
95
+ def resources(name, id: :id, path: nil, paths: {}, callbacks: [], before: [], after: [], &block)
96
+ @nested_resources ||= []
97
+ @nested_resources.push(name)
75
98
 
76
- get_const = ->(type, action) do
77
- if Object.const_defined?("#{type}::#{@resource_namespace.join('::')}::#{action}")
78
- Object.const_get("#{type}::#{@resource_namespace.join('::')}::#{action}")
79
- end
99
+ infer_action_const = lambda do |action|
100
+ scope_parts = @router.not_empty_scopes
101
+ .map(&:to_s)
102
+ .reject { |s| s.start_with?(':') }
103
+ .map(&:capitalize)
104
+
105
+ parts = ['Actions'] + scope_parts + [name.to_s.capitalize, action]
106
+ const_path = parts.join('::')
107
+
108
+ Object.const_get(const_path) if Object.const_defined?(const_path)
109
+ end
110
+
111
+ infer_assign_const = lambda do
112
+ parts = @nested_resources.map { |s| s.to_s.capitalize }
113
+ const_path = "Callbacks::#{parts.join('::')}::Assign"
114
+ Object.const_get(const_path) if Object.const_defined?(const_path)
80
115
  end
81
116
 
82
117
  actions = {
83
- index: { method: :get, path: nil, action: get_const.call('Actions', 'Index') },
84
- new: { method: :get, path: 'new', action: get_const.call('Actions', 'New') },
85
- create: { method: :post, path: nil, action: get_const.call('Actions', 'Create') },
118
+ index: { method: :get, path: nil, action: infer_action_const.call('Index') },
119
+ new: { method: :get, path: 'new', action: infer_action_const.call('New') },
120
+ create: { method: :post, path: nil, action: infer_action_const.call('Create') }
86
121
  }
87
122
 
88
123
  actions_for_id = {
89
- show: { method: :get, path: nil, action: get_const.call('Actions', 'Show') },
90
- edit: { method: :get, path: "edit", action: get_const.call('Actions', 'Edit') },
91
- update: { method: :put, path: nil, action: get_const.call('Actions', 'Update') },
92
- delete: { method: :delete, path: nil, action: get_const.call('Actions', 'Delete') }
124
+ show: { method: :get, path: nil, action: infer_action_const.call('Show') },
125
+ edit: { method: :get, path: 'edit', action: infer_action_const.call('Edit') },
126
+ update: { method: :put, path: nil, action: infer_action_const.call('Update') },
127
+ delete: { method: :delete, path: nil, action: infer_action_const.call('Delete') }
93
128
  }
94
129
 
130
+ received_callbacks = Hash.new { |h, k| h[k] = { before: [], after: [] } }
131
+ (callbacks || []).each do |callback_config|
132
+ ensure_array(callback_config[:actions]).each do |action|
133
+ received_callbacks[action][:before].concat(ensure_array(callback_config[:before]))
134
+ received_callbacks[action][:after].concat(ensure_array(callback_config[:after]))
135
+ end
136
+ end
137
+
138
+ (paths || {}).each do |action, new_path|
139
+ if actions[action]
140
+ actions[action][:path] = new_path
141
+ elsif actions_for_id[action]
142
+ actions_for_id[action][:path] = new_path
143
+ end
144
+ end
145
+
95
146
  block_for_id = proc do
96
- actions_for_id.each do |_, definition|
97
- send(definition[:method], definition[:path], definition[:action]) if definition[:action]
147
+ actions_for_id.each do |action_name, definition|
148
+ next unless definition[:action]
149
+
150
+ action_callbacks = received_callbacks[action_name]
151
+ send(
152
+ definition[:method],
153
+ definition[:path],
154
+ definition[:action],
155
+ before: action_callbacks[:before],
156
+ after: action_callbacks[:after]
157
+ )
98
158
  end
99
159
 
100
160
  instance_eval(&block) if block_given?
101
161
  end
102
162
 
103
- scope(name.to_s, before:, after:) do
104
- actions.each do |_, definition|
105
- send(definition[:method], definition[:path], definition[:action]) if definition[:action]
163
+ scope_name = path || name.to_s
164
+ assign_callback = infer_assign_const.call
165
+
166
+ scope(scope_name, before:, after:) do
167
+ actions.each do |action_name, definition|
168
+ next unless definition[:action]
169
+
170
+ action_callbacks = received_callbacks[action_name]
171
+ send(
172
+ definition[:method],
173
+ definition[:path],
174
+ definition[:action],
175
+ before: action_callbacks[:before],
176
+ after: action_callbacks[:after]
177
+ )
106
178
  end
107
179
 
108
- assign_callback = get_const.call('Callbacks', 'Assign')
109
180
  if assign_callback
110
181
  scope(id.to_sym, before: assign_callback, &block_for_id)
111
182
  else
@@ -113,7 +184,7 @@ class Rackr
113
184
  end
114
185
  end
115
186
 
116
- @resource_namespace = @resource_namespace.first(@resource_namespace.size - 1)
187
+ @nested_resources.pop
117
188
  end
118
189
 
119
190
  HTTP_METHODS.each do |http_method|
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rackr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.64
4
+ version: 0.0.67
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrique F. Teixeira
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-12-07 00:00:00.000000000 Z
10
+ date: 2026-01-05 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: erubi
@@ -58,7 +57,7 @@ dependencies:
58
57
  - - "<"
59
58
  - !ruby/object:Gem::Version
60
59
  version: '4.0'
61
- description: A complete, simple and easy web micro-framework.
60
+ description: A friendly web micro-framework.
62
61
  email: hriqueft@gmail.com
63
62
  executables: []
64
63
  extensions: []
@@ -69,14 +68,17 @@ files:
69
68
  - lib/rackr/callback.rb
70
69
  - lib/rackr/router.rb
71
70
  - lib/rackr/router/build_request.rb
71
+ - lib/rackr/router/dev_html/dump.rb
72
+ - lib/rackr/router/dev_html/errors.rb
73
+ - lib/rackr/router/endpoint.rb
72
74
  - lib/rackr/router/errors.rb
73
- - lib/rackr/router/errors/dev_html.rb
75
+ - lib/rackr/router/path_route.rb
74
76
  - lib/rackr/router/route.rb
77
+ - lib/rackr/utils.rb
75
78
  homepage: https://github.com/henrique-ft/rackr
76
79
  licenses:
77
80
  - MIT
78
81
  metadata: {}
79
- post_install_message:
80
82
  rdoc_options: []
81
83
  require_paths:
82
84
  - lib
@@ -91,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
93
  - !ruby/object:Gem::Version
92
94
  version: '0'
93
95
  requirements: []
94
- rubygems_version: 3.3.3
95
- signing_key:
96
+ rubygems_version: 3.6.6
96
97
  specification_version: 4
97
- summary: A complete, simple and easy web micro-framework.
98
+ summary: A friendly web micro-framework.
98
99
  test_files: []