wallaby-core 0.3.0.beta1 → 0.3.0
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.
- checksums.yaml +4 -4
- data/app/security/ability.rb +1 -1
- data/config/routes.rb +38 -24
- data/lib/adaptors/wallaby/custom/model_decorator.rb +3 -3
- data/lib/concerns/wallaby/configurable.rb +1 -1
- data/lib/concerns/wallaby/decoratable.rb +10 -5
- data/lib/decorators/wallaby/resource_decorator.rb +19 -0
- data/lib/helpers/wallaby/links_helper.rb +8 -8
- data/lib/interfaces/wallaby/model_decorator.rb +12 -11
- data/lib/responders/wallaby/resources_responder.rb +3 -1
- data/lib/routes/wallaby/id_regexp.rb +29 -0
- data/lib/routes/wallaby/lazy_regexp.rb +24 -0
- data/lib/routes/wallaby/resources_regexp.rb +26 -0
- data/lib/routes/wallaby/resources_router.rb +1 -1
- data/lib/services/wallaby/map/mode_mapper.rb +1 -1
- data/lib/utils/wallaby/inflector.rb +1 -1
- data/lib/wallaby/classifier.rb +16 -8
- data/lib/wallaby/configuration.rb +4 -0
- data/lib/wallaby/core/version.rb +1 -1
- data/lib/wallaby/core.rb +3 -0
- data/lib/wallaby/engine.rb +1 -1
- data/lib/wallaby/map.rb +12 -0
- data/lib/wallaby/preloader.rb +5 -2
- metadata +24 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78bd6d5518f084f9d968a6e880148186171a5d9e57155750d695c50a6cf40b70
|
4
|
+
data.tar.gz: b61387cb2a538b3befff1646adfdf2b9c207585b9bc0f4a42f56bb5e34465820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce828c53a527a2dae0fe51aeb81e1a95d3282242f7b324de4f87542a6c670f90938612e0c263677cb3f2d68287fa182081a4a931762886d22467cdde0ec99d05
|
7
|
+
data.tar.gz: 5a18a775749c109e769d285d09d188c49f370faf13bde75e3a0ca7626ec31b95060b35fa5d4fd3a44b7438d433ca9f56b5b7966aa3bcbc01b43ae7d7256ef21a
|
data/app/security/ability.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# @!visibility private
|
4
|
-
#
|
4
|
+
# Default ability for {Wallaby}
|
5
5
|
# If main app has defined `ability.rb`, this file will not be loaded/used.
|
6
6
|
class Ability
|
7
7
|
include ::CanCan::Ability if defined?(::CanCan)
|
data/config/routes.rb
CHANGED
@@ -5,42 +5,56 @@ Wallaby::Engine.routes.draw do
|
|
5
5
|
# @see Wallaby::ApplicationConcern#healthy
|
6
6
|
get 'status', to: 'wallaby/resources#healthy'
|
7
7
|
|
8
|
-
with_options to: Wallaby::ResourcesRouter.new do
|
8
|
+
with_options to: Wallaby::ResourcesRouter.new do
|
9
9
|
# @see Wallaby::ResourcesConcern#home
|
10
|
-
|
10
|
+
root defaults: { action: 'home' }
|
11
11
|
|
12
12
|
# Error pages for all supported HTTP status in {Wallaby::ERRORS}
|
13
13
|
Wallaby::ERRORS.each do |status|
|
14
14
|
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[status]
|
15
|
-
|
16
|
-
|
15
|
+
get status, defaults: { action: status.to_s }
|
16
|
+
get code.to_s, defaults: { action: status.to_s }
|
17
17
|
end
|
18
18
|
|
19
19
|
# resourceful routes.
|
20
20
|
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# `*resources` param here will be converted to the model class
|
22
|
+
# used in the controller that [Wallaby::ResourcesRouter] dispatches to.
|
23
|
+
# For instance, `"order/items"` will become `Order::Item` later,
|
23
24
|
# and `Order::Item` will be used by servicer/authorizer/paginator through out the whole request process.
|
24
25
|
#
|
25
|
-
# Using colons in the `:resources` param e.g. `"order::items"` instead of `"order/items"` is
|
26
|
-
# to make nested namespace possible to be handled by these dynamic routes.
|
27
26
|
# @see Wallaby::ResourcesRouter
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
27
|
+
constraints = {
|
28
|
+
id: Wallaby::LazyRegexp.new(:id_regexp),
|
29
|
+
resources: Wallaby::LazyRegexp.new(:resources_regexp)
|
30
|
+
}
|
31
|
+
|
32
|
+
scope path: '*resources' do
|
33
|
+
with_options(constraints: constraints) do
|
34
|
+
# NOTE: DO NOT change the order of the following routes!!!
|
35
|
+
|
36
|
+
# Exact match for `*resources/new`
|
37
|
+
# @see Wallaby::ResourcesConcern#new
|
38
|
+
get 'new', defaults: { action: 'new' }, as: :new_resource
|
39
|
+
|
40
|
+
# Match `*resources`
|
41
|
+
# `''` needs to be before `':id'` so that the resourcesful route will match `orders/items` with:
|
42
|
+
# `resources: 'orders/items'` instead of `resources: 'orders', id: 'items'`
|
43
|
+
# @see Wallaby::ResourcesConcern#index
|
44
|
+
get '', defaults: { action: 'index' }, as: :resources
|
45
|
+
# @see Wallaby::ResourcesConcern#create
|
46
|
+
post '', defaults: { action: 'create' }
|
47
|
+
|
48
|
+
# Match `*resources/:id`
|
49
|
+
# @see Wallaby::ResourcesConcern#edit
|
50
|
+
get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
|
51
|
+
# @see Wallaby::ResourcesConcern#show
|
52
|
+
get ':id', defaults: { action: 'show' }, as: :resource
|
53
|
+
# @see Wallaby::ResourcesConcern#update
|
54
|
+
match ':id', via: %i[patch put], defaults: { action: 'update' }
|
55
|
+
# @see Wallaby::ResourcesConcern#destroy
|
56
|
+
delete ':id', defaults: { action: 'destroy' }
|
57
|
+
end
|
44
58
|
end
|
45
59
|
end
|
46
60
|
end
|
@@ -9,9 +9,9 @@ module Wallaby
|
|
9
9
|
def fields
|
10
10
|
@fields ||=
|
11
11
|
::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
|
12
|
-
methods = model_class.public_instance_methods
|
12
|
+
methods = model_class.public_instance_methods.map(&:to_s)
|
13
13
|
methods
|
14
|
-
.grep(/[
|
14
|
+
.grep(/(\A[^!=]|[^!=]\Z)/).select { |method_id| methods.include? "#{method_id}=" }
|
15
15
|
.each { |attribute| hash[attribute] = { label: attribute.humanize, type: 'string' } }
|
16
16
|
end.freeze
|
17
17
|
end
|
@@ -45,7 +45,7 @@ module Wallaby
|
|
45
45
|
|
46
46
|
# @return [String, Symbole] default to `:id`
|
47
47
|
def primary_key
|
48
|
-
@primary_key ||= :id
|
48
|
+
@primary_key ||= fields.key?(:id) ? :id : fields.keys.first.try(:to_sym)
|
49
49
|
end
|
50
50
|
|
51
51
|
# @param resource [Object]
|
@@ -23,11 +23,7 @@ module Wallaby
|
|
23
23
|
# @return [ResourceDecorator] current resource decorator for this request
|
24
24
|
def current_decorator
|
25
25
|
@current_decorator ||=
|
26
|
-
|
27
|
-
script_name: script_name,
|
28
|
-
model_class: current_model_class,
|
29
|
-
current_controller_class: wallaby_controller
|
30
|
-
).execute.tap do |decorator|
|
26
|
+
decorator_of(current_model_class).tap do |decorator|
|
31
27
|
Logger.debug %(Current decorator: #{decorator}), sourcing: false
|
32
28
|
end
|
33
29
|
end
|
@@ -39,6 +35,15 @@ module Wallaby
|
|
39
35
|
current_model_decorator.try(:"#{action_name}_fields")
|
40
36
|
end
|
41
37
|
|
38
|
+
# Get the decorator of a klass
|
39
|
+
def decorator_of(klass)
|
40
|
+
DecoratorFinder.new(
|
41
|
+
script_name: script_name,
|
42
|
+
model_class: klass,
|
43
|
+
current_controller_class: wallaby_controller
|
44
|
+
).execute
|
45
|
+
end
|
46
|
+
|
42
47
|
# Wrap resource(s) with decorator(s).
|
43
48
|
# @param resource [Object, Enumerable]
|
44
49
|
# @return [ResourceDecorator, Enumerable<Wallaby::ResourceDecorator>] decorator(s)
|
@@ -99,6 +99,13 @@ module Wallaby
|
|
99
99
|
@h ||= superclass.try(:h) || ResourcesController.helpers
|
100
100
|
end
|
101
101
|
|
102
|
+
# @!attribute [w] readonly
|
103
|
+
attr_writer :readonly
|
104
|
+
|
105
|
+
def readonly?
|
106
|
+
@readonly
|
107
|
+
end
|
108
|
+
|
102
109
|
# Delegate missing method to {.model_decorator}
|
103
110
|
def method_missing(method_id, *args, &block)
|
104
111
|
return if ModelDecorator::MISSING_METHODS_RELATED_TO_FIELDS.match?(method_id.to_s) && model_decorator.blank?
|
@@ -179,6 +186,12 @@ module Wallaby
|
|
179
186
|
resource.try(:model_name) || ActiveModel::Name.new(model_class)
|
180
187
|
end
|
181
188
|
|
189
|
+
# @see https://github.com/rails/rails/compare/v7.0.2.4..7-0-stable#diff-44b94eca66c7497711821a8e6bcdfde4684bb7b8efa15e64da6532449f03ef0bR441
|
190
|
+
# @note This overwritten method is a response to the above change
|
191
|
+
def to_model
|
192
|
+
self
|
193
|
+
end
|
194
|
+
|
182
195
|
# @note this method is for the Rails form helper methods to recognize non-ActiveModel models
|
183
196
|
# @return [nil] if no primary key
|
184
197
|
# @return [Array<String>] primary key
|
@@ -187,6 +200,12 @@ module Wallaby
|
|
187
200
|
key ? [key] : nil
|
188
201
|
end
|
189
202
|
|
203
|
+
# @return [true, false] if resource responds to method `.readonly?`
|
204
|
+
# @return [false] otherwise
|
205
|
+
def readonly?
|
206
|
+
resource.try(:readonly?) || self.class.try(:readonly?)
|
207
|
+
end
|
208
|
+
|
190
209
|
# Delegate missing method to {#resource}
|
191
210
|
def method_missing(method_id, *args, &block)
|
192
211
|
if resource.respond_to?(method_id)
|
@@ -15,7 +15,7 @@ module Wallaby
|
|
15
15
|
# @return [String] anchor link to index page for a given model class
|
16
16
|
# @return [nil] if user's not authorized
|
17
17
|
def index_link(model_class, options: {}, url_params: {}, html_options: {}, &block)
|
18
|
-
return if unauthorized?
|
18
|
+
return if unauthorized?(:index, model_class)
|
19
19
|
|
20
20
|
html_options, block = LinkOptionsNormalizer.normalize(
|
21
21
|
html_options, block,
|
@@ -38,7 +38,7 @@ module Wallaby
|
|
38
38
|
# @return [String, nil] anchor element
|
39
39
|
# @return [nil] if user's not authorized
|
40
40
|
def new_link(model_class, options: {}, url_params: {}, html_options: {}, &block)
|
41
|
-
return if unauthorized?
|
41
|
+
return if unauthorized?(:new, model_class) || decorator_of(model_class).readonly?
|
42
42
|
|
43
43
|
html_options, block = LinkOptionsNormalizer.normalize(
|
44
44
|
html_options, block,
|
@@ -73,9 +73,9 @@ module Wallaby
|
|
73
73
|
)
|
74
74
|
|
75
75
|
default = (options[:readonly] && block.call) || nil
|
76
|
-
return default if unauthorized?
|
76
|
+
return default if unauthorized?(:show, extract(resource))
|
77
77
|
|
78
|
-
url = options[:url] || show_path(resource, url_params: url_params)
|
78
|
+
url = options[:url] || show_path(resource.itself, url_params: url_params)
|
79
79
|
link_to url, html_options, &block
|
80
80
|
end
|
81
81
|
|
@@ -100,9 +100,9 @@ module Wallaby
|
|
100
100
|
)
|
101
101
|
|
102
102
|
default = (options[:readonly] && block.call) || nil
|
103
|
-
return default if unauthorized?
|
103
|
+
return default if unauthorized?(:edit, extract(resource)) || resource.try(:readonly?)
|
104
104
|
|
105
|
-
url = options[:url] || edit_path(resource, url_params: url_params)
|
105
|
+
url = options[:url] || edit_path(resource.itself, url_params: url_params)
|
106
106
|
link_to url, html_options, &block
|
107
107
|
end
|
108
108
|
|
@@ -119,7 +119,7 @@ module Wallaby
|
|
119
119
|
# @return [String, nil] anchor element
|
120
120
|
# @return [nil] if user's not authorized
|
121
121
|
def delete_link(resource, options: {}, url_params: {}, html_options: {}, &block)
|
122
|
-
return if unauthorized?
|
122
|
+
return if unauthorized?(:destroy, extract(resource)) || resource.try(:readonly?)
|
123
123
|
|
124
124
|
html_options, block = LinkOptionsNormalizer.normalize(
|
125
125
|
html_options, block, class: 'resource__destroy', block: -> { wt 'links.delete' }
|
@@ -128,7 +128,7 @@ module Wallaby
|
|
128
128
|
html_options[:method] ||= :delete
|
129
129
|
(html_options[:data] ||= {})[:confirm] ||= wt 'links.confirm.delete'
|
130
130
|
|
131
|
-
url = options[:url] || show_path(resource, url_params: url_params)
|
131
|
+
url = options[:url] || show_path(resource.itself, url_params: url_params)
|
132
132
|
link_to url, html_options, &block
|
133
133
|
end
|
134
134
|
|
@@ -7,7 +7,7 @@ module Wallaby
|
|
7
7
|
include Fieldable
|
8
8
|
|
9
9
|
MISSING_METHODS_RELATED_TO_FIELDS =
|
10
|
-
/\A(?<
|
10
|
+
/\A(?<method_prefix>[a-zA-Z]\w*_)(?<method_suffix>fields=?|field_names=?|metadata_of|label_of|type_of)\Z/.freeze
|
11
11
|
|
12
12
|
# Initialize with model class
|
13
13
|
# @param model_class [Class]
|
@@ -123,7 +123,7 @@ module Wallaby
|
|
123
123
|
return super unless method_name.match?(MISSING_METHODS_RELATED_TO_FIELDS)
|
124
124
|
|
125
125
|
matched = MISSING_METHODS_RELATED_TO_FIELDS.match(method_name)
|
126
|
-
try("prefix_#{matched[:
|
126
|
+
try("prefix_#{matched[:method_suffix]}", *args, matched[:method_prefix], &block)
|
127
127
|
end
|
128
128
|
|
129
129
|
# Check if method looks like: `_fields`, `_field_names` that can be processed by {Fieldable}
|
@@ -150,19 +150,20 @@ module Wallaby
|
|
150
150
|
# @return [String, Symbol] type
|
151
151
|
# @raise [ArgumentError] when type is nil
|
152
152
|
def ensure_type_is_present(field_name, type, prefix = '')
|
153
|
-
type || raise(::ArgumentError, <<~INSTRUCTION
|
154
|
-
The
|
155
|
-
The possible causes are:
|
153
|
+
type || raise(::ArgumentError, <<~INSTRUCTION)
|
154
|
+
The field `#{field_name}` is missing its type definition. Potential causes include:
|
156
155
|
|
157
|
-
1. Check type
|
158
|
-
If it is
|
156
|
+
1. Check the type value from the metadata `#{prefix}fields[:#{field_name}][:type]`.
|
157
|
+
If it is absent, specify the type as shown in the example below:
|
159
158
|
|
160
|
-
#{prefix}fields[:#{field_name}][:type] = 'string'
|
159
|
+
#{prefix}fields[:#{field_name}][:type] = 'string' # or the specified type
|
161
160
|
|
162
|
-
2. If metadata `#{prefix}
|
163
|
-
|
161
|
+
2. If the metadata `#{prefix}fields[:#{field_name}]` is empty, the field may not exist.
|
162
|
+
Search for `index_field_names` and `#{field_name}` to determine if `#{field_name}` is inserted elsewhere.
|
163
|
+
|
164
|
+
3. If the metadata `#{prefix}fields` is empty, the table may not have been created yet,
|
165
|
+
or there may be an error in the decorator class declaration.
|
164
166
|
INSTRUCTION
|
165
|
-
)
|
166
167
|
end
|
167
168
|
end
|
168
169
|
end
|
@@ -17,7 +17,9 @@ module Wallaby
|
|
17
17
|
|
18
18
|
# @return [String] file name with export timestamp
|
19
19
|
def file_name_to_export
|
20
|
-
timestamp = Time.zone.now.
|
20
|
+
timestamp = Time.zone.now.try do |t|
|
21
|
+
t.respond_to?(:to_fs) ? t.to_fs(:number) : t.to_s(:number)
|
22
|
+
end
|
21
23
|
filename =
|
22
24
|
(request.params[:resources] || controller.controller_path)
|
23
25
|
.gsub(/#{SLASH}|#{COLONS}/o, HYPHEN)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class IdRegexp < ResourcesRegexp
|
5
|
+
# This method works with {Map.resources_regexp} to complete the constraint restriction in `config/routes.rb`.
|
6
|
+
# This regular expression matches the ids which have all the possible resources names in front
|
7
|
+
#
|
8
|
+
# It looks like `((?<=products/)|(?<=orders/)|(?<=order/items/)|...|(?<!.))[^/]+`:
|
9
|
+
#
|
10
|
+
# - `(?<=products/)` is a positive lookbehind assertion,
|
11
|
+
# it means the ids must have `products/` in front of itself, but the match data won't include `products/`.
|
12
|
+
# it matches string e.g. `/admin/products/1`, and the match data is `1`.
|
13
|
+
# - `(?<!.)` is a negative lookbehind assertion,
|
14
|
+
# it means the ids must have nothing in front of itself.
|
15
|
+
# it matches string e.g. `1`, and the match data is `1`.
|
16
|
+
# this is required for URL helper when `:id` param is given,
|
17
|
+
# e.g. `resources_path(action: 'show', resources: 'products', id: 1)`
|
18
|
+
# - `[^/]+` is to match id. id can be anything as long as it doesn't contain `|` character.
|
19
|
+
def execute
|
20
|
+
Regexp.new(<<~REGEXP, Regexp::EXTENDED)
|
21
|
+
(
|
22
|
+
#{resources_sources.map { |resources| "(?<=#{resources}/)" }.join('|')} # all the possible resources names in front of the id
|
23
|
+
|(?<!.) # nothing is in front of the id, this is needed by URL helpers
|
24
|
+
)
|
25
|
+
[^/]+ # id
|
26
|
+
REGEXP
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# This is designed to delegate all the methods to {#lazy_regexp}
|
5
|
+
# So that it doesn't need to load all the models for {Map.mode_map}
|
6
|
+
# when the engine is mounted in `config/routes.rb`
|
7
|
+
#
|
8
|
+
# @see Map.resources_regexp
|
9
|
+
# @see Map.id_regexp
|
10
|
+
class LazyRegexp < Regexp
|
11
|
+
delegate(*Regexp.instance_methods(false), to: :lazy_regexp)
|
12
|
+
|
13
|
+
def initialize(source, **options)
|
14
|
+
@lazy_source = source
|
15
|
+
super(source.to_s, **options)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def lazy_regexp
|
21
|
+
Map.try(@lazy_source)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class ResourcesRegexp
|
5
|
+
# This method works with {Map.id_regexp} to complete the constraint restriction in `config/routes.rb`.
|
6
|
+
# This regular expression matches all the possible resources names that are loaded from the {.mode_map}
|
7
|
+
#
|
8
|
+
# It looks like `(products|orders|order/items|...)`
|
9
|
+
def execute
|
10
|
+
Regexp.new(<<~REGEXP, Regexp::EXTENDED)
|
11
|
+
(#{resources_sources.join('|')}) # all the possible resources names
|
12
|
+
REGEXP
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def resources_sources
|
18
|
+
# NOTE: `.reverse` is required so that for `order/items`,
|
19
|
+
# `%r{order/items|order}` matches `order/items`, not `order`
|
20
|
+
Map
|
21
|
+
.mode_map
|
22
|
+
.keys.flat_map { |klass| Inflector.to_resources_name(klass.to_s) }
|
23
|
+
.sort.reverse.uniq
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -31,7 +31,7 @@ module Wallaby
|
|
31
31
|
controller_class = find_controller_class_by(options)
|
32
32
|
controller_class.action(options[:action]).call(env)
|
33
33
|
rescue ::AbstractController::ActionNotFound, ModelNotFound => e
|
34
|
-
|
34
|
+
Wallaby::Logger.warn(e, sourcing: 1)
|
35
35
|
default_controller(options).action(:not_found).call(env)
|
36
36
|
rescue UnprocessableEntity => e
|
37
37
|
set_flash_error_for(e, env)
|
@@ -16,7 +16,7 @@ module Wallaby
|
|
16
16
|
next if class_names.blank?
|
17
17
|
|
18
18
|
class_names.each_with_object(hash) do |mode_name, map|
|
19
|
-
mode_name.model_finder.new.all.each do |model_class|
|
19
|
+
mode_name.model_finder.new.all.each do |model_class| # rubocop:disable Rails/FindEach
|
20
20
|
map[model_class] = mode_name
|
21
21
|
end
|
22
22
|
end
|
data/lib/wallaby/classifier.rb
CHANGED
@@ -7,10 +7,10 @@ module Wallaby
|
|
7
7
|
|
8
8
|
# Convert Class to String. If not Class, unchanged.
|
9
9
|
# @param klass [Object]
|
10
|
-
# @return [String] if klass is
|
11
|
-
# @return [
|
10
|
+
# @return [String] if klass is not nil
|
11
|
+
# @return [nil] if klass is nil or klass is an anonymous Class
|
12
12
|
def class_name_of(klass)
|
13
|
-
klass.try(:name)
|
13
|
+
klass.is_a?(Class) ? klass.try(:name) : klass.try(:to_s)
|
14
14
|
end
|
15
15
|
|
16
16
|
# Convert String to Class. If not String, unchanged.
|
@@ -18,13 +18,21 @@ module Wallaby
|
|
18
18
|
# @return [Class] if name is a Class
|
19
19
|
# @return [Object] if name is not a String
|
20
20
|
# @return [nil] if class cannot be found
|
21
|
-
def to_class(name)
|
22
|
-
return name unless name.is_a?
|
21
|
+
def to_class(name, raising: Wallaby.configuration.raise_on_name_error)
|
22
|
+
return name unless name.is_a?(String)
|
23
|
+
# blank string will lead to NameError `wrong constant name`
|
24
|
+
return if name.blank?
|
23
25
|
|
24
|
-
# NOTE: DO NOT try to use const_defined
|
25
|
-
#
|
26
|
+
# NOTE: DO NOT try to use `const_defined?` and `const_get` EVER.
|
27
|
+
# Rails does all the class loading magics using `constantize`
|
26
28
|
name.constantize
|
27
|
-
rescue NameError
|
29
|
+
rescue NameError => e
|
30
|
+
raise if raising
|
31
|
+
|
32
|
+
uninitialized = e.message.start_with?('uninitialized constant')
|
33
|
+
raise unless uninitialized
|
34
|
+
|
35
|
+
# block to handle this missing constant, e.g. use a default class or log useful instruction
|
28
36
|
yield(name) if block_given?
|
29
37
|
end
|
30
38
|
end
|
@@ -6,6 +6,9 @@ module Wallaby
|
|
6
6
|
class Configuration
|
7
7
|
include Classifier
|
8
8
|
|
9
|
+
# @!attribute [w] raise_on_name_error
|
10
|
+
attr_accessor :raise_on_name_error
|
11
|
+
|
9
12
|
# @!attribute [w] logger
|
10
13
|
attr_writer :logger
|
11
14
|
|
@@ -101,6 +104,7 @@ module Wallaby
|
|
101
104
|
Deprecator.alert 'config.models.presence', from: '0.3.0', alternative: <<~INSTRUCTION
|
102
105
|
Please use controller_class.models instead.
|
103
106
|
INSTRUCTION
|
107
|
+
@models ||= Models.new
|
104
108
|
end
|
105
109
|
|
106
110
|
# To globally configure the models that Wallaby should handle.
|
data/lib/wallaby/core/version.rb
CHANGED
data/lib/wallaby/core.rb
CHANGED
@@ -30,6 +30,9 @@ require 'wallaby/map'
|
|
30
30
|
|
31
31
|
require 'support/action_dispatch/routing/mapper'
|
32
32
|
|
33
|
+
require 'routes/wallaby/lazy_regexp'
|
34
|
+
require 'routes/wallaby/resources_regexp'
|
35
|
+
require 'routes/wallaby/id_regexp'
|
33
36
|
require 'routes/wallaby/resources_router'
|
34
37
|
require 'routes/wallaby/engines/base_route'
|
35
38
|
require 'routes/wallaby/engines/engine_route'
|
data/lib/wallaby/engine.rb
CHANGED
@@ -5,7 +5,7 @@ module Wallaby
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
6
|
initializer 'wallaby.development.reload' do |_|
|
7
7
|
# NOTE: Rails reload! will hit here
|
8
|
-
# @see
|
8
|
+
# @see https://rmosolgo.github.io/ruby/rails/2017/04/12/watching-files-during-rails-development.html
|
9
9
|
config.to_prepare do
|
10
10
|
Map.clear if Rails.env.development? || Rails.configuration.eager_load
|
11
11
|
end
|
data/lib/wallaby/map.rb
CHANGED
@@ -90,6 +90,18 @@ module Wallaby
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
class << self
|
94
|
+
# @return [Regexp] regexp to match data for param `:resources`
|
95
|
+
def resources_regexp
|
96
|
+
@resources_regexp ||= ResourcesRegexp.new.execute
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [Regexp] regexp to match data for param `:id`
|
100
|
+
def id_regexp
|
101
|
+
@id_regexp ||= IdRegexp.new.execute
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
93
105
|
class << self
|
94
106
|
# Reset all the instance variables to nil
|
95
107
|
def clear
|
data/lib/wallaby/preloader.rb
CHANGED
@@ -15,7 +15,7 @@ module Wallaby
|
|
15
15
|
# Require models under {Configuration#model_paths}
|
16
16
|
# @see #model_file_paths
|
17
17
|
def require_models
|
18
|
-
new.model_file_paths.each { |path| require_dependency(path) }
|
18
|
+
new.model_file_paths.each { |path| require_dependency(path) } # rubocop:disable Rails/RequireDependency, Lint/RedundantCopDisableDirective
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -30,7 +30,10 @@ module Wallaby
|
|
30
30
|
# @!attribute [r] eager_load_paths
|
31
31
|
# @return [Array<String, Pathname>]
|
32
32
|
def eager_load_paths # :nodoc:
|
33
|
-
@eager_load_paths ||=
|
33
|
+
@eager_load_paths ||=
|
34
|
+
Rails.configuration.paths['app'].expanded
|
35
|
+
.concat(Rails.configuration.eager_load_paths)
|
36
|
+
.uniq
|
34
37
|
end
|
35
38
|
|
36
39
|
# @!attribute [w] model_paths
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wallaby-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
7
|
+
- Tianwen Chen
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -16,40 +16,40 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 6.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 8.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 6.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 8.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: railties
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 6.0.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 8.0.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 6.0.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 8.0.0
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: parslet
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -273,6 +273,9 @@ files:
|
|
273
273
|
- lib/routes/wallaby/engines/base_route.rb
|
274
274
|
- lib/routes/wallaby/engines/custom_app_route.rb
|
275
275
|
- lib/routes/wallaby/engines/engine_route.rb
|
276
|
+
- lib/routes/wallaby/id_regexp.rb
|
277
|
+
- lib/routes/wallaby/lazy_regexp.rb
|
278
|
+
- lib/routes/wallaby/resources_regexp.rb
|
276
279
|
- lib/routes/wallaby/resources_router.rb
|
277
280
|
- lib/servicers/wallaby/model_servicer.rb
|
278
281
|
- lib/services/wallaby/authorizer_finder.rb
|
@@ -323,15 +326,15 @@ files:
|
|
323
326
|
- lib/wallaby/logger.rb
|
324
327
|
- lib/wallaby/map.rb
|
325
328
|
- lib/wallaby/preloader.rb
|
326
|
-
homepage: https://github.com/wallaby-rails/wallaby-core
|
329
|
+
homepage: https://github.com/wallaby-rails/wallaby-rails/blob/main/wallaby-core
|
327
330
|
licenses:
|
328
331
|
- MIT
|
329
332
|
metadata:
|
330
|
-
homepage_uri: https://github.com/wallaby-rails/wallaby-core
|
331
|
-
source_code_uri: https://github.com/wallaby-rails/wallaby-core
|
332
|
-
changelog_uri: https://github.com/wallaby-rails/wallaby-
|
333
|
+
homepage_uri: https://github.com/wallaby-rails/wallaby-rails/blob/main/wallaby-core
|
334
|
+
source_code_uri: https://github.com/wallaby-rails/wallaby-rails/blob/main/wallaby-core
|
335
|
+
changelog_uri: https://github.com/wallaby-rails/wallaby-rails/blob/main/wallaby-core/CHANGELOG.md
|
333
336
|
rubygems_mfa_required: 'true'
|
334
|
-
post_install_message:
|
337
|
+
post_install_message:
|
335
338
|
rdoc_options: []
|
336
339
|
require_paths:
|
337
340
|
- lib
|
@@ -342,12 +345,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
342
345
|
version: '0'
|
343
346
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
344
347
|
requirements:
|
345
|
-
- - "
|
348
|
+
- - ">="
|
346
349
|
- !ruby/object:Gem::Version
|
347
|
-
version:
|
350
|
+
version: '0'
|
348
351
|
requirements: []
|
349
|
-
rubygems_version: 3.
|
350
|
-
signing_key:
|
352
|
+
rubygems_version: 3.5.5
|
353
|
+
signing_key:
|
351
354
|
specification_version: 4
|
352
355
|
summary: The core of Wallaby
|
353
356
|
test_files: []
|