wallaby-core 0.3.0.beta1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac0d0b6d6922e91c8efb73f107bd9565911f7484b56f4cf3790d156e2de64ff9
4
- data.tar.gz: 1217566eccf96b6d26d4bc52e0a44674d8bf3681f0b5d8a3ca8def1f57377743
3
+ metadata.gz: 78bd6d5518f084f9d968a6e880148186171a5d9e57155750d695c50a6cf40b70
4
+ data.tar.gz: b61387cb2a538b3befff1646adfdf2b9c207585b9bc0f4a42f56bb5e34465820
5
5
  SHA512:
6
- metadata.gz: 652027a296d62af1e939591fa866e2fc6fa1a37fc2717e192cf893a02a7ca51ccd862985624fb5d1bedbbc48cfd5e53a9accf491e16b30ea7b09aa2ba2ac1588
7
- data.tar.gz: 3457d4933495eb845198f869cd74c32c6deba85c500bb5d0e07bd8159004fda5bbbc0972f008facf5d04c44136f86b2e5ae09c2daec44934c22ba385316515fc
6
+ metadata.gz: ce828c53a527a2dae0fe51aeb81e1a95d3282242f7b324de4f87542a6c670f90938612e0c263677cb3f2d68287fa182081a4a931762886d22467cdde0ec99d05
7
+ data.tar.gz: 5a18a775749c109e769d285d09d188c49f370faf13bde75e3a0ca7626ec31b95060b35fa5d4fd3a44b7438d433ca9f56b5b7966aa3bcbc01b43ae7d7256ef21a
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @!visibility private
4
- # Defualt ability for {Wallaby}
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 |route|
8
+ with_options to: Wallaby::ResourcesRouter.new do
9
9
  # @see Wallaby::ResourcesConcern#home
10
- route.root defaults: { action: 'home' }
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
- route.get status, defaults: { action: status.to_s }
16
- route.get code.to_s, defaults: { action: status.to_s }
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
- # `:resources` param here will be converted to the model class in the controller.
22
- # For instance, `"order::items"` will become `Order::Item` later,
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
- scope path: ':resources' do
29
- # @see Wallaby::ResourcesConcern#index
30
- route.get '', defaults: { action: 'index' }, as: :resources
31
- # @see Wallaby::ResourcesConcern#new
32
- route.get 'new', defaults: { action: 'new' }, as: :new_resource
33
- # @see Wallaby::ResourcesConcern#edit
34
- route.get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
35
- # @see Wallaby::ResourcesConcern#show
36
- route.get ':id', defaults: { action: 'show' }, as: :resource
37
-
38
- # @see Wallaby::ResourcesConcern#create
39
- route.post '', defaults: { action: 'create' }
40
- # @see Wallaby::ResourcesConcern#update
41
- route.match ':id', via: %i[patch put], defaults: { action: 'update' }
42
- # @see Wallaby::ResourcesConcern#destroy
43
- route.delete ':id', defaults: { action: 'destroy' }
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(false).map(&:to_s)
12
+ methods = model_class.public_instance_methods.map(&:to_s)
13
13
  methods
14
- .grep(/[^=]$/).select { |method_id| methods.include? "#{method_id}=" }
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]
@@ -403,7 +403,7 @@ module Wallaby
403
403
  # Clear all configurations
404
404
  def clear
405
405
  ClassMethods.instance_methods.grep(/=/).each do |name|
406
- instance_variable_set "@#{name[0...-1]}", nil
406
+ instance_variable_set :"@#{name[0...-1]}", nil
407
407
  end
408
408
  end
409
409
  end
@@ -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
- DecoratorFinder.new(
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? :index, model_class
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? :new, model_class
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? :show, extract(resource)
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? :edit, extract(resource)
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? :destroy, extract(resource)
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(?<prefix>[a-zA-Z]\w*_)(?<method_partial>fields=?|field_names=?|metadata_of|label_of|type_of)\Z/.freeze
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[:method_partial]}", *args, matched[:prefix], &block)
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 type for field `#{field_name}` is missing in metadata `#{prefix}_fields`.
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's value from metadata `#{prefix}_fields[:#{field_name}][:type]`.
158
- If it is missing, specify the type as below:
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}_fields` is blank, maybe table hasn't be created yet
163
- or there is some error in the decorator class declaration.
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.to_s(:number)
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
- set_flash_error_for(e, env)
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
@@ -65,7 +65,7 @@ module Wallaby
65
65
  return EMPTY_STRING if name.blank?
66
66
 
67
67
  name = name.to_s unless name.is_a?(String)
68
- name.tableize.gsub(SLASH, COLONS)
68
+ name.tableize
69
69
  end
70
70
 
71
71
  # @param name [Class, String]
@@ -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 a Class
11
- # @return [Object] if klass is not a Class
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) || klass || nil
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? String
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? and const_get EVER.
25
- # This is Rails, use constantize
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.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Wallaby
4
4
  module Core
5
- VERSION = '0.3.0.beta1' # :nodoc:
5
+ VERSION = '0.3.0' # :nodoc:
6
6
  end
7
7
  end
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'
@@ -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 http://rmosolgo.github.io/blog/2017/04/12/watching-files-during-rails-development/
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
@@ -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 ||= Rails.configuration.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.beta1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - Tian Chen
8
- autorequire:
7
+ - Tianwen Chen
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-22 00:00:00.000000000 Z
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: 4.2.0
19
+ version: 6.0.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 7.1.0
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: 4.2.0
29
+ version: 6.0.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 7.1.0
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: 4.2.0
39
+ version: 6.0.0
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: 7.1.0
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: 4.2.0
49
+ version: 6.0.0
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: 7.1.0
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-core/blob/master/CHANGELOG.md
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: 1.3.1
350
+ version: '0'
348
351
  requirements: []
349
- rubygems_version: 3.3.25
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: []