wallaby-core 0.1.2 → 0.2.3

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -13
  3. data/app/controllers/wallaby/resources_controller.rb +15 -374
  4. data/app/security/ability.rb +1 -1
  5. data/config/locales/wallaby.en.yml +92 -128
  6. data/config/locales/wallaby_class.en.yml +2 -23
  7. data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
  8. data/lib/adaptors/wallaby/custom/model_decorator.rb +8 -7
  9. data/lib/adaptors/wallaby/custom/model_finder.rb +3 -2
  10. data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
  11. data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -40
  12. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +30 -24
  13. data/lib/authorizers/wallaby/default_authorization_provider.rb +6 -13
  14. data/lib/authorizers/wallaby/model_authorizer.rb +43 -67
  15. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +21 -30
  16. data/lib/concerns/wallaby/application_concern.rb +110 -0
  17. data/lib/concerns/wallaby/authentication_concern.rb +162 -0
  18. data/lib/concerns/wallaby/authorizable.rb +8 -14
  19. data/lib/concerns/wallaby/baseable.rb +91 -10
  20. data/lib/concerns/wallaby/decoratable.rb +3 -3
  21. data/lib/concerns/wallaby/engineable.rb +1 -1
  22. data/lib/concerns/wallaby/fieldable.rb +4 -4
  23. data/lib/concerns/wallaby/paginatable.rb +3 -3
  24. data/lib/concerns/wallaby/prefixable.rb +21 -0
  25. data/lib/concerns/wallaby/resourcable.rb +4 -35
  26. data/lib/concerns/wallaby/resources_concern.rb +434 -0
  27. data/lib/concerns/wallaby/servicable.rb +4 -10
  28. data/lib/decorators/wallaby/resource_decorator.rb +53 -80
  29. data/lib/errors/wallaby/{cell_handling.rb → class_not_found.rb} +1 -1
  30. data/lib/errors/wallaby/model_not_found.rb +3 -1
  31. data/lib/errors/wallaby/resource_not_found.rb +1 -1
  32. data/lib/helpers/wallaby/application_helper.rb +6 -9
  33. data/lib/helpers/wallaby/form_helper.rb +2 -9
  34. data/lib/helpers/wallaby/index_helper.rb +2 -14
  35. data/lib/helpers/wallaby/links_helper.rb +5 -5
  36. data/lib/helpers/wallaby/resources_helper.rb +3 -7
  37. data/lib/helpers/wallaby/secure_helper.rb +3 -3
  38. data/lib/helpers/wallaby/styling_helper.rb +17 -3
  39. data/lib/interfaces/wallaby/mode.rb +5 -5
  40. data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
  41. data/lib/interfaces/wallaby/model_decorator.rb +15 -3
  42. data/lib/paginators/wallaby/model_paginator.rb +14 -45
  43. data/lib/parsers/wallaby/parser.rb +49 -14
  44. data/lib/routes/wallaby/resources_router.rb +1 -1
  45. data/lib/servicers/wallaby/model_servicer.rb +32 -62
  46. data/lib/services/wallaby/map/mode_mapper.rb +14 -14
  47. data/lib/services/wallaby/map/model_class_collector.rb +2 -2
  48. data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
  49. data/lib/services/wallaby/prefixes_builder.rb +15 -49
  50. data/lib/services/wallaby/type_renderer.rb +3 -13
  51. data/lib/utils/wallaby/locale.rb +53 -0
  52. data/lib/utils/wallaby/model_utils.rb +4 -3
  53. data/lib/utils/wallaby/module_utils.rb +1 -1
  54. data/lib/utils/wallaby/utils.rb +10 -15
  55. data/lib/wallaby/class_array.rb +75 -0
  56. data/lib/wallaby/class_hash.rb +94 -0
  57. data/lib/wallaby/classifier.rb +29 -0
  58. data/lib/wallaby/configuration/mapping.rb +33 -27
  59. data/lib/wallaby/configuration/metadata.rb +1 -1
  60. data/lib/wallaby/configuration/models.rb +5 -9
  61. data/lib/wallaby/configuration/security.rb +6 -3
  62. data/lib/wallaby/configuration/sorting.rb +1 -1
  63. data/lib/wallaby/configuration.rb +31 -2
  64. data/lib/wallaby/constants.rb +10 -8
  65. data/lib/wallaby/core/version.rb +1 -1
  66. data/lib/wallaby/core.rb +21 -16
  67. data/lib/wallaby/engine.rb +9 -20
  68. data/lib/wallaby/logger.rb +35 -0
  69. data/lib/wallaby/map.rb +20 -17
  70. data/lib/wallaby/preloader.rb +77 -0
  71. metadata +48 -22
  72. data/app/controllers/wallaby/application_controller.rb +0 -84
  73. data/app/controllers/wallaby/secure_controller.rb +0 -81
  74. data/lib/concerns/wallaby/rails_overridden_methods.rb +0 -42
  75. data/lib/concerns/wallaby/themeable.rb +0 -40
  76. data/lib/paginators/wallaby/resource_paginator.rb +0 -12
  77. data/lib/renderers/wallaby/cell.rb +0 -137
  78. data/lib/renderers/wallaby/cell_resolver.rb +0 -89
  79. data/lib/renderers/wallaby/custom_lookup_context.rb +0 -64
  80. data/lib/renderers/wallaby/custom_partial_renderer.rb +0 -33
  81. data/lib/renderers/wallaby/custom_renderer.rb +0 -16
  82. data/lib/utils/wallaby/cell_utils.rb +0 -34
  83. data/lib/utils/wallaby/preload_utils.rb +0 -44
@@ -1,137 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # In order to improve the rendering performance, cell is designed as simple partial component.
5
- # @since 5.2.0
6
- class Cell
7
- # @!attribute [r] context
8
- # @return [Object] view context
9
- attr_reader :context
10
-
11
- # @!attribute [r] local_assigns
12
- # @return [Hash] a list of local_assigns containing {#object}, {#field_name}, {#value}, {#metadata} and {#form}
13
- attr_reader :local_assigns
14
-
15
- # @!attribute [r] buffer
16
- # @return [String] output string buffer
17
- attr_reader :buffer
18
-
19
- delegate(*ERB::Util.singleton_methods, to: ERB::Util)
20
-
21
- # @param context [ActionView::Context] view context
22
- # @param local_assigns [Hash] local variables
23
- def initialize(context, local_assigns)
24
- @context = context
25
- @local_assigns = local_assigns
26
- end
27
-
28
- # @!attribute [r] object
29
- # @return [Object] object
30
- def object
31
- local_assigns[:object]
32
- end
33
-
34
- # @!attribute [w] object
35
- def object=(object)
36
- local_assigns[:object] = object
37
- end
38
-
39
- # @!attribute [r] field_name
40
- # @return [String] field name
41
- def field_name
42
- local_assigns[:field_name]
43
- end
44
-
45
- # @!attribute [w] field_name
46
- def field_name=(field_name)
47
- local_assigns[:field_name] = field_name
48
- end
49
-
50
- # @!attribute [r] value
51
- # @return [String] value
52
- def value
53
- local_assigns[:value]
54
- end
55
-
56
- # @!attribute [w] value
57
- def value=(value)
58
- local_assigns[:value] = value
59
- end
60
-
61
- # @!attribute [r] metadata
62
- # @return [String] metadata
63
- def metadata
64
- local_assigns[:metadata]
65
- end
66
-
67
- # @!attribute [w] metadata
68
- def metadata=(metadata)
69
- local_assigns[:metadata] = metadata
70
- end
71
-
72
- # @!attribute [r] form
73
- # @return [ActionView::Helpers::FormBuilder] form object
74
- def form
75
- local_assigns[:form]
76
- end
77
-
78
- # @!attribute [w] form
79
- def form=(form)
80
- local_assigns[:form] = form
81
- end
82
-
83
- # @note this is a template method that can be overridden by subclasses
84
- # Produce output for this cell component.
85
- #
86
- # Please note that the output doesn't include the buffer produced by {#concat}.
87
- # Therefore, use {#render_complete} method instead when the cell is rendered.
88
- def render; end
89
-
90
- # This method produces the complete rendered string including the buffer produced by {#concat}.
91
- # @return [String] output of the cell
92
- def render_complete(&block)
93
- @buffer = EMPTY_STRING.dup # reset buffer before rendering
94
- last_part = render(&block)
95
- @buffer << last_part.to_s
96
- end
97
-
98
- # Append string to output buffer
99
- # @param string [String] string to concat
100
- def concat(string)
101
- (@buffer ||= EMPTY_STRING.dup) << string
102
- end
103
-
104
- # @overload at(name)
105
- # Get view instance variable value
106
- # @example To get view instance variable value
107
- # at('name') # => get value of `@name` from the view
108
- # @param name [String, Symbol] view instance variable name without `@`
109
- # @overload at(name, value)
110
- # Set view instance variable value
111
- # @example To set view instance variable value
112
- # at('name', value) # => set value of `@name` in the view
113
- # @param name [String, Symbol] view instance variable name without `@`
114
- # @param value [object] value
115
- # @return [object] view instance variable value
116
- def at(*args)
117
- raise ArgumentError unless args.length.in? [1, 2]
118
- return context.instance_variable_get :"@#{args.first}" if args.length == 1
119
-
120
- context.instance_variable_set :"@#{args.first}", args.last
121
- end
122
-
123
- private
124
-
125
- # Delegate missing method to {#context}
126
- def method_missing(method_id, *args, &block)
127
- return super unless context.respond_to? method_id
128
-
129
- context.public_send method_id, *args, &block
130
- end
131
-
132
- # Delegate missing method check to {#context}
133
- def respond_to_missing?(method_id, _include_private)
134
- context.respond_to?(method_id) || super
135
- end
136
- end
137
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # Resolver to provide support for cell and partial
5
- # @since 5.2.0
6
- class CellResolver < ActionView::OptimizedFileSystemResolver
7
- # for Rails 5.2 and below
8
- begin
9
- # @note this method is only applicable to Rails 5.2 and below
10
- # A cell query looks like:
11
- #
12
- # ```
13
- # app/views/wallaby/resources/index/integer{_en,}{_html,}.rb
14
- # ```
15
- #
16
- # Wallaby adds it to the front of the whole query as below:
17
- #
18
- # ```
19
- # {app/views/wallaby/resources/index/integer{_en,}{_html,}.rb,
20
- # app/views/wallaby/resources/index/_integer{.en,}{.html,}{.erb,}}
21
- # ```
22
- # @param path [String]
23
- # @param details [Hash]
24
- # see {https://api.rubyonrails.org/classes/ActionView/LookupContext/ViewPaths.html#method-i-detail_args_for
25
- # Detials from ViewPaths}
26
- # @return [String] a path query
27
- def build_query(path, details)
28
- # NOTE: super is impacted by {#escape_entry}
29
- origin = super
30
- file_name = origin[%r{(?<=/\{,_\})[^/\{]+}]
31
- return origin unless file_name
32
-
33
- base_dir = origin.gsub(%r{/[^/]*$}, '')
34
- locales = convert details[:locale]
35
- formats = convert details[:formats]
36
- cell = "#{base_dir}/#{file_name}{#{locales}}{#{formats}}.rb"
37
- "{#{cell},#{origin}}"
38
- end
39
- end
40
-
41
- # for Rails 6 and above
42
- begin
43
- # @note this method is only applicable to Rails 6 and above
44
- # This is to extend the origin functionality to enable to return cell file.
45
- # at highest precedence.
46
- # @param path [String]
47
- # @param details [Hash]
48
- # @return [ActionView::Template] found template
49
- def find_template_paths_from_details(path, details)
50
- details[:handlers].unshift(:rb) if details[:handlers].try(:first) != :rb
51
- super
52
- end
53
-
54
- # @note this method is only applicable to Rails 6 and above
55
- # This is to extend the origin functionality to enable to query cell files.
56
- # @param path [String]
57
- # @param details [Hash]
58
- # @return [Regexp]
59
- def build_regex(path, details)
60
- origin = super.source
61
- Regexp.new(
62
- origin
63
- .gsub(%r{/\{,_\}([^/]+)\z}, '/_?\\1')
64
- .gsub('\\.', '[_\\.]')
65
- .gsub('raw|', 'rb|raw|')
66
- )
67
- end
68
- end
69
-
70
- # This is to extend the origin funcationality to enable the query
71
- # to look for cell files
72
- # @example extend the query
73
- # escape_entry('integer') # => '/{,_}integer'
74
- # @param entry [String]
75
- # @return [String] an escaped and extended query
76
- def escape_entry(entry)
77
- super.gsub(%r{/_([^/]+)\z}, '/{,_}\1')
78
- end
79
-
80
- private
81
-
82
- # @example concat a list of values into a string
83
- # convert(['html', 'csv']) # => '_html,_cvs,'
84
- # @param values [Array<String>]
85
- def convert(values)
86
- (values.map { |v| "_#{v}" } << '').join ','
87
- end
88
- end
89
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # A custom lookup context that uses {Wallaby::CellResolver} to find cell/partial
5
- class CustomLookupContext < ::ActionView::LookupContext
6
- def self.normalize(lookup, details: nil, prefixes: nil)
7
- return lookup if lookup.is_a? self
8
-
9
- CustomLookupContext.new(
10
- lookup.view_paths,
11
- details || lookup.instance_variable_get('@details'),
12
- prefixes || lookup.prefixes
13
- )
14
- end
15
-
16
- # @note for Rails 6 and above
17
- # It overrides the origin method to convert paths to {Wallaby::CellResolver}
18
- # @param paths [Array]
19
- # @return [ActionView::PathSet]
20
- def build_view_paths(paths)
21
- ActionView::PathSet.new Array(paths).map(&method(:convert))
22
- end
23
-
24
- # @note for Rails 5.2 and below
25
- # It overrides the origin method to convert paths to {Wallaby::CellResolver}
26
- # @param paths [Array]
27
- # @return [ActionView::PathSet]
28
- def view_paths=(paths)
29
- @view_paths = build_view_paths paths
30
- end
31
-
32
- # It overrides the oirgin method to call the origin `find_template` and cache the result during a request.
33
- # @param name [String]
34
- # @param prefixes [Array<String>]
35
- # @param partial [Boolean]
36
- # @param keys [Array<String>] keys of local variables
37
- # @param options [Hash]
38
- def find_template(name, prefixes = [], partial = false, keys = [], options = {})
39
- prefixes = [] if partial && name.include?(SLASH) # reset the prefixes if `/` is detected
40
- key = [name, prefixes, partial, keys, options].map(&:inspect).join(SLASH)
41
- cached_lookup[key] ||= super
42
- end
43
-
44
- protected
45
-
46
- # @!attribute [r] cached_lookup
47
- # Cached lookup result
48
- def cached_lookup
49
- @cached_lookup ||= {}
50
- end
51
-
52
- # Convert path to {Wallaby::CellResolver}
53
- # @param path [Object]
54
- # @return [Wallaby::CellResolver]
55
- def convert(path)
56
- case path
57
- when ActionView::OptimizedFileSystemResolver, Pathname, String
58
- CellResolver.new path.to_s
59
- else
60
- path
61
- end
62
- end
63
- end
64
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # Custom partial renderer to provide support for cell rendering
5
- class CustomPartialRenderer < ::ActionView::PartialRenderer
6
- # When a type partial is found, it works as usual.
7
- #
8
- # But when a cell is found, there is an exception {Wallaby::CellHandling} raised. This error will be captured,
9
- # and the cell will be rendered.
10
- # @param context [ActionView::Context]
11
- # @param options [Hash]
12
- # @param block [Proc]
13
- # @return [String] HTML output
14
- def render(context, options, block)
15
- super.try do |rendered|
16
- ModuleUtils.try_to(rendered, :body) || # Rails 6 and above
17
- rendered # Rails 5.2 and below
18
- end
19
- rescue CellHandling => e
20
- CellUtils.render context, e.message, options[:locals], &block
21
- end
22
-
23
- # Override origin method to stop rendering when a cell is found.
24
- # @return [ActionView::Template] partial template
25
- # @raise [Wallaby:::CellHandling] when a cell is found
26
- def find_partial(*)
27
- super.tap do |partial|
28
- cell = CellUtils.find_cell(partial.identifier, partial.inspect)
29
- raise CellHandling, cell if cell
30
- end
31
- end
32
- end
33
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # Custom view renderer to provide support for cell rendering
5
- class CustomRenderer < ::ActionView::Renderer
6
- def initialize(lookup_context)
7
- super CustomLookupContext.normalize(lookup_context)
8
- end
9
-
10
- # @return [String] HTML output
11
- # @see Wallaby::CustomPartialRenderer
12
- def render_partial(context, options, &block) #:nodoc:
13
- CustomPartialRenderer.new(lookup_context).render(context, options, block)
14
- end
15
- end
16
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # Cell utils
5
- module CellUtils
6
- class << self
7
- # Render a cell and produce output
8
- # @param context [ActionView::Context]
9
- # @param file_name [String]
10
- # @param locals [Hash]
11
- # @return [String] output
12
- def render(context, file_name, locals = {}, &block)
13
- snake_class = file_name[%r{(?<=app/views/).+(?=\.rb)}]
14
- cell_class = snake_class.camelize.constantize
15
- Rails.logger.info " Rendered [cell] #{file_name}"
16
- cell_class.new(context, locals).render_complete(&block)
17
- end
18
-
19
- # Check if a partial is a cell or not
20
- # @param partial_path [String]
21
- # @return [true] if partial is a `rb` file
22
- # @return [false] otherwise
23
- def find_cell(*partials)
24
- partials.find { |partial| partial.end_with? '.rb' }
25
- end
26
-
27
- # @param action_name [String, Symbol]
28
- # @return [String, Symbol] action prefix
29
- def to_action_prefix(action_name)
30
- FORM_ACTIONS[action_name] || action_name
31
- end
32
- end
33
- end
34
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wallaby
4
- # Preload utils
5
- module PreloadUtils
6
- class << self
7
- # Preload all files under app folder
8
- def require_all
9
- eager_load_paths.map(&method(:require_one))
10
- end
11
-
12
- # Require files under a load path
13
- # @param load_path [String, Pathname]
14
- # @see https://api.rubyonrails.org/classes/Rails/Engine.html#method-i-eager_load-21 Rails::Engine#eager_load!
15
- def require_one(load_path)
16
- Dir.glob("#{load_path}/**/*.rb").sort.each(&method(:load_class_for))
17
- end
18
-
19
- protected
20
-
21
- # @return [Array<String, Pathname>] a list of sorted eager load paths which lists `app/models`
22
- # at highest precedence
23
- def eager_load_paths
24
- Rails.configuration.eager_load_paths.sort_by do |path|
25
- - path.index(%r{/models$}).to_i
26
- end
27
- end
28
-
29
- # `constantize` is used to make Rails to handle all sort of load errors
30
- #
31
- # NOTE: don't try to use `ActiveSupport::Dependencies::Loadable.require_dependency`.
32
- # As `require_dependency` does not take care all errors raised when class/module is loaded.
33
- # @param file_path [Pathname, String]
34
- def load_class_for(file_path)
35
- module_name = file_path[%r{app/[^/]+/(.+)\.rb}, 1].gsub('/concerns/', '/')
36
- class_name = module_name.camelize
37
- class_name.constantize unless Module.const_defined? class_name
38
- rescue NameError, LoadError => e
39
- Rails.logger.debug " [WALLABY] Preload warning: #{e.message} from #{file_path}"
40
- Rails.logger.debug e.backtrace.slice(0, 5)
41
- end
42
- end
43
- end
44
- end